@cube-dev/ui-kit 0.157.3 → 0.159.0
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/CHANGELOG.md +155 -0
- 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.js +10 -4
- package/dist/components/actions/Button/Button.js.map +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 +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.d.ts +7 -0
- package/dist/components/content/Item/Item.js +13 -6
- package/dist/components/content/Item/Item.js.map +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 +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 +41 -32
- package/dist/components/content/use-auto-tooltip.js.map +1 -1
- package/dist/components/data/DataTable/DataTable.js +82 -24
- package/dist/components/data/DataTable/DataTable.js.map +1 -1
- package/dist/components/data/DataTable/types.d.ts +56 -1
- package/dist/components/data/ItemTable/ItemTable.js +13 -5
- package/dist/components/data/ItemTable/ItemTable.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +3 -7
- package/dist/components/data/ItemTable/ItemTableBulkBar.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
- package/dist/components/data/ItemTable/ItemTableToolbar.js +1 -1
- package/dist/components/data/ItemTable/types.d.ts +19 -0
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/RowCollection.js +5 -3
- package/dist/components/data/TableBase/RowCollection.js.map +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +115 -0
- package/dist/components/data/TableBase/TableHeaderCell.js.map +1 -0
- package/dist/components/data/TableBase/TableRow.js +1 -1
- package/dist/components/data/TableBase/TableView.js +195 -33
- package/dist/components/data/TableBase/TableView.js.map +1 -1
- package/dist/components/data/TableBase/column-menu.d.ts +36 -0
- package/dist/components/data/TableBase/column-menu.js +104 -0
- package/dist/components/data/TableBase/column-menu.js.map +1 -0
- package/dist/components/data/TableBase/column-tint.js +168 -0
- package/dist/components/data/TableBase/column-tint.js.map +1 -0
- package/dist/components/data/TableBase/index.d.ts +3 -2
- package/dist/components/data/TableBase/row-menu.js +11 -6
- package/dist/components/data/TableBase/row-menu.js.map +1 -1
- package/dist/components/data/TableBase/styled.js +45 -16
- package/dist/components/data/TableBase/styled.js.map +1 -1
- package/dist/components/data/TableBase/types.d.ts +104 -6
- package/dist/components/data/TableBase/types.js +1 -1
- package/dist/components/data/TableBase/types.js.map +1 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-column-order.js +100 -0
- package/dist/components/data/TableBase/use-column-order.js.map +1 -0
- package/dist/components/data/TableBase/use-container-width.js +1 -1
- package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
- package/dist/components/data/TableBase/use-scrollability.js +1 -1
- package/dist/components/data/TableBase/use-table-columns.js +24 -2
- package/dist/components/data/TableBase/use-table-columns.js.map +1 -1
- package/dist/components/data/TableBase/use-table-search.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +20 -1
- package/dist/components/data/TableBase/use-table-sort.js.map +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +40 -1
- package/dist/components/data/TableBase/use-table-sorts.js.map +1 -1
- package/dist/components/data/TableBase/use-table-storage.d.ts +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +6 -2
- package/dist/components/data/TableBase/use-table-storage.js.map +1 -1
- package/dist/components/data/index.d.ts +2 -1
- 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/ColorInput/ColorInput.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.js +1 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +1 -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 +1 -1
- 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/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.js +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/color/ColorPanel.js +1 -1
- package/dist/components/fields/color/ColorSwatch.js +1 -1
- package/dist/components/fields/color/channels.js +1 -1
- package/dist/components/fields/color/color.js +1 -1
- package/dist/components/fields/color/context.js +1 -1
- 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.js +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js +1 -1
- 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/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.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -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/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.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/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +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 +13 -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 +5 -1
- package/dist/i18n/locales/en-US/uikit.js +5 -1
- package/dist/i18n/locales/en-US/uikit.json.d.ts +4 -0
- package/dist/i18n/locales/es-ES/uikit.js +5 -1
- package/dist/i18n/locales/es-MX/uikit.js +5 -1
- package/dist/i18n/locales/fr-FR/uikit.js +5 -1
- package/dist/i18n/locales/it-IT/uikit.js +5 -1
- package/dist/i18n/locales/ja-JP/uikit.js +5 -1
- package/dist/i18n/locales/nb-NO/uikit.js +5 -1
- package/dist/i18n/locales/pt-BR/uikit.js +5 -1
- package/dist/i18n/locales/pt-PT/uikit.js +5 -1
- package/dist/i18n/locales/sv-SE/uikit.js +5 -1
- package/dist/i18n/locales/vi-VN/uikit.js +5 -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/ArrowNarrowDownIcon.d.ts +12 -0
- package/dist/icons/ArrowNarrowDownIcon.js +11 -0
- package/dist/icons/ArrowNarrowDownIcon.js.map +1 -0
- package/dist/icons/ArrowNarrowUpIcon.d.ts +12 -0
- package/dist/icons/ArrowNarrowUpIcon.js +11 -0
- package/dist/icons/ArrowNarrowUpIcon.js.map +1 -0
- 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/index.d.ts +2 -0
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -2
- 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/color-theme.d.ts +86 -0
- package/dist/tokens/color-theme.js +156 -0
- package/dist/tokens/color-theme.js.map +1 -0
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.js +2 -1
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.d.ts +1 -1
- package/dist/tokens/palette-config.js +17 -5
- package/dist/tokens/palette-config.js.map +1 -1
- package/dist/tokens/palette.d.ts +1 -1
- package/dist/tokens/palette.js +44 -2
- package/dist/tokens/palette.js.map +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.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/index.d.ts +1 -0
- 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/disabledProps.d.ts +49 -0
- package/dist/utils/react/disabledProps.js +82 -0
- package/dist/utils/react/disabledProps.js.map +1 -0
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.d.ts +1 -0
- package/dist/utils/react/index.js +2 -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/Theming.md +20 -13
- package/docs/components/actions/Button.md +17 -0
- package/docs/components/content/Item.md +8 -1
- package/docs/components/data/DataTable.md +118 -2
- package/docs/components/data/ItemTable.md +37 -5
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette-config.js","names":[],"sources":["../../src/tokens/palette-config.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react';\n\n/**\n * Runtime configuration for the Glaze-generated color palette.\n *\n * The palette recipe itself lives in `./palette.ts`; this module owns only the\n * *seeds* it is built from, plus a version counter the token caches watch. It\n * deliberately imports nothing else — not the token modules, not `glaze` — so\n * there is no import cycle and no ordering hazard.\n *\n * Reading is free; writing rebuilds the palette on the next token read. See\n * `Getting Started/Theming` in Storybook for the full contract.\n */\n\n// ============================================================================\n// Default seeds\n// ============================================================================\n\n/** Brand hue. Drives the `default`, `primary`, `purple` and `special` themes. */\nexport const DEFAULT_HUE = 280.3;\nexport const DEFAULT_SUCCESS_HUE = 156.9;\nexport const DEFAULT_DANGER_HUE = 23.1;\nexport const DEFAULT_WARNING_HUE = 84.3;\nexport const DEFAULT_NOTE_HUE = 302.3;\n\n/** Seed saturation. Per-color `saturation` in the recipe is a 0–1 factor of it. */\nexport const DEFAULT_SATURATION = 80;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Hue / saturation seed override for one colored theme. */\nexport interface PaletteThemeSeed {\n /** Hue in degrees (0–360). */\n hue?: number;\n /** Saturation (0–100). Defaults to the palette-level `saturation`. */\n saturation?: number;\n}\n\n/**\n * The `code-*` syntax family takes a saturation and nothing else — and answers to\n * nothing else either. This is the one knob that moves it.\n *\n * Its hues are absolute literals by design, so syntax colors never rotate with the\n * brand — strings would collide with numbers the moment the brand went green. Unlike\n * every other theme, its saturation does **not** inherit the palette-level one: the\n * code palette is calibrated once and stays there, so re-seeding the app cannot\n * quietly wash out a code block. {@link PaletteConfig.pastel} skips it for the same\n * reason.\n */\nexport interface PaletteCodeSeed {\n /** Saturation (0–100). Defaults to {@link DEFAULT_SATURATION}, not to `saturation`. */\n saturation?: number;\n}\n\n/** Names of the themes whose seeds can be overridden individually. */\nexport type PaletteThemeName =\n | 'success'\n | 'danger'\n | 'warning'\n | 'note'\n | 'code';\n\n/**\n * Palette tuning. Every field is optional; omitted fields keep their default,\n * and per-theme fields left unset inherit the palette-level value.\n */\nexport interface PaletteConfig {\n /**\n * Accent hue in degrees (0–360) — the brand.\n *\n * Drives the `accent-*` family on every theme, `primary` / `purple` / `special`,\n * and the brand-tinted odds and ends (`focus`, the loading faces, the disabled\n * chip). Also the default for {@link PaletteConfig.baseHue}.\n */\n hue?: number;\n /**\n * Hue of the **base** zone in degrees (0–360): the neutral chrome — `surface`\n * and its ladder, the `surface-text*` ramp, `border`, `placeholder`. Defaults to\n * `hue`, so the chrome carries a faint tint of the brand unless you say otherwise.\n *\n * Splitting it lets the chrome sit on a different hue from the accent — a warm\n * grey UI with a cool blue brand, say. Only the `default` theme is affected: a\n * colored theme's tinted `surface` deliberately follows *its own* hue, because a\n * danger banner should read as red.\n */\n baseHue?: number;\n /**\n * Seed saturation (0–100), and the fallback for every theme that does not set\n * its own.\n *\n * One scale for the whole theme, by design. Every color's own `saturation` is a\n * 0–1 factor of this seed — `surface` at 0.12, `border` at 0.175, the text ramp\n * at 0.2, the accent family at ~1.0 — so moving it rescales the palette while\n * keeping those proportions. Unlike hue, which is configured separately for the\n * brand and for each status theme, saturation is deliberately not split: the\n * ratio between a subtle surface tint and a saturated accent is part of the\n * design.\n */\n saturation?: number;\n /**\n * Global. Widens the usable chroma range by relaxing the sRGB-safe limit,\n * producing a softer, more even palette across hues. Glaze treats `pastel` as\n * instance-level, so it is threaded into every theme.\n *\n * Every theme except `code`. The syntax family is calibrated on its own\n * saturation and is deliberately left out — softening it collapses the chroma\n * spread the syntax hues rely on to stay apart. To soften a code block, lower\n * {@link PaletteCodeSeed.saturation} instead.\n */\n pastel?: boolean;\n /**\n * Global. `'auto'` (the default) keeps the two-tier model: normal colors plus\n * a separate high-contrast tier driven by `<html data-contrast=\"high\">` /\n * `prefers-contrast: more`.\n *\n * A number (0–100) replaces that switch with a slider — and, because a manual\n * level already carries the contrast preference, **drops the high-contrast\n * tier entirely**. `0` reproduces the normal output and `100` the\n * high-contrast output, bit for bit.\n */\n contrastLevel?: number | 'auto';\n /** Per-theme seed overrides. */\n themes?: {\n success?: PaletteThemeSeed;\n danger?: PaletteThemeSeed;\n warning?: PaletteThemeSeed;\n note?: PaletteThemeSeed;\n code?: PaletteCodeSeed;\n };\n}\n\n/** {@link PaletteConfig} with every field resolved to a concrete value. */\nexport interface ResolvedPaletteConfig {\n hue: number;\n baseHue: number;\n saturation: number;\n pastel: boolean;\n contrastLevel: number | 'auto';\n themes: {\n success: { hue: number; saturation: number };\n danger: { hue: number; saturation: number };\n warning: { hue: number; saturation: number };\n note: { hue: number; saturation: number };\n code: { saturation: number };\n };\n}\n\n// ============================================================================\n// Resolution\n// ============================================================================\n\nconst DEFAULT_THEME_HUES = {\n success: DEFAULT_SUCCESS_HUE,\n danger: DEFAULT_DANGER_HUE,\n warning: DEFAULT_WARNING_HUE,\n note: DEFAULT_NOTE_HUE,\n} as const;\n\nfunction resolveConfig(input: PaletteConfig): ResolvedPaletteConfig {\n const saturation = input.saturation ?? DEFAULT_SATURATION;\n const themes = input.themes ?? {};\n\n const hue = input.hue ?? DEFAULT_HUE;\n\n return {\n hue,\n baseHue: input.baseHue ?? hue,\n saturation,\n pastel: input.pastel ?? false,\n contrastLevel: input.contrastLevel ?? 'auto',\n themes: {\n success: {\n hue: themes.success?.hue ?? DEFAULT_THEME_HUES.success,\n saturation: themes.success?.saturation ?? saturation,\n },\n danger: {\n hue: themes.danger?.hue ?? DEFAULT_THEME_HUES.danger,\n saturation: themes.danger?.saturation ?? saturation,\n },\n warning: {\n hue: themes.warning?.hue ?? DEFAULT_THEME_HUES.warning,\n saturation: themes.warning?.saturation ?? saturation,\n },\n note: {\n hue: themes.note?.hue ?? DEFAULT_THEME_HUES.note,\n saturation: themes.note?.saturation ?? saturation,\n },\n // Deliberately NOT `?? saturation`: the code palette is calibrated once and\n // does not follow the palette-level seed. See `PaletteCodeSeed`.\n code: { saturation: themes.code?.saturation ?? DEFAULT_SATURATION },\n },\n };\n}\n\n/**\n * The palette as it ships, with no tuning applied. Frozen — it is the baseline\n * every resolution falls back to, so a stray write to it would move the defaults\n * for the whole process.\n */\nexport const DEFAULT_PALETTE_CONFIG: ResolvedPaletteConfig = freezeConfig(\n resolveConfig({}),\n);\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * The last config *as written*, sparse — not the resolved one. Keeping the sparse\n * form is what makes inheritance live: a `saturation` with no `themes.danger.\n * saturation` beside it means danger genuinely follows the palette, rather than\n * having been frozen at whatever the palette read when it was set.\n */\nlet input: PaletteConfig = {};\nlet resolved: ResolvedPaletteConfig = DEFAULT_PALETTE_CONFIG;\nlet version = 0;\n\nconst listeners = new Set<() => void>();\n\nfunction mergeSeed<T extends PaletteThemeSeed | PaletteCodeSeed>(\n base: T | undefined,\n patch: T | undefined,\n): T | undefined {\n if (!base) return patch;\n // A patch that omits the theme entirely says nothing about it, so the base\n // survives. Clearing one of its fields is `{ theme: { hue: undefined } }`.\n if (!patch) return base;\n\n return { ...base, ...patch };\n}\n\n/**\n * Layer a patch over a base config. Used by {@link resolvePaletteConfig} for\n * previews — *not* by {@link setPaletteConfig}, which replaces.\n */\nfunction mergeInput(base: PaletteConfig, patch: PaletteConfig): PaletteConfig {\n const next: PaletteConfig = { ...base, ...patch };\n\n if (base.themes || patch.themes) {\n next.themes = {\n success: mergeSeed(base.themes?.success, patch.themes?.success),\n danger: mergeSeed(base.themes?.danger, patch.themes?.danger),\n warning: mergeSeed(base.themes?.warning, patch.themes?.warning),\n note: mergeSeed(base.themes?.note, patch.themes?.note),\n code: mergeSeed(base.themes?.code, patch.themes?.code),\n };\n }\n\n return next;\n}\n\nfunction isSameConfig(a: ResolvedPaletteConfig, b: ResolvedPaletteConfig) {\n return (\n a.hue === b.hue &&\n a.baseHue === b.baseHue &&\n a.saturation === b.saturation &&\n a.pastel === b.pastel &&\n a.contrastLevel === b.contrastLevel &&\n a.themes.code.saturation === b.themes.code.saturation &&\n (['success', 'danger', 'warning', 'note'] as const).every(\n (name) =>\n a.themes[name].hue === b.themes[name].hue &&\n a.themes[name].saturation === b.themes[name].saturation,\n )\n );\n}\n\n/**\n * Which fields are *explicitly set*, as an order-independent signature.\n *\n * Two configs can resolve to identical values yet differ in which of those values\n * are pinned rather than inherited — pinning `primary.saturation` to the number it\n * already inherited is the obvious case. That difference is invisible to\n * {@link isSameConfig} but visible through {@link getPaletteConfigInput}, so it has\n * to count as a change or a settings UI reading it would never re-render.\n */\nfunction pinSignature(config: PaletteConfig): string {\n const set = (value: unknown) => (value === undefined ? '0' : '1');\n\n return [\n set(config.hue),\n set(config.baseHue),\n set(config.saturation),\n set(config.pastel),\n set(config.contrastLevel),\n set(config.themes?.code?.saturation),\n ...(['success', 'danger', 'warning', 'note'] as const).flatMap((name) => [\n set(config.themes?.[name]?.hue),\n set(config.themes?.[name]?.saturation),\n ]),\n ].join('');\n}\n\n/**\n * Snapshot a config so the store owns it outright.\n *\n * Two hazards this closes. The caller's object stays theirs, so mutating it after\n * the call cannot desync `input` from `resolved`. And what we hand back from\n * {@link getPaletteConfig} / {@link getPaletteConfigInput} is frozen, so a caller\n * who writes to it gets a clear failure rather than silently corrupting the store\n * — the version would not bump, and every token cache would go on serving values\n * that no longer match the config.\n */\nfunction freezeConfig<T extends PaletteConfig | ResolvedPaletteConfig>(\n config: T,\n): T {\n const themes = config.themes;\n\n if (themes) {\n for (const seed of Object.values(themes)) {\n if (seed) Object.freeze(seed);\n }\n Object.freeze(themes);\n }\n\n return Object.freeze(config);\n}\n\n/** {@link freezeConfig} on a copy, for a config we did not create ourselves. */\nfunction snapshotConfig(config: PaletteConfig): PaletteConfig {\n const themes = config.themes;\n\n return freezeConfig({\n ...config,\n ...(themes\n ? {\n themes: {\n ...(themes.success ? { success: { ...themes.success } } : null),\n ...(themes.danger ? { danger: { ...themes.danger } } : null),\n ...(themes.warning ? { warning: { ...themes.warning } } : null),\n ...(themes.note ? { note: { ...themes.note } } : null),\n ...(themes.code ? { code: { ...themes.code } } : null),\n },\n }\n : null),\n });\n}\n\nfunction commit(nextInput: PaletteConfig) {\n const nextResolved = resolveConfig(nextInput);\n\n // Bail before bumping the version when nothing observable moved, so re-applying\n // the same config — an inline `<Root palette={{ … }}>` literal on every\n // render, a StrictMode double render — costs nothing.\n if (\n isSameConfig(resolved, nextResolved) &&\n pinSignature(input) === pinSignature(nextInput)\n ) {\n return;\n }\n\n input = snapshotConfig(nextInput);\n resolved = freezeConfig(nextResolved);\n version++;\n\n listeners.forEach((listener) => listener());\n}\n\n/**\n * Set the palette config.\n *\n * **Replaces**, like `useState` — the config you pass *is* the config, resolved\n * against the shipped defaults. Nothing accumulates, so a field you leave out is a\n * field you do not have: dropping a customization means dropping it from the\n * object, and re-applying the same object twice is the same as applying it once.\n *\n * ```ts\n * setPaletteConfig({ hue: 200, baseHue: 60 });\n * setPaletteConfig({ hue: 200 }); // baseHue is gone — back to inheriting `hue`\n * ```\n *\n * To adjust one field of the config already in place — a slider in a settings UI —\n * pass an updater. It receives the config as written, sparse, so spreading it\n * preserves which fields are pinned and which still inherit:\n *\n * ```ts\n * setPaletteConfig((config) => ({ ...config, hue: 200 }));\n * ```\n *\n * The palette is rebuilt lazily on the next token read, and any mounted `<Root>`\n * re-injects the token block — no component re-render is involved, because every\n * color in the kit resolves through a CSS custom property.\n */\nexport function setPaletteConfig(\n config: PaletteConfig | ((previous: PaletteConfig) => PaletteConfig),\n): void {\n commit(typeof config === 'function' ? config(input) : config);\n}\n\n/**\n * Drop all tuning and restore the palette the kit ships with. Identical to\n * `setPaletteConfig({})`; it exists to be readable at a call site.\n */\nexport function resetPaletteConfig(): void {\n commit({});\n}\n\n/**\n * Force every token to re-resolve without changing the palette config.\n *\n * Only needed if you drive Glaze directly — `glaze.configure({ darkTone })` and\n * the like. Glaze invalidates its own caches, but the kit's token maps are\n * memoized against *this* module's version, so they need telling. Calling it\n * before the first paint is unnecessary; nothing has been resolved yet.\n */\nexport function invalidatePaletteTokens(): void {\n version++;\n listeners.forEach((listener) => listener());\n}\n\n/** The current config, with every field resolved to a concrete value. */\nexport function getPaletteConfig(): ResolvedPaletteConfig {\n return resolved;\n}\n\n/**\n * The config **as set**, sparse — omitted fields are the ones still inheriting.\n *\n * {@link getPaletteConfig} resolves everything to concrete values, which loses the\n * distinction between \"explicitly 80\" and \"80 because it follows the brand\". A\n * settings UI needs that distinction to show an inherited value as inherited, and\n * to offer a way back:\n *\n * ```ts\n * const pinned = getPaletteConfigInput().baseHue !== undefined;\n *\n * // Re-link it to the brand by dropping the field.\n * setPaletteConfig(({ baseHue, ...config }) => config);\n * ```\n *\n * It is also the value handed to a {@link setPaletteConfig} updater.\n */\nexport function getPaletteConfigInput(): PaletteConfig {\n return input;\n}\n\n/**\n * Resolve a patch **over** the current config, without applying it.\n *\n * This one layers, unlike {@link setPaletteConfig}: a preview wants \"the theme in\n * use, but in dark\", so the fields it does not mention have to come from the live\n * config rather than from the defaults. The store is not touched and no listener\n * fires.\n */\nexport function resolvePaletteConfig(\n config?: PaletteConfig,\n): ResolvedPaletteConfig {\n if (!config) return resolved;\n\n return resolveConfig(mergeInput(input, config));\n}\n\n/**\n * Increments whenever the resolved config changes. The token caches in\n * `./palette.ts`, `./colors.ts` and `./index.ts` compare against it instead of\n * memoizing forever — the same idiom Glaze uses for its own config version.\n */\nexport function getPaletteVersion(): number {\n return version;\n}\n\n/** Subscribe to palette config changes. Returns an unsubscribe function. */\nexport function subscribePaletteConfig(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n// ============================================================================\n// React bindings\n// ============================================================================\n\n/**\n * Re-render on palette config changes. Returns the version, not the config, so\n * the snapshot is a primitive and React never warns about an uncached snapshot.\n */\nexport function usePaletteVersion(): number {\n return useSyncExternalStore(\n subscribePaletteConfig,\n getPaletteVersion,\n getPaletteVersion,\n );\n}\n\n/**\n * Read and tune the palette from React, `useState`-style — including the part\n * where the setter *replaces*. A control that changes one field wants the updater\n * form, or it will drop every other field:\n *\n * ```tsx\n * const [palette, setPalette] = usePaletteConfig();\n *\n * <HueSlider\n * value={palette.hue}\n * onChange={(hue) => setPalette((config) => ({ ...config, hue }))}\n * />\n * ```\n *\n * The first element is the *resolved* config, so `palette.hue` is always a number.\n * The updater's argument is the sparse one — see {@link getPaletteConfigInput}.\n *\n * The config is global process state, so every consumer of this hook — and every\n * mounted `<Root>` — sees the same palette.\n */\nexport function usePaletteConfig(): readonly [\n ResolvedPaletteConfig,\n typeof setPaletteConfig,\n] {\n usePaletteVersion();\n\n return [getPaletteConfig(), setPaletteConfig];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"palette-config.js","names":[],"sources":["../../src/tokens/palette-config.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react';\n\n/**\n * Runtime configuration for the Glaze-generated color palette.\n *\n * The palette recipe itself lives in `./palette.ts`; this module owns only the\n * *seeds* it is built from, plus a version counter the token caches watch. It\n * deliberately imports nothing else — not the token modules, not `glaze` — so\n * there is no import cycle and no ordering hazard.\n *\n * Reading is free; writing rebuilds the palette on the next token read. See\n * `Getting Started/Theming` in Storybook for the full contract.\n */\n\n// ============================================================================\n// Default seeds\n// ============================================================================\n\n/** Brand hue. Drives the `default`, `primary`, `purple` and `special` themes. */\nexport const DEFAULT_HUE = 280.3;\nexport const DEFAULT_SUCCESS_HUE = 156.9;\nexport const DEFAULT_DANGER_HUE = 23.1;\nexport const DEFAULT_WARNING_HUE = 84.3;\nexport const DEFAULT_NOTE_HUE = 302.3;\n\n/** Seed saturation. Per-color `saturation` in the recipe is a 0–1 factor of it. */\nexport const DEFAULT_SATURATION = 100;\n\n/**\n * Seed saturation for the `code-*` syntax family, deliberately **not** the same\n * constant as {@link DEFAULT_SATURATION}.\n *\n * The two were one value until the app seed moved to 100 for the pastel palette.\n * Sharing it would have dragged the syntax colors along for the ride — the exact\n * coupling that `PaletteCodeSeed` and the `pastel` opt-out both exist to prevent,\n * and the reason the code family answers to its own saturation and nothing else.\n * Splitting the constant is what lets the app seed move while the code palette\n * stays on the value it was calibrated against.\n */\nexport const DEFAULT_CODE_SATURATION = 80;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Hue / saturation seed override for one colored theme. */\nexport interface PaletteThemeSeed {\n /** Hue in degrees (0–360). */\n hue?: number;\n /** Saturation (0–100). Defaults to the palette-level `saturation`. */\n saturation?: number;\n}\n\n/**\n * The `code-*` syntax family takes a saturation and nothing else — and answers to\n * nothing else either. This is the one knob that moves it.\n *\n * Its hues are absolute literals by design, so syntax colors never rotate with the\n * brand — strings would collide with numbers the moment the brand went green. Unlike\n * every other theme, its saturation does **not** inherit the palette-level one: the\n * code palette is calibrated once and stays there, so re-seeding the app cannot\n * quietly wash out a code block. {@link PaletteConfig.pastel} skips it for the same\n * reason.\n */\nexport interface PaletteCodeSeed {\n /** Saturation (0–100). Defaults to {@link DEFAULT_CODE_SATURATION}, not to `saturation`. */\n saturation?: number;\n}\n\n/** Names of the themes whose seeds can be overridden individually. */\nexport type PaletteThemeName =\n | 'success'\n | 'danger'\n | 'warning'\n | 'note'\n | 'code';\n\n/**\n * Palette tuning. Every field is optional; omitted fields keep their default,\n * and per-theme fields left unset inherit the palette-level value.\n */\nexport interface PaletteConfig {\n /**\n * Accent hue in degrees (0–360) — the brand.\n *\n * Drives the `accent-*` family on every theme, `primary` / `purple` / `special`,\n * and the brand-tinted odds and ends (`focus`, the loading faces, the disabled\n * chip). Also the default for {@link PaletteConfig.baseHue}.\n */\n hue?: number;\n /**\n * Hue of the **base** zone in degrees (0–360): the neutral chrome — `surface`\n * and its ladder, the `surface-text*` ramp, `border`, `placeholder`. Defaults to\n * `hue`, so the chrome carries a faint tint of the brand unless you say otherwise.\n *\n * Splitting it lets the chrome sit on a different hue from the accent — a warm\n * grey UI with a cool blue brand, say. Only the `default` theme is affected: a\n * colored theme's tinted `surface` deliberately follows *its own* hue, because a\n * danger banner should read as red.\n */\n baseHue?: number;\n /**\n * Seed saturation (0–100), and the fallback for every theme that does not set\n * its own.\n *\n * One scale for the whole theme, by design. Every color's own `saturation` is a\n * 0–1 factor of this seed — `surface` at 0.12, `border` at 0.175, the text ramp\n * at 0.2, the accent family at ~1.0 — so moving it rescales the palette while\n * keeping those proportions. Unlike hue, which is configured separately for the\n * brand and for each status theme, saturation is deliberately not split: the\n * ratio between a subtle surface tint and a saturated accent is part of the\n * design.\n */\n saturation?: number;\n /**\n * Global. Widens the usable chroma range by relaxing the sRGB-safe limit,\n * producing a softer, more even palette across hues. Glaze treats `pastel` as\n * instance-level, so it is threaded into every theme.\n *\n * Every theme except `code`. The syntax family is calibrated on its own\n * saturation and is deliberately left out — softening it collapses the chroma\n * spread the syntax hues rely on to stay apart. To soften a code block, lower\n * {@link PaletteCodeSeed.saturation} instead.\n */\n pastel?: boolean;\n /**\n * Global. `'auto'` (the default) keeps the two-tier model: normal colors plus\n * a separate high-contrast tier driven by `<html data-contrast=\"high\">` /\n * `prefers-contrast: more`.\n *\n * A number (0–100) replaces that switch with a slider — and, because a manual\n * level already carries the contrast preference, **drops the high-contrast\n * tier entirely**. `0` reproduces the normal output and `100` the\n * high-contrast output, bit for bit.\n */\n contrastLevel?: number | 'auto';\n /** Per-theme seed overrides. */\n themes?: {\n success?: PaletteThemeSeed;\n danger?: PaletteThemeSeed;\n warning?: PaletteThemeSeed;\n note?: PaletteThemeSeed;\n code?: PaletteCodeSeed;\n };\n}\n\n/** {@link PaletteConfig} with every field resolved to a concrete value. */\nexport interface ResolvedPaletteConfig {\n hue: number;\n baseHue: number;\n saturation: number;\n pastel: boolean;\n contrastLevel: number | 'auto';\n themes: {\n success: { hue: number; saturation: number };\n danger: { hue: number; saturation: number };\n warning: { hue: number; saturation: number };\n note: { hue: number; saturation: number };\n code: { saturation: number };\n };\n}\n\n// ============================================================================\n// Resolution\n// ============================================================================\n\nconst DEFAULT_THEME_HUES = {\n success: DEFAULT_SUCCESS_HUE,\n danger: DEFAULT_DANGER_HUE,\n warning: DEFAULT_WARNING_HUE,\n note: DEFAULT_NOTE_HUE,\n} as const;\n\nfunction resolveConfig(input: PaletteConfig): ResolvedPaletteConfig {\n const saturation = input.saturation ?? DEFAULT_SATURATION;\n const themes = input.themes ?? {};\n\n const hue = input.hue ?? DEFAULT_HUE;\n\n return {\n hue,\n baseHue: input.baseHue ?? hue,\n saturation,\n pastel: input.pastel ?? true,\n contrastLevel: input.contrastLevel ?? 'auto',\n themes: {\n success: {\n hue: themes.success?.hue ?? DEFAULT_THEME_HUES.success,\n saturation: themes.success?.saturation ?? saturation,\n },\n danger: {\n hue: themes.danger?.hue ?? DEFAULT_THEME_HUES.danger,\n saturation: themes.danger?.saturation ?? saturation,\n },\n warning: {\n hue: themes.warning?.hue ?? DEFAULT_THEME_HUES.warning,\n saturation: themes.warning?.saturation ?? saturation,\n },\n note: {\n hue: themes.note?.hue ?? DEFAULT_THEME_HUES.note,\n saturation: themes.note?.saturation ?? saturation,\n },\n // Deliberately NOT `?? saturation`: the code palette is calibrated once and\n // does not follow the palette-level seed. See `PaletteCodeSeed`.\n code: { saturation: themes.code?.saturation ?? DEFAULT_CODE_SATURATION },\n },\n };\n}\n\n/**\n * The palette as it ships, with no tuning applied. Frozen — it is the baseline\n * every resolution falls back to, so a stray write to it would move the defaults\n * for the whole process.\n */\nexport const DEFAULT_PALETTE_CONFIG: ResolvedPaletteConfig = freezeConfig(\n resolveConfig({}),\n);\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * The last config *as written*, sparse — not the resolved one. Keeping the sparse\n * form is what makes inheritance live: a `saturation` with no `themes.danger.\n * saturation` beside it means danger genuinely follows the palette, rather than\n * having been frozen at whatever the palette read when it was set.\n */\nlet input: PaletteConfig = {};\nlet resolved: ResolvedPaletteConfig = DEFAULT_PALETTE_CONFIG;\nlet version = 0;\n\nconst listeners = new Set<() => void>();\n\nfunction mergeSeed<T extends PaletteThemeSeed | PaletteCodeSeed>(\n base: T | undefined,\n patch: T | undefined,\n): T | undefined {\n if (!base) return patch;\n // A patch that omits the theme entirely says nothing about it, so the base\n // survives. Clearing one of its fields is `{ theme: { hue: undefined } }`.\n if (!patch) return base;\n\n return { ...base, ...patch };\n}\n\n/**\n * Layer a patch over a base config. Used by {@link resolvePaletteConfig} for\n * previews — *not* by {@link setPaletteConfig}, which replaces.\n */\nfunction mergeInput(base: PaletteConfig, patch: PaletteConfig): PaletteConfig {\n const next: PaletteConfig = { ...base, ...patch };\n\n if (base.themes || patch.themes) {\n next.themes = {\n success: mergeSeed(base.themes?.success, patch.themes?.success),\n danger: mergeSeed(base.themes?.danger, patch.themes?.danger),\n warning: mergeSeed(base.themes?.warning, patch.themes?.warning),\n note: mergeSeed(base.themes?.note, patch.themes?.note),\n code: mergeSeed(base.themes?.code, patch.themes?.code),\n };\n }\n\n return next;\n}\n\nfunction isSameConfig(a: ResolvedPaletteConfig, b: ResolvedPaletteConfig) {\n return (\n a.hue === b.hue &&\n a.baseHue === b.baseHue &&\n a.saturation === b.saturation &&\n a.pastel === b.pastel &&\n a.contrastLevel === b.contrastLevel &&\n a.themes.code.saturation === b.themes.code.saturation &&\n (['success', 'danger', 'warning', 'note'] as const).every(\n (name) =>\n a.themes[name].hue === b.themes[name].hue &&\n a.themes[name].saturation === b.themes[name].saturation,\n )\n );\n}\n\n/**\n * Which fields are *explicitly set*, as an order-independent signature.\n *\n * Two configs can resolve to identical values yet differ in which of those values\n * are pinned rather than inherited — pinning `primary.saturation` to the number it\n * already inherited is the obvious case. That difference is invisible to\n * {@link isSameConfig} but visible through {@link getPaletteConfigInput}, so it has\n * to count as a change or a settings UI reading it would never re-render.\n */\nfunction pinSignature(config: PaletteConfig): string {\n const set = (value: unknown) => (value === undefined ? '0' : '1');\n\n return [\n set(config.hue),\n set(config.baseHue),\n set(config.saturation),\n set(config.pastel),\n set(config.contrastLevel),\n set(config.themes?.code?.saturation),\n ...(['success', 'danger', 'warning', 'note'] as const).flatMap((name) => [\n set(config.themes?.[name]?.hue),\n set(config.themes?.[name]?.saturation),\n ]),\n ].join('');\n}\n\n/**\n * Snapshot a config so the store owns it outright.\n *\n * Two hazards this closes. The caller's object stays theirs, so mutating it after\n * the call cannot desync `input` from `resolved`. And what we hand back from\n * {@link getPaletteConfig} / {@link getPaletteConfigInput} is frozen, so a caller\n * who writes to it gets a clear failure rather than silently corrupting the store\n * — the version would not bump, and every token cache would go on serving values\n * that no longer match the config.\n */\nfunction freezeConfig<T extends PaletteConfig | ResolvedPaletteConfig>(\n config: T,\n): T {\n const themes = config.themes;\n\n if (themes) {\n for (const seed of Object.values(themes)) {\n if (seed) Object.freeze(seed);\n }\n Object.freeze(themes);\n }\n\n return Object.freeze(config);\n}\n\n/** {@link freezeConfig} on a copy, for a config we did not create ourselves. */\nfunction snapshotConfig(config: PaletteConfig): PaletteConfig {\n const themes = config.themes;\n\n return freezeConfig({\n ...config,\n ...(themes\n ? {\n themes: {\n ...(themes.success ? { success: { ...themes.success } } : null),\n ...(themes.danger ? { danger: { ...themes.danger } } : null),\n ...(themes.warning ? { warning: { ...themes.warning } } : null),\n ...(themes.note ? { note: { ...themes.note } } : null),\n ...(themes.code ? { code: { ...themes.code } } : null),\n },\n }\n : null),\n });\n}\n\nfunction commit(nextInput: PaletteConfig) {\n const nextResolved = resolveConfig(nextInput);\n\n // Bail before bumping the version when nothing observable moved, so re-applying\n // the same config — an inline `<Root palette={{ … }}>` literal on every\n // render, a StrictMode double render — costs nothing.\n if (\n isSameConfig(resolved, nextResolved) &&\n pinSignature(input) === pinSignature(nextInput)\n ) {\n return;\n }\n\n input = snapshotConfig(nextInput);\n resolved = freezeConfig(nextResolved);\n version++;\n\n listeners.forEach((listener) => listener());\n}\n\n/**\n * Set the palette config.\n *\n * **Replaces**, like `useState` — the config you pass *is* the config, resolved\n * against the shipped defaults. Nothing accumulates, so a field you leave out is a\n * field you do not have: dropping a customization means dropping it from the\n * object, and re-applying the same object twice is the same as applying it once.\n *\n * ```ts\n * setPaletteConfig({ hue: 200, baseHue: 60 });\n * setPaletteConfig({ hue: 200 }); // baseHue is gone — back to inheriting `hue`\n * ```\n *\n * To adjust one field of the config already in place — a slider in a settings UI —\n * pass an updater. It receives the config as written, sparse, so spreading it\n * preserves which fields are pinned and which still inherit:\n *\n * ```ts\n * setPaletteConfig((config) => ({ ...config, hue: 200 }));\n * ```\n *\n * The palette is rebuilt lazily on the next token read, and any mounted `<Root>`\n * re-injects the token block — no component re-render is involved, because every\n * color in the kit resolves through a CSS custom property.\n */\nexport function setPaletteConfig(\n config: PaletteConfig | ((previous: PaletteConfig) => PaletteConfig),\n): void {\n commit(typeof config === 'function' ? config(input) : config);\n}\n\n/**\n * Drop all tuning and restore the palette the kit ships with. Identical to\n * `setPaletteConfig({})`; it exists to be readable at a call site.\n */\nexport function resetPaletteConfig(): void {\n commit({});\n}\n\n/**\n * Force every token to re-resolve without changing the palette config.\n *\n * Only needed if you drive Glaze directly — `glaze.configure({ darkTone })` and\n * the like. Glaze invalidates its own caches, but the kit's token maps are\n * memoized against *this* module's version, so they need telling. Calling it\n * before the first paint is unnecessary; nothing has been resolved yet.\n */\nexport function invalidatePaletteTokens(): void {\n version++;\n listeners.forEach((listener) => listener());\n}\n\n/** The current config, with every field resolved to a concrete value. */\nexport function getPaletteConfig(): ResolvedPaletteConfig {\n return resolved;\n}\n\n/**\n * The config **as set**, sparse — omitted fields are the ones still inheriting.\n *\n * {@link getPaletteConfig} resolves everything to concrete values, which loses the\n * distinction between \"explicitly 80\" and \"80 because it follows the brand\". A\n * settings UI needs that distinction to show an inherited value as inherited, and\n * to offer a way back:\n *\n * ```ts\n * const pinned = getPaletteConfigInput().baseHue !== undefined;\n *\n * // Re-link it to the brand by dropping the field.\n * setPaletteConfig(({ baseHue, ...config }) => config);\n * ```\n *\n * It is also the value handed to a {@link setPaletteConfig} updater.\n */\nexport function getPaletteConfigInput(): PaletteConfig {\n return input;\n}\n\n/**\n * Resolve a patch **over** the current config, without applying it.\n *\n * This one layers, unlike {@link setPaletteConfig}: a preview wants \"the theme in\n * use, but in dark\", so the fields it does not mention have to come from the live\n * config rather than from the defaults. The store is not touched and no listener\n * fires.\n */\nexport function resolvePaletteConfig(\n config?: PaletteConfig,\n): ResolvedPaletteConfig {\n if (!config) return resolved;\n\n return resolveConfig(mergeInput(input, config));\n}\n\n/**\n * Increments whenever the resolved config changes. The token caches in\n * `./palette.ts`, `./colors.ts` and `./index.ts` compare against it instead of\n * memoizing forever — the same idiom Glaze uses for its own config version.\n */\nexport function getPaletteVersion(): number {\n return version;\n}\n\n/** Subscribe to palette config changes. Returns an unsubscribe function. */\nexport function subscribePaletteConfig(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n// ============================================================================\n// React bindings\n// ============================================================================\n\n/**\n * Re-render on palette config changes. Returns the version, not the config, so\n * the snapshot is a primitive and React never warns about an uncached snapshot.\n */\nexport function usePaletteVersion(): number {\n return useSyncExternalStore(\n subscribePaletteConfig,\n getPaletteVersion,\n getPaletteVersion,\n );\n}\n\n/**\n * Read and tune the palette from React, `useState`-style — including the part\n * where the setter *replaces*. A control that changes one field wants the updater\n * form, or it will drop every other field:\n *\n * ```tsx\n * const [palette, setPalette] = usePaletteConfig();\n *\n * <HueSlider\n * value={palette.hue}\n * onChange={(hue) => setPalette((config) => ({ ...config, hue }))}\n * />\n * ```\n *\n * The first element is the *resolved* config, so `palette.hue` is always a number.\n * The updater's argument is the sparse one — see {@link getPaletteConfigInput}.\n *\n * The config is global process state, so every consumer of this hook — and every\n * mounted `<Root>` — sees the same palette.\n */\nexport function usePaletteConfig(): readonly [\n ResolvedPaletteConfig,\n typeof setPaletteConfig,\n] {\n usePaletteVersion();\n\n return [getPaletteConfig(), setPaletteConfig];\n}\n"],"mappings":"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"}
|
package/dist/tokens/palette.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { PaletteConfig } from "./palette-config.js";
|
|
3
3
|
import { Styles, Tokens } from "@tenphi/tasty";
|
|
4
|
-
import { GlazePalette, GlazeTheme } from "@tenphi/glaze";
|
|
4
|
+
import { ColorMap, GlazePalette, GlazeTheme } from "@tenphi/glaze";
|
|
5
5
|
|
|
6
6
|
//#region src/tokens/palette.d.ts
|
|
7
7
|
/** Which resolved scheme variant {@link renderPaletteTokens} should return. */
|
package/dist/tokens/palette.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { getPaletteConfig, getPaletteVersion, resolvePaletteConfig } from "./palette-config.js";
|
|
3
3
|
import { lazyStyles } from "./lazy-styles.js";
|
|
4
4
|
import { glaze } from "@tenphi/glaze";
|
|
@@ -198,6 +198,48 @@ const TINTED_SURFACE_OVERRIDE = {
|
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
200
|
/**
|
|
201
|
+
* A tinted surface, a banding step, and text guaranteed to read on both.
|
|
202
|
+
*
|
|
203
|
+
* The recipe behind {@link getColorTheme} in `./color-theme.ts`, which builds
|
|
204
|
+
* one-off themes at runtime from an arbitrary hue. It lives here so it shares
|
|
205
|
+
* `TINTED_SURFACE_SATURATION`, the tone offsets and the text ramp with
|
|
206
|
+
* {@link TINTED_SURFACE_OVERRIDE} above rather than forking them — a runtime tint
|
|
207
|
+
* and a built-in theme's `surface` should be the same colour for the same hue.
|
|
208
|
+
*
|
|
209
|
+
* Three colours, because that is what banded, readable table column needs:
|
|
210
|
+
* `surface` for even rows, `surface-2` one tone step down for odd rows and
|
|
211
|
+
* pinned totals, and `surface-2-text`.
|
|
212
|
+
*
|
|
213
|
+
* The text is anchored to `surface-2`, not `surface`. `surface-2` has the lower
|
|
214
|
+
* contrast headroom in BOTH schemes — a darker background under dark text in
|
|
215
|
+
* light, a lighter one under light text in dark — so solving the floor there
|
|
216
|
+
* clears it on both bands. The neutral ramp's own `surface-2-text` is shaped the
|
|
217
|
+
* same way for the same reason.
|
|
218
|
+
*/
|
|
219
|
+
const TINT_RECIPE = {
|
|
220
|
+
surface: {
|
|
221
|
+
tone: [100 - TINTED_SURFACE_TONE_OFFSET, 100 - TINTED_SURFACE_TONE_OFFSET * 2],
|
|
222
|
+
saturation: TINTED_SURFACE_SATURATION
|
|
223
|
+
},
|
|
224
|
+
"surface-2": {
|
|
225
|
+
base: "surface",
|
|
226
|
+
tone: ["-2", "-4"],
|
|
227
|
+
saturation: TINTED_SURFACE_SATURATION
|
|
228
|
+
},
|
|
229
|
+
"surface-2-text": {
|
|
230
|
+
base: "surface-2",
|
|
231
|
+
tone: `${TEXT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,
|
|
232
|
+
saturation: .25,
|
|
233
|
+
contrast: ["AA", "AAA"]
|
|
234
|
+
},
|
|
235
|
+
"surface-2-text-soft": {
|
|
236
|
+
base: "surface-2",
|
|
237
|
+
tone: `${TEXT_SOFT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,
|
|
238
|
+
saturation: .25,
|
|
239
|
+
contrast: ["AA", "AAA"]
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
201
243
|
* Build the full palette from a resolved config.
|
|
202
244
|
*
|
|
203
245
|
* Pure: it reads nothing but its argument (and the global Glaze config, which
|
|
@@ -708,5 +750,5 @@ function renderPaletteTokens(options = {}) {
|
|
|
708
750
|
const PALETTE_TOKENS = lazyStyles(getPaletteTokens);
|
|
709
751
|
|
|
710
752
|
//#endregion
|
|
711
|
-
export { PALETTE_TOKENS, getCodeTheme, getPalette, getPaletteTokens, renderPaletteTokens };
|
|
753
|
+
export { PALETTE_TOKENS, TINT_RECIPE, getCodeTheme, getPalette, getPaletteTokens, renderPaletteTokens };
|
|
712
754
|
//# sourceMappingURL=palette.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.js","names":[],"sources":["../../src/tokens/palette.ts"],"sourcesContent":["import { glaze } from '@tenphi/glaze';\n\nimport { lazyStyles } from './lazy-styles';\nimport {\n getPaletteConfig,\n getPaletteVersion,\n resolvePaletteConfig,\n} from './palette-config';\n\nimport type {\n ColorMap,\n GlazeConfigOverride,\n GlazePalette,\n GlazeTheme,\n} from '@tenphi/glaze';\nimport type { Styles, Tokens } from '@tenphi/tasty';\nimport type { PaletteConfig, ResolvedPaletteConfig } from './palette-config';\n\n/** Which resolved scheme variant {@link renderPaletteTokens} should return. */\nexport interface RenderPaletteOptions extends PaletteConfig {\n /** Color scheme to resolve. Default: `'light'`. */\n scheme?: 'light' | 'dark';\n /** Resolve the high-contrast variant of that scheme. Default: `false`. */\n highContrast?: boolean;\n}\n\n/**\n * Glaze-generated color palette for the Cube UI Kit.\n *\n * Produces light, dark, and high-contrast color variants from a single\n * source of truth. Every color token is emitted as a tasty state map:\n *\n * '#surface': { '': 'oklch(...)', '@dark': 'oklch(...)', '@hc': 'oklch(...)' }\n *\n * The `@dark` and `@hc` state aliases are wired up globally in\n * `src/components/Root.tsx` (see `setGlobalPredefinedStates`).\n *\n * This module owns the *recipe* — which colors exist and how each one is\n * positioned relative to its base. The *seeds* it is built from (hue,\n * saturation, pastel, contrast level) live in `./palette-config.ts` and are\n * tunable at runtime; `buildPalette()` below is a pure function of them.\n */\n\n// ============================================================================\n// Recipe constants\n// ============================================================================\n\n// Relative tone ramp from a white surface.\n// Tone is a contrast-uniform 0–100 scale (OKHST). A relative tone delta of -N\n// yields a fixed WCAG contrast step against the base regardless of where the\n// base sits on the scale. These constants form the primary text ramp; the\n// surface-2 / surface-3 variants reuse the same absolute targets via a small\n// offset because their bases are shifted down from `surface`.\nconst TEXT_TONE = -98; // relative tone delta from white surface (~cr 21)\nconst TEXT_SOFT_TONE = -72; // relative tone delta from white surface (~cr 9)\nconst TEXT_SOFT2_TONE = -52; // relative tone delta from white surface (~cr 4.5)\nconst SURFACE_2_TEXT_OFFSET = 2;\nconst SURFACE_3_TEXT_OFFSET = 4;\n\n// Syntax highlighting keeps its own fixed hue reference (see the `code-*` block\n// below). This is the kit's default brand hue, frozen as a literal: string\n// literals were historically purple because the brand is, but they must not\n// follow a re-seeded brand hue — a green brand would collide `code-string` with\n// `code-number` (156°) and make strings and numbers indistinguishable.\nconst CODE_STRING_HUE = 280.3;\n\n/**\n * Saturation factor of the neutral `surface`.\n *\n * Shared with the code theme, which mirrors `surface` to solve its contrast floors\n * against the real page background — the two must not drift apart.\n */\nconst SURFACE_SATURATION = 0.12;\n\nconst TINTED_SURFACE_SATURATION = 0.2;\nconst TINTED_SURFACE_TONE_OFFSET = 2;\n\n/**\n * Syntax highlighting for `PrismCode`, as its own theme.\n *\n * A small palette of *adaptive* colored tokens. Each one is anchored to `surface`\n * with a relative tone plus an `['AA','AAA']` readability floor, so it stays legible\n * in light, dark and high contrast. Hues mirror the long-standing PrismCode\n * reference (pink keywords / pink functions / purple strings / green numbers / gray\n * comments); `code-attribute` keeps cyan for HTML attribute names, CSS properties\n * and selectors, while HTML/XML tag names reuse `code-keyword`. Diff insertion and\n * deletion reuse the `success-*` / `danger-*` ramps instead.\n *\n * Three things are deliberately static here. Every hue is an absolute literal, so a\n * re-seeded brand cannot rotate the syntax palette — a green brand would otherwise\n * collide `code-string` with `code-number` (156°). These factors are relative to\n * the *code* theme's own seed (`themes.code.saturation`), not the palette-level one,\n * so tuning the app's saturation cannot wash out a code block. And `pastel` is held\n * off here whatever the palette does, for the same reason: it lowers the chroma\n * ceiling hard enough to take `code-keyword` from ~0.19 to ~0.07, which is the\n * difference between distinguishable syntax and mud. Between them, these mean the\n * emitted `code-*` values are a function of the code saturation alone.\n *\n * That separate seed is the only reason these live outside the default theme: a\n * theme colour can never exceed its own seed, and four of these sit at factor `1.0`,\n * so they could not hold their chroma inside a default theme seeded below 80.\n */\nconst CODE_COLORS: ColorMap = {\n 'code-comment': {\n base: 'surface',\n hue: 280,\n saturation: 0.1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-punctuation': {\n base: 'surface',\n hue: 348,\n saturation: 0.4,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-keyword': {\n base: 'surface',\n hue: 348,\n saturation: 1,\n tone: '-54',\n contrast: ['AA', 'AAA'],\n },\n 'code-string': {\n base: 'surface',\n hue: CODE_STRING_HUE,\n saturation: 1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-number': {\n base: 'surface',\n hue: 156,\n saturation: 0.9,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-function': {\n base: 'surface',\n hue: 348,\n saturation: 1,\n tone: '-54',\n contrast: ['AA', 'AAA'],\n },\n 'code-attribute': {\n base: 'surface',\n hue: 200,\n saturation: 1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n};\n\n/**\n * Build the standalone theme the `code-*` tokens live in.\n *\n * Its seed is the code saturation, so {@link CODE_COLORS} keeps its authored factors\n * verbatim and resolves identically at any palette saturation. The mirrored `surface`\n * is an implementation detail — it exists only as the contrast base, and is filtered\n * out of the emitted tokens by {@link pickCodeTokens}.\n *\n * `instanceConfig` arrives with `pastel` pinned off, so the mirror is non-pastel too\n * even when the app is. Harmless: at saturation factor 0.12 the pastel ceiling moves\n * the mirror's chroma and leaves its tone — the axis every `code-*` contrast floor is\n * solved against — bit-identical.\n */\nfunction buildCodeTheme(\n config: ResolvedPaletteConfig,\n instanceConfig: GlazeConfigOverride | undefined,\n): GlazeTheme {\n const codeSaturation = config.themes.code.saturation;\n const theme = glaze(config.hue, codeSaturation, instanceConfig);\n\n // Re-express the default theme's `surface` as a factor of the *code* seed, so it\n // resolves to the same colour the code actually sits on. Written as a ratio of\n // seeds so the default config lands on exactly `SURFACE_SATURATION`.\n let mirrorFactor = SURFACE_SATURATION * (config.saturation / codeSaturation);\n\n if (mirrorFactor > 1) {\n // Only reachable with a code saturation far below the palette's. Glaze would\n // clamp this silently and then solve every contrast floor against the wrong\n // background, so say so.\n // eslint-disable-next-line no-console\n console.warn(\n `[cube-ui-kit] themes.code.saturation (${codeSaturation}) is too low for ` +\n `saturation ${config.saturation}: the mirrored code surface would need a ` +\n `factor of ${mirrorFactor.toFixed(3)}. Clamped to 1; raise the code ` +\n `saturation to keep syntax contrast accurate.`,\n );\n mirrorFactor = 1;\n }\n\n theme.colors({\n surface: { tone: 100, saturation: mirrorFactor },\n ...CODE_COLORS,\n });\n\n return theme;\n}\n\n/** What {@link buildPalette} produces: the themed palette plus the code theme. */\ninterface BuiltPalette {\n palette: GlazePalette;\n codeTheme: GlazeTheme;\n}\n\n/** Drop the mirrored `surface`, keeping only the `code-*` tokens. */\nfunction pickCodeTokens<T>(tokens: Record<string, T>): Record<string, T> {\n const out: Record<string, T> = {};\n\n for (const name of Object.keys(tokens)) {\n if (name.startsWith('code-') || name.startsWith('#code-')) {\n out[name] = tokens[name];\n }\n }\n\n return out;\n}\n\n// ============================================================================\n// Global Glaze configuration\n// ============================================================================\n\nglaze.configure({\n states: {\n dark: '@dark',\n highContrast: '@hc',\n },\n modes: {\n dark: true,\n highContrast: true,\n },\n darkTone: [14, 95],\n darkDesaturation: 0,\n});\n\n/**\n * Per-colored-theme overrides on top of the default theme:\n * - `surface` — bumped saturation so the banner bg is visibly tinted.\n * - `border` — bumped saturation so OUTLINE-variant borders pick up the\n * theme hue (used by `#<theme>-border` in `item-themes.ts`). Mirrors the\n * default-theme `border` shape (`base: 'surface'`, tone window) but\n * with higher saturation. Glaze's `extend({ colors })` redefines each\n * listed color from scratch, so we restate the full definition here.\n */\nconst TINTED_SURFACE_OVERRIDE: ColorMap = {\n surface: {\n tone: [\n 100 - TINTED_SURFACE_TONE_OFFSET,\n 100 - TINTED_SURFACE_TONE_OFFSET * 2,\n ],\n saturation: TINTED_SURFACE_SATURATION,\n },\n border: {\n base: 'surface',\n tone: ['-10', '-30'],\n saturation: 0.3,\n },\n 'surface-text': {\n base: 'surface',\n tone: `${TEXT_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft': {\n base: 'surface',\n tone: `${TEXT_SOFT_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft-2': {\n base: 'surface',\n tone: `${TEXT_SOFT2_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n};\n\n// ============================================================================\n// Palette construction\n// ============================================================================\n\n/**\n * Build the full palette from a resolved config.\n *\n * Pure: it reads nothing but its argument (and the global Glaze config, which\n * the caller sets first), so re-running it with the same config yields the same\n * tokens. Theme instances are immutable with respect to their hue / saturation\n * seed and a `GlazePalette` has no mutation API, so re-seeding means rebuilding.\n */\nfunction buildPalette(\n config: ResolvedPaletteConfig,\n options: {\n /**\n * Carry `contrastLevel` on the theme instances instead of relying on the\n * global Glaze config. Used when rendering a palette the app is not running,\n * so a preview cannot disturb the live one. The resolved values are the same\n * either way; only which scheme variants get *emitted* differs, and callers\n * that isolate pick their variant explicitly.\n */\n isolateContrastLevel?: boolean;\n } = {},\n): BuiltPalette {\n const { hue, baseHue, saturation, pastel, themes, contrastLevel } = config;\n\n // The one override the code theme shares with the rest of the palette.\n const sharedOverrides: GlazeConfigOverride = options.isolateContrastLevel\n ? { contrastLevel }\n : {};\n\n // `pastel` is instance-level in Glaze (not settable via `glaze.configure`).\n // Setting it on the two root themes is enough: `extend({ config })` merges\n // with the parent's override, so the derived themes inherit it. When it is\n // off we omit the field entirely rather than pass `false` — the two are\n // equivalent, and omitting keeps the default output provably untouched.\n const overrides: GlazeConfigOverride = {\n ...sharedOverrides,\n ...(pastel ? { pastel: true } : null),\n };\n const instanceConfig: GlazeConfigOverride | undefined = Object.keys(overrides)\n .length\n ? overrides\n : undefined;\n\n // `pastel` deliberately does *not* reach the code theme: syntax colors answer\n // to `themes.code.saturation` and nothing else. Pinned to `false` rather than\n // omitted — the same value Glaze defaults to, but here it is the point of the\n // override, not an absence. See {@link buildCodeTheme}.\n const codeInstanceConfig: GlazeConfigOverride = {\n ...sharedOverrides,\n pastel: false,\n };\n\n // --------------------------------------------------------------------------\n // Default theme (neutral, primary in palette → exported unprefixed)\n // --------------------------------------------------------------------------\n\n const defaultTheme = glaze(hue, saturation, instanceConfig);\n\n defaultTheme.colors({\n // ---- Surfaces (neutral, very low saturation) ----\n surface: { tone: 100, saturation: SURFACE_SATURATION, hue: baseHue },\n 'surface-2': {\n hue: baseHue,\n base: 'surface',\n tone: ['-2', '-4'],\n saturation: 0.1,\n inherit: false,\n },\n 'surface-3': {\n hue: baseHue,\n base: 'surface',\n tone: ['-4', '-8'],\n saturation: 0.1,\n inherit: false,\n },\n 'surface-4': {\n hue: baseHue,\n base: 'surface',\n tone: ['-6', '-12'],\n saturation: 0.1,\n inherit: false,\n },\n\n // ---- Text on surfaces ----\n // Tone is the contrast-uniform OKHST axis, so a relative tone delta directly\n // encodes a WCAG contrast step. `surface-text` sits at tone 2 (a -98 delta\n // from white), giving the same near-black appearance as the legacy `#dark`.\n // We still keep an `['AA','AAA']` contrast floor on every text-on-surface\n // color so a future low-contrast scale can shift the ramp down without ever\n // breaking readability.\n 'surface-text': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_SOFT_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-text-soft-2': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_SOFT2_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-2-text': {\n hue: baseHue,\n base: 'surface-2',\n tone: `${TEXT_TONE + SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-2-text-soft': {\n hue: baseHue,\n base: 'surface-2',\n tone: `${TEXT_SOFT_TONE + SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-3-text': {\n hue: baseHue,\n base: 'surface-3',\n tone: `${TEXT_TONE + SURFACE_3_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-3-text-soft': {\n hue: baseHue,\n base: 'surface-3',\n tone: `${TEXT_SOFT_TONE + SURFACE_3_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n\n // ---- Other neutral UI primitives (default-only) ----\n border: {\n hue: baseHue,\n base: 'surface',\n tone: ['-10', '-30'],\n saturation: 0.175,\n },\n placeholder: {\n hue: baseHue,\n base: 'surface',\n tone: '-33',\n saturation: 0.175,\n inherit: false,\n },\n focus: {\n base: 'surface',\n tone: '-29',\n saturation: 0.8625,\n inherit: false,\n },\n disabled: {\n tone: 80.8,\n saturation: 0.4,\n inherit: false,\n },\n // Disabled fill chip + text — both adaptive (mode 'auto') and positioned\n // with relative tone deltas against `surface` so the disabled state has the\n // same perceived intensity in light, dark, and high-contrast schemes. No\n // numeric contrast prop is needed: tone is already on a WCAG-uniform scale.\n //\n // Tone deltas reproduce the legacy palette's disabled appearance exactly:\n // the chip sits ~cr 1.11 vs `surface` (a faint greyed pill for\n // OUTLINE/SECONDARY/item disabled states) and the label ~cr 2.02 vs\n // `surface` — intentionally sub-AA so it reads as disabled while staying the\n // same softness clear/link disabled labels had before. PRIMARY-style buttons\n // use the brand-tinted `accent-disabled-*` variants below instead. Both\n // tokens stay default-only (`inherit: false`) — colored themes inherit their\n // own disabled chip via the accent variants.\n 'disabled-surface': {\n hue: baseHue,\n base: 'surface',\n tone: '-3.5',\n saturation: 0.2,\n inherit: false,\n },\n 'disabled-surface-text': {\n base: 'surface',\n tone: '-23',\n saturation: 0.3,\n inherit: false,\n },\n\n // Fixed-mode \"always dark\" surface for elements that intentionally stay\n // inverted regardless of scheme (tooltips, code blocks, popovers with their\n // own dark theme, etc.). `mode: 'fixed'` bypasses the dark-scheme inversion\n // so the color reads as a dark surface in light, dark, and high-contrast.\n // Pair with `#white` (built-in) for foreground text.\n 'surface-inverse': {\n hue: baseHue,\n tone: 12,\n saturation: 0.475,\n mode: 'fixed',\n inherit: false,\n },\n\n // ---- Accent system (theme-aware, inherited by colored themes) ----\n // Everything here is anchored to a fixed white \"accent-surface-text\" via\n // `mode: 'fixed'` + relative tone deltas, so accent colors stay visually\n // consistent across light/dark/high-contrast schemes (the brand color does\n // not flip). The solid fills are white-text-on-brand backgrounds, so they\n // keep an `['AA','AAA']` contrast floor even though the chosen tone deltas\n // already exceed it. This leaves room for a future low-contrast scale.\n 'accent-surface-text': { tone: 100, mode: 'fixed' },\n 'accent-surface': {\n base: 'accent-surface-text',\n tone: '-49',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-2': {\n base: 'accent-surface-text',\n tone: '-52',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-3': {\n base: 'accent-surface-text',\n tone: '-55',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n // Hover variant of `accent-surface` — a *fixed*-mode darker shade used as\n // the hover fill for solid PRIMARY-type buttons. Anchored to the same\n // accent-surface-text so it stays in the same hue family. The relative tone\n // lands a few steps darker than the pressed state in both schemes.\n 'accent-surface-hover': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n // Border for accent surfaces — a small relative tone step away from the\n // brand fill so it stays in the brand hue family and does not flip in dark\n // mode. No contrast prop needed; the delta is chosen directly on the tone\n // scale.\n 'accent-surface-border': {\n base: 'accent-surface',\n tone: '+13',\n mode: 'fixed',\n },\n // Opaque stand-in for the BASE selected fill used by outline / outline-2 /\n // clear Item types (`#surface|#surface-2|#surface-3` + `#accent-surface.09`).\n // Anchors `accent-text` contrast. `value: 9` matches the `.09` alpha overlay;\n // `space: 'srgb'` approximates CSS two-layer compositing. Inherited so\n // colored themes re-resolve against their own `surface` + `accent-surface`\n // (default `surface-2`/`surface-3` are `inherit: false` and can't be the mix\n // base). Primary's tinted `surface` makes this slightly harder than default\n // clear-selected, covering outline / outline-2 selected fills as well.\n 'accent-selected-fill': {\n type: 'mix',\n base: 'surface',\n target: 'accent-surface',\n value: 9,\n space: 'srgb',\n },\n // Stronger brand text for HOVERED selected outline/clear labels and LINK\n // hover. Same anchor + preferred tone as `accent-text-soft`, but a higher\n // `contrast: { wcag: [6, 7] }` floor against `accent-selected-fill` so it\n // reads as a clear step up from the soft rest color while staying saturated\n // (a bare `AAA`/`7` floor over-darkens light and desaturates dark). The HC\n // pair keeps it at/above the soft variant (which auto-promotes AA→AAA in HC).\n // `mode: 'auto'` (default) keeps dark-mode text readable on dark surfaces.\n 'accent-text': {\n base: 'accent-selected-fill',\n tone: '-49',\n saturation: 1,\n contrast: [6, 11],\n },\n // Rest brand text for selected outline/clear labels and LINK base color.\n // Anchored to `accent-selected-fill` with `contrast: 'AA'` — the measured\n // floor for every BASE state of those Item types (surface / outline /\n // outline-2 / clear selected fills). Sits visibly less prominent than\n // `accent-text` (lighter in light, darker in dark) so the rest→hover\n // intensify is real.\n 'accent-text-soft': {\n base: 'accent-selected-fill',\n tone: '-49',\n saturation: 1,\n contrast: ['AA', 'AAA'],\n },\n 'accent-icon': {\n base: 'surface',\n tone: '-38',\n saturation: 0.9375,\n },\n\n // Brand-tinted disabled chip + label for PRIMARY-style buttons (solid brand\n // fill). The chip is scheme-symmetric (`mode: 'fixed'`) so the muted state\n // reads the same weight in light/dark/HC; saturation is bumped so it stays\n // identifiable as a muted brand color.\n //\n // The label rides the extreme away from the chip (`tone: 'max'`, ~cr 1.7):\n // deliberately faint, so it reads as disabled rather than as live text.\n // `'max'` is the authored intent — it was temporarily hand-approximated as a\n // relative `tone: '+15'` with `autoFlip: false`, because Glaze < 1.2.0\n // re-mapped the extreme through the dark tone window, compressing the\n // base-to-extreme span and dropping the dark label's contrast. Glaze 1.2.0\n // (tenphi/glaze#82) instead replays the light scheme's base→extreme tone\n // shift against the base's resolved dark tone — same-signed under\n // `mode: 'fixed'` — so `'max'` holds its intended separation in every scheme\n // and the approximation is no longer needed. Inherited per theme.\n //\n // The special theme keeps its own relative `+18` pair: its `surface` is a\n // fixed dark tone, so an extreme there would resolve to white and read as\n // live text rather than disabled.\n 'accent-disabled-surface': {\n base: 'surface',\n tone: '-13',\n saturation: 0.5,\n mode: 'fixed',\n },\n 'accent-disabled-surface-text': {\n base: 'accent-disabled-surface',\n tone: 'max',\n saturation: 0.4,\n mode: 'fixed',\n },\n\n // ---- Loading-animation cube faces ----\n // Decorative gradient steps from `surface` to a saturated mid-tone. Tone\n // deltas are chosen directly on the contrast-uniform scale; no contrast prop\n // is needed for a non-text decorative element.\n 'loading-face-1': {\n base: 'surface',\n tone: '-2',\n saturation: 0.3,\n inherit: false,\n },\n 'loading-face-2': {\n base: 'surface',\n tone: '-9',\n saturation: 0.62,\n inherit: false,\n },\n 'loading-face-3': {\n base: 'surface',\n tone: '-21',\n saturation: 0.66,\n inherit: false,\n },\n\n // ---- Shadows (default-only) ----\n 'shadow-sm': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 5,\n inherit: false,\n },\n 'shadow-md': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 10,\n inherit: false,\n },\n 'shadow-lg': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 15,\n inherit: false,\n },\n\n // Backdrop overlay (translucent)\n overlay: { tone: 10, opacity: 0.5, inherit: false, hue: baseHue },\n });\n\n // --------------------------------------------------------------------------\n // Colored themes\n // --------------------------------------------------------------------------\n //\n // `primary` is the brand theme: it shares both the accent hue and the palette\n // seed saturation with `default`, and differs only in carrying a tinted surface.\n // Each status theme adds its own hue on top.\n const primaryTheme = defaultTheme.extend({\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const successTheme = defaultTheme.extend({\n hue: themes.success.hue,\n saturation: themes.success.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const dangerTheme = defaultTheme.extend({\n hue: themes.danger.hue,\n saturation: themes.danger.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const warningTheme = defaultTheme.extend({\n hue: themes.warning.hue,\n saturation: themes.warning.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const noteTheme = defaultTheme.extend({\n hue: themes.note.hue,\n saturation: themes.note.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n\n // --------------------------------------------------------------------------\n // Special theme (fixed-mode, NOT inherited from the default theme)\n // --------------------------------------------------------------------------\n //\n // Standalone theme for `special`-variant components (hero CTAs, banners, etc.)\n // that intentionally sit on a dark surface regardless of the active scheme.\n //\n // Every token here is `mode: 'fixed'` so the resolved value is identical in\n // light, dark, and high-contrast. The shape is purpose-built (not a full\n // mirror of the default theme) — only what `SPECIAL_*_STYLES` in\n // `src/data/item-themes.ts` consumes is emitted. It follows the *primary*\n // seed, since it is the brand-on-dark theme.\n //\n // Token rundown:\n // - `surface` — dark L≈12 backdrop (same value as `#surface-inverse`).\n // - `accent-surface` / `accent-surface-2` / `accent-surface-3` —\n // brand PRIMARY fill ramp (default → hover → pressed). Mirrors the\n // `#primary-accent-surface` / `-2` / `-3` ramp on the colored themes so\n // `SPECIAL_PRIMARY_STYLES.fill` can use the same shape.\n // - `accent-surface-hover` — legacy alias kept around for the\n // `#special-hover` color shortcut in `src/tokens/colors.ts`. Item\n // themes themselves no longer reference it.\n // - `accent-surface-text` — fixed white (= built-in `#white`), exposed\n // for explicit references.\n // - `accent-text` — dark brand foreground readable on white. Used as\n // CLEAR-variant text on the always-white pill, and as the\n // pressed/focused border on the brand primary fill. Matches the\n // legacy `#fixed-primary-text` alias (= `#primary-accent-surface-hover`).\n // - `accent-disabled-surface` / `accent-disabled-surface-text` —\n // brand-tinted disabled chip + label, positioned with relative tone\n // deltas against the fixed dark `surface` so the disabled state is\n // scheme-symmetric.\n\n const specialTheme = glaze(hue, saturation, instanceConfig);\n\n specialTheme.colors({\n surface: { tone: 12, saturation: 0.475, mode: 'fixed' },\n\n 'accent-surface-text': { tone: 100, mode: 'fixed' },\n 'accent-surface': {\n base: 'accent-surface-text',\n tone: '-49',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-2': {\n base: 'accent-surface-text',\n tone: '-52',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-3': {\n base: 'accent-surface-text',\n tone: '-55',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-border': {\n base: 'accent-surface',\n tone: '+13',\n mode: 'fixed',\n },\n 'accent-surface-hover': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-text': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n\n 'accent-disabled-surface': {\n base: 'surface',\n tone: '+4',\n saturation: 0.5,\n mode: 'fixed',\n },\n 'accent-disabled-surface-text': {\n base: 'accent-disabled-surface',\n tone: '+18',\n saturation: 0.4,\n mode: 'fixed',\n },\n });\n\n // --------------------------------------------------------------------------\n // Palette composition\n // --------------------------------------------------------------------------\n //\n // `purple` is the legacy alias for `primary` and resolves to identical tokens\n // (same theme instance, different prefix → no token-value collision).\n //\n // `default` is emitted with an empty prefix (custom map in `getPaletteTokens`),\n // so its tokens appear unprefixed (`#surface`, `#border`, …). All other themes\n // are prefixed with `<themeName>-`.\n return {\n palette: glaze.palette({\n default: defaultTheme,\n primary: primaryTheme,\n purple: primaryTheme,\n success: successTheme,\n danger: dangerTheme,\n warning: warningTheme,\n note: noteTheme,\n special: specialTheme,\n }),\n // Kept out of the palette on purpose: it has to emit `code-*` unprefixed, and\n // its mirrored `surface` would collide with the default theme's.\n codeTheme: buildCodeTheme(config, codeInstanceConfig),\n };\n}\n\n// ============================================================================\n// Tasty-formatted token export\n// ============================================================================\n\nconst TOKEN_PREFIXES = {\n default: '',\n primary: 'primary-',\n purple: 'purple-',\n success: 'success-',\n danger: 'danger-',\n warning: 'warning-',\n note: 'note-',\n special: 'special-',\n};\n\nlet paletteCache: GlazePalette | null = null;\nlet codeThemeCache: GlazeTheme | null = null;\nlet paletteTokensCache: Styles | null = null;\nlet cachedVersion = -1;\n\n/**\n * Whether *we* are the ones holding a manual level in Glaze's global config.\n *\n * `contrastLevel` is the one palette option that has to be global: a global\n * level pins `modes.highContrast: false` so no high-contrast tier is emitted at\n * all (which is the point — a manual level already carries the preference),\n * whereas a per-instance level would leave the tier in place and report its own\n * values there. `palette.tasty({ modes })` cannot override that either.\n *\n * Being global means it is shared with the host app, so we only write it when\n * asked. A host that sets its own `glaze.configure({ contrastLevel })` and never\n * touches `setPaletteConfig({ contrastLevel })` keeps its level — without this\n * flag we would silently reset it to `'auto'` on the first token read.\n */\nlet ownsContrastLevel = false;\n\nfunction applyContrastLevel(contrastLevel: number | 'auto') {\n // Nothing to do: we hold no level, and the config does not ask for one.\n if (contrastLevel === 'auto' && !ownsContrastLevel) return;\n\n // Always explicit — `configure()` never clears a field by omission, so\n // returning to `'auto'` has to say so.\n glaze.configure({ contrastLevel });\n ownsContrastLevel = contrastLevel !== 'auto';\n}\n\nfunction refresh() {\n const version = getPaletteVersion();\n\n if (paletteTokensCache && cachedVersion === version) return;\n\n const config = getPaletteConfig();\n\n applyContrastLevel(config.contrastLevel);\n\n const built = buildPalette(config);\n\n paletteCache = built.palette;\n paletteTokensCache = {\n ...built.palette.tasty({ prefix: TOKEN_PREFIXES, format: 'oklch' }),\n ...pickCodeTokens(built.codeTheme.tasty({ format: 'oklch' })),\n } as Styles;\n codeThemeCache = built.codeTheme;\n cachedVersion = version;\n}\n\n/**\n * Resolve Glaze palette tokens against the current palette config.\n *\n * Memoized against the config version (see `./palette-config.ts`), so repeated\n * reads are free and `setPaletteConfig()` invalidates them. Resolution is\n * deferred rather than done at module import, so host apps can call\n * `setPaletteConfig(...)` / `glaze.configure(...)` after importing\n * `@cube-dev/ui-kit` and still affect the first paint.\n *\n * Keys use `#name` syntax; values are state maps:\n * '#surface': { '': 'oklch(...)', '@dark': 'oklch(...)', '@hc': 'oklch(...)' }\n */\nexport function getPaletteTokens(): Styles {\n refresh();\n\n return paletteTokensCache!;\n}\n\n/** The live `GlazePalette`. Rebuilt whenever the palette config changes. */\nexport function getPalette(): GlazePalette {\n refresh();\n\n return paletteCache!;\n}\n\n/**\n * The live theme behind the `code-*` tokens. Separate from {@link getPalette}\n * because it carries its own saturation seed — see {@link CODE_COLORS}.\n */\nexport function getCodeTheme(): GlazeTheme {\n refresh();\n\n return codeThemeCache!;\n}\n\n// ============================================================================\n// One-variant render (for previewing a palette on a region)\n// ============================================================================\n\nconst VARIANT_KEY = {\n 'light:false': 'light',\n 'light:true': 'lightContrast',\n 'dark:false': 'dark',\n 'dark:true': 'darkContrast',\n} as const;\n\n/**\n * Single-entry memo: all four variants of the last config rendered.\n *\n * Keyed on the palette version as well as the config, because the config is not\n * the only input — `buildPalette` also reads Glaze's own global config\n * (`darkTone`, `darkDesaturation`, the state map). A host that drives Glaze\n * directly and then calls `invalidatePaletteTokens()` bumps the version without\n * touching the config, and the region previews have to follow the document.\n */\nlet renderKey: string | null = null;\nlet renderVariants: Record<string, Record<string, string>> = {};\n\n/**\n * Resolve one scheme variant of a palette to flat, literal color values.\n *\n * Unlike {@link getPaletteTokens}, which emits state maps (`@dark` / `@hc`) for\n * the whole document, this collapses the palette to the single variant you ask\n * for. That is what makes a **region** preview possible: applied through a tasty\n * `tokens` prop, the values override the inherited ones for that subtree only, so\n * a dark or high-contrast theme can be shown inside a light page.\n *\n * Prefer `renderColorTokens()` from `./colors` unless you specifically want the\n * palette without the legacy aliases.\n */\nexport function renderPaletteTokens(\n options: RenderPaletteOptions = {},\n): Tokens {\n const { scheme = 'light', highContrast = false, ...config } = options;\n const resolved = resolvePaletteConfig(config);\n const key = `${getPaletteVersion()}:${JSON.stringify(resolved)}`;\n\n if (renderKey !== key) {\n // Force the *global* level to `'auto'` for the duration of the export.\n // Glaze suppresses high-contrast output whenever a global level is set, and\n // that check reads the global config — so without this, a preview's variants\n // would depend on whatever contrast mode the surrounding app happens to be\n // in. The preview's own level rides on the theme instances instead\n // (`isolateContrastLevel`), so the values stay correct. Restored in `finally`;\n // resolution is synchronous, so nothing can observe the window.\n const previousLevel = glaze.getConfig().contrastLevel;\n\n try {\n glaze.configure({ contrastLevel: 'auto' });\n\n const built = buildPalette(resolved, { isolateContrastLevel: true });\n const modes = { dark: true, highContrast: true };\n const themed = built.palette.tokens({\n prefix: TOKEN_PREFIXES,\n format: 'oklch',\n modes,\n });\n const code = built.codeTheme.tokens({ format: 'oklch', modes });\n\n // Built into a local and published together, so a throw part-way through\n // cannot leave a half-filled map sitting under the previous key.\n const variants: typeof renderVariants = {};\n\n for (const name of Object.keys(themed)) {\n variants[name] = {\n ...themed[name],\n ...pickCodeTokens(code[name] ?? {}),\n };\n }\n\n renderVariants = variants;\n renderKey = key;\n } finally {\n glaze.configure({ contrastLevel: previousLevel });\n }\n }\n\n const variant = VARIANT_KEY[`${scheme}:${highContrast}`];\n // A manual `contrastLevel` leaves no separate high-contrast tier — Glaze\n // mirrors the contrast variants onto the normal ones — so asking for\n // `highContrast` there correctly yields the same colors.\n const flat = renderVariants[variant] ?? renderVariants[scheme];\n const out: Tokens = {};\n\n for (const name of Object.keys(flat)) out[`#${name}`] = flat[name];\n\n return out;\n}\n\n/**\n * Lazy proxy of {@link getPaletteTokens}. Prefer `getPaletteTokens()` in new\n * code. Property / enumeration access always reflects the current palette\n * config.\n */\nexport const PALETTE_TOKENS: Styles = lazyStyles(getPaletteTokens);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"palette.js","names":[],"sources":["../../src/tokens/palette.ts"],"sourcesContent":["import { glaze } from '@tenphi/glaze';\n\nimport { lazyStyles } from './lazy-styles';\nimport {\n getPaletteConfig,\n getPaletteVersion,\n resolvePaletteConfig,\n} from './palette-config';\n\nimport type {\n ColorMap,\n GlazeConfigOverride,\n GlazePalette,\n GlazeTheme,\n} from '@tenphi/glaze';\nimport type { Styles, Tokens } from '@tenphi/tasty';\nimport type { PaletteConfig, ResolvedPaletteConfig } from './palette-config';\n\n/** Which resolved scheme variant {@link renderPaletteTokens} should return. */\nexport interface RenderPaletteOptions extends PaletteConfig {\n /** Color scheme to resolve. Default: `'light'`. */\n scheme?: 'light' | 'dark';\n /** Resolve the high-contrast variant of that scheme. Default: `false`. */\n highContrast?: boolean;\n}\n\n/**\n * Glaze-generated color palette for the Cube UI Kit.\n *\n * Produces light, dark, and high-contrast color variants from a single\n * source of truth. Every color token is emitted as a tasty state map:\n *\n * '#surface': { '': 'oklch(...)', '@dark': 'oklch(...)', '@hc': 'oklch(...)' }\n *\n * The `@dark` and `@hc` state aliases are wired up globally in\n * `src/components/Root.tsx` (see `setGlobalPredefinedStates`).\n *\n * This module owns the *recipe* — which colors exist and how each one is\n * positioned relative to its base. The *seeds* it is built from (hue,\n * saturation, pastel, contrast level) live in `./palette-config.ts` and are\n * tunable at runtime; `buildPalette()` below is a pure function of them.\n */\n\n// ============================================================================\n// Recipe constants\n// ============================================================================\n\n// Relative tone ramp from a white surface.\n// Tone is a contrast-uniform 0–100 scale (OKHST). A relative tone delta of -N\n// yields a fixed WCAG contrast step against the base regardless of where the\n// base sits on the scale. These constants form the primary text ramp; the\n// surface-2 / surface-3 variants reuse the same absolute targets via a small\n// offset because their bases are shifted down from `surface`.\nconst TEXT_TONE = -98; // relative tone delta from white surface (~cr 21)\nconst TEXT_SOFT_TONE = -72; // relative tone delta from white surface (~cr 9)\nconst TEXT_SOFT2_TONE = -52; // relative tone delta from white surface (~cr 4.5)\nconst SURFACE_2_TEXT_OFFSET = 2;\nconst SURFACE_3_TEXT_OFFSET = 4;\n\n// Syntax highlighting keeps its own fixed hue reference (see the `code-*` block\n// below). This is the kit's default brand hue, frozen as a literal: string\n// literals were historically purple because the brand is, but they must not\n// follow a re-seeded brand hue — a green brand would collide `code-string` with\n// `code-number` (156°) and make strings and numbers indistinguishable.\nconst CODE_STRING_HUE = 280.3;\n\n/**\n * Saturation factor of the neutral `surface`.\n *\n * Shared with the code theme, which mirrors `surface` to solve its contrast floors\n * against the real page background — the two must not drift apart.\n */\nconst SURFACE_SATURATION = 0.12;\n\nconst TINTED_SURFACE_SATURATION = 0.2;\nconst TINTED_SURFACE_TONE_OFFSET = 2;\n\n/**\n * Syntax highlighting for `PrismCode`, as its own theme.\n *\n * A small palette of *adaptive* colored tokens. Each one is anchored to `surface`\n * with a relative tone plus an `['AA','AAA']` readability floor, so it stays legible\n * in light, dark and high contrast. Hues mirror the long-standing PrismCode\n * reference (pink keywords / pink functions / purple strings / green numbers / gray\n * comments); `code-attribute` keeps cyan for HTML attribute names, CSS properties\n * and selectors, while HTML/XML tag names reuse `code-keyword`. Diff insertion and\n * deletion reuse the `success-*` / `danger-*` ramps instead.\n *\n * Three things are deliberately static here. Every hue is an absolute literal, so a\n * re-seeded brand cannot rotate the syntax palette — a green brand would otherwise\n * collide `code-string` with `code-number` (156°). These factors are relative to\n * the *code* theme's own seed (`themes.code.saturation`), not the palette-level one,\n * so tuning the app's saturation cannot wash out a code block. And `pastel` is held\n * off here whatever the palette does, for the same reason: it lowers the chroma\n * ceiling hard enough to take `code-keyword` from ~0.19 to ~0.07, which is the\n * difference between distinguishable syntax and mud. Between them, these mean the\n * emitted `code-*` values are a function of the code saturation alone.\n *\n * That separate seed is the only reason these live outside the default theme: a\n * theme colour can never exceed its own seed, and four of these sit at factor `1.0`,\n * so they could not hold their chroma inside a default theme seeded below 80.\n */\nconst CODE_COLORS: ColorMap = {\n 'code-comment': {\n base: 'surface',\n hue: 280,\n saturation: 0.1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-punctuation': {\n base: 'surface',\n hue: 348,\n saturation: 0.4,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-keyword': {\n base: 'surface',\n hue: 348,\n saturation: 1,\n tone: '-54',\n contrast: ['AA', 'AAA'],\n },\n 'code-string': {\n base: 'surface',\n hue: CODE_STRING_HUE,\n saturation: 1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-number': {\n base: 'surface',\n hue: 156,\n saturation: 0.9,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n 'code-function': {\n base: 'surface',\n hue: 348,\n saturation: 1,\n tone: '-54',\n contrast: ['AA', 'AAA'],\n },\n 'code-attribute': {\n base: 'surface',\n hue: 200,\n saturation: 1,\n tone: '-50',\n contrast: ['AA', 'AAA'],\n },\n};\n\n/**\n * Build the standalone theme the `code-*` tokens live in.\n *\n * Its seed is the code saturation, so {@link CODE_COLORS} keeps its authored factors\n * verbatim and resolves identically at any palette saturation. The mirrored `surface`\n * is an implementation detail — it exists only as the contrast base, and is filtered\n * out of the emitted tokens by {@link pickCodeTokens}.\n *\n * `instanceConfig` arrives with `pastel` pinned off, so the mirror is non-pastel too\n * even when the app is. Harmless: at saturation factor 0.12 the pastel ceiling moves\n * the mirror's chroma and leaves its tone — the axis every `code-*` contrast floor is\n * solved against — bit-identical.\n */\nfunction buildCodeTheme(\n config: ResolvedPaletteConfig,\n instanceConfig: GlazeConfigOverride | undefined,\n): GlazeTheme {\n const codeSaturation = config.themes.code.saturation;\n const theme = glaze(config.hue, codeSaturation, instanceConfig);\n\n // Re-express the default theme's `surface` as a factor of the *code* seed, so it\n // resolves to the same colour the code actually sits on. Written as a ratio of\n // seeds so the default config lands on exactly `SURFACE_SATURATION`.\n let mirrorFactor = SURFACE_SATURATION * (config.saturation / codeSaturation);\n\n if (mirrorFactor > 1) {\n // Only reachable with a code saturation far below the palette's. Glaze would\n // clamp this silently and then solve every contrast floor against the wrong\n // background, so say so.\n // eslint-disable-next-line no-console\n console.warn(\n `[cube-ui-kit] themes.code.saturation (${codeSaturation}) is too low for ` +\n `saturation ${config.saturation}: the mirrored code surface would need a ` +\n `factor of ${mirrorFactor.toFixed(3)}. Clamped to 1; raise the code ` +\n `saturation to keep syntax contrast accurate.`,\n );\n mirrorFactor = 1;\n }\n\n theme.colors({\n surface: { tone: 100, saturation: mirrorFactor },\n ...CODE_COLORS,\n });\n\n return theme;\n}\n\n/** What {@link buildPalette} produces: the themed palette plus the code theme. */\ninterface BuiltPalette {\n palette: GlazePalette;\n codeTheme: GlazeTheme;\n}\n\n/** Drop the mirrored `surface`, keeping only the `code-*` tokens. */\nfunction pickCodeTokens<T>(tokens: Record<string, T>): Record<string, T> {\n const out: Record<string, T> = {};\n\n for (const name of Object.keys(tokens)) {\n if (name.startsWith('code-') || name.startsWith('#code-')) {\n out[name] = tokens[name];\n }\n }\n\n return out;\n}\n\n// ============================================================================\n// Global Glaze configuration\n// ============================================================================\n\nglaze.configure({\n states: {\n dark: '@dark',\n highContrast: '@hc',\n },\n modes: {\n dark: true,\n highContrast: true,\n },\n darkTone: [14, 95],\n darkDesaturation: 0,\n});\n\n/**\n * Per-colored-theme overrides on top of the default theme:\n * - `surface` — bumped saturation so the banner bg is visibly tinted.\n * - `border` — bumped saturation so OUTLINE-variant borders pick up the\n * theme hue (used by `#<theme>-border` in `item-themes.ts`). Mirrors the\n * default-theme `border` shape (`base: 'surface'`, tone window) but\n * with higher saturation. Glaze's `extend({ colors })` redefines each\n * listed color from scratch, so we restate the full definition here.\n */\nconst TINTED_SURFACE_OVERRIDE: ColorMap = {\n surface: {\n tone: [\n 100 - TINTED_SURFACE_TONE_OFFSET,\n 100 - TINTED_SURFACE_TONE_OFFSET * 2,\n ],\n saturation: TINTED_SURFACE_SATURATION,\n },\n border: {\n base: 'surface',\n tone: ['-10', '-30'],\n saturation: 0.3,\n },\n 'surface-text': {\n base: 'surface',\n tone: `${TEXT_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft': {\n base: 'surface',\n tone: `${TEXT_SOFT_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft-2': {\n base: 'surface',\n tone: `${TEXT_SOFT2_TONE - TINTED_SURFACE_TONE_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n};\n\n/**\n * A tinted surface, a banding step, and text guaranteed to read on both.\n *\n * The recipe behind {@link getColorTheme} in `./color-theme.ts`, which builds\n * one-off themes at runtime from an arbitrary hue. It lives here so it shares\n * `TINTED_SURFACE_SATURATION`, the tone offsets and the text ramp with\n * {@link TINTED_SURFACE_OVERRIDE} above rather than forking them — a runtime tint\n * and a built-in theme's `surface` should be the same colour for the same hue.\n *\n * Three colours, because that is what banded, readable table column needs:\n * `surface` for even rows, `surface-2` one tone step down for odd rows and\n * pinned totals, and `surface-2-text`.\n *\n * The text is anchored to `surface-2`, not `surface`. `surface-2` has the lower\n * contrast headroom in BOTH schemes — a darker background under dark text in\n * light, a lighter one under light text in dark — so solving the floor there\n * clears it on both bands. The neutral ramp's own `surface-2-text` is shaped the\n * same way for the same reason.\n */\nexport const TINT_RECIPE: ColorMap = {\n surface: {\n tone: [\n 100 - TINTED_SURFACE_TONE_OFFSET,\n 100 - TINTED_SURFACE_TONE_OFFSET * 2,\n ],\n saturation: TINTED_SURFACE_SATURATION,\n },\n 'surface-2': {\n base: 'surface',\n // Mirrors the neutral ramp's step from `surface` to `surface-2`: enough to\n // read as banding down a column, not enough to read as two colours.\n tone: ['-2', '-4'],\n saturation: TINTED_SURFACE_SATURATION,\n },\n 'surface-2-text': {\n base: 'surface-2',\n tone: `${TEXT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.25,\n // The whole point: Glaze binary-searches the tone per scheme until the floor\n // is met, so a caller cannot persist an unreadable pair.\n contrast: ['AA', 'AAA'],\n },\n /**\n * The softer step, for a tinted column HEADER.\n *\n * A neutral header is deliberately muted (`HeadRow` publishes `#dark-03`), so\n * a tinted one taking the full-strength body text read markedly darker than\n * the headers either side of it — measured at 16:1 against their 4.9:1. This\n * keeps the two consistent, and the `AA` floor still applies.\n */\n 'surface-2-text-soft': {\n base: 'surface-2',\n tone: `${TEXT_SOFT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.25,\n contrast: ['AA', 'AAA'],\n },\n};\n\n// ============================================================================\n// Palette construction\n// ============================================================================\n\n/**\n * Build the full palette from a resolved config.\n *\n * Pure: it reads nothing but its argument (and the global Glaze config, which\n * the caller sets first), so re-running it with the same config yields the same\n * tokens. Theme instances are immutable with respect to their hue / saturation\n * seed and a `GlazePalette` has no mutation API, so re-seeding means rebuilding.\n */\nfunction buildPalette(\n config: ResolvedPaletteConfig,\n options: {\n /**\n * Carry `contrastLevel` on the theme instances instead of relying on the\n * global Glaze config. Used when rendering a palette the app is not running,\n * so a preview cannot disturb the live one. The resolved values are the same\n * either way; only which scheme variants get *emitted* differs, and callers\n * that isolate pick their variant explicitly.\n */\n isolateContrastLevel?: boolean;\n } = {},\n): BuiltPalette {\n const { hue, baseHue, saturation, pastel, themes, contrastLevel } = config;\n\n // The one override the code theme shares with the rest of the palette.\n const sharedOverrides: GlazeConfigOverride = options.isolateContrastLevel\n ? { contrastLevel }\n : {};\n\n // `pastel` is instance-level in Glaze (not settable via `glaze.configure`).\n // Setting it on the two root themes is enough: `extend({ config })` merges\n // with the parent's override, so the derived themes inherit it. When it is\n // off we omit the field entirely rather than pass `false` — the two are\n // equivalent, and omitting keeps the default output provably untouched.\n const overrides: GlazeConfigOverride = {\n ...sharedOverrides,\n ...(pastel ? { pastel: true } : null),\n };\n const instanceConfig: GlazeConfigOverride | undefined = Object.keys(overrides)\n .length\n ? overrides\n : undefined;\n\n // `pastel` deliberately does *not* reach the code theme: syntax colors answer\n // to `themes.code.saturation` and nothing else. Pinned to `false` rather than\n // omitted — the same value Glaze defaults to, but here it is the point of the\n // override, not an absence. See {@link buildCodeTheme}.\n const codeInstanceConfig: GlazeConfigOverride = {\n ...sharedOverrides,\n pastel: false,\n };\n\n // --------------------------------------------------------------------------\n // Default theme (neutral, primary in palette → exported unprefixed)\n // --------------------------------------------------------------------------\n\n const defaultTheme = glaze(hue, saturation, instanceConfig);\n\n defaultTheme.colors({\n // ---- Surfaces (neutral, very low saturation) ----\n surface: { tone: 100, saturation: SURFACE_SATURATION, hue: baseHue },\n 'surface-2': {\n hue: baseHue,\n base: 'surface',\n tone: ['-2', '-4'],\n saturation: 0.1,\n inherit: false,\n },\n 'surface-3': {\n hue: baseHue,\n base: 'surface',\n tone: ['-4', '-8'],\n saturation: 0.1,\n inherit: false,\n },\n 'surface-4': {\n hue: baseHue,\n base: 'surface',\n tone: ['-6', '-12'],\n saturation: 0.1,\n inherit: false,\n },\n\n // ---- Text on surfaces ----\n // Tone is the contrast-uniform OKHST axis, so a relative tone delta directly\n // encodes a WCAG contrast step. `surface-text` sits at tone 2 (a -98 delta\n // from white), giving the same near-black appearance as the legacy `#dark`.\n // We still keep an `['AA','AAA']` contrast floor on every text-on-surface\n // color so a future low-contrast scale can shift the ramp down without ever\n // breaking readability.\n 'surface-text': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n },\n 'surface-text-soft': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_SOFT_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-text-soft-2': {\n hue: baseHue,\n base: 'surface',\n tone: `${TEXT_SOFT2_TONE - 2}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-2-text': {\n hue: baseHue,\n base: 'surface-2',\n tone: `${TEXT_TONE + SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-2-text-soft': {\n hue: baseHue,\n base: 'surface-2',\n tone: `${TEXT_SOFT_TONE + SURFACE_2_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-3-text': {\n hue: baseHue,\n base: 'surface-3',\n tone: `${TEXT_TONE + SURFACE_3_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n 'surface-3-text-soft': {\n hue: baseHue,\n base: 'surface-3',\n tone: `${TEXT_SOFT_TONE + SURFACE_3_TEXT_OFFSET}`,\n saturation: 0.2,\n contrast: ['AA', 'AAA'],\n inherit: false,\n },\n\n // ---- Other neutral UI primitives (default-only) ----\n border: {\n hue: baseHue,\n base: 'surface',\n tone: ['-10', '-30'],\n saturation: 0.175,\n },\n placeholder: {\n hue: baseHue,\n base: 'surface',\n tone: '-33',\n saturation: 0.175,\n inherit: false,\n },\n focus: {\n base: 'surface',\n tone: '-29',\n saturation: 0.8625,\n inherit: false,\n },\n disabled: {\n tone: 80.8,\n saturation: 0.4,\n inherit: false,\n },\n // Disabled fill chip + text — both adaptive (mode 'auto') and positioned\n // with relative tone deltas against `surface` so the disabled state has the\n // same perceived intensity in light, dark, and high-contrast schemes. No\n // numeric contrast prop is needed: tone is already on a WCAG-uniform scale.\n //\n // Tone deltas reproduce the legacy palette's disabled appearance exactly:\n // the chip sits ~cr 1.11 vs `surface` (a faint greyed pill for\n // OUTLINE/SECONDARY/item disabled states) and the label ~cr 2.02 vs\n // `surface` — intentionally sub-AA so it reads as disabled while staying the\n // same softness clear/link disabled labels had before. PRIMARY-style buttons\n // use the brand-tinted `accent-disabled-*` variants below instead. Both\n // tokens stay default-only (`inherit: false`) — colored themes inherit their\n // own disabled chip via the accent variants.\n 'disabled-surface': {\n hue: baseHue,\n base: 'surface',\n tone: '-3.5',\n saturation: 0.2,\n inherit: false,\n },\n 'disabled-surface-text': {\n base: 'surface',\n tone: '-23',\n saturation: 0.3,\n inherit: false,\n },\n\n // Fixed-mode \"always dark\" surface for elements that intentionally stay\n // inverted regardless of scheme (tooltips, code blocks, popovers with their\n // own dark theme, etc.). `mode: 'fixed'` bypasses the dark-scheme inversion\n // so the color reads as a dark surface in light, dark, and high-contrast.\n // Pair with `#white` (built-in) for foreground text.\n 'surface-inverse': {\n hue: baseHue,\n tone: 12,\n saturation: 0.475,\n mode: 'fixed',\n inherit: false,\n },\n\n // ---- Accent system (theme-aware, inherited by colored themes) ----\n // Everything here is anchored to a fixed white \"accent-surface-text\" via\n // `mode: 'fixed'` + relative tone deltas, so accent colors stay visually\n // consistent across light/dark/high-contrast schemes (the brand color does\n // not flip). The solid fills are white-text-on-brand backgrounds, so they\n // keep an `['AA','AAA']` contrast floor even though the chosen tone deltas\n // already exceed it. This leaves room for a future low-contrast scale.\n 'accent-surface-text': { tone: 100, mode: 'fixed' },\n 'accent-surface': {\n base: 'accent-surface-text',\n tone: '-49',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-2': {\n base: 'accent-surface-text',\n tone: '-52',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-3': {\n base: 'accent-surface-text',\n tone: '-55',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n // Hover variant of `accent-surface` — a *fixed*-mode darker shade used as\n // the hover fill for solid PRIMARY-type buttons. Anchored to the same\n // accent-surface-text so it stays in the same hue family. The relative tone\n // lands a few steps darker than the pressed state in both schemes.\n 'accent-surface-hover': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n // Border for accent surfaces — a small relative tone step away from the\n // brand fill so it stays in the brand hue family and does not flip in dark\n // mode. No contrast prop needed; the delta is chosen directly on the tone\n // scale.\n 'accent-surface-border': {\n base: 'accent-surface',\n tone: '+13',\n mode: 'fixed',\n },\n // Opaque stand-in for the BASE selected fill used by outline / outline-2 /\n // clear Item types (`#surface|#surface-2|#surface-3` + `#accent-surface.09`).\n // Anchors `accent-text` contrast. `value: 9` matches the `.09` alpha overlay;\n // `space: 'srgb'` approximates CSS two-layer compositing. Inherited so\n // colored themes re-resolve against their own `surface` + `accent-surface`\n // (default `surface-2`/`surface-3` are `inherit: false` and can't be the mix\n // base). Primary's tinted `surface` makes this slightly harder than default\n // clear-selected, covering outline / outline-2 selected fills as well.\n 'accent-selected-fill': {\n type: 'mix',\n base: 'surface',\n target: 'accent-surface',\n value: 9,\n space: 'srgb',\n },\n // Stronger brand text for HOVERED selected outline/clear labels and LINK\n // hover. Same anchor + preferred tone as `accent-text-soft`, but a higher\n // `contrast: { wcag: [6, 7] }` floor against `accent-selected-fill` so it\n // reads as a clear step up from the soft rest color while staying saturated\n // (a bare `AAA`/`7` floor over-darkens light and desaturates dark). The HC\n // pair keeps it at/above the soft variant (which auto-promotes AA→AAA in HC).\n // `mode: 'auto'` (default) keeps dark-mode text readable on dark surfaces.\n 'accent-text': {\n base: 'accent-selected-fill',\n tone: '-49',\n saturation: 1,\n contrast: [6, 11],\n },\n // Rest brand text for selected outline/clear labels and LINK base color.\n // Anchored to `accent-selected-fill` with `contrast: 'AA'` — the measured\n // floor for every BASE state of those Item types (surface / outline /\n // outline-2 / clear selected fills). Sits visibly less prominent than\n // `accent-text` (lighter in light, darker in dark) so the rest→hover\n // intensify is real.\n 'accent-text-soft': {\n base: 'accent-selected-fill',\n tone: '-49',\n saturation: 1,\n contrast: ['AA', 'AAA'],\n },\n 'accent-icon': {\n base: 'surface',\n tone: '-38',\n saturation: 0.9375,\n },\n\n // Brand-tinted disabled chip + label for PRIMARY-style buttons (solid brand\n // fill). The chip is scheme-symmetric (`mode: 'fixed'`) so the muted state\n // reads the same weight in light/dark/HC; saturation is bumped so it stays\n // identifiable as a muted brand color.\n //\n // The label rides the extreme away from the chip (`tone: 'max'`, ~cr 1.7):\n // deliberately faint, so it reads as disabled rather than as live text.\n // `'max'` is the authored intent — it was temporarily hand-approximated as a\n // relative `tone: '+15'` with `autoFlip: false`, because Glaze < 1.2.0\n // re-mapped the extreme through the dark tone window, compressing the\n // base-to-extreme span and dropping the dark label's contrast. Glaze 1.2.0\n // (tenphi/glaze#82) instead replays the light scheme's base→extreme tone\n // shift against the base's resolved dark tone — same-signed under\n // `mode: 'fixed'` — so `'max'` holds its intended separation in every scheme\n // and the approximation is no longer needed. Inherited per theme.\n //\n // The special theme keeps its own relative `+18` pair: its `surface` is a\n // fixed dark tone, so an extreme there would resolve to white and read as\n // live text rather than disabled.\n 'accent-disabled-surface': {\n base: 'surface',\n tone: '-13',\n saturation: 0.5,\n mode: 'fixed',\n },\n 'accent-disabled-surface-text': {\n base: 'accent-disabled-surface',\n tone: 'max',\n saturation: 0.4,\n mode: 'fixed',\n },\n\n // ---- Loading-animation cube faces ----\n // Decorative gradient steps from `surface` to a saturated mid-tone. Tone\n // deltas are chosen directly on the contrast-uniform scale; no contrast prop\n // is needed for a non-text decorative element.\n 'loading-face-1': {\n base: 'surface',\n tone: '-2',\n saturation: 0.3,\n inherit: false,\n },\n 'loading-face-2': {\n base: 'surface',\n tone: '-9',\n saturation: 0.62,\n inherit: false,\n },\n 'loading-face-3': {\n base: 'surface',\n tone: '-21',\n saturation: 0.66,\n inherit: false,\n },\n\n // ---- Shadows (default-only) ----\n 'shadow-sm': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 5,\n inherit: false,\n },\n 'shadow-md': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 10,\n inherit: false,\n },\n 'shadow-lg': {\n type: 'shadow',\n bg: 'surface',\n fg: 'surface-text',\n intensity: 15,\n inherit: false,\n },\n\n // Backdrop overlay (translucent)\n overlay: { tone: 10, opacity: 0.5, inherit: false, hue: baseHue },\n });\n\n // --------------------------------------------------------------------------\n // Colored themes\n // --------------------------------------------------------------------------\n //\n // `primary` is the brand theme: it shares both the accent hue and the palette\n // seed saturation with `default`, and differs only in carrying a tinted surface.\n // Each status theme adds its own hue on top.\n const primaryTheme = defaultTheme.extend({\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const successTheme = defaultTheme.extend({\n hue: themes.success.hue,\n saturation: themes.success.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const dangerTheme = defaultTheme.extend({\n hue: themes.danger.hue,\n saturation: themes.danger.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const warningTheme = defaultTheme.extend({\n hue: themes.warning.hue,\n saturation: themes.warning.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n const noteTheme = defaultTheme.extend({\n hue: themes.note.hue,\n saturation: themes.note.saturation,\n colors: TINTED_SURFACE_OVERRIDE,\n });\n\n // --------------------------------------------------------------------------\n // Special theme (fixed-mode, NOT inherited from the default theme)\n // --------------------------------------------------------------------------\n //\n // Standalone theme for `special`-variant components (hero CTAs, banners, etc.)\n // that intentionally sit on a dark surface regardless of the active scheme.\n //\n // Every token here is `mode: 'fixed'` so the resolved value is identical in\n // light, dark, and high-contrast. The shape is purpose-built (not a full\n // mirror of the default theme) — only what `SPECIAL_*_STYLES` in\n // `src/data/item-themes.ts` consumes is emitted. It follows the *primary*\n // seed, since it is the brand-on-dark theme.\n //\n // Token rundown:\n // - `surface` — dark L≈12 backdrop (same value as `#surface-inverse`).\n // - `accent-surface` / `accent-surface-2` / `accent-surface-3` —\n // brand PRIMARY fill ramp (default → hover → pressed). Mirrors the\n // `#primary-accent-surface` / `-2` / `-3` ramp on the colored themes so\n // `SPECIAL_PRIMARY_STYLES.fill` can use the same shape.\n // - `accent-surface-hover` — legacy alias kept around for the\n // `#special-hover` color shortcut in `src/tokens/colors.ts`. Item\n // themes themselves no longer reference it.\n // - `accent-surface-text` — fixed white (= built-in `#white`), exposed\n // for explicit references.\n // - `accent-text` — dark brand foreground readable on white. Used as\n // CLEAR-variant text on the always-white pill, and as the\n // pressed/focused border on the brand primary fill. Matches the\n // legacy `#fixed-primary-text` alias (= `#primary-accent-surface-hover`).\n // - `accent-disabled-surface` / `accent-disabled-surface-text` —\n // brand-tinted disabled chip + label, positioned with relative tone\n // deltas against the fixed dark `surface` so the disabled state is\n // scheme-symmetric.\n\n const specialTheme = glaze(hue, saturation, instanceConfig);\n\n specialTheme.colors({\n surface: { tone: 12, saturation: 0.475, mode: 'fixed' },\n\n 'accent-surface-text': { tone: 100, mode: 'fixed' },\n 'accent-surface': {\n base: 'accent-surface-text',\n tone: '-49',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-2': {\n base: 'accent-surface-text',\n tone: '-52',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-3': {\n base: 'accent-surface-text',\n tone: '-55',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-surface-border': {\n base: 'accent-surface',\n tone: '+13',\n mode: 'fixed',\n },\n 'accent-surface-hover': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n 'accent-text': {\n base: 'accent-surface-text',\n tone: '-58',\n contrast: ['AA', 'AAA'],\n mode: 'fixed',\n },\n\n 'accent-disabled-surface': {\n base: 'surface',\n tone: '+4',\n saturation: 0.5,\n mode: 'fixed',\n },\n 'accent-disabled-surface-text': {\n base: 'accent-disabled-surface',\n tone: '+18',\n saturation: 0.4,\n mode: 'fixed',\n },\n });\n\n // --------------------------------------------------------------------------\n // Palette composition\n // --------------------------------------------------------------------------\n //\n // `purple` is the legacy alias for `primary` and resolves to identical tokens\n // (same theme instance, different prefix → no token-value collision).\n //\n // `default` is emitted with an empty prefix (custom map in `getPaletteTokens`),\n // so its tokens appear unprefixed (`#surface`, `#border`, …). All other themes\n // are prefixed with `<themeName>-`.\n return {\n palette: glaze.palette({\n default: defaultTheme,\n primary: primaryTheme,\n purple: primaryTheme,\n success: successTheme,\n danger: dangerTheme,\n warning: warningTheme,\n note: noteTheme,\n special: specialTheme,\n }),\n // Kept out of the palette on purpose: it has to emit `code-*` unprefixed, and\n // its mirrored `surface` would collide with the default theme's.\n codeTheme: buildCodeTheme(config, codeInstanceConfig),\n };\n}\n\n// ============================================================================\n// Tasty-formatted token export\n// ============================================================================\n\nconst TOKEN_PREFIXES = {\n default: '',\n primary: 'primary-',\n purple: 'purple-',\n success: 'success-',\n danger: 'danger-',\n warning: 'warning-',\n note: 'note-',\n special: 'special-',\n};\n\nlet paletteCache: GlazePalette | null = null;\nlet codeThemeCache: GlazeTheme | null = null;\nlet paletteTokensCache: Styles | null = null;\nlet cachedVersion = -1;\n\n/**\n * Whether *we* are the ones holding a manual level in Glaze's global config.\n *\n * `contrastLevel` is the one palette option that has to be global: a global\n * level pins `modes.highContrast: false` so no high-contrast tier is emitted at\n * all (which is the point — a manual level already carries the preference),\n * whereas a per-instance level would leave the tier in place and report its own\n * values there. `palette.tasty({ modes })` cannot override that either.\n *\n * Being global means it is shared with the host app, so we only write it when\n * asked. A host that sets its own `glaze.configure({ contrastLevel })` and never\n * touches `setPaletteConfig({ contrastLevel })` keeps its level — without this\n * flag we would silently reset it to `'auto'` on the first token read.\n */\nlet ownsContrastLevel = false;\n\nfunction applyContrastLevel(contrastLevel: number | 'auto') {\n // Nothing to do: we hold no level, and the config does not ask for one.\n if (contrastLevel === 'auto' && !ownsContrastLevel) return;\n\n // Always explicit — `configure()` never clears a field by omission, so\n // returning to `'auto'` has to say so.\n glaze.configure({ contrastLevel });\n ownsContrastLevel = contrastLevel !== 'auto';\n}\n\nfunction refresh() {\n const version = getPaletteVersion();\n\n if (paletteTokensCache && cachedVersion === version) return;\n\n const config = getPaletteConfig();\n\n applyContrastLevel(config.contrastLevel);\n\n const built = buildPalette(config);\n\n paletteCache = built.palette;\n paletteTokensCache = {\n ...built.palette.tasty({ prefix: TOKEN_PREFIXES, format: 'oklch' }),\n ...pickCodeTokens(built.codeTheme.tasty({ format: 'oklch' })),\n } as Styles;\n codeThemeCache = built.codeTheme;\n cachedVersion = version;\n}\n\n/**\n * Resolve Glaze palette tokens against the current palette config.\n *\n * Memoized against the config version (see `./palette-config.ts`), so repeated\n * reads are free and `setPaletteConfig()` invalidates them. Resolution is\n * deferred rather than done at module import, so host apps can call\n * `setPaletteConfig(...)` / `glaze.configure(...)` after importing\n * `@cube-dev/ui-kit` and still affect the first paint.\n *\n * Keys use `#name` syntax; values are state maps:\n * '#surface': { '': 'oklch(...)', '@dark': 'oklch(...)', '@hc': 'oklch(...)' }\n */\nexport function getPaletteTokens(): Styles {\n refresh();\n\n return paletteTokensCache!;\n}\n\n/** The live `GlazePalette`. Rebuilt whenever the palette config changes. */\nexport function getPalette(): GlazePalette {\n refresh();\n\n return paletteCache!;\n}\n\n/**\n * The live theme behind the `code-*` tokens. Separate from {@link getPalette}\n * because it carries its own saturation seed — see {@link CODE_COLORS}.\n */\nexport function getCodeTheme(): GlazeTheme {\n refresh();\n\n return codeThemeCache!;\n}\n\n// ============================================================================\n// One-variant render (for previewing a palette on a region)\n// ============================================================================\n\nconst VARIANT_KEY = {\n 'light:false': 'light',\n 'light:true': 'lightContrast',\n 'dark:false': 'dark',\n 'dark:true': 'darkContrast',\n} as const;\n\n/**\n * Single-entry memo: all four variants of the last config rendered.\n *\n * Keyed on the palette version as well as the config, because the config is not\n * the only input — `buildPalette` also reads Glaze's own global config\n * (`darkTone`, `darkDesaturation`, the state map). A host that drives Glaze\n * directly and then calls `invalidatePaletteTokens()` bumps the version without\n * touching the config, and the region previews have to follow the document.\n */\nlet renderKey: string | null = null;\nlet renderVariants: Record<string, Record<string, string>> = {};\n\n/**\n * Resolve one scheme variant of a palette to flat, literal color values.\n *\n * Unlike {@link getPaletteTokens}, which emits state maps (`@dark` / `@hc`) for\n * the whole document, this collapses the palette to the single variant you ask\n * for. That is what makes a **region** preview possible: applied through a tasty\n * `tokens` prop, the values override the inherited ones for that subtree only, so\n * a dark or high-contrast theme can be shown inside a light page.\n *\n * Prefer `renderColorTokens()` from `./colors` unless you specifically want the\n * palette without the legacy aliases.\n */\nexport function renderPaletteTokens(\n options: RenderPaletteOptions = {},\n): Tokens {\n const { scheme = 'light', highContrast = false, ...config } = options;\n const resolved = resolvePaletteConfig(config);\n const key = `${getPaletteVersion()}:${JSON.stringify(resolved)}`;\n\n if (renderKey !== key) {\n // Force the *global* level to `'auto'` for the duration of the export.\n // Glaze suppresses high-contrast output whenever a global level is set, and\n // that check reads the global config — so without this, a preview's variants\n // would depend on whatever contrast mode the surrounding app happens to be\n // in. The preview's own level rides on the theme instances instead\n // (`isolateContrastLevel`), so the values stay correct. Restored in `finally`;\n // resolution is synchronous, so nothing can observe the window.\n const previousLevel = glaze.getConfig().contrastLevel;\n\n try {\n glaze.configure({ contrastLevel: 'auto' });\n\n const built = buildPalette(resolved, { isolateContrastLevel: true });\n const modes = { dark: true, highContrast: true };\n const themed = built.palette.tokens({\n prefix: TOKEN_PREFIXES,\n format: 'oklch',\n modes,\n });\n const code = built.codeTheme.tokens({ format: 'oklch', modes });\n\n // Built into a local and published together, so a throw part-way through\n // cannot leave a half-filled map sitting under the previous key.\n const variants: typeof renderVariants = {};\n\n for (const name of Object.keys(themed)) {\n variants[name] = {\n ...themed[name],\n ...pickCodeTokens(code[name] ?? {}),\n };\n }\n\n renderVariants = variants;\n renderKey = key;\n } finally {\n glaze.configure({ contrastLevel: previousLevel });\n }\n }\n\n const variant = VARIANT_KEY[`${scheme}:${highContrast}`];\n // A manual `contrastLevel` leaves no separate high-contrast tier — Glaze\n // mirrors the contrast variants onto the normal ones — so asking for\n // `highContrast` there correctly yields the same colors.\n const flat = renderVariants[variant] ?? renderVariants[scheme];\n const out: Tokens = {};\n\n for (const name of Object.keys(flat)) out[`#${name}`] = flat[name];\n\n return out;\n}\n\n/**\n * Lazy proxy of {@link getPaletteTokens}. Prefer `getPaletteTokens()` in new\n * code. Property / enumeration access always reflects the current palette\n * config.\n */\nexport const PALETTE_TOKENS: Styles = lazyStyles(getPaletteTokens);\n"],"mappings":"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"}
|
package/dist/tokens/shadows.js
CHANGED
package/dist/tokens/sizes.js
CHANGED
package/dist/tokens/spacing.js
CHANGED
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { chain } from "./react/chain.js";
|
|
3
|
+
import { DisabledElementOptions, DisabledElementProps, getDisabledElementProps, omitActivationEventProps } from "./react/disabledProps.js";
|
|
3
4
|
import { forwardRefWithGenerics } from "./react/forwardRefWithGenerics.js";
|
|
4
5
|
import { isTextOnly } from "./react/isTextOnly.js";
|
|
5
6
|
import { mergeProps } from "./react/mergeProps.js";
|
package/dist/utils/is-dev-env.js
CHANGED
package/dist/utils/modules.js
CHANGED
package/dist/utils/promise.js
CHANGED
package/dist/utils/raf.js
CHANGED
package/dist/utils/random.js
CHANGED
package/dist/utils/range.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { mergeProps } from "./mergeProps.js";
|
|
3
3
|
import { Children, cloneElement, createContext, useContext, useMemo } from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
import { Props } from "../../props.js";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/react/disabledProps.d.ts
|
|
5
|
+
interface DisabledElementOptions {
|
|
6
|
+
/** Whether the component is disabled. */
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the element has to keep receiving pointer and focus events while
|
|
10
|
+
* disabled. Set it when the element hosts a tooltip: the tooltip is there to
|
|
11
|
+
* explain why the element is unavailable, so hover has to reach it.
|
|
12
|
+
*/
|
|
13
|
+
keepEvents?: boolean;
|
|
14
|
+
/** The tag the component renders. */
|
|
15
|
+
as?: string;
|
|
16
|
+
}
|
|
17
|
+
interface DisabledElementProps {
|
|
18
|
+
/** Whether the element has to carry the native `disabled` attribute. */
|
|
19
|
+
isNativelyDisabled: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the element is disabled through `aria-disabled` only and therefore
|
|
22
|
+
* has to be kept inert by hand.
|
|
23
|
+
*/
|
|
24
|
+
isInert: boolean;
|
|
25
|
+
/** Props that mark the element disabled and inert. Spread them last. */
|
|
26
|
+
inertProps: Props;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Decides how the disabled state reaches the DOM.
|
|
30
|
+
*
|
|
31
|
+
* The native `disabled` attribute is the strongest option, but it also makes
|
|
32
|
+
* the browser swallow the events the element needs to open a tooltip. When
|
|
33
|
+
* such an element has to stay hoverable, it is marked `aria-disabled` instead
|
|
34
|
+
* and kept inert by blocking activation — the outcome a user sees is the same,
|
|
35
|
+
* except the tooltip now opens and screen readers still announce the state.
|
|
36
|
+
*/
|
|
37
|
+
declare function getDisabledElementProps({
|
|
38
|
+
isDisabled,
|
|
39
|
+
keepEvents,
|
|
40
|
+
as
|
|
41
|
+
}: DisabledElementOptions): DisabledElementProps;
|
|
42
|
+
/**
|
|
43
|
+
* Removes the handlers that would activate an element which is disabled
|
|
44
|
+
* without the native attribute.
|
|
45
|
+
*/
|
|
46
|
+
declare function omitActivationEventProps<T extends Props>(props: T): T;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { DisabledElementOptions, DisabledElementProps, getDisabledElementProps, omitActivationEventProps };
|
|
49
|
+
//# sourceMappingURL=disabledProps.d.ts.map
|