Browse Source

Update colorpicker component

Add indicator in colorpicker component.
master
TheoryOfNekomata 1 year ago
parent
commit
aa783268eb
4 changed files with 107 additions and 55 deletions
  1. +12
    -11
      TODO.md
  2. +65
    -41
      categories/color/react/src/components/ColorPicker/index.tsx
  3. +3
    -3
      categories/color/react/src/components/Swatch/index.tsx
  4. +27
    -0
      showcases/web-kitchensink-reactnext/src/pages/categories/color/index.tsx

+ 12
- 11
TODO.md View File

@@ -11,7 +11,7 @@
- [X] RadioButton
- [X] RadioTickBox
- Color
- [ ] ColorPicker
- [X] ColorPicker
- [X] Swatch (unify with color picker? Swatch is basically a readonly color picker with click-to-copy behavior)
- Code
- [ ] CodeInput (extract to own package)
@@ -20,6 +20,7 @@
- Formatted
- [X] EmailInput
- [X] PhoneNumberInput
- [X] PatternTextInput
- [X] UrlInput
- Freeform
- [X] MaskedTextInput
@@ -53,24 +54,24 @@
- RichText (extract to own package)
- [ ] RichTextInput
- Temporal
- [ ] Calendar
- [ ] ~~Calendar~~
- [X] DateDropdown
- [ ] DateTimeRangeInput
- [ ] DurationInput
- [ ] MonthInput
- [ ] MonthDayInput
- [ ] ~~DateTimeRangeInput~~
- [ ] ~~DurationInput~~
- [ ] ~~MonthInput~~
- [ ] ~~MonthDayInput~~
- [X] TimeSpinner
- [-] YearMonthInput
- [-] WeekInput
- [ ] YearInput
- [ ] ~~YearInput~~

# Others
- [X] Add `select-none` to input labels, etc.
- [X] Add indicators to components (select, datetime input etc)
- [ ] Add proxies for setting component values
- [ ] formatted/phonenumberinput
- [ ] multichoice/taginput
- [ ] blob/fileselectbox (?)
- [X] Add proxies for setting component values
- [X] formatted/phonenumberinput
- [X] multichoice/taginput
- [X] blob/fileselectbox (?)
- [ ] Test all components!
- [ ] Where to put the "click-to-copy" textboxes? Does `Swatch`
belong to this category?


+ 65
- 41
categories/color/react/src/components/ColorPicker/index.tsx View File

