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 (
+
+
+
+
+
+
+
+
+ );
+}
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) => ;