@cube-dev/ui-kit 0.0.0-canary-e530064 → 0.0.0-canary-52c46a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Button/Button.d.ts +0 -1
- package/dist/components/actions/Button/Button.js +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -1
- package/dist/components/actions/use-context-menu.js +42 -44
- package/dist/components/actions/use-context-menu.js.map +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/Item/Item.js +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +2 -2
- package/dist/components/content/Tag/Tag.js.map +1 -1
- package/dist/components/content/Text.d.ts +14 -14
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/TreeNode.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.js +1 -1
- package/dist/components/data/DataTable/DataTable.d.ts +13 -0
- package/dist/components/data/DataTable/DataTable.js +246 -0
- package/dist/components/data/DataTable/DataTable.js.map +1 -0
- package/dist/components/data/DataTable/index.d.ts +3 -0
- package/dist/components/data/DataTable/types.d.ts +145 -0
- package/dist/components/data/ItemTable/ItemTable.d.ts +19 -0
- package/dist/components/data/ItemTable/ItemTable.js +350 -0
- package/dist/components/data/ItemTable/ItemTable.js.map +1 -0
- package/dist/components/data/ItemTable/ItemTableBulkBar.d.ts +23 -0
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +131 -0
- package/dist/components/data/ItemTable/ItemTableBulkBar.js.map +1 -0
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +46 -0
- package/dist/components/data/ItemTable/ItemTableDragPreview.js.map +1 -0
- package/dist/components/data/ItemTable/ItemTableFooter.js +79 -0
- package/dist/components/data/ItemTable/ItemTableFooter.js.map +1 -0
- package/dist/components/data/ItemTable/ItemTableToolbar.d.ts +34 -0
- package/dist/components/data/ItemTable/ItemTableToolbar.js +91 -0
- package/dist/components/data/ItemTable/ItemTableToolbar.js.map +1 -0
- package/dist/components/data/ItemTable/index.d.ts +4 -0
- package/dist/components/data/ItemTable/types.d.ts +327 -0
- package/dist/components/data/TableBase/ColumnResizer.js +70 -0
- package/dist/components/data/TableBase/ColumnResizer.js.map +1 -0
- package/dist/components/data/TableBase/RowCollection.js +99 -0
- package/dist/components/data/TableBase/RowCollection.js.map +1 -0
- package/dist/components/data/TableBase/TableRow.js +89 -0
- package/dist/components/data/TableBase/TableRow.js.map +1 -0
- package/dist/components/data/TableBase/TableView.d.ts +22 -0
- package/dist/components/data/TableBase/TableView.js +921 -0
- package/dist/components/data/TableBase/TableView.js.map +1 -0
- package/dist/components/data/TableBase/index.d.ts +5 -0
- package/dist/components/data/TableBase/row-menu.js +40 -0
- package/dist/components/data/TableBase/row-menu.js.map +1 -0
- package/dist/components/data/TableBase/styled.d.ts +5 -0
- package/dist/components/data/TableBase/styled.js +532 -0
- package/dist/components/data/TableBase/styled.js.map +1 -0
- package/dist/components/data/TableBase/types.d.ts +160 -0
- package/dist/components/data/TableBase/types.js +31 -0
- package/dist/components/data/TableBase/types.js.map +1 -0
- package/dist/components/data/TableBase/use-cell-selection.d.ts +3 -0
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-cell-selection.js.map +1 -0
- package/dist/components/data/TableBase/use-container-width.js +35 -0
- package/dist/components/data/TableBase/use-container-width.js.map +1 -0
- package/dist/components/data/TableBase/use-row-move-animation.js +90 -0
- package/dist/components/data/TableBase/use-row-move-animation.js.map +1 -0
- package/dist/components/data/TableBase/use-scrollability.js +49 -0
- package/dist/components/data/TableBase/use-scrollability.js.map +1 -0
- package/dist/components/data/TableBase/use-table-columns.d.ts +2 -0
- package/dist/components/data/TableBase/use-table-columns.js +166 -0
- package/dist/components/data/TableBase/use-table-columns.js.map +1 -0
- package/dist/components/data/TableBase/use-table-search.js +64 -0
- package/dist/components/data/TableBase/use-table-search.js.map +1 -0
- package/dist/components/data/TableBase/use-table-selection.d.ts +4 -0
- package/dist/components/data/TableBase/use-table-selection.js +233 -0
- package/dist/components/data/TableBase/use-table-selection.js.map +1 -0
- package/dist/components/data/TableBase/use-table-sort.js +91 -0
- package/dist/components/data/TableBase/use-table-sort.js.map +1 -0
- package/dist/components/data/TableBase/use-table-sorts.js +97 -0
- package/dist/components/data/TableBase/use-table-sorts.js.map +1 -0
- package/dist/components/data/TableBase/use-table-storage.d.ts +8 -0
- package/dist/components/data/TableBase/use-table-storage.js +58 -0
- package/dist/components/data/TableBase/use-table-storage.js.map +1 -0
- package/dist/components/data/index.d.ts +10 -0
- package/dist/components/fields/Checkbox/Checkbox.js +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.d.ts +37 -34
- package/dist/components/fields/ColorPicker/ColorPicker.js +182 -131
- package/dist/components/fields/ColorPicker/ColorPicker.js.map +1 -1
- package/dist/components/fields/{color/ColorPanel.js → ColorPicker/ColorPickerPanel.js} +11 -14
- package/dist/components/fields/ColorPicker/ColorPickerPanel.js.map +1 -0
- package/dist/components/fields/{color → ColorPicker}/channels.d.ts +1 -1
- package/dist/components/fields/{color → ColorPicker}/channels.js +2 -2
- package/dist/components/fields/ColorPicker/channels.js.map +1 -0
- package/dist/components/fields/ColorPicker/color.d.ts +15 -0
- package/dist/components/fields/{color → ColorPicker}/color.js +2 -2
- package/dist/components/fields/ColorPicker/color.js.map +1 -0
- package/dist/components/fields/ColorPicker/index.d.ts +3 -1
- package/dist/components/fields/ComboBox/ComboBox.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DatePicker.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
- package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
- package/dist/components/fields/DatePicker/YearPicker.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/period.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.js +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
- package/dist/components/fields/Input/Input.js +2 -2
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
- package/dist/components/fields/ListBoxPopover/index.d.ts +0 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/RadioGroup/Radio.d.ts +2 -2
- package/dist/components/fields/RadioGroup/Radio.js +4 -4
- package/dist/components/fields/RadioGroup/Radio.js.map +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.js +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/SliderBase.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +1 -1
- package/dist/components/fields/Switch/Switch.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/index.d.ts +3 -9
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/Form/Field.js +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/form/Form/SubmitError.js +1 -1
- package/dist/components/form/Form/index.js +1 -1
- package/dist/components/form/Form/use-field/use-field-props.js +1 -1
- package/dist/components/form/Form/use-field/use-field.js +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Board/Board.js +1 -1
- package/dist/components/layout/Board/BoardProvider.js +1 -1
- package/dist/components/layout/Board/BoardResponsive.js +1 -1
- package/dist/components/layout/Board/Widget.js +1 -1
- package/dist/components/layout/Board/WidgetHost.js +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-store.js +1 -1
- package/dist/components/layout/Board/grid-core/calculate.js +1 -1
- package/dist/components/layout/Board/grid-core/collision.js +1 -1
- package/dist/components/layout/Board/grid-core/compactors.js +1 -1
- package/dist/components/layout/Board/grid-core/constraints.js +1 -1
- package/dist/components/layout/Board/grid-core/group-move.js +1 -1
- package/dist/components/layout/Board/grid-core/layout.js +1 -1
- package/dist/components/layout/Board/grid-core/sort.js +1 -1
- package/dist/components/layout/Board/index.js +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +1 -1
- package/dist/components/layout/Board/use-board-registry.js +1 -1
- package/dist/components/layout/Board/use-board-select-modifier-key.js +1 -1
- package/dist/components/layout/Board/use-board-selection.js +1 -1
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Pagination/Pagination.d.ts +9 -0
- package/dist/components/navigation/Pagination/Pagination.js +258 -0
- package/dist/components/navigation/Pagination/Pagination.js.map +1 -0
- package/dist/components/navigation/Pagination/index.d.ts +4 -0
- package/dist/components/navigation/Pagination/types.d.ts +81 -0
- package/dist/components/navigation/Pagination/use-pagination.d.ts +52 -0
- package/dist/components/navigation/Pagination/use-pagination.js +83 -0
- package/dist/components/navigation/Pagination/use-pagination.js.map +1 -0
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/navigation/index.d.ts +5 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.d.ts +1 -2
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.d.ts +0 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -1
- package/dist/components/overlays/Modal/Popover.js +1 -1
- package/dist/components/overlays/Modal/Tray.js +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Modal/types.d.ts +0 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.d.ts +0 -2
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useToast.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/index.d.ts +0 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +24 -8
- package/dist/components/shared/DraggableCollection.js.map +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +203 -1
- package/dist/eslint-plugin/defaults.generated.js.map +1 -1
- package/dist/eslint-plugin/index.js +1 -1
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locales/de-DE/uikit.js +36 -1
- package/dist/i18n/locales/en-US/uikit.js +36 -1
- package/dist/i18n/locales/en-US/uikit.json.d.ts +41 -1
- package/dist/i18n/locales/es-ES/uikit.js +36 -1
- package/dist/i18n/locales/es-MX/uikit.js +36 -1
- package/dist/i18n/locales/fr-FR/uikit.js +36 -1
- package/dist/i18n/locales/it-IT/uikit.js +36 -1
- package/dist/i18n/locales/ja-JP/uikit.js +36 -1
- package/dist/i18n/locales/nb-NO/uikit.js +36 -1
- package/dist/i18n/locales/pt-BR/uikit.js +36 -1
- package/dist/i18n/locales/pt-PT/uikit.js +36 -1
- package/dist/i18n/locales/sv-SE/uikit.js +36 -1
- package/dist/i18n/locales/vi-VN/uikit.js +36 -1
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PipetteIcon.js +1 -1
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +22 -15
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/provider.js +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.js +1 -1
- package/dist/tokens/palette.js +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.d.ts +1 -1
- package/dist/tokens/typography.js +11 -2
- package/dist/tokens/typography.js.map +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useBufferedValue.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +2 -2
- package/docs/components/data/DataTable.md +298 -0
- package/docs/components/data/ItemTable.md +984 -0
- package/docs/components/fields/ColorPicker.md +144 -85
- package/docs/components/navigation/Pagination.md +245 -0
- package/package.json +8 -3
- package/dist/components/fields/ColorInput/ColorInput.d.ts +0 -67
- package/dist/components/fields/ColorInput/ColorInput.js +0 -230
- package/dist/components/fields/ColorInput/ColorInput.js.map +0 -1
- package/dist/components/fields/ColorInput/index.d.ts +0 -2
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.d.ts +0 -50
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +0 -269
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js.map +0 -1
- package/dist/components/fields/ColorSwatchGroup/index.d.ts +0 -2
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.d.ts +0 -2
- package/dist/components/fields/color/ColorPanel.js.map +0 -1
- package/dist/components/fields/color/ColorSwatch.d.ts +0 -22
- package/dist/components/fields/color/ColorSwatch.js +0 -58
- package/dist/components/fields/color/ColorSwatch.js.map +0 -1
- package/dist/components/fields/color/channels.js.map +0 -1
- package/dist/components/fields/color/color.d.ts +0 -21
- package/dist/components/fields/color/color.js.map +0 -1
- package/dist/components/fields/color/context.js +0 -20
- package/dist/components/fields/color/context.js.map +0 -1
- package/dist/components/fields/color/index.d.ts +0 -4
- package/dist/components/portal/PortalProvider.d.ts +0 -2
- package/docs/components/fields/ColorInput.md +0 -284
- package/docs/components/fields/ColorSwatchGroup.md +0 -206
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorSwatchGroup.js","names":["useFocus","mergeProps"],"sources":["../../../../src/components/fields/ColorSwatchGroup/ColorSwatchGroup.tsx"],"sourcesContent":["import { useObjectRef } from '@react-aria/utils';\nimport {\n BaseProps,\n BLOCK_STYLES,\n BlockStyleProps,\n OUTER_STYLES,\n OuterStyleProps,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport { ForwardedRef, forwardRef, useMemo, useRef, useState } from 'react';\nimport { useRadio, useRadioGroup } from 'react-aria';\nimport { useRadioGroupState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal';\nimport { FieldBaseProps } from '../../../shared';\nimport { mergeProps } from '../../../utils/react';\nimport { useFocus } from '../../../utils/react/interactions';\nimport { extractStyles } from '../../../utils/styles';\nimport { getValidationMods, useFieldProps, wrapWithField } from '../../form';\nimport { HiddenInput } from '../../HiddenInput';\nimport { ColorFormat, formatColor, parseColor, toHex } from '../color/color';\nimport { useIsInsideColorPopover } from '../color/context';\nimport { ColorPicker } from '../ColorPicker';\n\nimport type { RadioGroupState } from 'react-stately';\n\n/** A swatch: a color, and optionally a name to announce instead of the color. */\nexport type CubeColorSwatchItem = string | { color: string; label?: string };\n\n/**\n * Two rings drawn inside the swatch, as React Aria marks selection. Outer ring\n * first: earlier shadows paint over later ones, so this reads as 2bw of\n * `#surface-text` at the edge and 2bw of `#surface` within it. Two tones that\n * flip with the scheme stay visible against any color the swatch holds.\n */\nconst SELECTED_RING = 'inset 0 0 0 2bw #surface-text, inset 0 0 0 4bw #surface';\n\n/** The swatch edge in px, per size. `Item` takes an exact number. */\nconst SWATCH_PX: Record<string, number> = {\n small: 16,\n medium: 20,\n large: 24,\n};\n\n/**\n * The trailing picker is a button wrapping a swatch, which would otherwise read\n * as a box inside a box. Stripping its chrome leaves just the swatch, so it\n * sits in the row as one of them.\n */\nconst CUSTOM_TRIGGER_STYLES: Styles = {\n // `size` sets the control's height; the box is pinned here as well so a flex\n // row cannot let the button size itself to its content instead.\n width: '$swatch-size $swatch-size',\n height: '$swatch-size $swatch-size',\n padding: 0,\n radius: '1r',\n border: 0,\n position: 'relative',\n};\n\n/**\n * The swatch is docked over the whole button rather than placed inside it.\n * `Item` lays its icon out in a grid that reserves room for a label even when\n * there is none, which left the swatch a pixel off centre.\n */\nconst CUSTOM_SWATCH_STYLES: Styles = {\n position: 'absolute',\n inset: 0,\n width: 'auto',\n height: 'auto',\n radius: '1r',\n};\n\n/**\n * The ring goes on the swatch, not on the button around it: an inset shadow\n * paints under child content, and the swatch covers the button edge to edge.\n */\nconst CUSTOM_SWATCH_SELECTED_STYLES: Styles = {\n ...CUSTOM_SWATCH_STYLES,\n shadow: SELECTED_RING,\n};\n\nconst GroupElement = tasty({\n qa: 'ColorSwatchGroup',\n styles: {\n // Wrapping is the better default: it is a single row wherever there is\n // room, and folds instead of overflowing where there is not. A fixed\n // `columns` switches to a grid, sized to the swatches rather than to the\n // container — `1fr` tracks would stretch them apart.\n display: {\n '': 'flex',\n columns: 'grid',\n },\n flow: {\n '': 'row wrap',\n columns: 'row',\n },\n gap: '.5x',\n placeItems: {\n '': 'center start',\n columns: 'stretch',\n },\n width: {\n '': 'auto',\n columns: 'max-content',\n },\n gridColumns: 'repeat($columns, max-content)',\n\n // 20px, 16px and 24px — 1x is 8px.\n '$swatch-size': {\n '': '2.5x',\n 'size=small': '2x',\n 'size=large': '3x',\n },\n },\n});\n\n/**\n * Only the swatches belong to the radiogroup. The custom picker is a button,\n * and inside `role=\"radiogroup\"` it both misreports what the palette holds and\n * hands arrow keys to React Aria's radio walker — pressing one while the picker\n * is focused jumps into a swatch and changes the color. The box is dropped so\n * the swatches remain direct children of the group's own layout.\n */\nconst RadiosElement = tasty({\n styles: { display: 'contents' },\n});\n\nconst SwatchElement = tasty({\n as: 'label',\n qa: 'ColorSwatchOption',\n styles: {\n display: 'grid',\n placeItems: 'stretch',\n position: 'relative',\n radius: '1r',\n cursor: {\n '': 'pointer',\n disabled: 'default',\n },\n width: '$swatch-size $swatch-size',\n height: '$swatch-size $swatch-size',\n fill: '(#color-swatch, #clear)',\n opacity: {\n '': 1,\n disabled: '$disabled-opacity',\n },\n // A ring at one border-width's distance, so the color area stays whole —\n // the inner ring is the surface showing through as the gap. `outline` is\n // deliberately left to the focus ring.\n shadow: {\n '': 'inset 0 0 0 1bw #dark.15',\n selected: SELECTED_RING,\n },\n // A 1bw offset keeps the ring clear of the 4px gap to its neighbours.\n outline: {\n '': '2bw #focus.0 / 1bw',\n focused: '2bw #focus / 1bw',\n },\n transition: 'theme',\n },\n});\n\nexport interface CubeColorSwatchGroupProps\n extends BaseProps,\n OuterStyleProps,\n BlockStyleProps,\n FieldBaseProps {\n /** The colors to offer. Duplicates of the same color are dropped. */\n colors?: CubeColorSwatchItem[];\n /** The selected color (controlled). */\n value?: string | null;\n /** The selected color (uncontrolled). */\n defaultValue?: string | null;\n /** Called with the chosen color, written in `format`. */\n onChange?: (value: string | null) => void;\n /** Notation the value is written in. */\n format?: ColorFormat;\n /** How many swatches per row. Defaults to a single row. */\n columns?: number;\n /**\n * Append a `ColorPicker` for colors outside the set. Ignored inside a color\n * popover, which is where that picker would otherwise recurse.\n */\n allowCustom?: boolean;\n /** The size of each swatch. */\n size?: 'small' | 'medium' | 'large' | (string & {});\n styles?: Styles;\n /** Styles of an individual swatch. */\n swatchStyles?: Styles;\n 'aria-label'?: string;\n}\n\ninterface SwatchProps {\n colorKey: string;\n label: string;\n state: RadioGroupState;\n isDisabled?: boolean;\n size?: string;\n styles?: Styles;\n mods?: Record<string, boolean | undefined>;\n}\n\nfunction Swatch({\n colorKey,\n label,\n state,\n isDisabled,\n size,\n styles,\n mods,\n}: SwatchProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const {\n inputProps,\n isSelected,\n isDisabled: isRadioDisabled,\n } = useRadio(\n { value: colorKey, 'aria-label': label, isDisabled },\n state,\n inputRef,\n );\n // `useRadio` reports selection but not focus, and the swatch is the only\n // thing a keyboard user can see — without this the ring never appears.\n const { isFocused, focusProps } = useFocus({ isDisabled }, true);\n\n return (\n <SwatchElement\n data-size={size}\n mods={{\n selected: isSelected,\n disabled: isRadioDisabled,\n focused: isFocused,\n ...mods,\n }}\n styles={styles}\n style={{ '--color-swatch-color': colorKey }}\n >\n <HiddenInput\n {...mergeProps(inputProps, focusProps)}\n ref={inputRef}\n qa=\"ColorSwatchInput\"\n mods={{ button: true, disabled: isRadioDisabled }}\n />\n </SwatchElement>\n );\n}\n\n/**\n * A grid of color swatches, one of which can be selected — the palette half of\n * choosing a color, where `ColorPicker` is the freeform half.\n *\n * Swatches are keyed by their canonical hex, so the same color written two ways\n * collapses into one entry. Equivalent colors would otherwise make selection\n * ambiguous.\n */\nexport const ColorSwatchGroup = forwardRef(function ColorSwatchGroup(\n allProps: CubeColorSwatchGroupProps,\n ref: ForwardedRef<HTMLElement>,\n) {\n const props = useFieldProps(allProps, {\n defaultValidationTrigger: 'onChange',\n valuePropsMapper: ({ value, onChange }) => ({\n value: value as string | null | undefined,\n onChange,\n }),\n });\n\n const {\n qa,\n colors = [],\n value,\n defaultValue,\n onChange,\n format = 'hex',\n columns,\n allowCustom,\n size = 'medium',\n isDisabled,\n isInvalid,\n isValid,\n swatchStyles,\n 'aria-label': ariaLabel,\n } = props;\n\n const styles = extractStyles(props, [...OUTER_STYLES, ...BLOCK_STYLES]);\n const isInsidePopover = useIsInsideColorPopover();\n // A custom picker inside a color popover would open a popover of its own.\n const showCustom = allowCustom && !isInsidePopover;\n\n /** Keyed by canonical hex so the same color written two ways is one swatch. */\n const swatches = useMemo(() => {\n const seen = new Map<string, { key: string; label: string }>();\n\n for (const entry of colors) {\n const raw = typeof entry === 'string' ? entry : entry.color;\n const parsed = parseColor(raw);\n\n if (!parsed) continue;\n\n const key = toHex(parsed);\n\n if (seen.has(key)) continue;\n\n seen.set(key, {\n key,\n label:\n (typeof entry === 'string' ? undefined : entry.label) ??\n formatColor(parsed, format),\n });\n }\n\n return [...seen.values()];\n }, [colors, format]);\n\n const [internalValue, setInternalValue] = useState<string | null>(\n () => defaultValue ?? null,\n );\n const currentValue = value !== undefined ? value : internalValue;\n\n const selectedColor = parseColor((currentValue ?? '').toString());\n const selectedKey = selectedColor ? toHex(selectedColor) : null;\n const isCustom =\n !!selectedKey && !swatches.some((s) => s.key === selectedKey);\n\n const publish = useEvent((next: string | null) => {\n if (value === undefined) setInternalValue(next);\n\n onChange?.(next);\n });\n\n const handleChange = useEvent((nextKey: string) => {\n const parsed = parseColor(nextKey);\n\n publish(parsed ? formatColor(parsed, format) : null);\n });\n\n const state = useRadioGroupState({\n value: selectedKey ?? null,\n isDisabled,\n isReadOnly: props.isReadOnly,\n onChange: handleChange,\n });\n\n // `useFocusableRef` wants the ref of a real focusable control to forward to,\n // and a group of radios has no single one — `RadioGroup` takes the same\n // approach for the same reason.\n const domRef = useObjectRef(ref);\n const { radioGroupProps, labelProps } = useRadioGroup(\n {\n ...props,\n // Only name the group here when nothing else does: an `aria-label` set\n // unconditionally would outrank the visible label React Aria wires up.\n 'aria-label': props.label ? undefined : ariaLabel ?? 'Colors',\n orientation: 'horizontal',\n },\n state,\n );\n\n const group = (\n <GroupElement\n ref={domRef}\n qa={qa || 'ColorSwatchGroup'}\n data-size={size}\n data-input-type=\"colorswatchgroup\"\n styles={styles}\n mods={{\n ...getValidationMods({ isInvalid, isValid }),\n columns: !!columns,\n }}\n style={columns ? { '--columns': String(columns) } : undefined}\n >\n <RadiosElement {...radioGroupProps}>\n {swatches.map((swatch) => (\n <Swatch\n key={swatch.key}\n colorKey={swatch.key}\n label={swatch.label}\n state={state}\n isDisabled={isDisabled}\n size={size}\n styles={swatchStyles}\n />\n ))}\n </RadiosElement>\n {showCustom ? (\n <ColorPicker\n aria-label=\"Custom color\"\n qa=\"ColorSwatchGroupCustom\"\n format={format}\n type=\"clear\"\n size={SWATCH_PX[size] ?? SWATCH_PX.medium}\n value={isCustom ? currentValue ?? null : null}\n isDisabled={isDisabled}\n isReadOnly={props.isReadOnly}\n triggerStyles={CUSTOM_TRIGGER_STYLES}\n swatchStyles={\n isCustom ? CUSTOM_SWATCH_SELECTED_STYLES : CUSTOM_SWATCH_STYLES\n }\n onChange={publish}\n >\n {null}\n </ColorPicker>\n ) : null}\n </GroupElement>\n );\n\n return wrapWithField(group, domRef, {\n ...props,\n labelProps: mergeProps(props.labelProps, labelProps),\n });\n});\n\n(ColorSwatchGroup as any).cubeInputType = 'Picker';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPanel.js","names":["Slider","Radio"],"sources":["../../../../src/components/fields/color/ColorPanel.tsx"],"sourcesContent":["import { Styles, tasty } from '@tenphi/tasty';\nimport { ReactNode, useMemo } from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { Radio } from '../RadioGroup';\nimport { Slider } from '../Slider';\n\nimport {\n CHANNELS,\n COLOR_SPACE_HINTS,\n COLOR_SPACE_LABELS,\n COLOR_SPACES,\n ColorChannel,\n ColorSpace,\n} from './channels';\nimport {\n ColorFormat,\n ColorValue,\n formatColor,\n getContrastingColor,\n toHex,\n} from './color';\n\nconst PanelElement = tasty({\n qa: 'ColorPanel',\n styles: {\n display: 'grid',\n flow: 'row',\n gap: '1x',\n padding: '1x',\n width: '34x',\n },\n});\n\nconst PreviewElement = tasty({\n qa: 'ColorPreview',\n styles: {\n display: 'grid',\n placeItems: 'center',\n height: '6x',\n radius: true,\n preset: 's4',\n fill: '(#color-picker, #clear)',\n color: '(#color-picker-contrast, #dark)',\n shadow: 'inset 0 0 0 1bw #dark.1',\n },\n});\n\nconst ChannelsElement = tasty({\n styles: {\n display: 'grid',\n gridColumns: 'max-content 1sf max-content',\n placeItems: 'center stretch',\n gap: '1x',\n },\n});\n\nconst ChannelLabelElement = tasty({\n styles: {\n preset: 'c2',\n color: '#dark-03',\n textAlign: 'center',\n width: '2x',\n },\n});\n\nconst ChannelTrackElement = tasty({\n styles: {\n display: 'grid',\n placeItems: 'center stretch',\n },\n});\n\nconst ChannelValueElement = tasty({\n styles: {\n preset: 's4',\n color: '#dark-02',\n textAlign: 'right',\n whiteSpace: 'nowrap',\n width: '5.5x',\n },\n});\n\n/**\n * The gradient reaches the track through a plain custom property so the track\n * keeps a single cached style rule. A color picker moves its channels\n * continuously, and a fresh `styles` object per frame would emit a fresh CSS\n * rule per frame.\n */\nconst TRACK_STYLES: Styles = {\n height: '1x',\n top: '.5x',\n radius: '1r',\n fill: '#clear',\n image: '$channel-gradient',\n shadow: 'inset 0 0 0 1bw #dark.1',\n Fill: false,\n};\n\n/** A ring keeps the thumb visible wherever it sits on its own gradient. */\nconst THUMB_STYLES: Styles = {\n shadow: '0 0 0 2bw #surface, 0 0 0 3bw #dark.2',\n};\n\nconst THUMB_TOKENS = { '#slider-thumb': '(#color-picker, #surface)' };\n\nconst SPACE_STYLES: Styles = { width: '100%' };\nconst TAB_STYLES: Styles = { flexGrow: 1 };\n\nexport interface ColorPanelProps {\n color: ColorValue;\n space: ColorSpace;\n isDisabled?: boolean;\n /** Notation used for the preview caption. */\n previewFormat: ColorFormat;\n /** Optional palette rendered under the channels. */\n swatches?: ReactNode;\n /** Optional value field rendered above the preview. */\n input?: ReactNode;\n onChange: (color: ColorValue) => void;\n onSpaceChange: (space: ColorSpace) => void;\n}\n\ninterface ChannelRowProps {\n channel: ColorChannel;\n color: ColorValue;\n isDisabled?: boolean;\n onChange: (color: ColorValue) => void;\n}\n\nfunction ChannelRow({ channel, color, isDisabled, onChange }: ChannelRowProps) {\n const max = channel.max(color);\n\n const handleChange = useEvent((value: number) => {\n onChange(channel.apply(color, value));\n });\n\n return (\n <>\n <ChannelLabelElement aria-hidden=\"true\">\n {channel.label}\n </ChannelLabelElement>\n <ChannelTrackElement\n style={{\n '--channel-gradient': `linear-gradient(to right, ${channel.stops(\n color,\n )})`,\n }}\n >\n <Slider\n aria-label={channel.title}\n value={Math.min(channel.value(color), max)}\n minValue={channel.min}\n maxValue={max}\n step={channel.step}\n isDisabled={isDisabled}\n trackStyles={TRACK_STYLES}\n thumbStyles={THUMB_STYLES}\n thumbTokens={THUMB_TOKENS}\n onChange={handleChange}\n />\n </ChannelTrackElement>\n <ChannelValueElement>{channel.display(color)}</ChannelValueElement>\n </>\n );\n}\n\n/**\n * The popover body shared by `ColorInput` and `ColorPicker`: a preview, a\n * switch between the three color concepts, and one gradient slider per channel\n * of the active one.\n */\nexport function ColorPanel(props: ColorPanelProps) {\n const {\n color,\n space,\n isDisabled,\n previewFormat,\n swatches,\n input,\n onChange,\n onSpaceChange,\n } = props;\n\n const colorTokens = useMemo(\n () => ({\n '--color-picker-color': toHex(color),\n '--color-picker-contrast-color': getContrastingColor(color),\n }),\n [color],\n );\n\n const handleSpaceChange = useEvent((value: string) => {\n onSpaceChange(value as ColorSpace);\n });\n\n return (\n <PanelElement style={colorTokens}>\n {input}\n <PreviewElement>{formatColor(color, previewFormat)}</PreviewElement>\n <Radio.Tabs\n aria-label=\"Color space\"\n value={space}\n isDisabled={isDisabled}\n styles={SPACE_STYLES}\n onChange={handleSpaceChange}\n >\n {COLOR_SPACES.map((item) => (\n <Radio\n key={item}\n value={item}\n aria-label={COLOR_SPACE_LABELS[item]}\n tooltip={COLOR_SPACE_HINTS[item]}\n styles={TAB_STYLES}\n >\n {COLOR_SPACE_LABELS[item]}\n </Radio>\n ))}\n </Radio.Tabs>\n <ChannelsElement>\n {CHANNELS[space].map((channel) => (\n <ChannelRow\n key={`${space}-${channel.label}`}\n channel={channel}\n color={color}\n isDisabled={isDisabled}\n onChange={onChange}\n />\n ))}\n </ChannelsElement>\n {swatches}\n </PanelElement>\n );\n}\n"],"mappings":";;;;;;;;;;;AAuBA,MAAM,eAAe,MAAM;CACzB,IAAI;CACJ,QAAQ;EACN,SAAS;EACT,MAAM;EACN,KAAK;EACL,SAAS;EACT,OAAO;EACR;CACF,CAAC;AAEF,MAAM,iBAAiB,MAAM;CAC3B,IAAI;CACJ,QAAQ;EACN,SAAS;EACT,YAAY;EACZ,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CACF,CAAC;AAEF,MAAM,kBAAkB,MAAM,EAC5B,QAAQ;CACN,SAAS;CACT,aAAa;CACb,YAAY;CACZ,KAAK;CACN,EACF,CAAC;AAEF,MAAM,sBAAsB,MAAM,EAChC,QAAQ;CACN,QAAQ;CACR,OAAO;CACP,WAAW;CACX,OAAO;CACR,EACF,CAAC;AAEF,MAAM,sBAAsB,MAAM,EAChC,QAAQ;CACN,SAAS;CACT,YAAY;CACb,EACF,CAAC;AAEF,MAAM,sBAAsB,MAAM,EAChC,QAAQ;CACN,QAAQ;CACR,OAAO;CACP,WAAW;CACX,YAAY;CACZ,OAAO;CACR,EACF,CAAC;;;;;;;AAQF,MAAM,eAAuB;CAC3B,QAAQ;CACR,KAAK;CACL,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,MAAM;CACP;;AAGD,MAAM,eAAuB,EAC3B,QAAQ,yCACT;AAED,MAAM,eAAe,EAAE,iBAAiB,6BAA6B;AAErE,MAAM,eAAuB,EAAE,OAAO,QAAQ;AAC9C,MAAM,aAAqB,EAAE,UAAU,GAAG;AAuB1C,SAAS,WAAW,EAAE,SAAS,OAAO,YAAY,YAA6B;CAC7E,MAAM,MAAM,QAAQ,IAAI,MAAM;CAE9B,MAAM,eAAe,UAAU,UAAkB;AAC/C,WAAS,QAAQ,MAAM,OAAO,MAAM,CAAC;GACrC;AAEF,QACE;EACE,oBAAC;GAAoB,eAAY;aAC9B,QAAQ;IACW;EACtB,oBAAC;GACC,OAAO,EACL,sBAAsB,6BAA6B,QAAQ,MACzD,MACD,CAAC,IACH;aAED,oBAACA;IACC,cAAY,QAAQ;IACpB,OAAO,KAAK,IAAI,QAAQ,MAAM,MAAM,EAAE,IAAI;IAC1C,UAAU,QAAQ;IAClB,UAAU;IACV,MAAM,QAAQ;IACF;IACZ,aAAa;IACb,aAAa;IACb,aAAa;IACb,UAAU;KACV;IACkB;EACtB,oBAAC,iCAAqB,QAAQ,QAAQ,MAAM,GAAuB;KAClE;;;;;;;AASP,SAAgB,WAAW,OAAwB;CACjD,MAAM,EACJ,OACA,OACA,YACA,eACA,UACA,OACA,UACA,kBACE;CAEJ,MAAM,cAAc,eACX;EACL,wBAAwB,MAAM,MAAM;EACpC,iCAAiC,oBAAoB,MAAM;EAC5D,GACD,CAAC,MAAM,CACR;CAED,MAAM,oBAAoB,UAAU,UAAkB;AACpD,gBAAc,MAAoB;GAClC;AAEF,QACE,qBAAC;EAAa,OAAO;;GAClB;GACD,oBAAC,4BAAgB,YAAY,OAAO,cAAc,GAAkB;GACpE,oBAACC,QAAM;IACL,cAAW;IACX,OAAO;IACK;IACZ,QAAQ;IACR,UAAU;cAET,aAAa,KAAK,SACjB,oBAACA;KAEC,OAAO;KACP,cAAY,mBAAmB;KAC/B,SAAS,kBAAkB;KAC3B,QAAQ;eAEP,mBAAmB;OANf,KAOC,CACR;KACS;GACb,oBAAC,6BACE,SAAS,OAAO,KAAK,YACpB,oBAAC;IAEU;IACF;IACK;IACF;MAJL,GAAG,MAAM,GAAG,QAAQ,QAKzB,CACF,GACc;GACjB;;GACY"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { ColorValue } from "./color.js";
|
|
3
|
-
import { BaseProps, BaseStyleProps, BlockStyleProps, DimensionStyleProps, OuterStyleProps, Styles } from "@tenphi/tasty";
|
|
4
|
-
import * as react from "react";
|
|
5
|
-
|
|
6
|
-
//#region src/components/fields/color/ColorSwatch.d.ts
|
|
7
|
-
interface CubeColorSwatchProps extends BaseProps, BaseStyleProps, OuterStyleProps, BlockStyleProps, DimensionStyleProps {
|
|
8
|
-
/** The color to show. Anything the color inputs accept; `null` shows the empty state. */
|
|
9
|
-
color?: string | ColorValue | null;
|
|
10
|
-
styles?: Styles;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* A square of color. Decorative on its own — pair it with the value as text, or
|
|
14
|
-
* with a control that names it.
|
|
15
|
-
*
|
|
16
|
-
* The color travels as an inline custom property rather than through `styles`,
|
|
17
|
-
* so the swatch keeps a single cached style rule however often it changes.
|
|
18
|
-
*/
|
|
19
|
-
declare const ColorSwatch: react.ForwardRefExoticComponent<CubeColorSwatchProps & react.RefAttributes<HTMLDivElement>>;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { ColorSwatch, CubeColorSwatchProps };
|
|
22
|
-
//# sourceMappingURL=ColorSwatch.d.ts.map
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e530064 | Cube Dev Team */
|
|
2
|
-
import { extractStyles } from "../../../utils/styles.js";
|
|
3
|
-
import { parseColor, toHex } from "./color.js";
|
|
4
|
-
import { BASE_STYLES, BLOCK_STYLES, DIMENSION_STYLES, OUTER_STYLES, tasty } from "@tenphi/tasty";
|
|
5
|
-
import { forwardRef } from "react";
|
|
6
|
-
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
|
|
8
|
-
//#region src/components/fields/color/ColorSwatch.tsx
|
|
9
|
-
const STYLE_PROPS = [
|
|
10
|
-
...BASE_STYLES,
|
|
11
|
-
...OUTER_STYLES,
|
|
12
|
-
...BLOCK_STYLES,
|
|
13
|
-
...DIMENSION_STYLES
|
|
14
|
-
];
|
|
15
|
-
const SwatchElement = tasty({
|
|
16
|
-
qa: "ColorSwatch",
|
|
17
|
-
styles: {
|
|
18
|
-
display: "block",
|
|
19
|
-
width: "2.5x",
|
|
20
|
-
height: "2.5x",
|
|
21
|
-
radius: "1r",
|
|
22
|
-
fill: {
|
|
23
|
-
"": "(#color-picker, #clear)",
|
|
24
|
-
empty: "#clear"
|
|
25
|
-
},
|
|
26
|
-
shadow: "inset 0 0 0 1bw #dark.15",
|
|
27
|
-
image: {
|
|
28
|
-
"": false,
|
|
29
|
-
empty: "linear-gradient(to bottom right, #clear 46%, #danger 46%, #danger 54%, #clear 54%)"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
/**
|
|
34
|
-
* A square of color. Decorative on its own — pair it with the value as text, or
|
|
35
|
-
* with a control that names it.
|
|
36
|
-
*
|
|
37
|
-
* The color travels as an inline custom property rather than through `styles`,
|
|
38
|
-
* so the swatch keeps a single cached style rule however often it changes.
|
|
39
|
-
*/
|
|
40
|
-
const ColorSwatch = forwardRef(function ColorSwatch(props, ref) {
|
|
41
|
-
const { color, mods, qa } = props;
|
|
42
|
-
const styles = extractStyles(props, STYLE_PROPS);
|
|
43
|
-
const resolved = typeof color === "string" ? parseColor(color) : color ?? null;
|
|
44
|
-
return /* @__PURE__ */ jsx(SwatchElement, {
|
|
45
|
-
ref,
|
|
46
|
-
qa,
|
|
47
|
-
mods: {
|
|
48
|
-
empty: !resolved,
|
|
49
|
-
...mods
|
|
50
|
-
},
|
|
51
|
-
styles,
|
|
52
|
-
style: resolved ? { "--color-picker-color": toHex(resolved) } : void 0
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
//#endregion
|
|
57
|
-
export { ColorSwatch };
|
|
58
|
-
//# sourceMappingURL=ColorSwatch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorSwatch.js","names":[],"sources":["../../../../src/components/fields/color/ColorSwatch.tsx"],"sourcesContent":["import {\n BASE_STYLES,\n BaseProps,\n BaseStyleProps,\n BLOCK_STYLES,\n BlockStyleProps,\n DIMENSION_STYLES,\n DimensionStyleProps,\n OUTER_STYLES,\n OuterStyleProps,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport { ForwardedRef, forwardRef } from 'react';\n\nimport { extractStyles } from '../../../utils/styles';\n\nimport { ColorValue, parseColor, toHex } from './color';\n\nconst STYLE_PROPS = [\n ...BASE_STYLES,\n ...OUTER_STYLES,\n ...BLOCK_STYLES,\n ...DIMENSION_STYLES,\n];\n\nconst SwatchElement = tasty({\n qa: 'ColorSwatch',\n styles: {\n display: 'block',\n width: '2.5x',\n height: '2.5x',\n radius: '1r',\n fill: {\n '': '(#color-picker, #clear)',\n empty: '#clear',\n },\n shadow: 'inset 0 0 0 1bw #dark.15',\n // A single diagonal stroke is the conventional \"no color\" swatch.\n image: {\n '': false,\n empty:\n 'linear-gradient(to bottom right, #clear 46%, #danger 46%, #danger 54%, #clear 54%)',\n },\n },\n});\n\nexport interface CubeColorSwatchProps\n extends BaseProps,\n BaseStyleProps,\n OuterStyleProps,\n BlockStyleProps,\n DimensionStyleProps {\n /** The color to show. Anything the color inputs accept; `null` shows the empty state. */\n color?: string | ColorValue | null;\n styles?: Styles;\n}\n\n/**\n * A square of color. Decorative on its own — pair it with the value as text, or\n * with a control that names it.\n *\n * The color travels as an inline custom property rather than through `styles`,\n * so the swatch keeps a single cached style rule however often it changes.\n */\nexport const ColorSwatch = forwardRef(function ColorSwatch(\n props: CubeColorSwatchProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const { color, mods, qa } = props;\n const styles = extractStyles(props, STYLE_PROPS);\n\n const resolved =\n typeof color === 'string' ? parseColor(color) : color ?? null;\n\n return (\n <SwatchElement\n ref={ref}\n qa={qa}\n mods={{ empty: !resolved, ...mods }}\n styles={styles}\n style={resolved ? { '--color-picker-color': toHex(resolved) } : undefined}\n />\n );\n});\n"],"mappings":";;;;;;;;AAmBA,MAAM,cAAc;CAClB,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAED,MAAM,gBAAgB,MAAM;CAC1B,IAAI;CACJ,QAAQ;EACN,SAAS;EACT,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,MAAM;GACJ,IAAI;GACJ,OAAO;GACR;EACD,QAAQ;EAER,OAAO;GACL,IAAI;GACJ,OACE;GACH;EACF;CACF,CAAC;;;;;;;;AAoBF,MAAa,cAAc,WAAW,SAAS,YAC7C,OACA,KACA;CACA,MAAM,EAAE,OAAO,MAAM,OAAO;CAC5B,MAAM,SAAS,cAAc,OAAO,YAAY;CAEhD,MAAM,WACJ,OAAO,UAAU,WAAW,WAAW,MAAM,GAAG,SAAS;AAE3D,QACE,oBAAC;EACM;EACD;EACJ,MAAM;GAAE,OAAO,CAAC;GAAU,GAAG;GAAM;EAC3B;EACR,OAAO,WAAW,EAAE,wBAAwB,MAAM,SAAS,EAAE,GAAG;GAChE;EAEJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"channels.js","names":[],"sources":["../../../../src/components/fields/color/channels.ts"],"sourcesContent":["import {\n ColorValue,\n fromOkhst,\n fromOklch,\n fromRgb,\n isAchromatic,\n maxChroma,\n normalizeHue,\n toHex,\n toOkhst,\n toOklch,\n toRgb,\n} from './color';\n\n/**\n * The three color concepts the popover can be driven by. They all edit the\n * same canonical value — only the axes the user manipulates differ.\n */\nexport const COLOR_SPACES = ['hst', 'lch', 'rgb'] as const;\n\nexport type ColorSpace = (typeof COLOR_SPACES)[number];\n\nexport const COLOR_SPACE_LABELS: Record<ColorSpace, string> = {\n hst: 'HST',\n lch: 'LCH',\n rgb: 'RGB',\n};\n\nexport const COLOR_SPACE_HINTS: Record<ColorSpace, string> = {\n hst: 'OKHST — hue, saturation, tone',\n lch: 'OKLCH — lightness, chroma, hue',\n rgb: 'sRGB — red, green, blue',\n};\n\nexport interface ColorChannel {\n /** Single-letter axis name shown next to the slider. */\n label: string;\n /** Accessible name for the slider. */\n title: string;\n min: number;\n step: number;\n /** The upper bound. Chroma is gamut-bound, so it depends on the color. */\n max: (color: ColorValue) => number;\n value: (color: ColorValue) => number;\n /** The color this channel produces when moved to `value`. */\n apply: (color: ColorValue, value: number) => ColorValue;\n /** Comma-separated gradient stops describing the channel's whole range. */\n stops: (color: ColorValue) => string;\n /** Human-readable rendering of the current channel value. */\n display: (color: ColorValue) => string;\n}\n\nconst constant = (value: number) => () => value;\n\nfunction round(value: number, precision = 2): number {\n const factor = 10 ** precision;\n\n return Math.round(value * factor) / factor;\n}\n\n/**\n * `count` evenly spaced gradient stops, always as hex. Perceptual channels are\n * not linear in sRGB, so a two-stop gradient would misrepresent them —\n * sampling the real conversion keeps the track honest. Hex (rather than an\n * `okhsl()` string) because the gradient reaches the DOM as a raw custom\n * property, without passing through Tasty's color functions.\n */\nfunction ramp(count: number, at: (position: number) => ColorValue): string {\n return Array.from({ length: count }, (_, index) =>\n toHex(at(index / (count - 1))),\n ).join(', ');\n}\n\n/**\n * The hue strip is drawn at full saturation and a fixed OKHSL lightness, which\n * keeps it perceptually even instead of spiking at yellow the way a CSS-HSL\n * rainbow does. Its own saturation and tone stay fixed: the strip is the same\n * in HST and in LCH, where `H` means the same thing.\n */\nconst HUE_STOPS = ramp(25, (position) => ({\n h: position * 360,\n s: 1,\n l: 0.6,\n}));\n\nconst hueChannel: ColorChannel = {\n label: 'H',\n title: 'Hue',\n min: 0,\n // 360° is the same angle as 0°, so the last usable stop is 359 — the range\n // `HueSlider` exposes as well.\n max: constant(359),\n step: 1,\n value: (color) => round(color.h, 1),\n apply: (color, value) => ({ ...color, h: normalizeHue(value) }),\n stops: () => HUE_STOPS,\n display: (color) => `${Math.round(color.h)}°`,\n};\n\nconst saturationChannel: ColorChannel = {\n label: 'S',\n title: 'Saturation',\n min: 0,\n max: constant(100),\n step: 1,\n value: (color) => round(color.s * 100, 1),\n apply: (color, value) => ({ ...color, s: value / 100 }),\n stops: (color) => ramp(7, (position) => ({ ...color, s: position })),\n display: (color) => `${Math.round(color.s * 100)}%`,\n};\n\nconst toneChannel: ColorChannel = {\n label: 'T',\n title: 'Tone',\n min: 0,\n max: constant(100),\n step: 1,\n value: (color) => round(toOkhst(color).t * 100, 1),\n apply: (color, value) =>\n fromOkhst({ h: color.h, s: color.s, t: value / 100 }),\n stops: (color) =>\n ramp(7, (position) => fromOkhst({ h: color.h, s: color.s, t: position })),\n display: (color) => `${Math.round(toOkhst(color).t * 100)}%`,\n};\n\nconst lightnessChannel: ColorChannel = {\n label: 'L',\n title: 'Lightness',\n min: 0,\n max: constant(100),\n step: 1,\n value: (color) => round(toOklch(color).l * 100, 1),\n apply: (color, value) => {\n const { c, h } = toOklch(color);\n\n return fromOklch({ l: value / 100, c, h });\n },\n stops: (color) => {\n const { c, h } = toOklch(color);\n\n return ramp(7, (position) => fromOklch({ l: position, c, h }));\n },\n display: (color) => `${Math.round(toOklch(color).l * 100)}%`,\n};\n\nconst chromaChannel: ColorChannel = {\n label: 'C',\n title: 'Chroma',\n min: 0,\n // Chroma has no fixed ceiling: how far it can go depends on how far the sRGB\n // gamut reaches at the current lightness and hue. Never zero, so the slider\n // always has a range to divide by.\n max: (color) => Math.max(round(maxChroma(color.h, color.l), 4), 0.001),\n step: 0.001,\n value: (color) => round(toOklch(color).c, 4),\n apply: (color, value) => {\n const { l, h } = toOklch(color);\n\n return fromOklch({ l, c: value, h });\n },\n stops: (color) => {\n const { l, h } = toOklch(color);\n const limit = maxChroma(color.h, color.l);\n\n return ramp(7, (position) => fromOklch({ l, c: position * limit, h }));\n },\n display: (color) => toOklch(color).c.toFixed(3),\n};\n\nfunction rgbChannel(\n key: 'r' | 'g' | 'b',\n label: string,\n title: string,\n): ColorChannel {\n const at = (color: ColorValue, value: number) =>\n fromRgb({ ...toRgb(color), [key]: value });\n\n return {\n label,\n title,\n min: 0,\n max: constant(255),\n step: 1,\n value: (color) => toRgb(color)[key],\n apply: (color, value) => {\n const next = at(color, value);\n\n // A gray has no hue of its own, and the conversion invents one. Keeping\n // the authored hue means switching back to HST or LCH resumes where the\n // user left off.\n return isAchromatic(next) ? { ...next, h: color.h } : next;\n },\n // An sRGB channel is linear in the space CSS interpolates gradients in, so\n // the two ends describe the whole ramp exactly.\n stops: (color) => ramp(2, (position) => at(color, position * 255)),\n display: (color) => `${toRgb(color)[key]}`,\n };\n}\n\nexport const CHANNELS: Record<ColorSpace, ColorChannel[]> = {\n hst: [hueChannel, saturationChannel, toneChannel],\n lch: [lightnessChannel, chromaChannel, hueChannel],\n rgb: [\n rgbChannel('r', 'R', 'Red'),\n rgbChannel('g', 'G', 'Green'),\n rgbChannel('b', 'B', 'Blue'),\n ],\n};\n"],"mappings":";;;;;;;;AAkBA,MAAa,eAAe;CAAC;CAAO;CAAO;CAAM;AAIjD,MAAa,qBAAiD;CAC5D,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAED,MAAa,oBAAgD;CAC3D,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAoBD,MAAM,YAAY,gBAAwB;AAE1C,SAAS,MAAM,OAAe,YAAY,GAAW;CACnD,MAAM,SAAS,MAAM;AAErB,QAAO,KAAK,MAAM,QAAQ,OAAO,GAAG;;;;;;;;;AAUtC,SAAS,KAAK,OAAe,IAA8C;AACzE,QAAO,MAAM,KAAK,EAAE,QAAQ,OAAO,GAAG,GAAG,UACvC,MAAM,GAAG,SAAS,QAAQ,GAAG,CAAC,CAC/B,CAAC,KAAK,KAAK;;;;;;;;AASd,MAAM,YAAY,KAAK,KAAK,cAAc;CACxC,GAAG,WAAW;CACd,GAAG;CACH,GAAG;CACJ,EAAE;AAEH,MAAM,aAA2B;CAC/B,OAAO;CACP,OAAO;CACP,KAAK;CAGL,KAAK,SAAS,IAAI;CAClB,MAAM;CACN,QAAQ,UAAU,MAAM,MAAM,GAAG,EAAE;CACnC,QAAQ,OAAO,WAAW;EAAE,GAAG;EAAO,GAAG,aAAa,MAAM;EAAE;CAC9D,aAAa;CACb,UAAU,UAAU,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,oBAAkC;CACtC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK,SAAS,IAAI;CAClB,MAAM;CACN,QAAQ,UAAU,MAAM,MAAM,IAAI,KAAK,EAAE;CACzC,QAAQ,OAAO,WAAW;EAAE,GAAG;EAAO,GAAG,QAAQ;EAAK;CACtD,QAAQ,UAAU,KAAK,IAAI,cAAc;EAAE,GAAG;EAAO,GAAG;EAAU,EAAE;CACpE,UAAU,UAAU,GAAG,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC;CAClD;AAED,MAAM,cAA4B;CAChC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK,SAAS,IAAI;CAClB,MAAM;CACN,QAAQ,UAAU,MAAM,QAAQ,MAAM,CAAC,IAAI,KAAK,EAAE;CAClD,QAAQ,OAAO,UACb,UAAU;EAAE,GAAG,MAAM;EAAG,GAAG,MAAM;EAAG,GAAG,QAAQ;EAAK,CAAC;CACvD,QAAQ,UACN,KAAK,IAAI,aAAa,UAAU;EAAE,GAAG,MAAM;EAAG,GAAG,MAAM;EAAG,GAAG;EAAU,CAAC,CAAC;CAC3E,UAAU,UAAU,GAAG,KAAK,MAAM,QAAQ,MAAM,CAAC,IAAI,IAAI,CAAC;CAC3D;AAED,MAAM,mBAAiC;CACrC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK,SAAS,IAAI;CAClB,MAAM;CACN,QAAQ,UAAU,MAAM,QAAQ,MAAM,CAAC,IAAI,KAAK,EAAE;CAClD,QAAQ,OAAO,UAAU;EACvB,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM;AAE/B,SAAO,UAAU;GAAE,GAAG,QAAQ;GAAK;GAAG;GAAG,CAAC;;CAE5C,QAAQ,UAAU;EAChB,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM;AAE/B,SAAO,KAAK,IAAI,aAAa,UAAU;GAAE,GAAG;GAAU;GAAG;GAAG,CAAC,CAAC;;CAEhE,UAAU,UAAU,GAAG,KAAK,MAAM,QAAQ,MAAM,CAAC,IAAI,IAAI,CAAC;CAC3D;AAED,MAAM,gBAA8B;CAClC,OAAO;CACP,OAAO;CACP,KAAK;CAIL,MAAM,UAAU,KAAK,IAAI,MAAM,UAAU,MAAM,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,KAAM;CACtE,MAAM;CACN,QAAQ,UAAU,MAAM,QAAQ,MAAM,CAAC,GAAG,EAAE;CAC5C,QAAQ,OAAO,UAAU;EACvB,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM;AAE/B,SAAO,UAAU;GAAE;GAAG,GAAG;GAAO;GAAG,CAAC;;CAEtC,QAAQ,UAAU;EAChB,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM;EAC/B,MAAM,QAAQ,UAAU,MAAM,GAAG,MAAM,EAAE;AAEzC,SAAO,KAAK,IAAI,aAAa,UAAU;GAAE;GAAG,GAAG,WAAW;GAAO;GAAG,CAAC,CAAC;;CAExE,UAAU,UAAU,QAAQ,MAAM,CAAC,EAAE,QAAQ,EAAE;CAChD;AAED,SAAS,WACP,KACA,OACA,OACc;CACd,MAAM,MAAM,OAAmB,UAC7B,QAAQ;EAAE,GAAG,MAAM,MAAM;GAAG,MAAM;EAAO,CAAC;AAE5C,QAAO;EACL;EACA;EACA,KAAK;EACL,KAAK,SAAS,IAAI;EAClB,MAAM;EACN,QAAQ,UAAU,MAAM,MAAM,CAAC;EAC/B,QAAQ,OAAO,UAAU;GACvB,MAAM,OAAO,GAAG,OAAO,MAAM;AAK7B,UAAO,aAAa,KAAK,GAAG;IAAE,GAAG;IAAM,GAAG,MAAM;IAAG,GAAG;;EAIxD,QAAQ,UAAU,KAAK,IAAI,aAAa,GAAG,OAAO,WAAW,IAAI,CAAC;EAClE,UAAU,UAAU,GAAG,MAAM,MAAM,CAAC;EACrC;;AAGH,MAAa,WAA+C;CAC1D,KAAK;EAAC;EAAY;EAAmB;EAAY;CACjD,KAAK;EAAC;EAAkB;EAAe;EAAW;CAClD,KAAK;EACH,WAAW,KAAK,KAAK,MAAM;EAC3B,WAAW,KAAK,KAAK,QAAQ;EAC7B,WAAW,KAAK,KAAK,OAAO;EAC7B;CACF"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { OkhslColor } from "@tenphi/glaze";
|
|
3
|
-
|
|
4
|
-
//#region src/components/fields/color/color.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Every color format the picker can read and write.
|
|
7
|
-
*
|
|
8
|
-
* `okhsl` and `okhst` are Glaze / Tasty spaces rather than native CSS ones,
|
|
9
|
-
* but Tasty parses both, so the produced strings are usable as style values.
|
|
10
|
-
*/
|
|
11
|
-
declare const COLOR_FORMATS: readonly ["hex", "rgb", "hsl", "okhsl", "okhst", "oklch"];
|
|
12
|
-
type ColorFormat = (typeof COLOR_FORMATS)[number];
|
|
13
|
-
/**
|
|
14
|
-
* OKHSL is the canonical space of the picker: it is Glaze's authoring space,
|
|
15
|
-
* every channel is bounded, and — unlike OKLCh — every value inside those
|
|
16
|
-
* bounds is inside the sRGB gamut, so no state can be unrepresentable.
|
|
17
|
-
*/
|
|
18
|
-
type ColorValue = OkhslColor;
|
|
19
|
-
//#endregion
|
|
20
|
-
export { COLOR_FORMATS, ColorFormat, ColorValue };
|
|
21
|
-
//# sourceMappingURL=color.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"color.js","names":[],"sources":["../../../../src/components/fields/color/color.ts"],"sourcesContent":["import {\n contrastRatioFromLuminance,\n formatHsl,\n formatOkhsl,\n formatOkhst,\n formatOklch,\n formatRgb,\n hslToSrgb,\n okhslToLinearSrgb,\n okhslToOkhst,\n okhslToOklch,\n okhslToSrgb,\n okhstToOkhsl,\n oklabToOkhsl,\n parseHexAlpha,\n relativeLuminanceFromLinearRgb,\n srgbToHex,\n srgbToOkhsl,\n} from '@tenphi/glaze';\n\nimport type {\n OkhslColor,\n OkhstColor,\n OklchColor,\n RgbColor,\n} from '@tenphi/glaze';\n\nexport type { OkhslColor, OkhstColor, OklchColor, RgbColor };\n\n/**\n * Every color format the picker can read and write.\n *\n * `okhsl` and `okhst` are Glaze / Tasty spaces rather than native CSS ones,\n * but Tasty parses both, so the produced strings are usable as style values.\n */\nexport const COLOR_FORMATS = [\n 'hex',\n 'rgb',\n 'hsl',\n 'okhsl',\n 'okhst',\n 'oklch',\n] as const;\n\nexport type ColorFormat = (typeof COLOR_FORMATS)[number];\n\n/**\n * OKHSL is the canonical space of the picker: it is Glaze's authoring space,\n * every channel is bounded, and — unlike OKLCh — every value inside those\n * bounds is inside the sRGB gamut, so no state can be unrepresentable.\n */\nexport type ColorValue = OkhslColor;\n\nconst FUNCTION_RE = /^([a-z]+)\\(([^()]+)\\)$/;\n/**\n * A number with an optional `%` or `deg` unit.\n *\n * The integer and fraction parts are deliberately written so that no two\n * quantifiers can consume the same digit — `\\d+(?:\\.\\d*)?` rather than\n * `\\d+\\.?\\d*`, whose `\\d+` and `\\d*` can split a digit run n ways and make\n * rejecting a long one quadratic. This runs on whatever the user types.\n */\nconst NUMBER_RE = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?(?:%|deg)?$/;\n\n/**\n * Saturation below this rounds to `0%` in every output notation, so the color\n * is achromatic for display purposes even when the conversion left a residue.\n */\nconst ACHROMATIC_SATURATION = 5e-5;\n\nfunction clamp(value: number, min: number, max: number): number {\n return value < min ? min : value > max ? max : value;\n}\n\nexport function normalizeHue(hue: number): number {\n if (!Number.isFinite(hue)) return 0;\n\n return ((hue % 360) + 360) % 360;\n}\n\n/**\n * The color carries no meaningful hue: every conversion out of it invents an\n * angle, so callers that need one should keep the hue they already had.\n */\nexport function isAchromatic(color: ColorValue): boolean {\n return color.s < ACHROMATIC_SATURATION;\n}\n\n/** Both channel objects describe the same color, within display precision. */\nexport function isSameColor(a?: ColorValue | null, b?: ColorValue | null) {\n if (!a || !b) return a === b;\n\n return (\n Math.abs(a.h - b.h) < 1e-6 &&\n Math.abs(a.s - b.s) < 1e-6 &&\n Math.abs(a.l - b.l) < 1e-6\n );\n}\n\n/**\n * Split a color-function body into its numeric arguments, dropping the alpha\n * component. Both the modern space-separated and the legacy comma-separated\n * syntaxes are accepted.\n *\n * Each argument keeps its unit so the caller can tell `50%` from `50`.\n */\nfunction splitArguments(body: string): string[] | null {\n const [values, ...rest] = body.split('/');\n\n // More than one slash is never valid syntax.\n if (rest.length > 1) return null;\n\n const args = values\n .trim()\n .split(values.includes(',') ? ',' : /\\s+/)\n .map((part) => part.trim())\n .filter(Boolean);\n\n // Legacy `rgba(r, g, b, a)` / `hsla(h, s, l, a)` carry alpha as a fourth\n // argument. Alpha is not part of the value, so it is dropped either way.\n if (args.length === 4) args.pop();\n\n return args.every((arg) => NUMBER_RE.test(arg)) ? args : null;\n}\n\n/** Parse an argument that may carry a `%` unit. `scale` is the 100% value. */\nfunction scalar(arg: string, scale: number): number {\n return arg.endsWith('%') ? (parseFloat(arg) / 100) * scale : parseFloat(arg);\n}\n\nfunction hueArgument(arg: string): number {\n // A percentage is not a valid hue angle.\n return arg.endsWith('%') ? NaN : normalizeHue(parseFloat(arg));\n}\n\nexport function fromRgb(color: RgbColor): ColorValue {\n const [h, s, l] = srgbToOkhsl([\n clamp(color.r, 0, 255) / 255,\n clamp(color.g, 0, 255) / 255,\n clamp(color.b, 0, 255) / 255,\n ]);\n\n return { h: normalizeHue(h), s: clamp(s, 0, 1), l: clamp(l, 0, 1) };\n}\n\nexport function toRgb(color: ColorValue): RgbColor {\n const [r, g, b] = okhslToSrgb(color.h, color.s, color.l);\n\n return {\n r: Math.round(clamp(r, 0, 1) * 255),\n g: Math.round(clamp(g, 0, 1) * 255),\n b: Math.round(clamp(b, 0, 1) * 255),\n };\n}\n\nexport function fromOkhst(color: OkhstColor): ColorValue {\n const { h, s, l } = okhstToOkhsl({\n h: normalizeHue(color.h),\n s: clamp(color.s, 0, 1),\n t: clamp(color.t, 0, 1),\n });\n\n return { h: normalizeHue(h), s: clamp(s, 0, 1), l: clamp(l, 0, 1) };\n}\n\nexport function toOkhst(color: ColorValue): OkhstColor {\n const { t } = okhslToOkhst(color);\n\n return { h: color.h, s: color.s, t: clamp(t, 0, 1) };\n}\n\n/**\n * The largest OKLCh chroma that stays inside the sRGB gamut for the given hue\n * and OKHSL lightness — that is exactly what OKHSL saturation `1` means.\n */\nexport function maxChroma(hue: number, lightness: number): number {\n return okhslToOklch(normalizeHue(hue), 1, clamp(lightness, 0, 1))[1];\n}\n\nexport function toOklch(color: ColorValue): OklchColor {\n const [l, c, h] = okhslToOklch(color.h, color.s, color.l);\n\n return { l, c, h: normalizeHue(h) };\n}\n\n/**\n * OKLCh addresses colors outside the sRGB gamut, so chroma is clipped to the\n * gamut boundary at the requested lightness before it is stored. Hue is taken\n * from the input rather than from the conversion, which loses it at zero\n * chroma.\n */\nexport function fromOklch(color: OklchColor): ColorValue {\n const h = normalizeHue(color.h);\n const c = Math.max(color.c, 0);\n const radians = (h * Math.PI) / 180;\n const [, s, l] = oklabToOkhsl([\n clamp(color.l, 0, 1),\n c * Math.cos(radians),\n c * Math.sin(radians),\n ]);\n const limit = maxChroma(h, l);\n\n return {\n h,\n s: limit > 0 ? (c >= limit ? 1 : clamp(s, 0, 1)) : 0,\n l: clamp(l, 0, 1),\n };\n}\n\nexport function toHex(color: ColorValue): string {\n return srgbToHex(okhslToSrgb(color.h, color.s, color.l));\n}\n\n/**\n * Read any supported color notation into the canonical space. Returns `null`\n * for anything that is not a real color — that is what lets the picker reject\n * partial input instead of guessing.\n *\n * Named CSS colors (`red`, `rebeccapurple`) are intentionally not supported,\n * matching `glaze.color()`.\n */\nexport function parseColor(input: string): ColorValue | null {\n const text = input.trim().toLowerCase();\n\n if (!text) return null;\n\n if (text.startsWith('#')) {\n const parsed = parseHexAlpha(text);\n\n return parsed ? fromRgb(rgbFromSrgb(parsed.rgb)) : null;\n }\n\n const match = FUNCTION_RE.exec(text);\n\n if (!match) return null;\n\n const [, name, body] = match;\n const args = splitArguments(body);\n\n if (!args || args.length !== 3) return null;\n\n switch (name) {\n case 'rgb':\n case 'rgba': {\n const [r, g, b] = args.map((arg) => scalar(arg, 255));\n\n return anyNaN(r, g, b) ? null : fromRgb({ r, g, b });\n }\n case 'hsl':\n case 'hsla': {\n const h = hueArgument(args[0]);\n const s = scalar(args[1], 100) / 100;\n const l = scalar(args[2], 100) / 100;\n\n if (anyNaN(h, s, l)) return null;\n\n return fromRgb(rgbFromSrgb(hslToSrgb(h, clamp(s, 0, 1), clamp(l, 0, 1))));\n }\n case 'okhsl': {\n const h = hueArgument(args[0]);\n const s = scalar(args[1], 100) / 100;\n const l = scalar(args[2], 100) / 100;\n\n if (anyNaN(h, s, l)) return null;\n\n return { h, s: clamp(s, 0, 1), l: clamp(l, 0, 1) };\n }\n case 'okhst': {\n const h = hueArgument(args[0]);\n const s = scalar(args[1], 100) / 100;\n const t = scalar(args[2], 100) / 100;\n\n if (anyNaN(h, s, t)) return null;\n\n return fromOkhst({ h, s, t });\n }\n case 'oklch': {\n // In `oklch()` a percentage means 1 for lightness and 0.4 for chroma.\n const l = scalar(args[0], 1);\n const c = scalar(args[1], 0.4);\n const h = hueArgument(args[2]);\n\n return anyNaN(l, c, h) ? null : fromOklch({ l, c, h });\n }\n default:\n return null;\n }\n}\n\nfunction anyNaN(...values: number[]): boolean {\n return values.some((value) => !Number.isFinite(value));\n}\n\nfunction rgbFromSrgb([r, g, b]: [number, number, number]): RgbColor {\n return { r: r * 255, g: g * 255, b: b * 255 };\n}\n\n/** Serialize the canonical color into one of the supported notations. */\nexport function formatColor(color: ColorValue, format: ColorFormat): string {\n // An achromatic color has no meaningful hue, and the conversions leave\n // whatever angle the source happened to carry. Zero reads better.\n const gray = isAchromatic(color);\n const hue = gray ? 0 : color.h;\n const saturation = color.s * 100;\n const lightness = color.l * 100;\n\n switch (format) {\n case 'rgb':\n return formatRgb(hue, saturation, lightness);\n case 'hsl': {\n const text = formatHsl(hue, saturation, lightness);\n\n // CSS HSL derives its hue from the sRGB channels, which is undefined\n // when they are equal — Glaze emits whatever the formula produces. Every\n // other notation carries the hue through, so only HSL needs this.\n return gray ? text.replace(/\\(-?[\\d.]+/, '(0') : text;\n }\n case 'okhsl':\n return formatOkhsl(hue, saturation, lightness);\n case 'okhst':\n return formatOkhst(hue, saturation, toOkhst(color).t * 100);\n case 'oklch':\n return formatOklch(hue, saturation, lightness);\n default:\n return toHex(color);\n }\n}\n\n/**\n * Which notation a string is written in, or `null` when it is not a color.\n * Used to keep the user's own notation while still normalizing the value.\n */\nexport function detectFormat(input: string): ColorFormat | null {\n const text = input.trim().toLowerCase();\n\n if (!parseColor(text)) return null;\n\n if (text.startsWith('#')) return 'hex';\n\n const name = FUNCTION_RE.exec(text)?.[1];\n\n switch (name) {\n case 'rgb':\n case 'rgba':\n return 'rgb';\n case 'hsl':\n case 'hsla':\n return 'hsl';\n case 'okhsl':\n return 'okhsl';\n case 'okhst':\n return 'okhst';\n case 'oklch':\n return 'oklch';\n default:\n return null;\n }\n}\n\n/**\n * Black or white — whichever the WCAG contrast ratio favors on the given\n * color. Keeps the popover preview label readable at any lightness. Returns a\n * literal hex rather than a token, because the answer is measured against this\n * exact fill and must not adapt with the color scheme.\n */\nexport function getContrastingColor(color: ColorValue): '#000000' | '#ffffff' {\n const luminance = relativeLuminanceFromLinearRgb(\n okhslToLinearSrgb(color.h, color.s, color.l),\n );\n\n return contrastRatioFromLuminance(luminance, 0) >=\n contrastRatioFromLuminance(1, luminance)\n ? '#000000'\n : '#ffffff';\n}\n"],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e530064 | Cube Dev Team */
|
|
2
|
-
import { createContext, useContext } from "react";
|
|
3
|
-
|
|
4
|
-
//#region src/components/fields/color/context.ts
|
|
5
|
-
/**
|
|
6
|
-
* Marks the subtree inside a color popover.
|
|
7
|
-
*
|
|
8
|
-
* A `ColorSwatchGroup` offers a custom-color escape hatch, and that escape
|
|
9
|
-
* hatch is a `ColorPicker` — which opens a popover that may itself contain a
|
|
10
|
-
* swatch group. Reading this flag lets the group drop the escape hatch when it
|
|
11
|
-
* is already inside one, so the recursion cannot be written even by accident.
|
|
12
|
-
*/
|
|
13
|
-
const ColorPopoverContext = createContext(false);
|
|
14
|
-
function useIsInsideColorPopover() {
|
|
15
|
-
return useContext(ColorPopoverContext);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
|
-
export { ColorPopoverContext, useIsInsideColorPopover };
|
|
20
|
-
//# sourceMappingURL=context.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../../../../src/components/fields/color/context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n/**\n * Marks the subtree inside a color popover.\n *\n * A `ColorSwatchGroup` offers a custom-color escape hatch, and that escape\n * hatch is a `ColorPicker` — which opens a popover that may itself contain a\n * swatch group. Reading this flag lets the group drop the escape hatch when it\n * is already inside one, so the recursion cannot be written even by accident.\n */\nexport const ColorPopoverContext = createContext(false);\n\nexport function useIsInsideColorPopover(): boolean {\n return useContext(ColorPopoverContext);\n}\n"],"mappings":";;;;;;;;;;;;AAUA,MAAa,sBAAsB,cAAc,MAAM;AAEvD,SAAgB,0BAAmC;AACjD,QAAO,WAAW,oBAAoB"}
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
# ColorInput
|
|
2
|
-
|
|
3
|
-
An input for a single color. It reads and writes color **text** — hex, `rgb()`,
|
|
4
|
-
`hsl()`, `okhsl()`, `okhst()` and `oklch()` — shows the current color as a
|
|
5
|
-
swatch, and opens a popover where the color can be dialed in on three
|
|
6
|
-
perceptual axes.
|
|
7
|
-
|
|
8
|
-
Every conversion goes through [Glaze](https://github.com/tenphi/glaze), so the
|
|
9
|
-
canonical value the picker holds is OKHSL: bounded on every channel, and always
|
|
10
|
-
inside the sRGB gamut. That is what makes an out-of-gamut state impossible and
|
|
11
|
-
lets the same value be re-serialized into any of the supported notations without
|
|
12
|
-
drift.
|
|
13
|
-
|
|
14
|
-
## When to Use
|
|
15
|
-
|
|
16
|
-
- Theme and branding forms — a seed color, an accent, a chart series color
|
|
17
|
-
- Anywhere a color has to be typed *or* explored, rather than chosen from a
|
|
18
|
-
fixed palette
|
|
19
|
-
- When the stored format matters (a design token file wants `oklch()`, a legacy
|
|
20
|
-
API wants hex) and the input has to guarantee it
|
|
21
|
-
|
|
22
|
-
Reach for a `RadioGroup` or `Picker` of swatches instead when the choice is
|
|
23
|
-
limited to a handful of approved colors.
|
|
24
|
-
|
|
25
|
-
## Component
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
### Properties
|
|
30
|
-
|
|
31
|
-
- **`value`** `string | null` — The selected color (controlled)
|
|
32
|
-
- **`defaultValue`** `string | null` — The selected color (uncontrolled)
|
|
33
|
-
- **`onChange`** `(value: string | null) => void` — Fired with the color string, or `null` when the field is cleared
|
|
34
|
-
- **`format`** `'hex' | 'rgb' | 'hsl' | 'okhsl' | 'okhst' | 'oklch'` (default: `hex`) — Notation the value is written in, and the one `forced` mode displays
|
|
35
|
-
- **`formatMode`** `'forced' | 'derive' | 'free'` (default: `forced`) — How strictly the input text is tied to `format`
|
|
36
|
-
- **`defaultSpace`** `'hst' | 'lch' | 'rgb'` (default: `hst`) — Color concept the popover opens with
|
|
37
|
-
- **`placeholder`** `string` (default: `Pick a color`) — Text shown while the field is empty
|
|
38
|
-
- **`size`** `'small' | 'medium' | 'large' | (string & {})` (default: `medium`) — Input size
|
|
39
|
-
- **`isOpen`** `boolean` — Whether the popover is open (controlled)
|
|
40
|
-
- **`defaultOpen`** `boolean` (default: `false`) — Whether the popover is open initially
|
|
41
|
-
- **`onOpenChange`** `(isOpen: boolean) => void` — Fired when the popover opens or closes
|
|
42
|
-
- **`shouldFlip`** `boolean` (default: `true`) — Whether the popover may flip to the other side of the input
|
|
43
|
-
- **`onFocus`** `(event: FocusEvent) => void` — Fired when the text input receives focus
|
|
44
|
-
- **`onBlur`** `(event: FocusEvent) => void` — Fired when the text input loses focus
|
|
45
|
-
|
|
46
|
-
Named CSS colors (`red`, `rebeccapurple`) are **not** accepted — they are not a
|
|
47
|
-
color space, and Glaze does not resolve them either. Alpha is parsed but
|
|
48
|
-
dropped: the value is always opaque.
|
|
49
|
-
|
|
50
|
-
Focusing the field selects the whole value, so a pasted color replaces it
|
|
51
|
-
outright. The string is the unit of editing here: a single channel is tuned with
|
|
52
|
-
the sliders rather than by hand-editing one number inside `oklch(…)`. Clicking a
|
|
53
|
-
field that already has focus positions the caret as usual, so the text stays
|
|
54
|
-
editable by hand.
|
|
55
|
-
|
|
56
|
-
Rendered inside a color popover — as `ColorPicker` does at the top of its panel
|
|
57
|
-
— the trigger is dropped automatically, since the popover it would open is the
|
|
58
|
-
one already showing.
|
|
59
|
-
|
|
60
|
-
### Base Properties
|
|
61
|
-
|
|
62
|
-
Supports [Base properties](../../BaseProperties.md)
|
|
63
|
-
|
|
64
|
-
### Field Properties
|
|
65
|
-
|
|
66
|
-
Supports all [Field properties](../../FieldProperties.md)
|
|
67
|
-
|
|
68
|
-
### Styling Properties
|
|
69
|
-
|
|
70
|
-
#### styles
|
|
71
|
-
|
|
72
|
-
Customizes the input wrapper — the element that owns the border, fill and size.
|
|
73
|
-
|
|
74
|
-
**Sub-elements:**
|
|
75
|
-
|
|
76
|
-
- `Prefix` — the container holding the color swatch
|
|
77
|
-
- `Suffix` — the container holding the validation state, then the popover trigger
|
|
78
|
-
- `InputIcon` — the swatch slot
|
|
79
|
-
- `State` — the validation / loading indicator
|
|
80
|
-
|
|
81
|
-
#### inputStyles
|
|
82
|
-
|
|
83
|
-
Customizes the `<input>` element itself.
|
|
84
|
-
|
|
85
|
-
#### triggerStyles
|
|
86
|
-
|
|
87
|
-
Customizes the popover trigger button.
|
|
88
|
-
|
|
89
|
-
#### swatchStyles
|
|
90
|
-
|
|
91
|
-
Customizes the color swatch shown inside the input.
|
|
92
|
-
|
|
93
|
-
### Style Properties
|
|
94
|
-
|
|
95
|
-
These properties allow direct style application without using the `styles` prop:
|
|
96
|
-
|
|
97
|
-
- **Base:** `display`, `font`, `preset`, `hide`, `whiteSpace`, `opacity`, `transition`
|
|
98
|
-
- **Position:** `gridArea`, `order`, `gridColumn`, `gridRow`, `placeSelf`, `alignSelf`, `justifySelf`, `zIndex`, `margin`, `inset`, `position`, `scrollMargin`
|
|
99
|
-
- **Dimension:** `width`, `height`, `flexBasis`, `flexGrow`, `flexShrink`, `flex`
|
|
100
|
-
- **Block:** `border`, `radius`, `shadow`, `outline`, `padding`, `paddingInline`, `paddingBlock`, `overflow`, `scrollbar`, `textAlign`
|
|
101
|
-
- **Color:** `color`, `fill`, `fade`, `image`
|
|
102
|
-
|
|
103
|
-
### Modifiers
|
|
104
|
-
|
|
105
|
-
The `mods` property accepts the following modifiers you can override:
|
|
106
|
-
|
|
107
|
-
| Modifier | Type | Description |
|
|
108
|
-
| ---------- | --------- | ------------------------------------------------- |
|
|
109
|
-
| `focused` | `boolean` | The text input has focus |
|
|
110
|
-
| `hovered` | `boolean` | The pointer is over the input |
|
|
111
|
-
| `disabled` | `boolean` | The picker is disabled |
|
|
112
|
-
| `valid` | `boolean` | The field is in the valid state |
|
|
113
|
-
| `invalid` | `boolean` | The field is in the invalid state |
|
|
114
|
-
| `prefix` | `boolean` | A prefix (the swatch) is rendered |
|
|
115
|
-
| `suffix` | `boolean` | A suffix (the trigger) is rendered |
|
|
116
|
-
|
|
117
|
-
The swatch carries its own `empty` modifier while there is no color to show.
|
|
118
|
-
|
|
119
|
-
## Format modes
|
|
120
|
-
|
|
121
|
-
The three modes differ in how much freedom the *text* gets. The value is always
|
|
122
|
-
a real color in every one of them.
|
|
123
|
-
|
|
124
|
-
| Mode | Text | Value |
|
|
125
|
-
| -------- | ----------------------------------- | ---------------------------------------------------- |
|
|
126
|
-
| `forced` | Rewritten in `format` on blur/Enter | Written in `format` from the first change on |
|
|
127
|
-
| `derive` | Left exactly as typed | Normalized in the notation the text is written in |
|
|
128
|
-
| `free` | Left exactly as typed | The text itself, verbatim |
|
|
129
|
-
|
|
130
|
-
In every mode an entry that is not a color is rejected: the previous valid color
|
|
131
|
-
stays the value while it is being typed, and the text snaps back to it on blur.
|
|
132
|
-
Emptying the field is not an error — it commits `null`.
|
|
133
|
-
|
|
134
|
-
**The value you pass in is left as you wrote it.** No mode reformats it on mount,
|
|
135
|
-
including `forced` — doing so would mean calling `onChange` before the user has
|
|
136
|
-
touched anything, which marks a form dirty for no reason. `forced` normalizes the
|
|
137
|
-
text for display straight away, so the field can show `#7a4dbf` while the value
|
|
138
|
-
is still the `rgb(122 77 191)` you supplied; from the first change onward the
|
|
139
|
-
value is written in `format` too. Normalize before storing if the notation
|
|
140
|
-
matters to you from the outset.
|
|
141
|
-
|
|
142
|
-
```jsx
|
|
143
|
-
// A design-token form that must store OKLCH
|
|
144
|
-
<ColorInput label="Accent" format="oklch" onChange={setAccent} />
|
|
145
|
-
|
|
146
|
-
// A CSS editor: keep whatever the author wrote, but guarantee it parses
|
|
147
|
-
<ColorInput label="Color" formatMode="free" onChange={setCss} />
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Color spaces
|
|
151
|
-
|
|
152
|
-
The popover edits one canonical color through three sets of axes:
|
|
153
|
-
|
|
154
|
-
| Space | Axes | Good for |
|
|
155
|
-
| ----- | ----------------------------- | ----------------------------------------------------- |
|
|
156
|
-
| `hst` | Hue, Saturation, Tone (OKHST) | Building ramps — equal tone steps read as equal steps |
|
|
157
|
-
| `lch` | Lightness, Chroma, Hue (OKLCH)| Matching a value from a design-token file |
|
|
158
|
-
| `rgb` | Red, Green, Blue | Matching a value from a legacy palette or a screenshot|
|
|
159
|
-
|
|
160
|
-
Each of these opens on its own space; the switcher inside the popover moves
|
|
161
|
-
between them at any time.
|
|
162
|
-
|
|
163
|
-
`H` means the same angle in HST and LCH, so the hue strip is identical in both.
|
|
164
|
-
The chroma slider is bounded by the sRGB gamut at the current lightness and hue,
|
|
165
|
-
which is why its range changes as `L` moves.
|
|
166
|
-
|
|
167
|
-
## Examples
|
|
168
|
-
|
|
169
|
-
### Basic usage
|
|
170
|
-
|
|
171
|
-
```jsx
|
|
172
|
-
<ColorInput label="Brand color" defaultValue="#7a4dbf" />
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Controlled
|
|
176
|
-
|
|
177
|
-
```jsx
|
|
178
|
-
const [color, setColor] = useState('#7a4dbf');
|
|
179
|
-
|
|
180
|
-
<ColorInput label="Brand color" value={color} onChange={setColor} />;
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Inside a form
|
|
184
|
-
|
|
185
|
-
```jsx
|
|
186
|
-
<Form onSubmit={onSubmit}>
|
|
187
|
-
<ColorInput
|
|
188
|
-
name="accent"
|
|
189
|
-
label="Accent color"
|
|
190
|
-
format="oklch"
|
|
191
|
-
rules={[{ required: true, message: 'Pick an accent color' }]}
|
|
192
|
-
/>
|
|
193
|
-
</Form>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Opening on a specific space
|
|
197
|
-
|
|
198
|
-
```jsx
|
|
199
|
-
<ColorInput label="Series color" defaultSpace="rgb" defaultValue="#26fcb2" />
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Using the value as a style
|
|
203
|
-
|
|
204
|
-
Because the emitted value is a plain color string, it can go straight into a
|
|
205
|
-
tasty style — including the `okhsl()` and `okhst()` notations, which tasty
|
|
206
|
-
parses natively.
|
|
207
|
-
|
|
208
|
-
```jsx
|
|
209
|
-
const [color, setColor] = useState('okhst(264 80% 60%)');
|
|
210
|
-
|
|
211
|
-
<>
|
|
212
|
-
<ColorInput label="Fill" format="okhst" value={color} onChange={setColor} />
|
|
213
|
-
<Block fill={color} height="10x" radius="1r" />
|
|
214
|
-
</>;
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## Accessibility
|
|
218
|
-
|
|
219
|
-
### Keyboard Navigation
|
|
220
|
-
|
|
221
|
-
- `Tab` — moves focus to the text input, then to the popover trigger
|
|
222
|
-
- `Enter` — commits and normalizes the typed color without leaving the field
|
|
223
|
-
- `Space` / `Enter` on the trigger — opens the popover
|
|
224
|
-
- `Escape` — closes the popover
|
|
225
|
-
- `Left` / `Right`, `Home` / `End` on a channel slider — moves that channel
|
|
226
|
-
- `Left` / `Right` on the space switcher — moves between HST, LCH and RGB
|
|
227
|
-
|
|
228
|
-
### Screen Reader Support
|
|
229
|
-
|
|
230
|
-
- The text input announces as a textbox with the field's label
|
|
231
|
-
- The trigger announces as "Open the color picker"
|
|
232
|
-
- The popover announces as a dialog named "Color picker"
|
|
233
|
-
- Each channel slider sits in a group named after its axis (`Hue`,
|
|
234
|
-
`Saturation`, `Tone`, `Lightness`, `Chroma`, `Red`, `Green`, `Blue`)
|
|
235
|
-
- The swatch is decorative and is not announced — the text carries the value
|
|
236
|
-
|
|
237
|
-
### ARIA Properties
|
|
238
|
-
|
|
239
|
-
- `aria-label` — names the field when there is no visible label
|
|
240
|
-
- `aria-describedby` — wired to the field description by the form system
|
|
241
|
-
|
|
242
|
-
## Best Practices
|
|
243
|
-
|
|
244
|
-
1. **Do**: name the field, so the text input is announced meaningfully
|
|
245
|
-
|
|
246
|
-
```jsx
|
|
247
|
-
<ColorInput label="Brand color" />
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
2. **Don't**: rely on the swatch alone to convey the value
|
|
251
|
-
|
|
252
|
-
```jsx
|
|
253
|
-
<ColorInput aria-label="" />
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
3. **Do**: pick the `format` your backend stores, and leave `formatMode` at
|
|
257
|
-
`forced` so the two can never disagree.
|
|
258
|
-
|
|
259
|
-
4. **Don't**: use `free` mode when the value is later parsed by something
|
|
260
|
-
stricter than a browser — the text is passed through as written.
|
|
261
|
-
|
|
262
|
-
## Integration with Forms
|
|
263
|
-
|
|
264
|
-
This component supports all
|
|
265
|
-
[Field properties](../../FieldProperties.md) when used
|
|
266
|
-
within a Form. The field value is the color string, and clearing the input
|
|
267
|
-
stores `null`, which makes `required` rules behave as expected.
|
|
268
|
-
|
|
269
|
-
## Suggested Improvements
|
|
270
|
-
|
|
271
|
-
- An eyedropper that samples a pixel from the page, where
|
|
272
|
-
[`EyeDropper`](https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper) is
|
|
273
|
-
available
|
|
274
|
-
- Optional alpha support, which the canonical value currently drops
|
|
275
|
-
- A row of recent or preset swatches inside the popover
|
|
276
|
-
- Editable numeric inputs next to each channel slider, for exact entry without
|
|
277
|
-
going through the text field
|
|
278
|
-
|
|
279
|
-
## Related Components
|
|
280
|
-
|
|
281
|
-
- [ColorPicker](./ColorPicker.md) — the same popover behind a swatch button, when the color is never typed
|
|
282
|
-
- [HueSlider](./HueSlider.md) — just the hue axis, when only a hue is needed
|
|
283
|
-
- [Slider](./Slider.md) — the primitive each channel is built from
|
|
284
|
-
- [TextInput](./TextInput.md) — the input chrome this component reuses
|