@@ -16,10 +16,10 @@ export const colorPickerPlugin = plugin(({ addComponents }) => {
'padding': '0',
},
'&::-webkit-color-swatch': {
'border': '2px solid black',
'border': '0',
},
'&::-moz-color-swatch': {
'border': '2px solid black',
'border': '0',
},
},
});
@@ -33,57 +33,81 @@ export const ColorPicker = React.forwardRef<
className,
id: idProp,
style,
square = false,
square = false as const,
size = 'medium' as const,
...etcProps
},
forwardedRef,
) => {
return (
<div
) => (
<div
className={clsx(
'inline-block align-center relative ring-secondary/50 rounded overflow-hidden box-border group has-[:disabled]:opacity-50',
'rounded focus-within:ring-4 active:ring-tertiary/50',
{
'w-8': square && size === 'small',
'w-12': square && size === 'medium',
'w-16': square && size === 'large',
},
{
'w-16': !square && size === 'small',
'w-24': !square && size === 'medium',
'w-32': !square && size === 'large',
},
className,
)}
style={style}
>
<span
className={clsx(
'inline-block align-center relative',
{
'w-4': square && size === 'small',
'w-6': square && size === 'medium',
'w-8': square && size === 'large',
},
'block w-full',
{
'w-8': !square && size === 'small',
'w-12': !square && size === 'medium',
'w-16': !square && size === 'large',
'p-[25%]': square,
'p-[12.5%]': !square,
},
className,
)}
style={style}
>
<span
<input
{...etcProps}
className={clsx(
'block w-full',
{
'p-[50%]': square,
'p-[25%]': !square,
},
'color-picker absolute top-0 left-0 w-full h-full overflow-hidden cursor-pointer disabled:cursor-not-allowed',
'focus:outline-0',
)}
ref={forwardedRef}
id={idProp}
type="color"
/>
</span>
<span
className={clsx(
'border-y-4 border-l-4 border-r-2 absolute top-0 left-0 h-full pointer-events-none border-[#000000]',
{
'w-1/2': square,
'w-3/4': !square,
},
)}
/>
<span
className={clsx(
'absolute flex items-center justify-center top-0 right-0 h-full pointer-events-none bg-negative text-primary group-has-[:disabled]:text-primary group-active:text-tertiary group-focus-within:text-secondary',
{
'w-1/2': square,
'w-1/4': !square,
},
)}
>
<svg
className="w-6 h-6 fill-none stroke-current stroke-2 linejoin-round linecap-round"
viewBox="0 0 24 24"
role="presentation"
>
{/* todo add chevron down to picker */}
<input
{...etcProps}
className={clsx(
'color-picker absolute top-0 left-0 w-full h-full overflow-hidden ring-secondary/50 rounded cursor-pointer',
'border-2 border-primary focus:border-secondary active:border-tertiary disabled:border-primary',
'focus:outline-0 focus:ring-4',
'active:ring-tertiary/50',
'disabled:opacity-50 disabled:cursor-not-allowed',
)}
ref={forwardedRef}
id={idProp}
type="color"
/>
</span>
</div>
);
});
<polyline points="6 9 12 15 18 9" />
</svg>
</span>
<span
className="border-2 absolute top-0 left-0 w-full h-full pointer-events-none border-primary group-active:border-tertiary group-has-[:disabled]:border-primary group-focus-within:border-secondary"
/>
</div>
));

ColorPicker.displayName = 'ColorPicker';



+ 3
- 3
categories/color/react/src/components/Swatch/index.tsx View File

@@ -16,10 +16,9 @@ export interface SwatchProps extends Omit<React.HTMLProps<SwatchDerivedElement>,

export const useSwatchControls = () => {
const id = React.useId();
const copyColor: React.ReactEventHandler<SwatchDerivedElement> = React.useCallback((e) => {
const copyColor: React.ReactEventHandler<SwatchDerivedElement> = React.useCallback(async (e) => {
const { value } = e.currentTarget;
// eslint-disable-next-line no-void
void window.navigator.clipboard.writeText(value);
await window.navigator.clipboard.writeText(value);
}, []);
return React.useMemo(() => ({
id,
@@ -68,6 +67,7 @@ export const Swatch = React.forwardRef<SwatchDerivedElement, SwatchProps>(({
title={colorValue}
htmlFor={id}
>
{/* todo border primary */}
<span
className="inline-block w-5 h-5 align-middle border border-[#ffffff]"
>


+ 27
- 0
showcases/web-kitchensink-reactnext/src/pages/categories/color/index.tsx View File

@@ -2,6 +2,7 @@ import {NextPage} from 'next';
import {DefaultLayout} from '@/components/DefaultLayout';
import {Section, Subsection} from '@/components/Section';
import * as Color from '@tesseract-design/web-color-react';
import { TextInput } from '@tesseract-design/web-freeform-react';

const ColorPage: NextPage = () => {
return (
@@ -55,6 +56,32 @@ const ColorPage: NextPage = () => {
disabled
/>
</Subsection>
<Subsection title="Copy on select">
<Color.ColorPicker
size="small"
defaultValue="#ff0000"
copyOnSelect
readOnly
/>
<Color.ColorPicker
size="medium"
defaultValue="#00ff00"
copyOnSelect
readOnly
/>
<Color.ColorPicker
size="large"
defaultValue="#0000ff"
copyOnSelect
readOnly
/>
<div>
<TextInput
label="Color"
border
/>
</div>
</Subsection>
</Section>
</DefaultLayout>
)


Loading…
Cancel
Save