@cube-dev/ui-kit 0.74.3 → 0.75.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/CHANGELOG.md +14 -0
- package/es/_internal/hooks/index.js +1 -1
- package/es/_internal/hooks/use-chained-callback.js +1 -1
- package/es/_internal/hooks/use-debounced-value.js +1 -1
- package/es/_internal/hooks/use-deprecation-warning.js +1 -1
- package/es/_internal/hooks/use-effect-once.js +1 -1
- package/es/_internal/hooks/use-event.js +1 -1
- package/es/_internal/hooks/use-is-first-render.js +1 -1
- package/es/_internal/hooks/use-sync-ref.js +1 -1
- package/es/_internal/hooks/use-timer/index.js +1 -1
- package/es/_internal/hooks/use-timer/timer.js +1 -1
- package/es/_internal/hooks/use-timer/use-timer.js +1 -1
- package/es/_internal/hooks/use-update-effect.js +1 -1
- package/es/_internal/hooks/use-warn.js +1 -1
- package/es/_internal/index.js +1 -1
- package/es/components/Block.js +1 -1
- package/es/components/GlobalStyles.js +10 -15
- package/es/components/GridProvider.js +1 -1
- package/es/components/HiddenInput.js +25 -24
- package/es/components/Item.js +1 -1
- package/es/components/OpenTrasition.js +1 -1
- package/es/components/Root.js +2 -2
- package/es/components/actions/Action/Action.js +15 -19
- package/es/components/actions/Button/Button.js +2 -1
- package/es/components/actions/Button/index.js +1 -1
- package/es/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/es/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/es/components/actions/CommandMenu/index.js +1 -1
- package/es/components/actions/CommandMenu/styled.js +1 -1
- package/es/components/actions/ItemButton/ItemButton.js +1 -1
- package/es/components/actions/ItemButton/index.js +1 -1
- package/es/components/actions/Menu/Menu.js +1 -1
- package/es/components/actions/Menu/MenuItem.js +3 -8
- package/es/components/actions/Menu/MenuSection.js +1 -1
- package/es/components/actions/Menu/MenuTrigger.js +1 -1
- package/es/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/es/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/es/components/actions/Menu/context.js +1 -1
- package/es/components/actions/Menu/index.js +1 -1
- package/es/components/actions/Menu/styled.js +1 -1
- package/es/components/actions/index.js +1 -1
- package/es/components/actions/use-action.js +1 -1
- package/es/components/actions/use-anchored-menu.js +1 -1
- package/es/components/actions/use-context-menu.js +1 -1
- package/es/components/content/ActiveZone/ActiveZone.js +1 -1
- package/es/components/content/Alert/Alert.js +1 -1
- package/es/components/content/Alert/index.js +1 -1
- package/es/components/content/Alert/types.js +1 -1
- package/es/components/content/Alert/use-alert.js +1 -1
- package/es/components/content/Avatar/Avatar.js +1 -1
- package/es/components/content/Badge/Badge.js +1 -1
- package/es/components/content/Card/Card.js +1 -1
- package/es/components/content/Content.js +1 -1
- package/es/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/es/components/content/CopyPasteBlock/index.js +1 -1
- package/es/components/content/CopySnippet/CopySnippet.js +1 -1
- package/es/components/content/CopySnippet/index.js +1 -1
- package/es/components/content/Divider.js +1 -1
- package/es/components/content/Footer.js +1 -1
- package/es/components/content/Header.js +1 -1
- package/es/components/content/HotKeys/HotKeys.js +1 -1
- package/es/components/content/HotKeys/index.js +1 -1
- package/es/components/content/ItemBase/ItemBase.js +9 -3
- package/es/components/content/ItemBase/index.js +1 -1
- package/es/components/content/List/SectionHeading.js +1 -1
- package/es/components/content/List/index.js +1 -1
- package/es/components/content/Paragraph.js +1 -1
- package/es/components/content/Placeholder/Placeholder.js +46 -41
- package/es/components/content/PrismCode/PrismCode.js +1 -1
- package/es/components/content/PrismCode/prismSetup.js +1 -1
- package/es/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/es/components/content/Result/Result.js +1 -1
- package/es/components/content/Skeleton/Skeleton.js +1 -1
- package/es/components/content/Tag/Tag.js +1 -1
- package/es/components/content/Text.js +3 -3
- package/es/components/content/Title.js +3 -3
- package/es/components/fields/Checkbox/Checkbox.js +1 -1
- package/es/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/es/components/fields/Checkbox/context.js +1 -1
- package/es/components/fields/Checkbox/index.js +1 -1
- package/es/components/fields/ComboBox/ComboBox.js +1 -1
- package/es/components/fields/ComboBox/index.js +1 -1
- package/es/components/fields/DatePicker/DateInput.js +1 -1
- package/es/components/fields/DatePicker/DateInputBase.js +1 -1
- package/es/components/fields/DatePicker/DatePicker.js +1 -1
- package/es/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/es/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/es/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/es/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/es/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/es/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/es/components/fields/DatePicker/TimeInput.js +1 -1
- package/es/components/fields/DatePicker/index.js +1 -1
- package/es/components/fields/DatePicker/intl.js +1 -1
- package/es/components/fields/DatePicker/parseDate.js +1 -1
- package/es/components/fields/DatePicker/props.js +1 -1
- package/es/components/fields/DatePicker/types.js +1 -1
- package/es/components/fields/DatePicker/utils.js +1 -1
- package/es/components/fields/FileInput/FileInput.js +1 -1
- package/es/components/fields/FilterListBox/FilterListBox.js +1 -1
- package/es/components/fields/FilterListBox/index.js +1 -1
- package/es/components/fields/FilterPicker/FilterPicker.js +1 -1
- package/es/components/fields/FilterPicker/index.js +1 -1
- package/es/components/fields/Input/Input.js +1 -1
- package/es/components/fields/Input/index.js +1 -1
- package/es/components/fields/ListBox/ListBox.js +1 -1
- package/es/components/fields/ListBox/index.js +1 -1
- package/es/components/fields/NumberInput/NumberInput.js +1 -1
- package/es/components/fields/NumberInput/StepButton.js +1 -1
- package/es/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/es/components/fields/RadioGroup/Radio.js +2 -2
- package/es/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/es/components/fields/RadioGroup/context.js +1 -1
- package/es/components/fields/RadioGroup/index.js +1 -1
- package/es/components/fields/SearchInput/SearchInput.js +1 -1
- package/es/components/fields/SearchInput/index.js +1 -1
- package/es/components/fields/Select/Select.js +1 -1
- package/es/components/fields/Select/index.js +1 -1
- package/es/components/fields/Slider/Gradation.js +1 -1
- package/es/components/fields/Slider/Header.js +1 -1
- package/es/components/fields/Slider/RangeSlider.js +1 -1
- package/es/components/fields/Slider/Slider.js +1 -1
- package/es/components/fields/Slider/SliderBase.js +1 -1
- package/es/components/fields/Slider/SliderInput.js +1 -1
- package/es/components/fields/Slider/SliderThumb.js +1 -1
- package/es/components/fields/Slider/SliderTrack.js +1 -1
- package/es/components/fields/Slider/elements.js +1 -1
- package/es/components/fields/Slider/index.js +1 -1
- package/es/components/fields/Slider/types.js +1 -1
- package/es/components/fields/Switch/Switch.js +1 -1
- package/es/components/fields/Switch/index.js +1 -1
- package/es/components/fields/TextArea/TextArea.js +1 -1
- package/es/components/fields/TextArea/index.js +1 -1
- package/es/components/fields/TextInput/TextInput.js +1 -1
- package/es/components/fields/TextInput/TextInputBase.js +3 -2
- package/es/components/fields/TextInput/index.js +1 -1
- package/es/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/es/components/fields/TextInputMapper/index.js +1 -1
- package/es/components/fields/index.js +1 -1
- package/es/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/es/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
- package/es/components/form/FieldWrapper/index.js +1 -1
- package/es/components/form/FieldWrapper/types.js +1 -1
- package/es/components/form/Form/Field.js +1 -1
- package/es/components/form/Form/Form.js +1 -1
- package/es/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/es/components/form/Form/ResetButton/index.js +1 -1
- package/es/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/es/components/form/Form/SubmitButton/index.js +1 -1
- package/es/components/form/Form/SubmitError.js +1 -1
- package/es/components/form/Form/index.js +1 -1
- package/es/components/form/Form/types.js +1 -1
- package/es/components/form/Form/use-field/index.js +1 -1
- package/es/components/form/Form/use-field/types.js +1 -1
- package/es/components/form/Form/use-field/use-field-props.js +1 -1
- package/es/components/form/Form/use-field/use-field.js +1 -1
- package/es/components/form/Form/use-form.js +1 -1
- package/es/components/form/Form/validation.js +1 -1
- package/es/components/form/Label.js +1 -1
- package/es/components/form/index.js +1 -1
- package/es/components/form/wrapper.js +1 -1
- package/es/components/layout/Flex.js +1 -1
- package/es/components/layout/Flow.js +1 -1
- package/es/components/layout/Grid.js +1 -1
- package/es/components/layout/Panel.js +1 -1
- package/es/components/layout/Prefix.js +1 -1
- package/es/components/layout/ResizablePanel.js +1 -1
- package/es/components/layout/Space.js +1 -1
- package/es/components/layout/Suffix.js +1 -1
- package/es/components/navigation/LegacyTabs/LegacyTabs.js +1 -1
- package/es/components/navigation/Link/Link.js +1 -1
- package/es/components/organisms/FileTabs/FileTabs.js +1 -1
- package/es/components/organisms/Modal/Modal.js +59 -68
- package/es/components/organisms/StatsCard/StatsCard.js +1 -1
- package/es/components/other/Base64Upload/Base64Upload.js +1 -1
- package/es/components/other/Calendar/Calendar.js +1 -1
- package/es/components/other/Calendar/CalendarCell.js +1 -1
- package/es/components/other/Calendar/CalendarGrid.js +1 -1
- package/es/components/other/Calendar/RangeCalendar.js +1 -1
- package/es/components/other/CloudLogo/CloudLogo.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/es/components/overlays/AlertDialog/index.js +1 -1
- package/es/components/overlays/AlertDialog/types.js +1 -1
- package/es/components/overlays/Dialog/Dialog.js +1 -1
- package/es/components/overlays/Dialog/DialogContainer.js +1 -1
- package/es/components/overlays/Dialog/DialogForm.js +1 -1
- package/es/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/es/components/overlays/Dialog/context.js +1 -1
- package/es/components/overlays/Dialog/index.js +1 -1
- package/es/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/es/components/overlays/Modal/Modal.js +1 -1
- package/es/components/overlays/Modal/OpenTransition.js +1 -1
- package/es/components/overlays/Modal/Overlay.js +1 -1
- package/es/components/overlays/Modal/Popover.js +1 -1
- package/es/components/overlays/Modal/Tray.js +1 -1
- package/es/components/overlays/Modal/Underlay.js +1 -1
- package/es/components/overlays/Modal/index.js +1 -1
- package/es/components/overlays/Modal/types.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/FloatingNotification.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/NotificationsBar.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/TransitionComponent.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/index.js +1 -1
- package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogTrigger.js +1 -1
- package/es/components/overlays/NewNotifications/Dialog/index.js +1 -1
- package/es/components/overlays/NewNotifications/Notification.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationAction.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationCloseButton.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationDescription.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationFooter.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationHeader.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationIcon.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationProvider.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationView.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/types.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsContext.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsProvider.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/use-notifications.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsList.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsListItem.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/types.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/index.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/types.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notification-list-item.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-api.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-list.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-observer.js +1 -1
- package/es/components/overlays/NewNotifications/index.js +1 -1
- package/es/components/overlays/NewNotifications/types.js +1 -1
- package/es/components/overlays/Notification/Notification.js +1 -1
- package/es/components/overlays/OverlayWrapper.js +1 -1
- package/es/components/overlays/Toasts/Toast.js +1 -1
- package/es/components/overlays/Toasts/index.js +1 -1
- package/es/components/overlays/Toasts/types.js +1 -1
- package/es/components/overlays/Toasts/use-toasts-api.js +1 -1
- package/es/components/overlays/Tooltip/Tooltip.js +1 -1
- package/es/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/es/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/es/components/overlays/Tooltip/context.js +1 -1
- package/es/components/overlays/Tooltip/index.js +1 -1
- package/es/components/portal/Portal.js +1 -1
- package/es/components/portal/PortalProvider.js +1 -1
- package/es/components/portal/index.js +1 -1
- package/es/components/portal/types.js +1 -1
- package/es/components/portal/usePortal.js +1 -1
- package/es/components/shared/InvalidIcon.js +1 -1
- package/es/components/shared/ValidIcon.js +1 -1
- package/es/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/es/components/status/LoadingAnimation/index.js +1 -1
- package/es/components/status/Spin/Cube.js +1 -1
- package/es/components/status/Spin/InternalSpinner.js +1 -1
- package/es/components/status/Spin/Spin.js +1 -1
- package/es/components/status/Spin/SpinsContainer.js +1 -1
- package/es/components/status/Spin/index.js +1 -1
- package/es/components/status/Spin/types.js +1 -1
- package/es/components/status/index.js +1 -1
- package/es/data/item-themes.js +1 -1
- package/es/data/themes.js +1 -1
- package/es/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/es/icons/AdjustmentsIcon.js +1 -1
- package/es/icons/AiIcon.js +1 -1
- package/es/icons/AreaChartIcon.js +1 -1
- package/es/icons/BackwardIcon.js +1 -1
- package/es/icons/BarChartIcon.js +1 -1
- package/es/icons/BellFilledIcon.js +1 -1
- package/es/icons/BellIcon.js +1 -1
- package/es/icons/BooleanIcon.js +1 -1
- package/es/icons/CalendarEditIcon.js +1 -1
- package/es/icons/CalendarIcon.js +1 -1
- package/es/icons/CaretDownIcon.js +1 -1
- package/es/icons/CaretUpIcon.js +1 -1
- package/es/icons/ChartAreaStackedIcon.js +1 -1
- package/es/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/es/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/es/icons/ChartBarGroupedIcon.js +1 -1
- package/es/icons/ChartBarHorizontalIcon.js +1 -1
- package/es/icons/ChartBarLineIcon.js +1 -1
- package/es/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/es/icons/ChartBarStackedIcon.js +1 -1
- package/es/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/es/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/es/icons/ChartBoxPlot2Icon.js +1 -1
- package/es/icons/ChartBoxPlotIcon.js +1 -1
- package/es/icons/ChartBubbleIcon.js +1 -1
- package/es/icons/ChartDonut2Icon.js +1 -1
- package/es/icons/ChartFunnelIcon.js +1 -1
- package/es/icons/ChartKPIIcon.js +1 -1
- package/es/icons/ChartPie2Icon.js +1 -1
- package/es/icons/ChartScatterIcon.js +1 -1
- package/es/icons/CheckCircleFilledIcon.js +1 -1
- package/es/icons/CheckCircleIcon.js +1 -1
- package/es/icons/CheckIcon.js +1 -1
- package/es/icons/CircleFilledIcon.js +1 -1
- package/es/icons/ClearIcon.js +1 -1
- package/es/icons/CloseCircleFilledIcon.js +1 -1
- package/es/icons/CloseCircleIcon.js +1 -1
- package/es/icons/CloseIcon.js +1 -1
- package/es/icons/CodeIcon.js +1 -1
- package/es/icons/CopyIcon.js +1 -1
- package/es/icons/CountIcon.js +1 -1
- package/es/icons/CubeIcon.js +1 -1
- package/es/icons/DangerIcon.js +1 -1
- package/es/icons/DashboardIcon.js +1 -1
- package/es/icons/DatabaseIcon.js +1 -1
- package/es/icons/DirectionIcon.js +1 -1
- package/es/icons/DonutIcon.js +1 -1
- package/es/icons/DownIcon.js +1 -1
- package/es/icons/EditIcon.js +1 -1
- package/es/icons/ExclamationCircleFilledIcon.js +1 -1
- package/es/icons/ExclamationCircleIcon.js +1 -1
- package/es/icons/ExclamationIcon.js +1 -1
- package/es/icons/EyeIcon.js +1 -1
- package/es/icons/EyeInvisibleIcon.js +1 -1
- package/es/icons/FilterIcon.js +1 -1
- package/es/icons/FolderFilledIcon.js +1 -1
- package/es/icons/FolderIcon.js +1 -1
- package/es/icons/FolderOpenFilledIcon.js +1 -1
- package/es/icons/FolderOpenIcon.js +1 -1
- package/es/icons/ForwardIcon.js +1 -1
- package/es/icons/HierarchyIcon.js +1 -1
- package/es/icons/Icon.js +1 -1
- package/es/icons/InfoCircleIcon.js +1 -1
- package/es/icons/InfoIcon.js +1 -1
- package/es/icons/KeyIcon.js +1 -1
- package/es/icons/LeftIcon.js +1 -1
- package/es/icons/LineChartIcon.js +1 -1
- package/es/icons/LoadingIcon.js +1 -1
- package/es/icons/LockFilledIcon.js +1 -1
- package/es/icons/LockIcon.js +1 -1
- package/es/icons/MoreIcon.js +1 -1
- package/es/icons/NotAllowedIcon.js +1 -1
- package/es/icons/NumberIcon.js +1 -1
- package/es/icons/PauseCircleFilledIcon.js +1 -1
- package/es/icons/PauseCircleIcon.js +1 -1
- package/es/icons/PauseIcon.js +1 -1
- package/es/icons/PieChartIcon.js +1 -1
- package/es/icons/PlayCircleIcon.js +1 -1
- package/es/icons/PlayIcon.js +1 -1
- package/es/icons/PlusIcon.js +1 -1
- package/es/icons/ReloadIcon.js +1 -1
- package/es/icons/ReportIcon.js +1 -1
- package/es/icons/ReturnIcon.js +1 -1
- package/es/icons/RightIcon.js +1 -1
- package/es/icons/SchemeIcon.js +1 -1
- package/es/icons/SearchIcon.js +1 -1
- package/es/icons/SettingsIcon.js +1 -1
- package/es/icons/ShieldFilledIcon.js +1 -1
- package/es/icons/ShieldIcon.js +1 -1
- package/es/icons/SlashIcon.js +1 -1
- package/es/icons/SparklesIcon.js +1 -1
- package/es/icons/SqlIcon.js +1 -1
- package/es/icons/StatsIcon.js +1 -1
- package/es/icons/StopIcon.js +1 -1
- package/es/icons/StringIcon.js +1 -1
- package/es/icons/SwitchIcon.js +1 -1
- package/es/icons/TableIcon.js +1 -1
- package/es/icons/ThumbsDownIcon.js +1 -1
- package/es/icons/ThumbsUpIcon.js +1 -1
- package/es/icons/ThunderboltCrossedIcon.js +1 -1
- package/es/icons/ThunderboltFilledIcon.js +1 -1
- package/es/icons/ThunderboltIcon.js +1 -1
- package/es/icons/TimeIcon.js +1 -1
- package/es/icons/UnlockIcon.js +1 -1
- package/es/icons/UpIcon.js +1 -1
- package/es/icons/UserGroupIcon.js +1 -1
- package/es/icons/UserIcon.js +1 -1
- package/es/icons/UserLockIcon.js +1 -1
- package/es/icons/ViewIcon.js +1 -1
- package/es/icons/WarningFilledIcon.js +1 -1
- package/es/icons/WarningIcon.js +1 -1
- package/es/icons/add-new-icon.js +1 -1
- package/es/icons/index.js +1 -1
- package/es/icons/wrap-icon.js +1 -1
- package/es/index.js +1 -1
- package/es/provider.js +1 -1
- package/es/providers/TrackingProvider.js +1 -1
- package/es/services/notification.js +1 -1
- package/es/shared/form.js +1 -1
- package/es/shared/index.js +1 -1
- package/es/stories/Form.legacy-stories.js +1 -1
- package/es/stories/FormFieldArgs.js +1 -1
- package/es/stories/Layout.stories.js +1 -1
- package/es/stories/Tasty.stories.js +1 -1
- package/es/stories/components/ConfirmDeletionDialogForm.js +1 -1
- package/es/stories/components/DialogFormApp.js +1 -1
- package/es/stories/components/StyledButton.js +1 -1
- package/es/stories/lists/baseProps.js +1 -2
- package/es/tasty/debug.js +906 -0
- package/es/tasty/index.js +3 -1
- package/es/tasty/injector/index.js +171 -0
- package/es/tasty/injector/injector.js +688 -0
- package/es/tasty/injector/sheet-manager.js +754 -0
- package/es/tasty/injector/types.js +10 -0
- package/es/tasty/parser/classify.js +1 -1
- package/es/tasty/parser/const.js +1 -1
- package/es/tasty/parser/lru.js +38 -2
- package/es/tasty/parser/parser.js +1 -1
- package/es/tasty/parser/tokenizer.js +1 -1
- package/es/tasty/parser/types.js +1 -1
- package/es/tasty/providers/BreakpointsProvider.js +1 -1
- package/es/tasty/styles/align.js +1 -1
- package/es/tasty/styles/border.js +1 -1
- package/es/tasty/styles/boxShadow.combinator.js +1 -1
- package/es/tasty/styles/color.js +8 -12
- package/es/tasty/styles/createStyle.js +19 -4
- package/es/tasty/styles/dimension.js +1 -1
- package/es/tasty/styles/display.js +1 -1
- package/es/tasty/styles/fade.js +1 -1
- package/es/tasty/styles/fill.js +6 -8
- package/es/tasty/styles/flow.js +1 -1
- package/es/tasty/styles/font.js +1 -1
- package/es/tasty/styles/fontStyle.js +1 -1
- package/es/tasty/styles/gap.js +1 -1
- package/es/tasty/styles/groupRadius.js +1 -1
- package/es/tasty/styles/height.js +1 -1
- package/es/tasty/styles/index.js +1 -1
- package/es/tasty/styles/inset.js +1 -1
- package/es/tasty/styles/justify.js +1 -1
- package/es/tasty/styles/list.js +1 -1
- package/es/tasty/styles/margin.js +1 -1
- package/es/tasty/styles/marginBlock.js +1 -1
- package/es/tasty/styles/marginInline.js +1 -1
- package/es/tasty/styles/outline.js +1 -1
- package/es/tasty/styles/padding.js +1 -1
- package/es/tasty/styles/paddingBlock.js +1 -1
- package/es/tasty/styles/paddingInline.js +1 -1
- package/es/tasty/styles/place.js +1 -1
- package/es/tasty/styles/predefined.js +1 -3
- package/es/tasty/styles/preset.js +1 -1
- package/es/tasty/styles/radius.js +1 -1
- package/es/tasty/styles/reset.js +40 -44
- package/es/tasty/styles/scrollbar.js +1 -1
- package/es/tasty/styles/shadow.js +1 -1
- package/es/tasty/styles/styledScrollbar.js +1 -1
- package/es/tasty/styles/transition.js +2 -1
- package/es/tasty/styles/types.js +1 -1
- package/es/tasty/styles/width.js +1 -1
- package/es/tasty/tasty.js +94 -20
- package/es/tasty/types.js +1 -1
- package/es/tasty/utils/cache-wrapper.js +1 -1
- package/es/tasty/utils/case-converter.js +1 -1
- package/es/tasty/utils/colors.js +1 -1
- package/es/tasty/utils/dotize.js +1 -1
- package/es/tasty/utils/filterBaseProps.js +1 -1
- package/es/tasty/utils/getDisplayName.js +1 -1
- package/es/tasty/utils/getModCombinations.js +26 -30
- package/es/tasty/utils/mergeStyles.js +1 -1
- package/es/tasty/utils/modAttrs.js +1 -1
- package/es/tasty/utils/renderStyles.js +670 -58
- package/es/tasty/utils/responsive.js +1 -7
- package/es/tasty/utils/string.js +1 -1
- package/es/tasty/utils/styles.js +62 -235
- package/es/tasty/utils/warnings.js +1 -1
- package/es/tokens.js +1 -12
- package/es/type-checks.js +1 -1
- package/es/utils/ResizeSensor.js +1 -1
- package/es/utils/modules.js +1 -1
- package/es/utils/promise.js +1 -1
- package/es/utils/random.js +1 -1
- package/es/utils/range.js +1 -1
- package/es/utils/react/Slots.js +1 -1
- package/es/utils/react/chain.js +1 -1
- package/es/utils/react/forwardRefWithGenerics.js +1 -1
- package/es/utils/react/index.js +1 -1
- package/es/utils/react/interactions.js +1 -1
- package/es/utils/react/isTextOnly.js +1 -1
- package/es/utils/react/mapProps.js +1 -1
- package/es/utils/react/mergeProps.js +1 -1
- package/es/utils/react/nullableValue.js +1 -1
- package/es/utils/react/sharedStore.js +1 -1
- package/es/utils/react/useCombinedRefs.js +1 -1
- package/es/utils/react/useControlledFocusVisible.js +1 -1
- package/es/utils/react/useEventBus.js +1 -1
- package/es/utils/react/useId.js +1 -1
- package/es/utils/react/useIsDarwin.js +1 -1
- package/es/utils/react/useKeySymbols.js +1 -1
- package/es/utils/react/useLayoutEffect.js +1 -1
- package/es/utils/react/useQaProps.js +1 -1
- package/es/utils/react/useViewportSize.js +1 -1
- package/es/utils/react/wrapNodeIfPlain.js +1 -1
- package/es/utils/transitions.js +1 -1
- package/es/utils/tree.js +1 -1
- package/es/utils/warnings.js +1 -1
- package/es/version.js +2 -2
- package/package.json +1 -1
- package/types/components/HiddenInput.d.ts +1 -3
- package/types/components/actions/Button/Button.d.ts +1 -0
- package/types/components/actions/Menu/styled.d.ts +702 -705
- package/types/components/actions/use-action.d.ts +1 -1
- package/types/components/content/List/SectionHeading.d.ts +234 -235
- package/types/components/fields/DatePicker/DatePickerElement.d.ts +234 -235
- package/types/tasty/debug.d.ts +250 -0
- package/types/tasty/index.d.ts +2 -0
- package/types/tasty/injector/index.d.ts +71 -0
- package/types/tasty/injector/injector.d.ts +109 -0
- package/types/tasty/injector/sheet-manager.d.ts +94 -0
- package/types/tasty/injector/types.d.ts +90 -0
- package/types/tasty/parser/lru.d.ts +5 -1
- package/types/tasty/styles/color.d.ts +3 -1
- package/types/tasty/styles/reset.d.ts +1 -2
- package/types/tasty/types.d.ts +0 -2
- package/types/tasty/utils/getModCombinations.d.ts +9 -1
- package/types/tasty/utils/renderStyles.d.ts +25 -7
- package/types/tasty/utils/responsive.d.ts +0 -1
- package/types/tasty/utils/styles.d.ts +6 -90
- package/types/tokens.d.ts +0 -11
@@ -0,0 +1,754 @@
|
|
1
|
+
/**
|
2
|
+
* @license MIT
|
3
|
+
* author: Cube Dev Team
|
4
|
+
* @cube-dev/ui-kit v0.75.0
|
5
|
+
* Released under the MIT license.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { createStyle, STYLE_HANDLER_MAP } from '../styles';
|
9
|
+
export class SheetManager {
|
10
|
+
rootRegistries = new WeakMap();
|
11
|
+
config;
|
12
|
+
constructor(config) {
|
13
|
+
this.config = config;
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Get or create registry for a root (Document or ShadowRoot)
|
17
|
+
*/
|
18
|
+
getRegistry(root) {
|
19
|
+
let registry = this.rootRegistries.get(root);
|
20
|
+
if (!registry) {
|
21
|
+
const metrics = this.config.collectMetrics
|
22
|
+
? {
|
23
|
+
hits: 0,
|
24
|
+
misses: 0,
|
25
|
+
unusedHits: 0,
|
26
|
+
bulkCleanups: 0,
|
27
|
+
totalInsertions: 0,
|
28
|
+
totalUnused: 0,
|
29
|
+
stylesCleanedUp: 0,
|
30
|
+
cleanupHistory: [],
|
31
|
+
startTime: Date.now(),
|
32
|
+
}
|
33
|
+
: undefined;
|
34
|
+
registry = {
|
35
|
+
sheets: [],
|
36
|
+
refCounts: new Map(),
|
37
|
+
rules: new Map(),
|
38
|
+
unusedRules: new Map(),
|
39
|
+
ruleTextSet: new Set(),
|
40
|
+
bulkCleanupTimeout: null,
|
41
|
+
metrics,
|
42
|
+
classCounter: 0,
|
43
|
+
keyframesCache: new Map(),
|
44
|
+
unusedKeyframes: new Map(),
|
45
|
+
keyframesCounter: 0,
|
46
|
+
injectedProperties: new Set(),
|
47
|
+
};
|
48
|
+
this.rootRegistries.set(root, registry);
|
49
|
+
}
|
50
|
+
return registry;
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* Create a new stylesheet for the registry
|
54
|
+
*/
|
55
|
+
createSheet(registry, root) {
|
56
|
+
const sheet = this.createStyleElement(root);
|
57
|
+
const sheetInfo = {
|
58
|
+
sheet,
|
59
|
+
ruleCount: 0,
|
60
|
+
holes: [],
|
61
|
+
};
|
62
|
+
registry.sheets.push(sheetInfo);
|
63
|
+
return sheetInfo;
|
64
|
+
}
|
65
|
+
/**
|
66
|
+
* Create a style element and append to document
|
67
|
+
*/
|
68
|
+
createStyleElement(root) {
|
69
|
+
const style = root.createElement?.('style') ||
|
70
|
+
document.createElement('style');
|
71
|
+
if (this.config.nonce) {
|
72
|
+
style.nonce = this.config.nonce;
|
73
|
+
}
|
74
|
+
style.setAttribute('data-tasty', '');
|
75
|
+
// Append to head or shadow root
|
76
|
+
if ('head' in root && root.head) {
|
77
|
+
root.head.appendChild(style);
|
78
|
+
}
|
79
|
+
else if ('appendChild' in root) {
|
80
|
+
root.appendChild(style);
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
document.head.appendChild(style);
|
84
|
+
}
|
85
|
+
// Verify it was actually added - log only if there's a problem and we're not using forceTextInjection
|
86
|
+
if (!style.isConnected && !this.config.forceTextInjection) {
|
87
|
+
console.error('SheetManager: Style element failed to connect to DOM!', {
|
88
|
+
parentNode: style.parentNode?.nodeName,
|
89
|
+
isConnected: style.isConnected,
|
90
|
+
});
|
91
|
+
}
|
92
|
+
return style;
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Insert CSS rules as a single block
|
96
|
+
*/
|
97
|
+
insertRule(registry, flattenedRules, className, root) {
|
98
|
+
// Find or create a sheet with available space
|
99
|
+
let targetSheet = this.findAvailableSheet(registry, root);
|
100
|
+
if (!targetSheet) {
|
101
|
+
targetSheet = this.createSheet(registry, root);
|
102
|
+
}
|
103
|
+
const ruleIndex = this.findAvailableRuleIndex(targetSheet);
|
104
|
+
const sheetIndex = registry.sheets.indexOf(targetSheet);
|
105
|
+
try {
|
106
|
+
// Group rules by selector and at-rules to combine declarations
|
107
|
+
const groupedRules = [];
|
108
|
+
const groupMap = new Map();
|
109
|
+
const atKey = (at) => (at && at.length ? at.join('|') : '');
|
110
|
+
flattenedRules.forEach((r) => {
|
111
|
+
const key = `${atKey(r.atRules)}||${r.selector}`;
|
112
|
+
const existing = groupMap.get(key);
|
113
|
+
if (existing) {
|
114
|
+
// Append declarations, preserving order
|
115
|
+
existing.declarations = existing.declarations
|
116
|
+
? `${existing.declarations} ${r.declarations}`
|
117
|
+
: r.declarations;
|
118
|
+
}
|
119
|
+
else {
|
120
|
+
groupMap.set(key, {
|
121
|
+
idx: groupedRules.length,
|
122
|
+
selector: r.selector,
|
123
|
+
atRules: r.atRules,
|
124
|
+
declarations: r.declarations,
|
125
|
+
});
|
126
|
+
groupedRules.push({ ...r });
|
127
|
+
}
|
128
|
+
});
|
129
|
+
// Normalize groupedRules from map (with merged declarations)
|
130
|
+
groupMap.forEach((val) => {
|
131
|
+
groupedRules[val.idx] = {
|
132
|
+
selector: val.selector,
|
133
|
+
atRules: val.atRules,
|
134
|
+
declarations: val.declarations,
|
135
|
+
};
|
136
|
+
});
|
137
|
+
// Insert grouped rules
|
138
|
+
const insertedRuleTexts = [];
|
139
|
+
let currentRuleIndex = ruleIndex;
|
140
|
+
let firstInsertedIndex = null;
|
141
|
+
let lastInsertedIndex = null;
|
142
|
+
for (const rule of groupedRules) {
|
143
|
+
const declarations = rule.declarations;
|
144
|
+
const baseRule = `${rule.selector} { ${declarations} }`;
|
145
|
+
// Wrap with at-rules if present
|
146
|
+
let fullRule = baseRule;
|
147
|
+
if (rule.atRules && rule.atRules.length > 0) {
|
148
|
+
fullRule = rule.atRules.reduce((css, atRule) => `${atRule} { ${css} }`, baseRule);
|
149
|
+
}
|
150
|
+
// Insert individual rule into style element
|
151
|
+
const styleElement = targetSheet.sheet;
|
152
|
+
const styleSheet = styleElement.sheet;
|
153
|
+
if (styleSheet && !this.config.forceTextInjection) {
|
154
|
+
const maxIndex = styleSheet.cssRules.length;
|
155
|
+
const safeIndex = Math.min(Math.max(0, currentRuleIndex), maxIndex);
|
156
|
+
// Helper: split comma-separated selectors safely (ignores commas inside [] () " ')
|
157
|
+
const splitSelectorsSafely = (selectorList) => {
|
158
|
+
const parts = [];
|
159
|
+
let buf = '';
|
160
|
+
let depthSq = 0; // [] depth
|
161
|
+
let depthPar = 0; // () depth
|
162
|
+
let inStr = '';
|
163
|
+
for (let i = 0; i < selectorList.length; i++) {
|
164
|
+
const ch = selectorList[i];
|
165
|
+
if (inStr) {
|
166
|
+
if (ch === inStr && selectorList[i - 1] !== '\\') {
|
167
|
+
inStr = '';
|
168
|
+
}
|
169
|
+
buf += ch;
|
170
|
+
continue;
|
171
|
+
}
|
172
|
+
if (ch === '"' || ch === "'") {
|
173
|
+
inStr = ch;
|
174
|
+
buf += ch;
|
175
|
+
continue;
|
176
|
+
}
|
177
|
+
if (ch === '[')
|
178
|
+
depthSq++;
|
179
|
+
else if (ch === ']')
|
180
|
+
depthSq = Math.max(0, depthSq - 1);
|
181
|
+
else if (ch === '(')
|
182
|
+
depthPar++;
|
183
|
+
else if (ch === ')')
|
184
|
+
depthPar = Math.max(0, depthPar - 1);
|
185
|
+
if (ch === ',' && depthSq === 0 && depthPar === 0) {
|
186
|
+
const part = buf.trim();
|
187
|
+
if (part)
|
188
|
+
parts.push(part);
|
189
|
+
buf = '';
|
190
|
+
}
|
191
|
+
else {
|
192
|
+
buf += ch;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
const tail = buf.trim();
|
196
|
+
if (tail)
|
197
|
+
parts.push(tail);
|
198
|
+
return parts;
|
199
|
+
};
|
200
|
+
try {
|
201
|
+
styleSheet.insertRule(fullRule, safeIndex);
|
202
|
+
if (firstInsertedIndex == null)
|
203
|
+
firstInsertedIndex = safeIndex;
|
204
|
+
lastInsertedIndex = safeIndex;
|
205
|
+
currentRuleIndex = safeIndex + 1;
|
206
|
+
}
|
207
|
+
catch (e) {
|
208
|
+
// If the browser rejects the combined selector (e.g., vendor pseudo-elements),
|
209
|
+
// try to split and insert each selector independently. Skip unsupported ones.
|
210
|
+
const selectors = splitSelectorsSafely(rule.selector);
|
211
|
+
if (selectors.length > 1) {
|
212
|
+
let anyInserted = false;
|
213
|
+
for (const sel of selectors) {
|
214
|
+
const singleBase = `${sel} { ${declarations} }`;
|
215
|
+
let singleRule = singleBase;
|
216
|
+
if (rule.atRules && rule.atRules.length > 0) {
|
217
|
+
singleRule = rule.atRules.reduce((css, atRule) => `${atRule} { ${css} }`, singleBase);
|
218
|
+
}
|
219
|
+
try {
|
220
|
+
const maxIdx = styleSheet.cssRules.length;
|
221
|
+
const idx = Math.min(Math.max(0, currentRuleIndex), maxIdx);
|
222
|
+
styleSheet.insertRule(singleRule, idx);
|
223
|
+
if (firstInsertedIndex == null)
|
224
|
+
firstInsertedIndex = idx;
|
225
|
+
lastInsertedIndex = idx;
|
226
|
+
currentRuleIndex = idx + 1;
|
227
|
+
anyInserted = true;
|
228
|
+
}
|
229
|
+
catch (_) {
|
230
|
+
// Skip unsupported selector in this engine (e.g., ::-moz-selection in Blink)
|
231
|
+
}
|
232
|
+
}
|
233
|
+
// If none inserted, continue without throwing to avoid aborting the whole batch
|
234
|
+
if (!anyInserted) {
|
235
|
+
// noop: all selectors invalid here; safe to skip
|
236
|
+
}
|
237
|
+
}
|
238
|
+
else {
|
239
|
+
// Single selector failed — skip it silently (likely unsupported in this engine)
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
else {
|
244
|
+
// Use textContent (either as fallback or when forceTextInjection is enabled)
|
245
|
+
styleElement.textContent =
|
246
|
+
(styleElement.textContent || '') + '\n' + fullRule;
|
247
|
+
if (firstInsertedIndex == null)
|
248
|
+
firstInsertedIndex = currentRuleIndex;
|
249
|
+
lastInsertedIndex = currentRuleIndex;
|
250
|
+
currentRuleIndex++;
|
251
|
+
}
|
252
|
+
// CRITICAL DEBUG: Verify the style element is in DOM only if there are issues and we're not using forceTextInjection
|
253
|
+
if (!styleElement.parentNode && !this.config.forceTextInjection) {
|
254
|
+
console.error('SheetManager: Style element is NOT in DOM! This is the problem!', {
|
255
|
+
className,
|
256
|
+
ruleIndex: currentRuleIndex,
|
257
|
+
});
|
258
|
+
}
|
259
|
+
// Conditionally store cssText and track for debug
|
260
|
+
if (this.config.debugMode) {
|
261
|
+
insertedRuleTexts.push(fullRule);
|
262
|
+
try {
|
263
|
+
registry.ruleTextSet.add(fullRule);
|
264
|
+
}
|
265
|
+
catch (_) {
|
266
|
+
// noop: defensive in case ruleTextSet is unavailable
|
267
|
+
}
|
268
|
+
}
|
269
|
+
// currentRuleIndex already adjusted above
|
270
|
+
}
|
271
|
+
// Update sheet info based on the number of rules inserted
|
272
|
+
const finalRuleIndex = currentRuleIndex - 1;
|
273
|
+
if (finalRuleIndex >= targetSheet.ruleCount) {
|
274
|
+
targetSheet.ruleCount = finalRuleIndex + 1;
|
275
|
+
}
|
276
|
+
return {
|
277
|
+
className,
|
278
|
+
ruleIndex: firstInsertedIndex ?? ruleIndex,
|
279
|
+
sheetIndex,
|
280
|
+
cssText: this.config.debugMode ? insertedRuleTexts : [],
|
281
|
+
endRuleIndex: lastInsertedIndex ?? finalRuleIndex,
|
282
|
+
};
|
283
|
+
}
|
284
|
+
catch (error) {
|
285
|
+
console.warn('Failed to insert CSS rules:', error, {
|
286
|
+
flattenedRules,
|
287
|
+
className,
|
288
|
+
});
|
289
|
+
return null;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
/**
|
293
|
+
* Insert global CSS rules
|
294
|
+
*/
|
295
|
+
insertGlobalRule(registry, flattenedRules, className, root) {
|
296
|
+
// For now, global rules are handled the same way as regular rules
|
297
|
+
return this.insertRule(registry, flattenedRules, className, root);
|
298
|
+
}
|
299
|
+
/**
|
300
|
+
* Delete a CSS rule from the sheet
|
301
|
+
*/
|
302
|
+
deleteRule(registry, ruleInfo) {
|
303
|
+
const sheet = registry.sheets[ruleInfo.sheetIndex];
|
304
|
+
if (!sheet) {
|
305
|
+
return;
|
306
|
+
}
|
307
|
+
try {
|
308
|
+
const texts = Array.isArray(ruleInfo.cssText)
|
309
|
+
? ruleInfo.cssText.slice()
|
310
|
+
: [];
|
311
|
+
const styleElement = sheet.sheet;
|
312
|
+
const styleSheet = styleElement.sheet;
|
313
|
+
if (styleSheet) {
|
314
|
+
const rules = styleSheet.cssRules;
|
315
|
+
// Prefer index-based deletion when possible
|
316
|
+
const startIdx = Math.max(0, ruleInfo.ruleIndex);
|
317
|
+
const endIdx = Math.min(rules.length - 1, Number.isFinite(ruleInfo.endRuleIndex)
|
318
|
+
? ruleInfo.endRuleIndex
|
319
|
+
: startIdx - 1);
|
320
|
+
if (Number.isFinite(startIdx) && endIdx >= startIdx) {
|
321
|
+
for (let idx = endIdx; idx >= startIdx; idx--) {
|
322
|
+
if (idx < 0 || idx >= styleSheet.cssRules.length)
|
323
|
+
continue;
|
324
|
+
styleSheet.deleteRule(idx);
|
325
|
+
}
|
326
|
+
sheet.ruleCount = Math.max(0, sheet.ruleCount - (endIdx - startIdx + 1));
|
327
|
+
}
|
328
|
+
else if (this.config.debugMode && texts.length) {
|
329
|
+
// Fallback: locate each rule by exact cssText and delete (debug mode only)
|
330
|
+
for (const text of texts) {
|
331
|
+
let idx = -1;
|
332
|
+
for (let i = styleSheet.cssRules.length - 1; i >= 0; i--) {
|
333
|
+
if (styleSheet.cssRules[i].cssText === text) {
|
334
|
+
idx = i;
|
335
|
+
break;
|
336
|
+
}
|
337
|
+
}
|
338
|
+
if (idx >= 0) {
|
339
|
+
styleSheet.deleteRule(idx);
|
340
|
+
}
|
341
|
+
}
|
342
|
+
sheet.ruleCount = Math.max(0, sheet.ruleCount - texts.length);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
// Remove texts from validation set
|
346
|
+
if (this.config.debugMode) {
|
347
|
+
try {
|
348
|
+
for (const text of texts) {
|
349
|
+
registry.ruleTextSet.delete(text);
|
350
|
+
}
|
351
|
+
}
|
352
|
+
catch (_) {
|
353
|
+
// noop
|
354
|
+
}
|
355
|
+
}
|
356
|
+
}
|
357
|
+
catch (error) {
|
358
|
+
console.warn('Failed to delete CSS rule:', error);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
/**
|
362
|
+
* Find a sheet with available space or return null
|
363
|
+
*/
|
364
|
+
findAvailableSheet(registry, root) {
|
365
|
+
const maxRules = this.config.maxRulesPerSheet;
|
366
|
+
if (!maxRules) {
|
367
|
+
// No limit, use the last sheet if it exists
|
368
|
+
const lastSheet = registry.sheets[registry.sheets.length - 1];
|
369
|
+
return lastSheet || null;
|
370
|
+
}
|
371
|
+
// Find sheet with space
|
372
|
+
for (const sheet of registry.sheets) {
|
373
|
+
if (sheet.ruleCount < maxRules) {
|
374
|
+
return sheet;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
return null; // No available sheet found
|
378
|
+
}
|
379
|
+
/**
|
380
|
+
* Find an available rule index in the sheet
|
381
|
+
*/
|
382
|
+
findAvailableRuleIndex(sheet) {
|
383
|
+
// Always append to the end - CSS doesn't have holes
|
384
|
+
return sheet.ruleCount;
|
385
|
+
}
|
386
|
+
/**
|
387
|
+
* Mark a ruleset as unused but keep it in the stylesheet
|
388
|
+
*/
|
389
|
+
markAsUnused(registry, className) {
|
390
|
+
const ruleInfo = registry.rules.get(className);
|
391
|
+
if (!ruleInfo)
|
392
|
+
return;
|
393
|
+
// Mark as unused (but keep in registry.rules)
|
394
|
+
const unusedInfo = {
|
395
|
+
ruleInfo,
|
396
|
+
markedUnusedAt: Date.now(),
|
397
|
+
};
|
398
|
+
registry.unusedRules.set(className, unusedInfo);
|
399
|
+
registry.refCounts.delete(className);
|
400
|
+
// Update metrics
|
401
|
+
if (registry.metrics) {
|
402
|
+
registry.metrics.totalUnused++;
|
403
|
+
}
|
404
|
+
// Schedule bulk cleanup if threshold exceeded
|
405
|
+
const threshold = this.config.unusedStylesThreshold || 500;
|
406
|
+
if (registry.unusedRules.size >= threshold) {
|
407
|
+
this.scheduleBulkCleanup(registry);
|
408
|
+
}
|
409
|
+
}
|
410
|
+
/**
|
411
|
+
* Restore a ruleset from unused styles
|
412
|
+
*/
|
413
|
+
restoreFromUnused(registry, className) {
|
414
|
+
const unusedInfo = registry.unusedRules.get(className);
|
415
|
+
if (!unusedInfo)
|
416
|
+
return null;
|
417
|
+
// Remove from unused rules (rules stays in registry.rules)
|
418
|
+
registry.unusedRules.delete(className);
|
419
|
+
registry.refCounts.set(className, 1);
|
420
|
+
// Update metrics
|
421
|
+
if (registry.metrics) {
|
422
|
+
registry.metrics.unusedHits++;
|
423
|
+
}
|
424
|
+
return unusedInfo.ruleInfo;
|
425
|
+
}
|
426
|
+
/**
|
427
|
+
* Schedule bulk cleanup of all unused styles
|
428
|
+
*/
|
429
|
+
scheduleBulkCleanup(registry) {
|
430
|
+
// Don't schedule if already scheduled
|
431
|
+
if (registry.bulkCleanupTimeout)
|
432
|
+
return;
|
433
|
+
const performCleanup = () => {
|
434
|
+
this.performBulkCleanup(registry);
|
435
|
+
registry.bulkCleanupTimeout = null;
|
436
|
+
};
|
437
|
+
if (this.config.idleCleanup && typeof requestIdleCallback !== 'undefined') {
|
438
|
+
registry.bulkCleanupTimeout = requestIdleCallback(performCleanup);
|
439
|
+
}
|
440
|
+
else {
|
441
|
+
const delay = this.config.bulkCleanupDelay || 5000;
|
442
|
+
registry.bulkCleanupTimeout = setTimeout(performCleanup, delay);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
/**
|
446
|
+
* Perform bulk cleanup of all unused styles
|
447
|
+
*/
|
448
|
+
performBulkCleanup(registry) {
|
449
|
+
if (registry.unusedRules.size === 0)
|
450
|
+
return;
|
451
|
+
const cleanupStartTime = Date.now();
|
452
|
+
const classNamesToCleanup = Array.from(registry.unusedRules.keys());
|
453
|
+
let cleanedUpCount = 0;
|
454
|
+
let totalCssSize = 0;
|
455
|
+
let totalRulesDeleted = 0;
|
456
|
+
// Group by sheet for efficient deletion
|
457
|
+
const rulesBySheet = new Map();
|
458
|
+
// Calculate CSS size before deletion and group rules
|
459
|
+
for (const className of classNamesToCleanup) {
|
460
|
+
const unusedInfo = registry.unusedRules.get(className);
|
461
|
+
if (!unusedInfo)
|
462
|
+
continue;
|
463
|
+
const ruleInfo = unusedInfo.ruleInfo;
|
464
|
+
const sheetIndex = ruleInfo.sheetIndex;
|
465
|
+
// Calculate CSS size for this rule
|
466
|
+
const cssSize = ruleInfo.cssText.reduce((total, css) => total + css.length, 0);
|
467
|
+
totalCssSize += cssSize;
|
468
|
+
// Count number of rules (based on cssText array length)
|
469
|
+
totalRulesDeleted += ruleInfo.cssText.length;
|
470
|
+
if (!rulesBySheet.has(sheetIndex)) {
|
471
|
+
rulesBySheet.set(sheetIndex, []);
|
472
|
+
}
|
473
|
+
rulesBySheet.get(sheetIndex).push({ className, ruleInfo });
|
474
|
+
}
|
475
|
+
// Delete rules from each sheet (in reverse order to preserve indices)
|
476
|
+
for (const [sheetIndex, rulesInSheet] of rulesBySheet) {
|
477
|
+
// Sort by rule index in descending order for safe deletion
|
478
|
+
rulesInSheet.sort((a, b) => b.ruleInfo.ruleIndex - a.ruleInfo.ruleIndex);
|
479
|
+
for (const { className, ruleInfo } of rulesInSheet) {
|
480
|
+
// SAFETY: Re-check that the rule is still unused at deletion time.
|
481
|
+
// Between scheduling and execution a class may have been restored
|
482
|
+
// (refCounts set and removed from unusedRules). Skip such entries.
|
483
|
+
if (!registry.unusedRules.has(className)) {
|
484
|
+
continue;
|
485
|
+
}
|
486
|
+
if (registry.refCounts.has(className)) {
|
487
|
+
// Class became active again; do not delete
|
488
|
+
continue;
|
489
|
+
}
|
490
|
+
// Ensure we delete the same RuleInfo we marked earlier to avoid
|
491
|
+
// accidentally deleting updated rules for the same class.
|
492
|
+
const currentInfo = registry.rules.get(className);
|
493
|
+
if (currentInfo && currentInfo !== ruleInfo) {
|
494
|
+
// Rule was replaced; skip deletion of the old reference
|
495
|
+
continue;
|
496
|
+
}
|
497
|
+
this.deleteRule(registry, ruleInfo);
|
498
|
+
registry.rules.delete(className);
|
499
|
+
registry.unusedRules.delete(className);
|
500
|
+
cleanedUpCount++;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
// Update metrics
|
504
|
+
if (registry.metrics) {
|
505
|
+
registry.metrics.bulkCleanups++;
|
506
|
+
registry.metrics.stylesCleanedUp += cleanedUpCount;
|
507
|
+
// Add detailed cleanup stats to history
|
508
|
+
registry.metrics.cleanupHistory.push({
|
509
|
+
timestamp: cleanupStartTime,
|
510
|
+
classesDeleted: cleanedUpCount,
|
511
|
+
cssSize: totalCssSize,
|
512
|
+
rulesDeleted: totalRulesDeleted,
|
513
|
+
});
|
514
|
+
}
|
515
|
+
}
|
516
|
+
/**
|
517
|
+
* Process the deletion queue for cleanup
|
518
|
+
*/
|
519
|
+
processCleanupQueue(registry) {
|
520
|
+
// This method is kept for compatibility but the logic has changed
|
521
|
+
// We no longer use a deletion queue, instead marking styles as unused immediately
|
522
|
+
}
|
523
|
+
/**
|
524
|
+
* Get total number of rules across all sheets
|
525
|
+
*/
|
526
|
+
getTotalRuleCount(registry) {
|
527
|
+
return registry.sheets.reduce((total, sheet) => total + sheet.ruleCount - sheet.holes.length, 0);
|
528
|
+
}
|
529
|
+
/**
|
530
|
+
* Get CSS text from all sheets (for SSR)
|
531
|
+
*/
|
532
|
+
getCssText(registry) {
|
533
|
+
const cssChunks = [];
|
534
|
+
for (const sheet of registry.sheets) {
|
535
|
+
try {
|
536
|
+
const styleElement = sheet.sheet;
|
537
|
+
if (styleElement.textContent) {
|
538
|
+
cssChunks.push(styleElement.textContent);
|
539
|
+
}
|
540
|
+
else if (styleElement.sheet) {
|
541
|
+
const rules = Array.from(styleElement.sheet.cssRules);
|
542
|
+
cssChunks.push(rules.map((rule) => rule.cssText).join('\n'));
|
543
|
+
}
|
544
|
+
}
|
545
|
+
catch (error) {
|
546
|
+
console.warn('Failed to read CSS from sheet:', error);
|
547
|
+
}
|
548
|
+
}
|
549
|
+
return cssChunks.join('\n');
|
550
|
+
}
|
551
|
+
/**
|
552
|
+
* Get cache performance metrics
|
553
|
+
*/
|
554
|
+
getMetrics(registry) {
|
555
|
+
return registry.metrics || null;
|
556
|
+
}
|
557
|
+
/**
|
558
|
+
* Reset cache performance metrics
|
559
|
+
*/
|
560
|
+
resetMetrics(registry) {
|
561
|
+
if (registry.metrics) {
|
562
|
+
registry.metrics = {
|
563
|
+
hits: 0,
|
564
|
+
misses: 0,
|
565
|
+
unusedHits: 0,
|
566
|
+
bulkCleanups: 0,
|
567
|
+
totalInsertions: 0,
|
568
|
+
totalUnused: 0,
|
569
|
+
stylesCleanedUp: 0,
|
570
|
+
cleanupHistory: [],
|
571
|
+
startTime: Date.now(),
|
572
|
+
};
|
573
|
+
}
|
574
|
+
}
|
575
|
+
/**
|
576
|
+
* Convert keyframes steps to CSS string
|
577
|
+
*/
|
578
|
+
stepsToCSS(steps) {
|
579
|
+
const rules = [];
|
580
|
+
for (const [key, value] of Object.entries(steps)) {
|
581
|
+
// Support raw CSS strings for backwards compatibility
|
582
|
+
if (typeof value === 'string') {
|
583
|
+
rules.push(`${key} { ${value.trim()} }`);
|
584
|
+
continue;
|
585
|
+
}
|
586
|
+
// Treat value as a style map and process via tasty style handlers
|
587
|
+
const styleMap = (value || {});
|
588
|
+
// Build a deterministic handler queue based on present style keys
|
589
|
+
const styleNames = Object.keys(styleMap).sort();
|
590
|
+
const handlerQueue = [];
|
591
|
+
const seenHandlers = new Set();
|
592
|
+
styleNames.forEach((styleName) => {
|
593
|
+
let handlers = STYLE_HANDLER_MAP[styleName];
|
594
|
+
if (!handlers) {
|
595
|
+
// Create a default handler for unknown styles (maps to kebab-case CSS or custom props)
|
596
|
+
handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];
|
597
|
+
}
|
598
|
+
handlers.forEach((handler) => {
|
599
|
+
if (!seenHandlers.has(handler)) {
|
600
|
+
seenHandlers.add(handler);
|
601
|
+
handlerQueue.push(handler);
|
602
|
+
}
|
603
|
+
});
|
604
|
+
});
|
605
|
+
// Accumulate declarations (ordered). We intentionally ignore `$` selector fan-out
|
606
|
+
// and any responsive/state bindings for keyframes.
|
607
|
+
const declarationPairs = [];
|
608
|
+
handlerQueue.forEach((handler) => {
|
609
|
+
const lookup = handler.__lookupStyles;
|
610
|
+
const filteredMap = lookup.reduce((acc, name) => {
|
611
|
+
const v = styleMap[name];
|
612
|
+
if (v !== undefined)
|
613
|
+
acc[name] = v;
|
614
|
+
return acc;
|
615
|
+
}, {});
|
616
|
+
const result = handler(filteredMap);
|
617
|
+
if (!result)
|
618
|
+
return;
|
619
|
+
const results = Array.isArray(result) ? result : [result];
|
620
|
+
results.forEach((cssMap) => {
|
621
|
+
if (!cssMap || typeof cssMap !== 'object')
|
622
|
+
return;
|
623
|
+
const { $, ...props } = cssMap;
|
624
|
+
Object.entries(props).forEach(([prop, val]) => {
|
625
|
+
if (val == null || val === '')
|
626
|
+
return;
|
627
|
+
if (Array.isArray(val)) {
|
628
|
+
// Multiple values for the same property -> emit in order
|
629
|
+
val.forEach((v) => {
|
630
|
+
if (v != null && v !== '') {
|
631
|
+
declarationPairs.push({ prop, value: String(v) });
|
632
|
+
}
|
633
|
+
});
|
634
|
+
}
|
635
|
+
else {
|
636
|
+
declarationPairs.push({ prop, value: String(val) });
|
637
|
+
}
|
638
|
+
});
|
639
|
+
});
|
640
|
+
});
|
641
|
+
// Fallback: if nothing produced (e.g., empty object), generate empty block
|
642
|
+
const declarations = declarationPairs
|
643
|
+
.map((d) => `${d.prop}: ${d.value}`)
|
644
|
+
.join('; ');
|
645
|
+
rules.push(`${key} { ${declarations.trim()} }`);
|
646
|
+
}
|
647
|
+
return rules.join(' ');
|
648
|
+
}
|
649
|
+
/**
|
650
|
+
* Insert keyframes rule
|
651
|
+
*/
|
652
|
+
insertKeyframes(registry, steps, name, root) {
|
653
|
+
let targetSheet = this.findAvailableSheet(registry, root);
|
654
|
+
if (!targetSheet) {
|
655
|
+
targetSheet = this.createSheet(registry, root);
|
656
|
+
}
|
657
|
+
const ruleIndex = this.findAvailableRuleIndex(targetSheet);
|
658
|
+
const sheetIndex = registry.sheets.indexOf(targetSheet);
|
659
|
+
try {
|
660
|
+
const cssSteps = this.stepsToCSS(steps);
|
661
|
+
const fullRule = `@keyframes ${name} { ${cssSteps} }`;
|
662
|
+
const styleElement = targetSheet.sheet;
|
663
|
+
const styleSheet = styleElement.sheet;
|
664
|
+
if (styleSheet && !this.config.forceTextInjection) {
|
665
|
+
const safeIndex = Math.min(Math.max(0, ruleIndex), styleSheet.cssRules.length);
|
666
|
+
styleSheet.insertRule(fullRule, safeIndex);
|
667
|
+
}
|
668
|
+
else {
|
669
|
+
styleElement.textContent =
|
670
|
+
(styleElement.textContent || '') + '\n' + fullRule;
|
671
|
+
}
|
672
|
+
targetSheet.ruleCount++;
|
673
|
+
return {
|
674
|
+
name,
|
675
|
+
ruleIndex,
|
676
|
+
sheetIndex,
|
677
|
+
cssText: fullRule,
|
678
|
+
};
|
679
|
+
}
|
680
|
+
catch (error) {
|
681
|
+
console.warn('Failed to insert keyframes:', error);
|
682
|
+
return null;
|
683
|
+
}
|
684
|
+
}
|
685
|
+
/**
|
686
|
+
* Delete keyframes rule
|
687
|
+
*/
|
688
|
+
deleteKeyframes(registry, info) {
|
689
|
+
const sheet = registry.sheets[info.sheetIndex];
|
690
|
+
if (!sheet)
|
691
|
+
return;
|
692
|
+
try {
|
693
|
+
const styleElement = sheet.sheet;
|
694
|
+
const styleSheet = styleElement.sheet;
|
695
|
+
if (styleSheet) {
|
696
|
+
if (info.ruleIndex >= 0 &&
|
697
|
+
info.ruleIndex < styleSheet.cssRules.length) {
|
698
|
+
styleSheet.deleteRule(info.ruleIndex);
|
699
|
+
sheet.ruleCount = Math.max(0, sheet.ruleCount - 1);
|
700
|
+
}
|
701
|
+
}
|
702
|
+
}
|
703
|
+
catch (error) {
|
704
|
+
console.warn('Failed to delete keyframes:', error);
|
705
|
+
}
|
706
|
+
}
|
707
|
+
/**
|
708
|
+
* Mark keyframes as unused
|
709
|
+
*/
|
710
|
+
markKeyframesAsUnused(registry, name) {
|
711
|
+
// Implementation similar to markAsUnused but for keyframes
|
712
|
+
const threshold = this.config.unusedStylesThreshold || 500;
|
713
|
+
if (registry.unusedKeyframes.size >= threshold) {
|
714
|
+
this.scheduleBulkCleanup(registry);
|
715
|
+
}
|
716
|
+
}
|
717
|
+
/**
|
718
|
+
* Clean up resources for a root
|
719
|
+
*/
|
720
|
+
cleanup(root) {
|
721
|
+
const registry = this.rootRegistries.get(root);
|
722
|
+
if (!registry) {
|
723
|
+
return;
|
724
|
+
}
|
725
|
+
// Cancel any scheduled bulk cleanup
|
726
|
+
if (registry.bulkCleanupTimeout) {
|
727
|
+
if (this.config.idleCleanup &&
|
728
|
+
typeof cancelIdleCallback !== 'undefined') {
|
729
|
+
cancelIdleCallback(registry.bulkCleanupTimeout);
|
730
|
+
}
|
731
|
+
else {
|
732
|
+
clearTimeout(registry.bulkCleanupTimeout);
|
733
|
+
}
|
734
|
+
registry.bulkCleanupTimeout = null;
|
735
|
+
}
|
736
|
+
// Remove all sheets
|
737
|
+
for (const sheet of registry.sheets) {
|
738
|
+
try {
|
739
|
+
// Remove style element
|
740
|
+
const styleElement = sheet.sheet;
|
741
|
+
if (styleElement.parentNode) {
|
742
|
+
styleElement.parentNode.removeChild(styleElement);
|
743
|
+
}
|
744
|
+
}
|
745
|
+
catch (error) {
|
746
|
+
console.warn('Failed to cleanup sheet:', error);
|
747
|
+
}
|
748
|
+
}
|
749
|
+
// Clear registry
|
750
|
+
this.rootRegistries.delete(root);
|
751
|
+
}
|
752
|
+
}
|
753
|
+
|
754
|
+
|