diff --git a/starters/tailwind/.gitignore b/starters/tailwind/.gitignore index fbf3418d3a7..20687473be0 100644 --- a/starters/tailwind/.gitignore +++ b/starters/tailwind/.gitignore @@ -1,3 +1 @@ -src -stories storybook-static diff --git a/starters/tailwind/src/ColorArea.tsx b/starters/tailwind/src/ColorArea.tsx new file mode 100644 index 00000000000..830d302fc6a --- /dev/null +++ b/starters/tailwind/src/ColorArea.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { + ColorArea as AriaColorArea, + ColorAreaProps as AriaColorAreaProps +} from 'react-aria-components'; +import { composeTailwindRenderProps } from './utils'; +import { ColorThumb } from './ColorThumb'; + +export interface ColorAreaProps extends AriaColorAreaProps {} + +export function ColorArea(props: ColorAreaProps) { + return ( + ({ + ...defaultStyle, + background: isDisabled ? undefined : defaultStyle.background + })}> + + + ); +} diff --git a/starters/tailwind/src/ColorField.tsx b/starters/tailwind/src/ColorField.tsx new file mode 100644 index 00000000000..074f9e6e29d --- /dev/null +++ b/starters/tailwind/src/ColorField.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { + ColorField as AriaColorField, + ColorFieldProps as AriaColorFieldProps, + ValidationResult +} from 'react-aria-components'; +import { tv } from 'tailwind-variants'; +import { Description, FieldError, Input, Label, fieldBorderStyles } from './Field'; +import { composeTailwindRenderProps, focusRing } from './utils'; + +const inputStyles = tv({ + extend: focusRing, + base: 'border-2 rounded-md', + variants: { + isFocused: fieldBorderStyles.variants.isFocusWithin, + ...fieldBorderStyles.variants, + } +}); + +export interface ColorFieldProps extends AriaColorFieldProps { + label?: string; + description?: string; + errorMessage?: string | ((validation: ValidationResult) => string); +} + +export function ColorField( + { label, description, errorMessage, ...props }: ColorFieldProps +) { + return ( + + {label && } + + {description && {description}} + {errorMessage} + + ); +} diff --git a/starters/tailwind/src/ColorPicker.tsx b/starters/tailwind/src/ColorPicker.tsx new file mode 100644 index 00000000000..75e1c063aa5 --- /dev/null +++ b/starters/tailwind/src/ColorPicker.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {Button, ColorPicker as AriaColorPicker, ColorPickerProps as AriaColorPickerProps, DialogTrigger} from 'react-aria-components'; +import {ColorSwatch} from './ColorSwatch'; +import {ColorArea} from './ColorArea'; +import {ColorSlider} from './ColorSlider'; +import {ColorField} from './ColorField'; +import {Dialog} from './Dialog'; +import {Popover} from './Popover'; +import { tv } from 'tailwind-variants'; +import { focusRing } from './utils'; + +const buttonStyles = tv({ + extend: focusRing, + base: 'flex gap-2 items-center cursor-default rounded text-sm text-gray-800 dark:text-gray-200' +}); + +export interface ColorPickerProps extends AriaColorPickerProps { + label?: string; + children?: React.ReactNode; +} + +export function ColorPicker({ label, children, ...props }: ColorPickerProps) { + return ( + + + + + + {children || ( + <> + + + + + )} + + + + + ); +} diff --git a/starters/tailwind/src/ColorSlider.tsx b/starters/tailwind/src/ColorSlider.tsx new file mode 100644 index 00000000000..38ef6142d59 --- /dev/null +++ b/starters/tailwind/src/ColorSlider.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { + ColorSlider as AriaColorSlider, + ColorSliderProps as AriaColorSliderProps, + SliderOutput, + SliderTrack +} from 'react-aria-components'; +import { tv } from 'tailwind-variants'; +import { Label } from './Field'; +import { composeTailwindRenderProps } from './utils'; +import { ColorThumb } from './ColorThumb'; + +const trackStyles = tv({ + base: 'group col-span-2 orientation-horizontal:h-6 rounded-lg', + variants: { + orientation: { + horizontal: 'w-full h-6', + vertical: 'w-6 h-56 ml-[50%] -translate-x-[50%]' + }, + isDisabled: { + true: 'bg-gray-300 dark:bg-zinc-800 forced-colors:bg-[GrayText]' + } + } +}); + +interface ColorSliderProps extends AriaColorSliderProps { + label?: string; +} + +export function ColorSlider({ label, ...props }: ColorSliderProps) { + return ( + + + + ({ + ...defaultStyle, + background: isDisabled ? undefined : `${defaultStyle.background}, repeating-conic-gradient(#CCC 0% 25%, white 0% 50%) 50% / 16px 16px` + })} + > + + + + ); +} diff --git a/starters/tailwind/src/ColorSwatch.tsx b/starters/tailwind/src/ColorSwatch.tsx new file mode 100644 index 00000000000..8b254a9e508 --- /dev/null +++ b/starters/tailwind/src/ColorSwatch.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import {ColorSwatch as AriaColorSwatch, ColorSwatchProps} from 'react-aria-components'; +import { composeTailwindRenderProps } from './utils'; + +export function ColorSwatch(props: ColorSwatchProps) { + return ( + ({ + background: `linear-gradient(${color}, ${color}), + repeating-conic-gradient(#CCC 0% 25%, white 0% 50%) 50% / 16px 16px` + })} /> + ); +} diff --git a/starters/tailwind/src/ColorSwatchPicker.tsx b/starters/tailwind/src/ColorSwatchPicker.tsx new file mode 100644 index 00000000000..2dc7540e756 --- /dev/null +++ b/starters/tailwind/src/ColorSwatchPicker.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { + ColorSwatchPicker as AriaColorSwatchPicker, + ColorSwatchPickerItem as AriaColorSwatchPickerItem, + ColorSwatchPickerItemProps, + ColorSwatchPickerProps +} from 'react-aria-components'; +import {ColorSwatch} from './ColorSwatch'; +import {composeTailwindRenderProps, focusRing} from './utils'; +import {tv} from 'tailwind-variants'; + +export function ColorSwatchPicker( + { children, ...props }: Omit +) { + return ( + + {children} + + ); +} + +const itemStyles = tv({ + extend: focusRing, + base: 'relative rounded' +}); + +export function ColorSwatchPickerItem(props: ColorSwatchPickerItemProps) { + return ( + + {({isSelected}) => <> + + {isSelected &&
} + } + + ); +} \ No newline at end of file diff --git a/starters/tailwind/src/ColorThumb.tsx b/starters/tailwind/src/ColorThumb.tsx new file mode 100644 index 00000000000..2edd9e42027 --- /dev/null +++ b/starters/tailwind/src/ColorThumb.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import {ColorThumb as AriaColorThumb, ColorThumbProps} from 'react-aria-components'; +import { tv } from 'tailwind-variants'; + +const thumbStyles = tv({ + base: 'w-6 h-6 top-[50%] left-[50%] rounded-full border-2 border-white', + variants: { + isFocusVisible: { + true: 'w-8 h-8' + }, + isDragging: { + true: 'bg-gray-700 dark:bg-gray-300 forced-colors:bg-[ButtonBorder]' + }, + isDisabled: { + true: 'border-gray-300 dark:border-zinc-700 forced-colors:border-[GrayText] bg-gray-300 dark:bg-zinc-800 forced-colors:bg-[GrayText]' + } + } +}); + +export function ColorThumb(props: ColorThumbProps) { + return ( + ({ + ...defaultStyle, + backgroundColor: isDisabled ? undefined : defaultStyle.backgroundColor, + boxShadow: '0 0 0 1px black, inset 0 0 0 1px black'} + )} + className={thumbStyles} /> + ); +} diff --git a/starters/tailwind/src/ColorWheel.tsx b/starters/tailwind/src/ColorWheel.tsx new file mode 100644 index 00000000000..0ab80b85a91 --- /dev/null +++ b/starters/tailwind/src/ColorWheel.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import {ColorWheel as AriaColorWheel, ColorWheelProps as AriaColorWheelProps, ColorWheelTrack} from 'react-aria-components'; +import { ColorThumb } from './ColorThumb'; + +export interface ColorWheelProps extends Omit {} + +export function ColorWheel(props: ColorWheelProps) { + return ( + + ({ + ...defaultStyle, + background: isDisabled ? undefined : `${defaultStyle.background}, repeating-conic-gradient(#CCC 0% 25%, white 0% 50%) 50% / 16px 16px` + })} /> + + + ); +} diff --git a/starters/tailwind/stories/ColorArea.stories.tsx b/starters/tailwind/stories/ColorArea.stories.tsx new file mode 100644 index 00000000000..919115d57fa --- /dev/null +++ b/starters/tailwind/stories/ColorArea.stories.tsx @@ -0,0 +1,16 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorArea } from '../src/ColorArea'; + +const meta: Meta = { + component: ColorArea, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +}; + +export default meta; + +export const Example = (args: any) => ; + diff --git a/starters/tailwind/stories/ColorField.stories.tsx b/starters/tailwind/stories/ColorField.stories.tsx new file mode 100644 index 00000000000..79a812eec0c --- /dev/null +++ b/starters/tailwind/stories/ColorField.stories.tsx @@ -0,0 +1,19 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorField } from '../src/ColorField'; + +const meta: Meta = { + component: ColorField, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'], + args: { + label: 'Color', + defaultValue: '#ff0' + } +}; + +export default meta; + +export const Example = (args: any) => ; diff --git a/starters/tailwind/stories/ColorPicker.stories.tsx b/starters/tailwind/stories/ColorPicker.stories.tsx new file mode 100644 index 00000000000..1a4fc805858 --- /dev/null +++ b/starters/tailwind/stories/ColorPicker.stories.tsx @@ -0,0 +1,19 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorPicker } from '../src/ColorPicker'; + +const meta: Meta = { + component: ColorPicker, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'], + args: { + label: 'Color', + defaultValue: '#ff0' + } +}; + +export default meta; + +export const Example = (args: any) => ; diff --git a/starters/tailwind/stories/ColorSlider.stories.tsx b/starters/tailwind/stories/ColorSlider.stories.tsx new file mode 100644 index 00000000000..49a02e2ab63 --- /dev/null +++ b/starters/tailwind/stories/ColorSlider.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorSlider } from '../src/ColorSlider'; + +const meta: Meta = { + component: ColorSlider, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +}; + +export default meta; + +export const Example = (args: any) => ; + +Example.args = { + label: 'Fill Color', + channel: 'hue', + colorSpace: 'hsl', + defaultValue: '#f00' +}; diff --git a/starters/tailwind/stories/ColorSwatch.stories.tsx b/starters/tailwind/stories/ColorSwatch.stories.tsx new file mode 100644 index 00000000000..e5e6926e9db --- /dev/null +++ b/starters/tailwind/stories/ColorSwatch.stories.tsx @@ -0,0 +1,19 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorSwatch } from '../src/ColorSwatch'; + +const meta: Meta = { + component: ColorSwatch, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +}; + +export default meta; + +export const Example = (args: any) => ; + +Example.args = { + color: '#f00a' +}; diff --git a/starters/tailwind/stories/ColorSwatchPicker.stories.tsx b/starters/tailwind/stories/ColorSwatchPicker.stories.tsx new file mode 100644 index 00000000000..0e77ed236bb --- /dev/null +++ b/starters/tailwind/stories/ColorSwatchPicker.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorSwatchPicker, ColorSwatchPickerItem } from '../src/ColorSwatchPicker'; + +const meta: Meta = { + component: ColorSwatchPicker, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +}; + +export default meta; + +export const Example = (args: any) => ( + + + + + + + + +); diff --git a/starters/tailwind/stories/ColorWheel.stories.tsx b/starters/tailwind/stories/ColorWheel.stories.tsx new file mode 100644 index 00000000000..478c2a75eab --- /dev/null +++ b/starters/tailwind/stories/ColorWheel.stories.tsx @@ -0,0 +1,15 @@ +import type { Meta } from '@storybook/react'; +import React from 'react'; +import { ColorWheel } from '../src/ColorWheel'; + +const meta: Meta = { + component: ColorWheel, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +}; + +export default meta; + +export const Example = (args: any) => ;