diff --git a/package.json b/package.json index bd4478a5a97..faa556d6e6b 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,6 @@ "core-js": "^3.0.0", "cross-env": "^7.0.2", "cross-spawn": "^7.0.3", - "css-parse": "^2.0.0", "delta-e": "^0.0.8", "diff": "^5.1.0", "eslint": "^8.56.0", diff --git a/packages/@adobe/react-spectrum/package.json b/packages/@adobe/react-spectrum/package.json index 3f5292f60fd..b7ab84a4e0e 100644 --- a/packages/@adobe/react-spectrum/package.json +++ b/packages/@adobe/react-spectrum/package.json @@ -51,6 +51,7 @@ "@react-spectrum/buttongroup": "^3.6.15", "@react-spectrum/calendar": "^3.4.11", "@react-spectrum/checkbox": "^3.9.8", + "@react-spectrum/color": "3.0.0-rc.1", "@react-spectrum/combobox": "^3.13.2", "@react-spectrum/contextualhelp": "^3.6.13", "@react-spectrum/datepicker": "^3.10.1", diff --git a/packages/@adobe/react-spectrum/src/index.ts b/packages/@adobe/react-spectrum/src/index.ts index f3aadb62d45..f66569292a0 100644 --- a/packages/@adobe/react-spectrum/src/index.ts +++ b/packages/@adobe/react-spectrum/src/index.ts @@ -23,6 +23,7 @@ export {Avatar} from '@react-spectrum/avatar'; export {ButtonGroup} from '@react-spectrum/buttongroup'; export {Calendar, RangeCalendar} from '@react-spectrum/calendar'; export {Checkbox, CheckboxGroup} from '@react-spectrum/checkbox'; +export {ColorArea, ColorEditor, ColorField, ColorPicker, ColorSlider, ColorSwatch, ColorSwatchPicker, ColorWheel, parseColor, getColorChannels} from '@react-spectrum/color'; export {ComboBox} from '@react-spectrum/combobox'; export {ContextualHelp} from '@react-spectrum/contextualhelp'; export {AlertDialog, Dialog, DialogTrigger, DialogContainer, useDialogContainer} from '@react-spectrum/dialog'; @@ -78,6 +79,7 @@ export type {SpectrumActionButtonProps, SpectrumButtonProps, SpectrumLogicButton export type {SpectrumButtonGroupProps} from '@react-spectrum/buttongroup'; export type {SpectrumCalendarProps, SpectrumRangeCalendarProps} from '@react-spectrum/calendar'; export type {SpectrumCheckboxGroupProps, SpectrumCheckboxProps} from '@react-spectrum/checkbox'; +export type {Color, ColorFormat, ColorSpace, SpectrumColorAreaProps, SpectrumColorEditorProps, SpectrumColorFieldProps, SpectrumColorPickerProps, SpectrumColorSliderProps, SpectrumColorSwatchPickerProps, SpectrumColorSwatchProps, SpectrumColorWheelProps} from '@react-spectrum/color'; export type {SpectrumComboBoxProps} from '@react-spectrum/combobox'; export type {SpectrumContextualHelpProps} from '@react-spectrum/contextualhelp'; export type {DialogContainerValue, SpectrumAlertDialogProps, SpectrumDialogContainerProps, SpectrumDialogProps, SpectrumDialogTriggerProps} from '@react-spectrum/dialog'; diff --git a/packages/@react-spectrum/color/package.json b/packages/@react-spectrum/color/package.json index 21a32999079..b3e956d3582 100644 --- a/packages/@react-spectrum/color/package.json +++ b/packages/@react-spectrum/color/package.json @@ -49,7 +49,7 @@ "@react-spectrum/textfield": "^3.12.3", "@react-spectrum/utils": "^3.11.9", "@react-spectrum/view": "^3.6.12", - "@react-stately/color": "^3.7.1", + "@react-stately/color": "^3.7.2", "@react-types/color": "3.0.0-rc.1", "@react-types/shared": "^3.24.1", "@react-types/textfield": "^3.9.5", diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorArea.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorArea.svg new file mode 100644 index 00000000000..5deb06da3ec --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorArea.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorField.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorField.svg new file mode 100644 index 00000000000..eaee4495cec --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorField.svg @@ -0,0 +1,12 @@ + + + + + Background + + + + + + #ABCDEF + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorPicker.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorPicker.svg new file mode 100644 index 00000000000..1e2ec967d66 --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorPicker.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #ABCDEF + + + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorSlider.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorSlider.svg new file mode 100644 index 00000000000..2c4f66e748d --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorSlider.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorSwatch.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorSwatch.svg new file mode 100644 index 00000000000..2c09c4623dc --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorSwatch.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorSwatchPicker.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorSwatchPicker.svg new file mode 100644 index 00000000000..004cfc637b1 --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorSwatchPicker.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/dev/docs/pages/assets/component-illustrations/ColorWheel.svg b/packages/dev/docs/pages/assets/component-illustrations/ColorWheel.svg new file mode 100644 index 00000000000..c167628aba3 --- /dev/null +++ b/packages/dev/docs/pages/assets/component-illustrations/ColorWheel.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/dev/docs/pages/react-aria/components.mdx b/packages/dev/docs/pages/react-aria/components.mdx index 7e0c376af70..4978fe8f1bf 100644 --- a/packages/dev/docs/pages/react-aria/components.mdx +++ b/packages/dev/docs/pages/react-aria/components.mdx @@ -55,7 +55,14 @@ import Focus from '../assets/component-illustrations/useFocus.svg'; import TagGroup from '../assets/component-illustrations/TagGroup.svg'; import DropZone from '../assets/component-illustrations/DropZone.svg'; import FileTrigger from '../assets/component-illustrations/FileTrigger.svg' -import Form from '../assets/component-illustrations/Form.svg' +import Form from '../assets/component-illustrations/Form.svg'; +import ColorSlider from '../assets/component-illustrations/ColorSlider.svg'; +import ColorWheel from '../assets/component-illustrations/ColorWheel.svg'; +import ColorArea from '../assets/component-illustrations/ColorArea.svg'; +import ColorField from '../assets/component-illustrations/ColorField.svg'; +import ColorSwatch from '../assets/component-illustrations/ColorSwatch.svg'; +import ColorSwatchPicker from '../assets/component-illustrations/ColorSwatchPicker.svg'; +import ColorPicker from '../assets/component-illustrations/ColorPicker.svg'; --- category: Introduction @@ -202,6 +209,61 @@ order: 5 +## Color + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ## Overlays
diff --git a/packages/dev/docs/pages/react-spectrum/index.mdx b/packages/dev/docs/pages/react-spectrum/index.mdx index c3c9f154b49..35ebc3321b5 100644 --- a/packages/dev/docs/pages/react-spectrum/index.mdx +++ b/packages/dev/docs/pages/react-spectrum/index.mdx @@ -69,6 +69,13 @@ import Badge from '../assets/component-illustrations/Badge.svg'; import TagGroup from '../assets/component-illustrations/TagGroup.svg'; import DropZone from '../assets/component-illustrations/DropZone.svg'; import FileTrigger from '../assets/component-illustrations/FileTrigger.svg' +import ColorSlider from '../assets/component-illustrations/ColorSlider.svg'; +import ColorWheel from '../assets/component-illustrations/ColorWheel.svg'; +import ColorArea from '../assets/component-illustrations/ColorArea.svg'; +import ColorField from '../assets/component-illustrations/ColorField.svg'; +import ColorSwatch from '../assets/component-illustrations/ColorSwatch.svg'; +import ColorSwatchPicker from '../assets/component-illustrations/ColorSwatchPicker.svg'; +import ColorPicker from '../assets/component-illustrations/ColorPicker.svg'; --- category: Libraries @@ -274,6 +281,61 @@ A React implementation of Spectrum, Adobe’s design system.
+### Color + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ### Overlays
diff --git a/packages/react-aria-components/docs/ColorArea.mdx b/packages/react-aria-components/docs/ColorArea.mdx index 5c4fd7c0e2d..ad04e318738 100644 --- a/packages/react-aria-components/docs/ColorArea.mdx +++ b/packages/react-aria-components/docs/ColorArea.mdx @@ -28,7 +28,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color area, color picker, aria] type: component -preRelease: beta --- # ColorArea diff --git a/packages/react-aria-components/docs/ColorField.mdx b/packages/react-aria-components/docs/ColorField.mdx index 2d2f6b13b89..760f7604b85 100644 --- a/packages/react-aria-components/docs/ColorField.mdx +++ b/packages/react-aria-components/docs/ColorField.mdx @@ -30,7 +30,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color field, color picker, aria] type: component -preRelease: beta --- # ColorField diff --git a/packages/react-aria-components/docs/ColorPicker.mdx b/packages/react-aria-components/docs/ColorPicker.mdx index eebb7a7d828..c02c0a8d94e 100644 --- a/packages/react-aria-components/docs/ColorPicker.mdx +++ b/packages/react-aria-components/docs/ColorPicker.mdx @@ -21,12 +21,17 @@ import {ExampleList} from '@react-spectrum/docs/src/ExampleList'; import {ExampleCard} from '@react-spectrum/docs/src/ExampleCard'; import {Keyboard} from '@react-spectrum/text'; import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; +import ColorSlider from '@react-spectrum/docs/pages/assets//component-illustrations/ColorSlider.svg'; +import ColorWheel from '@react-spectrum/docs/pages/assets//component-illustrations/ColorWheel.svg'; +import ColorArea from '@react-spectrum/docs/pages/assets//component-illustrations/ColorArea.svg'; +import ColorField from '@react-spectrum/docs/pages/assets//component-illustrations/ColorField.svg'; +import ColorSwatch from '@react-spectrum/docs/pages/assets//component-illustrations/ColorSwatch.svg'; +import ColorSwatchPicker from '@react-spectrum/docs/pages/assets//component-illustrations/ColorSwatchPicker.svg'; --- category: Color keywords: [color picker, aria] type: component -preRelease: beta --- # ColorPicker @@ -138,6 +143,56 @@ import {ColorPicker} from 'react-aria-components'; ``` +### Composed components + +A `ColorPicker` uses the following components, which may also be used standalone or reused in other components. + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ ## Reusable wrappers If you will use a ColorPicker in multiple places in your app, you can wrap all of the pieces into a reusable component. This way, the DOM structure, styling code, and other logic are defined in a single place and reused everywhere to ensure consistency. diff --git a/packages/react-aria-components/docs/ColorSlider.mdx b/packages/react-aria-components/docs/ColorSlider.mdx index 9f9ef85dcfe..8c681173438 100644 --- a/packages/react-aria-components/docs/ColorSlider.mdx +++ b/packages/react-aria-components/docs/ColorSlider.mdx @@ -28,7 +28,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color slider, color picker, aria] type: component -preRelease: beta --- # ColorSlider diff --git a/packages/react-aria-components/docs/ColorSwatch.mdx b/packages/react-aria-components/docs/ColorSwatch.mdx index 5681949e15f..ed7d9bbc8e7 100644 --- a/packages/react-aria-components/docs/ColorSwatch.mdx +++ b/packages/react-aria-components/docs/ColorSwatch.mdx @@ -26,7 +26,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color swatch, color picker, aria] type: component -preRelease: beta --- # ColorSwatch diff --git a/packages/react-aria-components/docs/ColorSwatchPicker.mdx b/packages/react-aria-components/docs/ColorSwatchPicker.mdx index 5461e75c90c..708320f8997 100644 --- a/packages/react-aria-components/docs/ColorSwatchPicker.mdx +++ b/packages/react-aria-components/docs/ColorSwatchPicker.mdx @@ -26,7 +26,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color swatch, color picker, aria] type: component -preRelease: beta --- # ColorSwatchPicker diff --git a/packages/react-aria-components/docs/ColorWheel.mdx b/packages/react-aria-components/docs/ColorWheel.mdx index 1fb2ea090af..ceecc43ae41 100644 --- a/packages/react-aria-components/docs/ColorWheel.mdx +++ b/packages/react-aria-components/docs/ColorWheel.mdx @@ -28,7 +28,6 @@ import {StarterKits} from '@react-spectrum/docs/src/StarterKits'; category: Color keywords: [color wheel, color picker, aria] type: component -preRelease: beta --- # ColorWheel diff --git a/packages/react-aria-components/docs/Tree.mdx b/packages/react-aria-components/docs/Tree.mdx index 01695fe824f..708beebf310 100644 --- a/packages/react-aria-components/docs/Tree.mdx +++ b/packages/react-aria-components/docs/Tree.mdx @@ -32,7 +32,7 @@ preRelease: beta packageData={packageData} componentNames={['UNSTABLE_Tree']} sourceData={[ - {type: 'W3C', url: 'https://www.w3.org/WAI/ARIA/apg/patterns/treeview/'} + {type: 'W3C', url: 'https://www.w3.org/WAI/ARIA/apg/patterns/treegrid/'} ]} /> diff --git a/packages/react-aria/package.json b/packages/react-aria/package.json index 89fa169188b..dfd7e35b731 100644 --- a/packages/react-aria/package.json +++ b/packages/react-aria/package.json @@ -42,6 +42,7 @@ "@react-aria/button": "^3.9.8", "@react-aria/calendar": "^3.5.11", "@react-aria/checkbox": "^3.14.6", + "@react-aria/color": "3.0.0-rc.2", "@react-aria/combobox": "^3.10.3", "@react-aria/datepicker": "^3.11.2", "@react-aria/dialog": "^3.5.17", diff --git a/packages/react-aria/src/index.ts b/packages/react-aria/src/index.ts index 93b4b9bf85a..0a59275fc72 100644 --- a/packages/react-aria/src/index.ts +++ b/packages/react-aria/src/index.ts @@ -14,6 +14,7 @@ export {useBreadcrumbItem, useBreadcrumbs} from '@react-aria/breadcrumbs'; export {useButton, useToggleButton} from '@react-aria/button'; export {useCalendar, useCalendarCell, useCalendarGrid, useRangeCalendar} from '@react-aria/calendar'; export {useCheckbox, useCheckboxGroup, useCheckboxGroupItem} from '@react-aria/checkbox'; +export {useColorArea, useColorChannelField, useColorField, useColorSlider, useColorSwatch, useColorWheel} from '@react-aria/color'; export {useComboBox} from '@react-aria/combobox'; export {useDateField, useDatePicker, useDateRangePicker, useDateSegment, useTimeField} from '@react-aria/datepicker'; export {useDialog} from '@react-aria/dialog'; @@ -50,6 +51,7 @@ export type {AriaBreadcrumbItemProps, AriaBreadcrumbsProps, BreadcrumbItemAria, export type {AriaButtonOptions, AriaButtonProps, AriaToggleButtonProps, ButtonAria} from '@react-aria/button'; export type {AriaCalendarCellProps, AriaCalendarGridProps, AriaCalendarProps, AriaRangeCalendarProps, CalendarAria, CalendarCellAria, CalendarGridAria, CalendarProps, RangeCalendarProps} from '@react-aria/calendar'; export type {AriaCheckboxGroupItemProps, AriaCheckboxGroupProps, AriaCheckboxProps, CheckboxAria, CheckboxGroupAria} from '@react-aria/checkbox'; +export type {AriaColorAreaOptions, AriaColorChannelFieldProps, AriaColorFieldProps, AriaColorSliderOptions, AriaColorSwatchProps, AriaColorWheelOptions, ColorAreaAria, ColorChannelFieldAria, ColorFieldAria, ColorSliderAria, ColorSwatchAria, ColorWheelAria} from '@react-aria/color'; export type {AriaComboBoxOptions, AriaComboBoxProps, ComboBoxAria} from '@react-aria/combobox'; export type {AriaDateFieldProps, AriaDatePickerProps, AriaDateRangePickerProps, AriaTimeFieldProps, DateFieldAria, DatePickerAria, DateRangePickerAria, DateSegmentAria, DateRange, DateValue, TimeValue} from '@react-aria/datepicker'; export type {AriaDialogProps, DialogAria} from '@react-aria/dialog'; diff --git a/packages/react-stately/package.json b/packages/react-stately/package.json index 9d4b3cd5153..1319b243683 100644 --- a/packages/react-stately/package.json +++ b/packages/react-stately/package.json @@ -27,6 +27,7 @@ "@react-stately/calendar": "^3.5.4", "@react-stately/checkbox": "^3.6.8", "@react-stately/collections": "^3.10.9", + "@react-stately/color": "^3.7.2", "@react-stately/combobox": "^3.9.2", "@react-stately/data": "^3.11.6", "@react-stately/datepicker": "^3.10.2", diff --git a/packages/react-stately/src/index.ts b/packages/react-stately/src/index.ts index 698c83d8743..3b234446766 100644 --- a/packages/react-stately/src/index.ts +++ b/packages/react-stately/src/index.ts @@ -12,6 +12,7 @@ export type {CalendarState, CalendarStateOptions, RangeCalendarState, RangeCalendarStateOptions} from '@react-stately/calendar'; export type {CheckboxGroupProps, CheckboxGroupState} from '@react-stately/checkbox'; +export type {Color, ColorAreaProps, ColorAreaState, ColorChannelFieldProps, ColorChannelFieldState, ColorChannelFieldStateOptions, ColorFieldProps, ColorFieldState, ColorPickerProps, ColorPickerState, ColorSliderState, ColorSliderStateOptions, ColorWheelProps, ColorWheelState} from '@react-stately/color'; export type {ComboBoxState, ComboBoxStateOptions} from '@react-stately/combobox'; export type {DateFieldState, DateFieldStateOptions, DatePickerState, DatePickerStateOptions, DateRangePickerState, DateRangePickerStateOptions, DateSegment, SegmentType as DateSegmentType, TimeFieldStateOptions, TimeFieldState} from '@react-stately/datepicker'; export type {DraggableCollectionStateOptions, DraggableCollectionState, DroppableCollectionStateOptions, DroppableCollectionState} from '@react-stately/dnd'; @@ -34,6 +35,7 @@ export type {ItemProps, Key, SectionProps, Collection, Node, Orientation, Disabl export {useCalendarState, useRangeCalendarState} from '@react-stately/calendar'; export {useCheckboxGroupState} from '@react-stately/checkbox'; +export {getColorChannels, parseColor, useColorAreaState, useColorChannelFieldState, useColorFieldState, useColorPickerState, useColorSliderState, useColorWheelState} from '@react-stately/color'; export {useComboBoxState} from '@react-stately/combobox'; export {useDateFieldState, useDatePickerState, useDateRangePickerState, useTimeFieldState} from '@react-stately/datepicker'; export {useDraggableCollectionState, useDroppableCollectionState} from '@react-stately/dnd'; diff --git a/scripts/esm-support/loader.mjs b/scripts/esm-support/loader.mjs index d79acde900e..b8234e092f2 100644 --- a/scripts/esm-support/loader.mjs +++ b/scripts/esm-support/loader.mjs @@ -1,67 +1,25 @@ -import fs from 'node:fs/promises'; -import { fileURLToPath } from 'node:url'; -import { parseArgs } from 'node:util'; - -import parseCSS from 'css-parse'; - -const { values: { loadFullStyles } } = parseArgs({ - options: { - loadFullStyles: { type: 'boolean' }, - }, -}); - export async function resolve(specifier, context, next) { const nextResult = await next(specifier, context); - if (!specifier.endsWith('.css')) return nextResult; + if (!specifier.endsWith('.css')) { + return nextResult; + } return { format: 'css', shortCircuit: true, - url: nextResult.url, + url: nextResult.url }; } export async function load(url, context, next) { - if (context.format !== 'css') return next(url, context); - - const rawSource = '' + await fs.readFile(fileURLToPath(url)); - const parsed = parseCssToObject(rawSource); + if (context.format !== 'css') { + return next(url, context); + } return { format: 'json', shortCircuit: true, - source: JSON.stringify(parsed), + source: '{}' }; } - -function parseCssToObject(rawSource) { - const output = {}; - - for (const rule of parseCSS(rawSource).stylesheet.rules) { - if (rule.selectors) { - let selector = rule['selectors'].at(-1); // Get right-most in the selector rule: `.Bar` in `.Foo > .Bar {…}` - if (selector[0] !== '.') break; // only care about classes - - selector = selector - .substr(1) // Skip the initial `.` - .match(/(\w+)/)[1]; // Get only the classname: `Qux` in `.Qux[type="number"]` - - output[selector] = loadFullStyles - ? getClassStyles(rule['declarations']) - : selector; - } - } - - return output; -} - -function getClassStyles(declarations) { - const styles = {}; - - for (const declaration of declarations) { - styles[declaration['property']] = declaration['value']; - } - - return styles; -} 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) => ; diff --git a/svgo.config.json b/svgo.config.json index 1430a955206..52175dbbd3d 100644 --- a/svgo.config.json +++ b/svgo.config.json @@ -10,6 +10,7 @@ } } } - } + }, + "prefixIds" ] } diff --git a/yarn.lock b/yarn.lock index c233f35de05..a663a65845e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -79,6 +79,7 @@ __metadata: "@react-spectrum/buttongroup": "npm:^3.6.15" "@react-spectrum/calendar": "npm:^3.4.11" "@react-spectrum/checkbox": "npm:^3.9.8" + "@react-spectrum/color": "npm:3.0.0-rc.1" "@react-spectrum/combobox": "npm:^3.13.2" "@react-spectrum/contextualhelp": "npm:^3.6.13" "@react-spectrum/datepicker": "npm:^3.10.1" @@ -6838,7 +6839,7 @@ __metadata: languageName: unknown linkType: soft -"@react-spectrum/color@workspace:packages/@react-spectrum/color": +"@react-spectrum/color@npm:3.0.0-rc.1, @react-spectrum/color@workspace:packages/@react-spectrum/color": version: 0.0.0-use.local resolution: "@react-spectrum/color@workspace:packages/@react-spectrum/color" dependencies: @@ -6857,7 +6858,7 @@ __metadata: "@react-spectrum/textfield": "npm:^3.12.3" "@react-spectrum/utils": "npm:^3.11.9" "@react-spectrum/view": "npm:^3.6.12" - "@react-stately/color": "npm:^3.7.1" + "@react-stately/color": "npm:^3.7.2" "@react-types/color": "npm:3.0.0-rc.1" "@react-types/shared": "npm:^3.24.1" "@react-types/textfield": "npm:^3.9.5" @@ -8110,7 +8111,7 @@ __metadata: languageName: unknown linkType: soft -"@react-stately/color@npm:^3.7.1, @react-stately/color@npm:^3.7.2, @react-stately/color@workspace:packages/@react-stately/color": +"@react-stately/color@npm:^3.7.2, @react-stately/color@workspace:packages/@react-stately/color": version: 0.0.0-use.local resolution: "@react-stately/color@workspace:packages/@react-stately/color" dependencies: @@ -15239,15 +15240,6 @@ __metadata: languageName: unknown linkType: soft -"css-parse@npm:^2.0.0": - version: 2.0.0 - resolution: "css-parse@npm:2.0.0" - dependencies: - css: "npm:^2.0.0" - checksum: 10c0/a97e409c0060918964609fb9695d04f03b814322b14e2577bc598a6e4b9f36f8a93d0ce911c1d918a765cf73d92812af289b5bcc714ca5fea33c0247e6e39604 - languageName: node - linkType: hard - "css-select-base-adapter@npm:^0.1.1": version: 0.1.1 resolution: "css-select-base-adapter@npm:0.1.1" @@ -15328,18 +15320,6 @@ __metadata: languageName: node linkType: hard -"css@npm:^2.0.0": - version: 2.2.4 - resolution: "css@npm:2.2.4" - dependencies: - inherits: "npm:^2.0.3" - source-map: "npm:^0.6.1" - source-map-resolve: "npm:^0.5.2" - urix: "npm:^0.1.0" - checksum: 10c0/496fa66568ebd9e51b3153817dd36ec004a45780da6f818e13117e3c4e50b774af41fff70a6ff2fa03777b239c4028ff655fe571b20964b90e886441cd141569 - languageName: node - linkType: hard - "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -28798,6 +28778,7 @@ __metadata: "@react-aria/button": "npm:^3.9.8" "@react-aria/calendar": "npm:^3.5.11" "@react-aria/checkbox": "npm:^3.14.6" + "@react-aria/color": "npm:3.0.0-rc.2" "@react-aria/combobox": "npm:^3.10.3" "@react-aria/datepicker": "npm:^3.11.2" "@react-aria/dialog": "npm:^3.5.17" @@ -29118,7 +29099,6 @@ __metadata: core-js: "npm:^3.0.0" cross-env: "npm:^7.0.2" cross-spawn: "npm:^7.0.3" - css-parse: "npm:^2.0.0" delta-e: "npm:^0.0.8" diff: "npm:^5.1.0" eslint: "npm:^8.56.0" @@ -29198,6 +29178,7 @@ __metadata: "@react-stately/calendar": "npm:^3.5.4" "@react-stately/checkbox": "npm:^3.6.8" "@react-stately/collections": "npm:^3.10.9" + "@react-stately/color": "npm:^3.7.2" "@react-stately/combobox": "npm:^3.9.2" "@react-stately/data": "npm:^3.11.6" "@react-stately/datepicker": "npm:^3.10.2" @@ -31029,7 +31010,7 @@ __metadata: languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": +"source-map-resolve@npm:^0.5.0": version: 0.5.3 resolution: "source-map-resolve@npm:0.5.3" dependencies: