@cube-dev/ui-kit 0.98.8 → 0.99.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 +44 -0
- package/es/_internal/hooks/index.js +10 -10
- package/es/_internal/hooks/use-chained-callback.js +2 -2
- package/es/_internal/hooks/use-debounced-value.js +1 -1
- package/es/_internal/hooks/use-deprecation-warning.js +2 -2
- package/es/_internal/hooks/use-effect-once.js +1 -1
- package/es/_internal/hooks/use-event.js +2 -2
- package/es/_internal/hooks/use-is-first-render.js +1 -1
- package/es/_internal/hooks/use-sync-ref.js +2 -2
- package/es/_internal/hooks/use-timer/index.js +3 -3
- package/es/_internal/hooks/use-timer/timer.js +1 -1
- package/es/_internal/hooks/use-timer/use-timer.js +3 -3
- package/es/_internal/hooks/use-update-effect.js +2 -2
- package/es/_internal/hooks/use-warn.js +3 -3
- package/es/_internal/index.js +2 -2
- package/es/components/Block.js +2 -2
- package/es/components/CollectionItem.js +3 -3
- package/es/components/GlobalStyles.js +56 -65
- package/es/components/GridProvider.js +4 -4
- package/es/components/HiddenInput.js +2 -2
- package/es/components/OpenTrasition.js +1 -1
- package/es/components/Root.js +22 -64
- package/es/components/actions/Action/Action.js +3 -3
- package/es/components/actions/Button/Button.js +12 -12
- package/es/components/actions/Button/index.js +2 -2
- package/es/components/actions/ButtonGroup/ButtonGroup.js +4 -4
- package/es/components/actions/CommandMenu/CommandMenu.js +11 -11
- package/es/components/actions/CommandMenu/index.js +2 -2
- package/es/components/actions/CommandMenu/styled.js +2 -2
- package/es/components/actions/ItemAction/ItemAction.js +9 -9
- package/es/components/actions/ItemAction/index.js +2 -2
- package/es/components/actions/ItemActionContext.js +1 -1
- package/es/components/actions/ItemButton/ItemButton.js +9 -9
- package/es/components/actions/ItemButton/index.js +2 -2
- package/es/components/actions/Link/Link.js +2 -2
- package/es/components/actions/Menu/Menu.js +10 -10
- package/es/components/actions/Menu/MenuItem.js +7 -7
- package/es/components/actions/Menu/MenuSection.js +4 -4
- package/es/components/actions/Menu/MenuTrigger.js +6 -6
- package/es/components/actions/Menu/SubMenuTrigger.js +6 -6
- 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 +10 -10
- package/es/components/actions/Menu/styled.js +5 -5
- package/es/components/actions/index.js +13 -13
- package/es/components/actions/use-action.js +7 -7
- package/es/components/actions/use-anchored-menu.js +6 -6
- package/es/components/actions/use-context-menu.js +6 -6
- package/es/components/content/ActiveZone/ActiveZone.js +4 -4
- package/es/components/content/Alert/Alert.js +4 -4
- package/es/components/content/Alert/index.js +2 -2
- package/es/components/content/Alert/types.js +1 -1
- package/es/components/content/Alert/use-alert.js +3 -3
- package/es/components/content/Avatar/Avatar.js +2 -2
- package/es/components/content/Badge/Badge.js +4 -4
- package/es/components/content/Card/Card.js +2 -2
- package/es/components/content/Content.js +3 -3
- package/es/components/content/CopyPasteBlock/CopyPasteBlock.js +8 -8
- package/es/components/content/CopyPasteBlock/index.js +2 -2
- package/es/components/content/CopySnippet/CopySnippet.js +9 -9
- package/es/components/content/CopySnippet/index.js +2 -2
- package/es/components/content/Disclosure/Disclosure.js +6 -6
- package/es/components/content/Disclosure/index.js +2 -2
- package/es/components/content/Divider.js +3 -3
- package/es/components/content/Footer.js +3 -3
- package/es/components/content/Header.js +3 -3
- package/es/components/content/HotKeys/HotKeys.js +5 -5
- package/es/components/content/HotKeys/index.js +2 -2
- package/es/components/content/Item/Item.js +25 -20
- package/es/components/content/Item/index.js +3 -3
- package/es/components/content/ItemBadge/ItemBadge.js +8 -8
- package/es/components/content/ItemBadge/index.js +2 -2
- package/es/components/content/Layout/GridLayout.js +13 -13
- package/es/components/content/Layout/Layout.js +7 -6
- package/es/components/content/Layout/LayoutBlock.js +4 -3
- package/es/components/content/Layout/LayoutCenter.js +3 -3
- package/es/components/content/Layout/LayoutContainer.js +4 -4
- package/es/components/content/Layout/LayoutContent.js +6 -5
- package/es/components/content/Layout/LayoutContext.js +1 -1
- package/es/components/content/Layout/LayoutFlex.js +4 -3
- package/es/components/content/Layout/LayoutFooter.js +4 -3
- package/es/components/content/Layout/LayoutGrid.js +4 -3
- package/es/components/content/Layout/LayoutHeader.js +8 -7
- package/es/components/content/Layout/LayoutPane.js +8 -7
- package/es/components/content/Layout/LayoutPanel.js +10 -9
- package/es/components/content/Layout/LayoutPanelHeader.js +7 -7
- package/es/components/content/Layout/LayoutToolbar.js +4 -3
- package/es/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/es/components/content/Layout/index.js +16 -16
- package/es/components/content/Layout/utils.js +1 -1
- package/es/components/content/List/SectionHeading.js +3 -3
- package/es/components/content/List/index.js +2 -2
- package/es/components/content/Paragraph.js +3 -3
- package/es/components/content/Placeholder/Placeholder.js +2 -2
- package/es/components/content/PrismCode/PrismCode.js +7 -7
- package/es/components/content/PrismCode/prismSetup.js +1 -1
- package/es/components/content/PrismDiffCode/PrismDiffCode.js +2 -2
- package/es/components/content/Result/Result.js +4 -4
- package/es/components/content/Skeleton/Skeleton.js +5 -5
- package/es/components/content/Tag/Tag.js +4 -4
- package/es/components/content/Text.js +3 -3
- package/es/components/content/TextItem/TextItem.js +5 -5
- package/es/components/content/TextItem/index.js +2 -2
- package/es/components/content/Title.js +4 -4
- package/es/components/content/highlightText.js +2 -2
- package/es/components/content/use-auto-tooltip.js +2 -2
- package/es/components/fields/Checkbox/Checkbox.js +12 -12
- package/es/components/fields/Checkbox/CheckboxGroup.js +7 -7
- package/es/components/fields/Checkbox/context.js +1 -1
- package/es/components/fields/Checkbox/index.js +3 -3
- package/es/components/fields/ComboBox/ComboBox.js +18 -18
- package/es/components/fields/ComboBox/index.js +2 -2
- package/es/components/fields/DatePicker/DateInput.js +10 -10
- package/es/components/fields/DatePicker/DateInputBase.js +6 -6
- package/es/components/fields/DatePicker/DatePicker.js +14 -14
- package/es/components/fields/DatePicker/DatePickerButton.js +4 -4
- package/es/components/fields/DatePicker/DatePickerElement.js +3 -3
- package/es/components/fields/DatePicker/DatePickerInput.js +5 -5
- package/es/components/fields/DatePicker/DatePickerSegment.js +2 -2
- package/es/components/fields/DatePicker/DateRangePicker.js +15 -15
- package/es/components/fields/DatePicker/DateRangeSeparatedPicker.js +15 -15
- package/es/components/fields/DatePicker/TimeInput.js +9 -9
- package/es/components/fields/DatePicker/index.js +8 -8
- 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 +6 -6
- package/es/components/fields/FilterListBox/FilterListBox.js +10 -10
- package/es/components/fields/FilterListBox/index.js +2 -2
- package/es/components/fields/FilterPicker/FilterPicker.js +14 -14
- package/es/components/fields/FilterPicker/index.js +2 -2
- package/es/components/fields/Input/Input.js +6 -6
- package/es/components/fields/Input/index.js +2 -2
- package/es/components/fields/ListBox/ListBox.js +14 -14
- package/es/components/fields/ListBox/index.js +2 -2
- package/es/components/fields/NumberInput/NumberInput.js +8 -8
- package/es/components/fields/NumberInput/StepButton.js +4 -4
- package/es/components/fields/PasswordInput/PasswordInput.js +8 -8
- package/es/components/fields/Picker/Picker.js +13 -13
- package/es/components/fields/Picker/index.js +2 -2
- package/es/components/fields/RadioGroup/Radio.js +10 -10
- package/es/components/fields/RadioGroup/RadioGroup.js +7 -7
- package/es/components/fields/RadioGroup/context.js +1 -1
- package/es/components/fields/RadioGroup/index.js +3 -3
- package/es/components/fields/SearchInput/SearchInput.js +8 -8
- package/es/components/fields/SearchInput/index.js +2 -2
- package/es/components/fields/Select/Select.js +20 -20
- package/es/components/fields/Select/index.js +2 -2
- package/es/components/fields/Slider/Gradation.js +2 -2
- package/es/components/fields/Slider/Header.js +1 -1
- package/es/components/fields/Slider/RangeSlider.js +5 -5
- package/es/components/fields/Slider/Slider.js +7 -7
- package/es/components/fields/Slider/SliderBase.js +6 -6
- package/es/components/fields/Slider/SliderInput.js +2 -2
- package/es/components/fields/Slider/SliderThumb.js +3 -3
- package/es/components/fields/Slider/SliderTrack.js +2 -2
- package/es/components/fields/Slider/elements.js +2 -2
- package/es/components/fields/Slider/index.js +4 -4
- package/es/components/fields/Slider/types.js +1 -1
- package/es/components/fields/Switch/Switch.js +11 -11
- package/es/components/fields/Switch/index.js +2 -2
- package/es/components/fields/TextArea/TextArea.js +7 -7
- package/es/components/fields/TextArea/index.js +2 -2
- package/es/components/fields/TextInput/TextInput.js +6 -6
- package/es/components/fields/TextInput/TextInputBase.js +9 -9
- package/es/components/fields/TextInput/index.js +3 -3
- package/es/components/fields/TextInputMapper/TextInputMapper.js +14 -14
- package/es/components/fields/TextInputMapper/index.js +2 -2
- package/es/components/fields/index.js +20 -20
- package/es/components/form/FieldWrapper/FieldWrapper.js +9 -9
- package/es/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
- package/es/components/form/FieldWrapper/index.js +4 -4
- package/es/components/form/FieldWrapper/types.js +1 -1
- package/es/components/form/Form/Field.js +6 -6
- package/es/components/form/Form/Form.js +6 -6
- package/es/components/form/Form/ResetButton/ResetButton.js +6 -6
- package/es/components/form/Form/ResetButton/index.js +2 -2
- package/es/components/form/Form/SubmitButton/SubmitButton.js +4 -4
- package/es/components/form/Form/SubmitButton/index.js +2 -2
- package/es/components/form/Form/SubmitError.js +3 -3
- package/es/components/form/Form/index.js +11 -11
- package/es/components/form/Form/types.js +1 -1
- package/es/components/form/Form/use-field/index.js +4 -4
- package/es/components/form/Form/use-field/types.js +1 -1
- package/es/components/form/Form/use-field/use-field-props.js +6 -6
- package/es/components/form/Form/use-field/use-field.js +4 -4
- package/es/components/form/Form/use-form.js +3 -3
- package/es/components/form/Form/validation.js +1 -1
- package/es/components/form/Label.js +3 -3
- package/es/components/form/index.js +5 -5
- package/es/components/form/wrapper.js +3 -3
- package/es/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/es/components/helpers/DisplayTransition/index.js +2 -2
- package/es/components/helpers/IconSwitch/IconSwitch.js +3 -3
- package/es/components/helpers/index.js +3 -3
- package/es/components/layout/Flex.js +2 -2
- package/es/components/layout/Flow.js +2 -2
- package/es/components/layout/Grid.js +2 -2
- package/es/components/layout/Panel.js +2 -2
- package/es/components/layout/Prefix.js +3 -3
- package/es/components/layout/ResizablePanel.js +5 -5
- package/es/components/layout/Space.js +2 -2
- package/es/components/layout/Suffix.js +3 -3
- package/es/components/organisms/FileTabs/FileTabs.js +8 -8
- package/es/components/organisms/StatsCard/StatsCard.js +4 -4
- package/es/components/other/Calendar/Calendar.js +8 -8
- package/es/components/other/Calendar/CalendarCell.js +2 -2
- package/es/components/other/Calendar/CalendarGrid.js +3 -3
- package/es/components/other/Calendar/RangeCalendar.js +8 -8
- package/es/components/other/CloudLogo/CloudLogo.js +3 -3
- package/es/components/overlays/AlertDialog/AlertDialog.js +11 -10
- package/es/components/overlays/AlertDialog/AlertDialogApiProvider.js +2 -2
- package/es/components/overlays/AlertDialog/AlertDialogZone.js +4 -4
- package/es/components/overlays/AlertDialog/index.js +4 -4
- package/es/components/overlays/AlertDialog/types.js +1 -1
- package/es/components/overlays/Dialog/Dialog.js +7 -7
- package/es/components/overlays/Dialog/DialogContainer.js +3 -3
- package/es/components/overlays/Dialog/DialogForm.js +8 -8
- package/es/components/overlays/Dialog/DialogTrigger.js +4 -4
- package/es/components/overlays/Dialog/context.js +1 -1
- package/es/components/overlays/Dialog/index.js +6 -6
- package/es/components/overlays/Dialog/use-dialog-container.js +4 -4
- package/es/components/overlays/Modal/Modal.js +5 -5
- package/es/components/overlays/Modal/OpenTransition.js +1 -1
- package/es/components/overlays/Modal/Overlay.js +3 -3
- package/es/components/overlays/Modal/Popover.js +4 -4
- package/es/components/overlays/Modal/Tray.js +6 -6
- package/es/components/overlays/Modal/Underlay.js +2 -2
- package/es/components/overlays/Modal/index.js +7 -7
- package/es/components/overlays/Modal/types.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/FloatingNotification.js +5 -5
- package/es/components/overlays/NewNotifications/Bar/NotificationsBar.js +7 -7
- package/es/components/overlays/NewNotifications/Bar/TransitionComponent.js +36 -34
- package/es/components/overlays/NewNotifications/Bar/index.js +2 -2
- package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogContext.js +1 -1
- package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogTrigger.js +8 -8
- package/es/components/overlays/NewNotifications/Dialog/index.js +2 -2
- package/es/components/overlays/NewNotifications/Notification.js +4 -4
- package/es/components/overlays/NewNotifications/NotificationView/NotificationAction.js +5 -5
- package/es/components/overlays/NewNotifications/NotificationView/NotificationCloseButton.js +4 -4
- package/es/components/overlays/NewNotifications/NotificationView/NotificationDescription.js +4 -4
- package/es/components/overlays/NewNotifications/NotificationView/NotificationFooter.js +3 -3
- package/es/components/overlays/NewNotifications/NotificationView/NotificationHeader.js +3 -3
- package/es/components/overlays/NewNotifications/NotificationView/NotificationIcon.js +4 -4
- package/es/components/overlays/NewNotifications/NotificationView/NotificationProvider.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationView.js +12 -12
- package/es/components/overlays/NewNotifications/NotificationView/index.js +3 -3
- 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 +5 -5
- package/es/components/overlays/NewNotifications/NotificationsContext/index.js +3 -3
- package/es/components/overlays/NewNotifications/NotificationsContext/use-notifications.js +2 -2
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsList.js +4 -4
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsListItem.js +5 -5
- package/es/components/overlays/NewNotifications/NotificationsList/index.js +2 -2
- package/es/components/overlays/NewNotifications/NotificationsList/types.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/index.js +6 -6
- 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 +2 -2
- package/es/components/overlays/NewNotifications/hooks/use-notifications-list.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-observer.js +3 -3
- package/es/components/overlays/NewNotifications/index.js +7 -7
- package/es/components/overlays/NewNotifications/types.js +1 -1
- package/es/components/overlays/Notification/Notification.js +7 -7
- package/es/components/overlays/OverlayWrapper.js +2 -2
- package/es/components/overlays/Toasts/Toast.js +4 -4
- package/es/components/overlays/Toasts/index.js +3 -3
- package/es/components/overlays/Toasts/types.js +1 -1
- package/es/components/overlays/Toasts/use-toasts-api.js +2 -2
- package/es/components/overlays/Tooltip/Tooltip.js +4 -4
- package/es/components/overlays/Tooltip/TooltipProvider.js +3 -3
- package/es/components/overlays/Tooltip/TooltipTrigger.js +6 -6
- package/es/components/overlays/Tooltip/context.js +1 -1
- package/es/components/overlays/Tooltip/index.js +4 -4
- package/es/components/portal/Portal.js +2 -2
- package/es/components/portal/PortalProvider.js +1 -1
- package/es/components/portal/index.js +3 -3
- package/es/components/portal/types.js +1 -1
- package/es/components/portal/usePortal.js +2 -2
- package/es/components/shared/InvalidIcon.js +2 -2
- package/es/components/shared/ValidIcon.js +2 -2
- package/es/components/status/LoadingAnimation/LoadingAnimation.js +58 -114
- package/es/components/status/LoadingAnimation/index.js +2 -2
- package/es/components/status/Spin/Cube.js +95 -179
- package/es/components/status/Spin/InternalSpinner.js +5 -5
- package/es/components/status/Spin/Spin.js +4 -4
- package/es/components/status/Spin/SpinsContainer.js +28 -30
- package/es/components/status/Spin/index.js +2 -2
- package/es/components/status/Spin/types.js +1 -1
- package/es/components/status/index.js +3 -3
- package/es/data/item-themes.js +1 -1
- package/es/data/themes.js +1 -1
- package/es/icons/AdjustmentsHorizontalIcon.js +2 -2
- package/es/icons/AdjustmentsIcon.js +2 -2
- package/es/icons/AiIcon.js +2 -2
- package/es/icons/AreaChartIcon.js +2 -2
- package/es/icons/BackwardIcon.js +2 -2
- package/es/icons/BarChartIcon.js +2 -2
- package/es/icons/BellFilledIcon.js +2 -2
- package/es/icons/BellIcon.js +2 -2
- package/es/icons/BooleanIcon.js +2 -2
- package/es/icons/CalendarEditIcon.js +2 -2
- package/es/icons/CalendarIcon.js +2 -2
- package/es/icons/CaretDownIcon.js +2 -2
- package/es/icons/CaretUpIcon.js +2 -2
- package/es/icons/ChartAreaStackedIcon.js +2 -2
- package/es/icons/ChartAreaStackedPercentageIcon.js +2 -2
- package/es/icons/ChartBarGroupedHorizontalIcon.js +2 -2
- package/es/icons/ChartBarGroupedIcon.js +2 -2
- package/es/icons/ChartBarHorizontalIcon.js +2 -2
- package/es/icons/ChartBarLineIcon.js +2 -2
- package/es/icons/ChartBarStackedHorizontalIcon.js +2 -2
- package/es/icons/ChartBarStackedIcon.js +2 -2
- package/es/icons/ChartBarStackedPercentageHorizontalIcon.js +2 -2
- package/es/icons/ChartBarStackedPercentageIcon.js +2 -2
- package/es/icons/ChartBoxPlot2Icon.js +2 -2
- package/es/icons/ChartBoxPlotIcon.js +2 -2
- package/es/icons/ChartBubbleIcon.js +2 -2
- package/es/icons/ChartDonut2Icon.js +2 -2
- package/es/icons/ChartFunnelIcon.js +2 -2
- package/es/icons/ChartHeatmapIcon.js +2 -2
- package/es/icons/ChartKPIIcon.js +2 -2
- package/es/icons/ChartPie2Icon.js +2 -2
- package/es/icons/ChartScatterIcon.js +2 -2
- package/es/icons/CheckCircleFilledIcon.js +2 -2
- package/es/icons/CheckCircleIcon.js +2 -2
- package/es/icons/CheckIcon.js +2 -2
- package/es/icons/CircleFilledIcon.js +2 -2
- package/es/icons/ClearIcon.js +2 -2
- package/es/icons/CloseCircleFilledIcon.js +2 -2
- package/es/icons/CloseCircleIcon.js +2 -2
- package/es/icons/CloseIcon.js +2 -2
- package/es/icons/CodeIcon.js +2 -2
- package/es/icons/ColumnTotalIcon.js +2 -2
- package/es/icons/CopyIcon.js +2 -2
- package/es/icons/CountIcon.js +2 -2
- package/es/icons/CubeIcon.js +2 -2
- package/es/icons/CubePauseIcon.js +2 -2
- package/es/icons/CubePlayIcon.js +2 -2
- package/es/icons/CurrencyDollarIcon.js +2 -2
- package/es/icons/DangerIcon.js +2 -2
- package/es/icons/DashboardIcon.js +2 -2
- package/es/icons/DatabaseIcon.js +2 -2
- package/es/icons/DecimalDecreaseIcon.js +2 -2
- package/es/icons/DecimalIncreaseIcon.js +2 -2
- package/es/icons/DirectionIcon.js +3 -3
- package/es/icons/DonutIcon.js +2 -2
- package/es/icons/DownIcon.js +2 -2
- package/es/icons/EditIcon.js +2 -2
- package/es/icons/ExclamationCircleFilledIcon.js +2 -2
- package/es/icons/ExclamationCircleIcon.js +2 -2
- package/es/icons/ExclamationIcon.js +2 -2
- package/es/icons/EyeIcon.js +2 -2
- package/es/icons/EyeInvisibleIcon.js +2 -2
- package/es/icons/FilterIcon.js +2 -2
- package/es/icons/FolderFilledIcon.js +2 -2
- package/es/icons/FolderIcon.js +2 -2
- package/es/icons/FolderOpenFilledIcon.js +2 -2
- package/es/icons/FolderOpenIcon.js +2 -2
- package/es/icons/ForwardIcon.js +2 -2
- package/es/icons/HierarchyIcon.js +2 -2
- package/es/icons/HierarchyOpenIcon.js +2 -2
- package/es/icons/Icon.js +2 -2
- package/es/icons/InfoCircleIcon.js +2 -2
- package/es/icons/InfoIcon.js +2 -2
- package/es/icons/KeyIcon.js +2 -2
- package/es/icons/LeftIcon.js +2 -2
- package/es/icons/LineChartIcon.js +2 -2
- package/es/icons/LoadingIcon.js +2 -2
- package/es/icons/LockFilledIcon.js +2 -2
- package/es/icons/LockIcon.js +2 -2
- package/es/icons/MoreIcon.js +2 -2
- package/es/icons/NotAllowedIcon.js +2 -2
- package/es/icons/Number123Icon.js +2 -2
- package/es/icons/NumberIcon.js +2 -2
- package/es/icons/PauseCircleFilledIcon.js +2 -2
- package/es/icons/PauseCircleIcon.js +2 -2
- package/es/icons/PauseIcon.js +2 -2
- package/es/icons/PercentageIcon.js +2 -2
- package/es/icons/PieChartIcon.js +2 -2
- package/es/icons/PlayCircleIcon.js +2 -2
- package/es/icons/PlayIcon.js +2 -2
- package/es/icons/PlusIcon.js +2 -2
- package/es/icons/ProgressBarIcon.js +2 -2
- package/es/icons/ReloadIcon.js +2 -2
- package/es/icons/ReportIcon.js +2 -2
- package/es/icons/ReturnIcon.js +2 -2
- package/es/icons/RightIcon.js +2 -2
- package/es/icons/RowTotalsIcon.js +2 -2
- package/es/icons/SchemeIcon.js +2 -2
- package/es/icons/SearchIcon.js +2 -2
- package/es/icons/SemanticQueryIcon.js +12 -0
- package/es/icons/SettingsIcon.js +2 -2
- package/es/icons/ShieldFilledIcon.js +2 -2
- package/es/icons/ShieldIcon.js +2 -2
- package/es/icons/SlashIcon.js +2 -2
- package/es/icons/SparklesIcon.js +2 -2
- package/es/icons/SqlIcon.js +2 -2
- package/es/icons/StatsIcon.js +2 -2
- package/es/icons/StopIcon.js +2 -2
- package/es/icons/StringIcon.js +2 -2
- package/es/icons/SubtotalsIcon.js +2 -2
- package/es/icons/SwitchIcon.js +2 -2
- package/es/icons/TableIcon.js +2 -2
- package/es/icons/ThumbsDownIcon.js +2 -2
- package/es/icons/ThumbsUpIcon.js +2 -2
- package/es/icons/ThunderboltCrossedIcon.js +2 -2
- package/es/icons/ThunderboltFilledIcon.js +2 -2
- package/es/icons/ThunderboltIcon.js +2 -2
- package/es/icons/TimeIcon.js +2 -2
- package/es/icons/TrashIcon.js +2 -2
- package/es/icons/UnlockIcon.js +2 -2
- package/es/icons/UpIcon.js +2 -2
- package/es/icons/UserGroupIcon.js +2 -2
- package/es/icons/UserIcon.js +2 -2
- package/es/icons/UserLockIcon.js +2 -2
- package/es/icons/ViewIcon.js +2 -2
- package/es/icons/WarningFilledIcon.js +2 -2
- package/es/icons/WarningIcon.js +2 -2
- package/es/icons/index.js +129 -128
- package/es/icons/wrap-icon.js +2 -2
- package/es/index.js +73 -74
- package/es/provider.js +4 -10
- package/es/providers/TrackingProvider.js +1 -1
- package/es/providers/navigation.types.js +1 -1
- package/es/providers/navigationAdapter.default.js +1 -1
- package/es/services/notification.js +2 -2
- package/es/shared/form.js +1 -1
- package/es/shared/index.js +2 -2
- package/es/stories/Form.legacy-stories.js +4 -4
- package/es/stories/FormFieldArgs.js +2 -2
- package/es/stories/SimpleLayout.stories.js +2 -2
- package/es/stories/Tasty.stories.js +2 -2
- package/es/stories/components/ConfirmDeletionDialogForm.js +2 -2
- package/es/stories/components/DialogFormApp.js +3 -3
- package/es/stories/components/StyledButton.js +19 -15
- package/es/stories/lists/baseProps.js +2 -2
- package/es/stories/playground/PlaygroundEditor.js +89 -0
- package/es/stories/playground/PlaygroundLayout.js +16 -0
- package/es/stories/playground/PlaygroundOutput.js +92 -0
- package/es/stories/playground/PlaygroundPreview.js +91 -0
- package/es/stories/playground/components/Button.js +45 -0
- package/es/stories/playground/components/Card.js +20 -0
- package/es/stories/playground/components/ScrollProgress.js +17 -0
- package/es/stories/playground/examples.js +158 -0
- package/es/tasty/chunks/cacheKey.js +98 -0
- package/es/tasty/chunks/definitions.js +281 -0
- package/es/tasty/chunks/index.js +12 -0
- package/es/tasty/chunks/renderChunk.js +97 -0
- package/es/tasty/config.js +280 -0
- package/es/tasty/debug.js +195 -9
- package/es/tasty/hooks/index.js +12 -0
- package/es/tasty/hooks/useGlobalStyles.js +67 -0
- package/es/tasty/hooks/useRawCSS.js +40 -0
- package/es/tasty/hooks/useStyles.js +206 -0
- package/es/tasty/index.js +31 -17
- package/es/tasty/injector/index.js +34 -90
- package/es/tasty/injector/injector.js +81 -299
- package/es/tasty/injector/sheet-manager.js +138 -3
- package/es/tasty/injector/types.js +1 -1
- package/es/tasty/keyframes/index.js +301 -0
- package/es/tasty/parser/classify.js +8 -6
- package/es/tasty/parser/const.js +1 -1
- package/es/tasty/parser/lru.js +1 -1
- package/es/tasty/parser/parser.js +18 -5
- package/es/tasty/parser/tokenizer.js +1 -1
- package/es/tasty/parser/types.js +2 -1
- package/es/tasty/pipeline/conditions.js +426 -0
- package/es/tasty/pipeline/exclusive.js +311 -0
- package/es/tasty/pipeline/index.js +543 -0
- package/es/tasty/pipeline/materialize.js +1260 -0
- package/es/tasty/pipeline/parseStateKey.js +592 -0
- package/es/tasty/pipeline/simplify.js +898 -0
- package/es/tasty/plugins/index.js +26 -0
- package/es/tasty/plugins/okhsl-plugin.js +400 -0
- package/es/tasty/plugins/types.js +10 -0
- package/es/tasty/states/index.js +523 -0
- package/es/tasty/static/index.js +47 -0
- package/es/tasty/static/tastyStatic.js +55 -0
- package/es/tasty/static/types.js +34 -0
- package/es/tasty/styles/align.js +1 -1
- package/es/tasty/styles/border.js +2 -2
- package/es/tasty/styles/boxShadow.combinator.js +1 -1
- package/es/tasty/styles/color.js +3 -3
- package/es/tasty/styles/createStyle.js +3 -3
- package/es/tasty/styles/dimension.js +2 -2
- package/es/tasty/styles/display.js +1 -1
- package/es/tasty/styles/fade.js +2 -2
- package/es/tasty/styles/fill.js +11 -21
- 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 +2 -2
- package/es/tasty/styles/groupRadius.js +2 -2
- package/es/tasty/styles/height.js +2 -2
- package/es/tasty/styles/index.js +3 -3
- package/es/tasty/styles/inset.js +2 -2
- package/es/tasty/styles/justify.js +1 -1
- package/es/tasty/styles/list.js +1 -1
- package/es/tasty/styles/margin.js +76 -56
- package/es/tasty/styles/outline.js +2 -2
- package/es/tasty/styles/padding.js +76 -56
- package/es/tasty/styles/place.js +1 -1
- package/es/tasty/styles/predefined.js +28 -27
- package/es/tasty/styles/preset.js +2 -2
- package/es/tasty/styles/radius.js +5 -12
- package/es/tasty/styles/reset.js +3 -7
- package/es/tasty/styles/scrollbar.js +2 -2
- package/es/tasty/styles/shadow.js +2 -2
- package/es/tasty/styles/styledScrollbar.js +1 -1
- package/es/tasty/styles/transition.js +10 -3
- package/es/tasty/styles/types.js +1 -1
- package/es/tasty/styles/width.js +2 -2
- package/es/tasty/tasty.js +81 -122
- 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/isDevEnv.js +1 -1
- package/es/tasty/utils/mergeStyles.js +2 -2
- package/es/tasty/utils/modAttrs.js +3 -3
- package/es/tasty/utils/processTokens.js +88 -2
- package/es/tasty/utils/string.js +1 -1
- package/es/tasty/utils/styles.js +255 -22
- package/es/tasty/utils/typography.js +67 -0
- package/es/tasty/utils/warnings.js +1 -1
- package/es/tasty/zero/babel.js +453 -0
- package/es/tasty/zero/css-writer.js +94 -0
- package/es/tasty/zero/extractor.js +222 -0
- package/es/tasty/zero/index.js +28 -0
- package/es/tasty/zero/next.js +102 -0
- package/es/tokens/base.js +64 -0
- package/es/tokens/colors.js +68 -0
- package/es/tokens/index.js +63 -0
- package/es/tokens/layout.js +26 -0
- package/es/tokens/shadows.js +27 -0
- package/es/tokens/sizes.js +42 -0
- package/es/tokens/spacing.js +22 -0
- package/es/tokens/typography.js +237 -0
- package/es/utils/ResizeSensor.js +1 -1
- package/es/utils/index.js +10 -10
- package/es/utils/modules.js +1 -1
- package/es/utils/promise.js +1 -1
- package/es/utils/raf.js +1 -1
- package/es/utils/random.js +1 -1
- package/es/utils/range.js +1 -1
- package/es/utils/react/RenderCache.js +1 -1
- package/es/utils/react/Slots.js +2 -2
- package/es/utils/react/chain.js +1 -1
- package/es/utils/react/forwardRefWithGenerics.js +1 -1
- package/es/utils/react/index.js +17 -17
- 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 +4 -4
- package/es/utils/react/nullableValue.js +1 -1
- package/es/utils/react/resolveIcon.js +1 -1
- package/es/utils/react/sharedStore.js +2 -2
- package/es/utils/react/useCombinedRefs.js +1 -1
- package/es/utils/react/useControlledFocusVisible.js +2 -2
- package/es/utils/react/useEventBus.js +1 -1
- package/es/utils/react/useId.js +2 -2
- package/es/utils/react/useIsDarwin.js +1 -1
- package/es/utils/react/useKeySymbols.js +2 -2
- package/es/utils/react/useLayoutEffect.js +1 -1
- package/es/utils/react/useLocalStorage.js +2 -2
- 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/tree.js +1 -1
- package/es/utils/warnings.js +1 -1
- package/es/version.js +2 -2
- package/package.json +14 -4
- package/types/components/GlobalStyles.d.ts +2 -1
- package/types/components/HiddenInput.d.ts +828 -826
- package/types/components/Root.d.ts +1 -0
- package/types/components/actions/Button/Button.d.ts +1649 -1645
- package/types/components/actions/CommandMenu/styled.d.ts +4140 -4130
- package/types/components/actions/ItemActionContext.d.ts +1 -1
- package/types/components/actions/Menu/styled.d.ts +4893 -4883
- package/types/components/actions/use-action.d.ts +1 -1
- package/types/components/content/List/SectionHeading.d.ts +251 -251
- package/types/components/content/Text.d.ts +1487 -1487
- package/types/components/fields/DatePicker/DatePickerElement.d.ts +251 -251
- package/types/components/fields/Select/Select.d.ts +828 -826
- package/types/components/fields/Slider/elements.d.ts +4968 -4956
- package/types/components/overlays/AlertDialog/AlertDialog.d.ts +1 -1
- package/types/components/status/Spin/Cube.d.ts +1 -1
- package/types/components/status/Spin/SpinsContainer.d.ts +6 -3
- package/types/icons/SemanticQueryIcon.d.ts +4 -0
- package/types/icons/index.d.ts +1 -0
- package/types/index.d.ts +1 -4
- package/types/provider.d.ts +1 -2
- package/types/stories/components/StyledButton.d.ts +1 -1
- package/types/stories/playground/PlaygroundEditor.d.ts +6 -0
- package/types/stories/playground/PlaygroundLayout.d.ts +8 -0
- package/types/stories/playground/PlaygroundOutput.d.ts +5 -0
- package/types/stories/playground/PlaygroundPreview.d.ts +6 -0
- package/types/stories/playground/components/Button.d.ts +11 -0
- package/types/stories/playground/components/Card.d.ts +7 -0
- package/types/stories/playground/components/ScrollProgress.d.ts +5 -0
- package/types/stories/playground/examples.d.ts +7 -0
- package/types/tasty/chunks/cacheKey.d.ts +26 -0
- package/types/tasty/chunks/definitions.d.ts +75 -0
- package/types/tasty/chunks/index.d.ts +4 -0
- package/types/tasty/chunks/renderChunk.d.ts +25 -0
- package/types/tasty/config.d.ts +171 -0
- package/types/tasty/debug.d.ts +35 -0
- package/types/tasty/hooks/index.d.ts +4 -0
- package/types/tasty/hooks/useGlobalStyles.d.ts +22 -0
- package/types/tasty/hooks/useRawCSS.d.ts +50 -0
- package/types/tasty/hooks/useStyles.d.ts +35 -0
- package/types/tasty/index.d.ts +14 -4
- package/types/tasty/injector/index.d.ts +30 -19
- package/types/tasty/injector/injector.d.ts +19 -13
- package/types/tasty/injector/sheet-manager.d.ts +25 -1
- package/types/tasty/injector/types.d.ts +23 -2
- package/types/tasty/keyframes/index.d.ts +49 -0
- package/types/tasty/parser/parser.d.ts +4 -0
- package/types/tasty/parser/types.d.ts +1 -0
- package/types/tasty/pipeline/conditions.d.ts +243 -0
- package/types/tasty/pipeline/exclusive.d.ts +103 -0
- package/types/tasty/pipeline/index.d.ts +67 -0
- package/types/tasty/pipeline/materialize.d.ts +162 -0
- package/types/tasty/pipeline/parseStateKey.d.ts +20 -0
- package/types/tasty/pipeline/simplify.d.ts +28 -0
- package/types/tasty/plugins/index.d.ts +17 -0
- package/types/tasty/plugins/okhsl-plugin.d.ts +45 -0
- package/types/tasty/plugins/types.d.ts +34 -0
- package/types/tasty/states/index.d.ts +101 -0
- package/types/tasty/static/index.d.ts +39 -0
- package/types/tasty/static/tastyStatic.d.ts +41 -0
- package/types/tasty/static/types.d.ts +44 -0
- package/types/tasty/styles/fill.d.ts +11 -1
- package/types/tasty/styles/margin.d.ts +3 -1
- package/types/tasty/styles/padding.d.ts +3 -1
- package/types/tasty/styles/radius.d.ts +2 -10
- package/types/tasty/styles/types.d.ts +24 -3
- package/types/tasty/tasty.d.ts +892 -840
- package/types/tasty/utils/styles.d.ts +50 -6
- package/types/tasty/utils/typography.d.ts +32 -0
- package/types/tasty/zero/babel.d.ts +63 -0
- package/types/tasty/zero/css-writer.d.ts +41 -0
- package/types/tasty/zero/extractor.d.ts +40 -0
- package/types/tasty/zero/index.d.ts +18 -0
- package/types/tasty/zero/next.d.ts +57 -0
- package/types/tokens/base.d.ts +8 -0
- package/types/tokens/colors.d.ts +6 -0
- package/types/tokens/index.d.ts +41 -0
- package/types/tokens/layout.d.ts +7 -0
- package/types/tokens/shadows.d.ts +12 -0
- package/types/tokens/sizes.d.ts +25 -0
- package/types/tokens/spacing.d.ts +8 -0
- package/types/tokens/typography.d.ts +30 -0
- package/es/components/navigation/LegacyTabs/LegacyTabs.js +0 -275
- package/es/components/other/Base64Upload/Base64Upload.js +0 -103
- package/es/icons/add-new-icon.js +0 -129
- package/es/tasty/providers/BreakpointsProvider.js +0 -16
- package/es/tasty/utils/getModCombinations.js +0 -38
- package/es/tasty/utils/renderStyles.js +0 -1050
- package/es/tasty/utils/responsive.js +0 -60
- package/es/tokens.js +0 -309
- package/types/components/navigation/LegacyTabs/LegacyTabs.d.ts +0 -43
- package/types/components/other/Base64Upload/Base64Upload.d.ts +0 -5
- package/types/icons/add-new-icon.d.ts +0 -2
- package/types/tasty/providers/BreakpointsProvider.d.ts +0 -8
- package/types/tasty/utils/getModCombinations.d.ts +0 -9
- package/types/tasty/utils/renderStyles.d.ts +0 -41
- package/types/tasty/utils/responsive.d.ts +0 -8
- package/types/tokens.d.ts +0 -221
|
@@ -0,0 +1,898 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* author: Cube Dev Team
|
|
4
|
+
* @cube-dev/ui-kit v0.99.0
|
|
5
|
+
* Released under the MIT license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Condition Simplification Engine
|
|
10
|
+
*
|
|
11
|
+
* Simplifies condition trees by applying boolean algebra rules,
|
|
12
|
+
* detecting contradictions, merging ranges, and deduplicating terms.
|
|
13
|
+
*
|
|
14
|
+
* This is critical for:
|
|
15
|
+
* 1. Detecting invalid combinations (A & !A → FALSE)
|
|
16
|
+
* 2. Reducing CSS output size
|
|
17
|
+
* 3. Producing cleaner selectors
|
|
18
|
+
*/
|
|
19
|
+
import { Lru } from '../parser/lru.js';
|
|
20
|
+
import { falseCondition, getConditionUniqueId, trueCondition, } from './conditions.js';
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Caching
|
|
23
|
+
// ============================================================================
|
|
24
|
+
const simplifyCache = new Lru(5000);
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Main Simplify Function
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Simplify a condition tree aggressively.
|
|
30
|
+
*
|
|
31
|
+
* This applies all possible simplification rules:
|
|
32
|
+
* - Boolean algebra (identity, annihilator, idempotent, absorption)
|
|
33
|
+
* - Contradiction detection (A & !A → FALSE)
|
|
34
|
+
* - Tautology detection (A | !A → TRUE)
|
|
35
|
+
* - Range intersection for numeric queries
|
|
36
|
+
* - Attribute value conflict detection
|
|
37
|
+
* - Deduplication and sorting
|
|
38
|
+
*/
|
|
39
|
+
export function simplifyCondition(node) {
|
|
40
|
+
// Check cache
|
|
41
|
+
const key = getConditionUniqueId(node);
|
|
42
|
+
const cached = simplifyCache.get(key);
|
|
43
|
+
if (cached) {
|
|
44
|
+
return cached;
|
|
45
|
+
}
|
|
46
|
+
const result = simplifyInner(node);
|
|
47
|
+
// Cache result
|
|
48
|
+
simplifyCache.set(key, result);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Clear the simplify cache (for testing)
|
|
53
|
+
*/
|
|
54
|
+
export function clearSimplifyCache() {
|
|
55
|
+
simplifyCache.clear();
|
|
56
|
+
}
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Inner Simplification
|
|
59
|
+
// ============================================================================
|
|
60
|
+
function simplifyInner(node) {
|
|
61
|
+
// Base cases
|
|
62
|
+
if (node.kind === 'true' || node.kind === 'false') {
|
|
63
|
+
return node;
|
|
64
|
+
}
|
|
65
|
+
// State conditions - return as-is (they're already leaf nodes)
|
|
66
|
+
if (node.kind === 'state') {
|
|
67
|
+
return node;
|
|
68
|
+
}
|
|
69
|
+
// Compound conditions - recursively simplify
|
|
70
|
+
if (node.kind === 'compound') {
|
|
71
|
+
// First, recursively simplify all children
|
|
72
|
+
const simplifiedChildren = node.children.map((c) => simplifyInner(c));
|
|
73
|
+
// Then apply compound-specific simplifications
|
|
74
|
+
if (node.operator === 'AND') {
|
|
75
|
+
return simplifyAnd(simplifiedChildren);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
return simplifyOr(simplifiedChildren);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return node;
|
|
82
|
+
}
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// AND Simplification
|
|
85
|
+
// ============================================================================
|
|
86
|
+
function simplifyAnd(children) {
|
|
87
|
+
let terms = [];
|
|
88
|
+
// Flatten nested ANDs and handle TRUE/FALSE
|
|
89
|
+
for (const child of children) {
|
|
90
|
+
if (child.kind === 'false') {
|
|
91
|
+
// AND with FALSE → FALSE
|
|
92
|
+
return falseCondition();
|
|
93
|
+
}
|
|
94
|
+
if (child.kind === 'true') {
|
|
95
|
+
// AND with TRUE → skip (identity)
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (child.kind === 'compound' && child.operator === 'AND') {
|
|
99
|
+
// Flatten nested AND
|
|
100
|
+
terms.push(...child.children);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
terms.push(child);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Empty → TRUE
|
|
107
|
+
if (terms.length === 0) {
|
|
108
|
+
return trueCondition();
|
|
109
|
+
}
|
|
110
|
+
// Single term → return it
|
|
111
|
+
if (terms.length === 1) {
|
|
112
|
+
return terms[0];
|
|
113
|
+
}
|
|
114
|
+
// Check for contradictions
|
|
115
|
+
if (hasContradiction(terms)) {
|
|
116
|
+
return falseCondition();
|
|
117
|
+
}
|
|
118
|
+
// Check for range contradictions in media/container queries
|
|
119
|
+
if (hasRangeContradiction(terms)) {
|
|
120
|
+
return falseCondition();
|
|
121
|
+
}
|
|
122
|
+
// Check for attribute value conflicts
|
|
123
|
+
if (hasAttributeConflict(terms)) {
|
|
124
|
+
return falseCondition();
|
|
125
|
+
}
|
|
126
|
+
// Check for container style query conflicts
|
|
127
|
+
if (hasContainerStyleConflict(terms)) {
|
|
128
|
+
return falseCondition();
|
|
129
|
+
}
|
|
130
|
+
// Remove redundant negations implied by positive terms
|
|
131
|
+
// e.g., style(--variant: danger) implies NOT style(--variant: success)
|
|
132
|
+
// and style(--variant: danger) implies style(--variant) (existence)
|
|
133
|
+
terms = removeImpliedNegations(terms);
|
|
134
|
+
// Deduplicate (by uniqueId)
|
|
135
|
+
terms = deduplicateTerms(terms);
|
|
136
|
+
// Try to merge numeric ranges
|
|
137
|
+
terms = mergeRanges(terms);
|
|
138
|
+
// Sort for canonical form
|
|
139
|
+
terms = sortTerms(terms);
|
|
140
|
+
// Apply absorption: A & (A | B) → A
|
|
141
|
+
terms = applyAbsorptionAnd(terms);
|
|
142
|
+
if (terms.length === 0) {
|
|
143
|
+
return trueCondition();
|
|
144
|
+
}
|
|
145
|
+
if (terms.length === 1) {
|
|
146
|
+
return terms[0];
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
kind: 'compound',
|
|
150
|
+
operator: 'AND',
|
|
151
|
+
children: terms,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// OR Simplification
|
|
156
|
+
// ============================================================================
|
|
157
|
+
function simplifyOr(children) {
|
|
158
|
+
let terms = [];
|
|
159
|
+
// Flatten nested ORs and handle TRUE/FALSE
|
|
160
|
+
for (const child of children) {
|
|
161
|
+
if (child.kind === 'true') {
|
|
162
|
+
// OR with TRUE → TRUE
|
|
163
|
+
return trueCondition();
|
|
164
|
+
}
|
|
165
|
+
if (child.kind === 'false') {
|
|
166
|
+
// OR with FALSE → skip (identity)
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (child.kind === 'compound' && child.operator === 'OR') {
|
|
170
|
+
// Flatten nested OR
|
|
171
|
+
terms.push(...child.children);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
terms.push(child);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Empty → FALSE
|
|
178
|
+
if (terms.length === 0) {
|
|
179
|
+
return falseCondition();
|
|
180
|
+
}
|
|
181
|
+
// Single term → return it
|
|
182
|
+
if (terms.length === 1) {
|
|
183
|
+
return terms[0];
|
|
184
|
+
}
|
|
185
|
+
// Check for tautologies (A | !A)
|
|
186
|
+
if (hasTautology(terms)) {
|
|
187
|
+
return trueCondition();
|
|
188
|
+
}
|
|
189
|
+
// Deduplicate
|
|
190
|
+
terms = deduplicateTerms(terms);
|
|
191
|
+
// Sort for canonical form
|
|
192
|
+
terms = sortTerms(terms);
|
|
193
|
+
// Apply absorption: A | (A & B) → A
|
|
194
|
+
terms = applyAbsorptionOr(terms);
|
|
195
|
+
if (terms.length === 0) {
|
|
196
|
+
return falseCondition();
|
|
197
|
+
}
|
|
198
|
+
if (terms.length === 1) {
|
|
199
|
+
return terms[0];
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
kind: 'compound',
|
|
203
|
+
operator: 'OR',
|
|
204
|
+
children: terms,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
// ============================================================================
|
|
208
|
+
// Contradiction Detection
|
|
209
|
+
// ============================================================================
|
|
210
|
+
/**
|
|
211
|
+
* Check if any term contradicts another (A & !A)
|
|
212
|
+
*/
|
|
213
|
+
function hasContradiction(terms) {
|
|
214
|
+
const uniqueIds = new Set();
|
|
215
|
+
for (const term of terms) {
|
|
216
|
+
if (term.kind !== 'state')
|
|
217
|
+
continue;
|
|
218
|
+
const id = term.uniqueId;
|
|
219
|
+
// Check if negation exists
|
|
220
|
+
const negatedId = term.negated ? id.slice(1) : `!${id}`;
|
|
221
|
+
if (uniqueIds.has(negatedId)) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
uniqueIds.add(id);
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Check for tautologies (A | !A)
|
|
230
|
+
*/
|
|
231
|
+
function hasTautology(terms) {
|
|
232
|
+
const uniqueIds = new Set();
|
|
233
|
+
for (const term of terms) {
|
|
234
|
+
if (term.kind !== 'state')
|
|
235
|
+
continue;
|
|
236
|
+
const id = term.uniqueId;
|
|
237
|
+
const negatedId = term.negated ? id.slice(1) : `!${id}`;
|
|
238
|
+
if (uniqueIds.has(negatedId)) {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
uniqueIds.add(id);
|
|
242
|
+
}
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Check for range contradictions in media/container queries
|
|
247
|
+
* e.g., @media(w < 400px) & @media(w > 800px) → FALSE
|
|
248
|
+
*
|
|
249
|
+
* Also handles negated conditions:
|
|
250
|
+
* - Single-bound negations are inverted (not (w < 600px) → w >= 600px)
|
|
251
|
+
* - Range negations create excluded ranges that are checked against positive bounds
|
|
252
|
+
*/
|
|
253
|
+
function hasRangeContradiction(terms) {
|
|
254
|
+
// Group by dimension, separating positive and negated conditions
|
|
255
|
+
const mediaByDim = new Map();
|
|
256
|
+
const containerByDim = new Map();
|
|
257
|
+
for (const term of terms) {
|
|
258
|
+
if (term.kind !== 'state')
|
|
259
|
+
continue;
|
|
260
|
+
if (term.type === 'media' && term.subtype === 'dimension') {
|
|
261
|
+
const key = term.dimension || 'width';
|
|
262
|
+
if (!mediaByDim.has(key)) {
|
|
263
|
+
mediaByDim.set(key, { positive: [], negated: [] });
|
|
264
|
+
}
|
|
265
|
+
const group = mediaByDim.get(key);
|
|
266
|
+
if (term.negated) {
|
|
267
|
+
group.negated.push(term);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
group.positive.push(term);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (term.type === 'container' && term.subtype === 'dimension') {
|
|
274
|
+
const key = `${term.containerName || '_'}:${term.dimension || 'width'}`;
|
|
275
|
+
if (!containerByDim.has(key)) {
|
|
276
|
+
containerByDim.set(key, { positive: [], negated: [] });
|
|
277
|
+
}
|
|
278
|
+
const group = containerByDim.get(key);
|
|
279
|
+
if (term.negated) {
|
|
280
|
+
group.negated.push(term);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
group.positive.push(term);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// Check each dimension group for impossible ranges
|
|
288
|
+
for (const group of mediaByDim.values()) {
|
|
289
|
+
if (rangesAreImpossibleWithNegations(group.positive, group.negated)) {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
for (const group of containerByDim.values()) {
|
|
294
|
+
if (rangesAreImpossibleWithNegations(group.positive, group.negated)) {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Check if conditions are impossible, including negated conditions.
|
|
302
|
+
*
|
|
303
|
+
* For negated single-bound conditions:
|
|
304
|
+
* not (w < 600px) → w >= 600px (inverted to lower bound)
|
|
305
|
+
* not (w >= 800px) → w < 800px (inverted to upper bound)
|
|
306
|
+
*
|
|
307
|
+
* For negated range conditions:
|
|
308
|
+
* not (400px <= w < 800px) → excludes [400, 800)
|
|
309
|
+
* If the effective bounds fall entirely within an excluded range, it's impossible.
|
|
310
|
+
*/
|
|
311
|
+
function rangesAreImpossibleWithNegations(positive, negated) {
|
|
312
|
+
// Start with bounds from positive conditions
|
|
313
|
+
const bounds = computeEffectiveBounds(positive);
|
|
314
|
+
// Apply inverted bounds from single-bound negated conditions
|
|
315
|
+
// and collect excluded ranges from range negated conditions
|
|
316
|
+
const excludedRanges = [];
|
|
317
|
+
for (const cond of negated) {
|
|
318
|
+
const hasLower = cond.lowerBound?.valueNumeric != null;
|
|
319
|
+
const hasUpper = cond.upperBound?.valueNumeric != null;
|
|
320
|
+
if (hasLower && hasUpper) {
|
|
321
|
+
// Range negation: not (lower <= w < upper) excludes [lower, upper)
|
|
322
|
+
excludedRanges.push({
|
|
323
|
+
lower: cond.lowerBound.valueNumeric,
|
|
324
|
+
lowerInclusive: cond.lowerBound.inclusive,
|
|
325
|
+
upper: cond.upperBound.valueNumeric,
|
|
326
|
+
upperInclusive: cond.upperBound.inclusive,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
else if (hasUpper) {
|
|
330
|
+
// not (w < upper) → w >= upper (becomes lower bound)
|
|
331
|
+
// not (w <= upper) → w > upper (becomes lower bound, exclusive)
|
|
332
|
+
const value = cond.upperBound.valueNumeric;
|
|
333
|
+
const inclusive = !cond.upperBound.inclusive; // flip inclusivity
|
|
334
|
+
if (bounds.lowerBound === null || value > bounds.lowerBound) {
|
|
335
|
+
bounds.lowerBound = value;
|
|
336
|
+
bounds.lowerInclusive = inclusive;
|
|
337
|
+
}
|
|
338
|
+
else if (value === bounds.lowerBound && !inclusive) {
|
|
339
|
+
bounds.lowerInclusive = false;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
else if (hasLower) {
|
|
343
|
+
// not (w >= lower) → w < lower (becomes upper bound)
|
|
344
|
+
// not (w > lower) → w <= lower (becomes upper bound, inclusive)
|
|
345
|
+
const value = cond.lowerBound.valueNumeric;
|
|
346
|
+
const inclusive = !cond.lowerBound.inclusive; // flip inclusivity
|
|
347
|
+
if (bounds.upperBound === null || value < bounds.upperBound) {
|
|
348
|
+
bounds.upperBound = value;
|
|
349
|
+
bounds.upperInclusive = inclusive;
|
|
350
|
+
}
|
|
351
|
+
else if (value === bounds.upperBound && !inclusive) {
|
|
352
|
+
bounds.upperInclusive = false;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// Check if effective bounds are impossible on their own
|
|
357
|
+
if (bounds.lowerBound !== null && bounds.upperBound !== null) {
|
|
358
|
+
if (bounds.lowerBound > bounds.upperBound) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
if (bounds.lowerBound === bounds.upperBound &&
|
|
362
|
+
(!bounds.lowerInclusive || !bounds.upperInclusive)) {
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Check if effective bounds fall entirely within any excluded range
|
|
367
|
+
if (bounds.lowerBound !== null &&
|
|
368
|
+
bounds.upperBound !== null &&
|
|
369
|
+
excludedRanges.length > 0) {
|
|
370
|
+
for (const excluded of excludedRanges) {
|
|
371
|
+
if (boundsWithinExcludedRange(bounds, excluded)) {
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Compute effective bounds from positive (non-negated) conditions
|
|
380
|
+
*/
|
|
381
|
+
function computeEffectiveBounds(conditions) {
|
|
382
|
+
let lowerBound = null;
|
|
383
|
+
let lowerInclusive = false;
|
|
384
|
+
let upperBound = null;
|
|
385
|
+
let upperInclusive = false;
|
|
386
|
+
for (const cond of conditions) {
|
|
387
|
+
if (cond.lowerBound?.valueNumeric != null) {
|
|
388
|
+
const value = cond.lowerBound.valueNumeric;
|
|
389
|
+
const inclusive = cond.lowerBound.inclusive;
|
|
390
|
+
if (lowerBound === null || value > lowerBound) {
|
|
391
|
+
lowerBound = value;
|
|
392
|
+
lowerInclusive = inclusive;
|
|
393
|
+
}
|
|
394
|
+
else if (value === lowerBound && !inclusive) {
|
|
395
|
+
lowerInclusive = false;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (cond.upperBound?.valueNumeric != null) {
|
|
399
|
+
const value = cond.upperBound.valueNumeric;
|
|
400
|
+
const inclusive = cond.upperBound.inclusive;
|
|
401
|
+
if (upperBound === null || value < upperBound) {
|
|
402
|
+
upperBound = value;
|
|
403
|
+
upperInclusive = inclusive;
|
|
404
|
+
}
|
|
405
|
+
else if (value === upperBound && !inclusive) {
|
|
406
|
+
upperInclusive = false;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return { lowerBound, lowerInclusive, upperBound, upperInclusive };
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Check if effective bounds fall entirely within an excluded range.
|
|
414
|
+
*
|
|
415
|
+
* For example:
|
|
416
|
+
* Effective: [400, 800)
|
|
417
|
+
* Excluded: [400, 800)
|
|
418
|
+
* → bounds fall entirely within excluded range → impossible
|
|
419
|
+
*/
|
|
420
|
+
function boundsWithinExcludedRange(bounds, excluded) {
|
|
421
|
+
if (bounds.lowerBound === null || bounds.upperBound === null) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
// Check if bounds.lower >= excluded.lower
|
|
425
|
+
let lowerOk = false;
|
|
426
|
+
if (bounds.lowerBound > excluded.lower) {
|
|
427
|
+
lowerOk = true;
|
|
428
|
+
}
|
|
429
|
+
else if (bounds.lowerBound === excluded.lower) {
|
|
430
|
+
// If excluded includes lower, and bounds includes or excludes lower, it's within
|
|
431
|
+
// If excluded excludes lower, bounds must also exclude it to be within
|
|
432
|
+
lowerOk = excluded.lowerInclusive || !bounds.lowerInclusive;
|
|
433
|
+
}
|
|
434
|
+
// Check if bounds.upper <= excluded.upper
|
|
435
|
+
let upperOk = false;
|
|
436
|
+
if (bounds.upperBound < excluded.upper) {
|
|
437
|
+
upperOk = true;
|
|
438
|
+
}
|
|
439
|
+
else if (bounds.upperBound === excluded.upper) {
|
|
440
|
+
// If excluded includes upper, and bounds includes or excludes upper, it's within
|
|
441
|
+
// If excluded excludes upper, bounds must also exclude it to be within
|
|
442
|
+
upperOk = excluded.upperInclusive || !bounds.upperInclusive;
|
|
443
|
+
}
|
|
444
|
+
return lowerOk && upperOk;
|
|
445
|
+
}
|
|
446
|
+
// ============================================================================
|
|
447
|
+
// Attribute Conflict Detection
|
|
448
|
+
// ============================================================================
|
|
449
|
+
/**
|
|
450
|
+
* Check for attribute value conflicts
|
|
451
|
+
* e.g., [data-theme="dark"] & [data-theme="light"] → FALSE
|
|
452
|
+
* e.g., [data-theme="dark"] & ![data-theme] → FALSE
|
|
453
|
+
*/
|
|
454
|
+
function hasAttributeConflict(terms) {
|
|
455
|
+
// Group modifiers by attribute
|
|
456
|
+
const modifiersByAttr = new Map();
|
|
457
|
+
for (const term of terms) {
|
|
458
|
+
if (term.kind !== 'state' || term.type !== 'modifier')
|
|
459
|
+
continue;
|
|
460
|
+
const attr = term.attribute;
|
|
461
|
+
if (!modifiersByAttr.has(attr)) {
|
|
462
|
+
modifiersByAttr.set(attr, { positive: [], negated: [] });
|
|
463
|
+
}
|
|
464
|
+
const group = modifiersByAttr.get(attr);
|
|
465
|
+
if (term.negated) {
|
|
466
|
+
group.negated.push(term);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
group.positive.push(term);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Check each attribute for conflicts
|
|
473
|
+
for (const [attr, group] of modifiersByAttr) {
|
|
474
|
+
// Multiple different values for same attribute in positive → conflict
|
|
475
|
+
const positiveValues = group.positive
|
|
476
|
+
.filter((m) => m.value !== undefined)
|
|
477
|
+
.map((m) => m.value);
|
|
478
|
+
const uniquePositiveValues = new Set(positiveValues);
|
|
479
|
+
if (uniquePositiveValues.size > 1) {
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
// Positive value + negated boolean for same attribute → conflict
|
|
483
|
+
// e.g., [data-theme="dark"] & ![data-theme]
|
|
484
|
+
const hasPositiveValue = group.positive.some((m) => m.value !== undefined);
|
|
485
|
+
const hasNegatedBoolean = group.negated.some((m) => m.value === undefined);
|
|
486
|
+
if (hasPositiveValue && hasNegatedBoolean) {
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
// Positive boolean + negated value (same value) → tautology not conflict
|
|
490
|
+
// But positive value + negated same value → conflict
|
|
491
|
+
for (const pos of group.positive) {
|
|
492
|
+
if (pos.value !== undefined) {
|
|
493
|
+
for (const neg of group.negated) {
|
|
494
|
+
if (neg.value === pos.value) {
|
|
495
|
+
return true; // [data-x="y"] & ![data-x="y"]
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
// ============================================================================
|
|
504
|
+
// Container Style Query Conflict Detection
|
|
505
|
+
// ============================================================================
|
|
506
|
+
/**
|
|
507
|
+
* Check for container style query conflicts
|
|
508
|
+
* e.g., style(--variant: danger) & style(--variant: success) → FALSE
|
|
509
|
+
* e.g., style(--variant: danger) & not style(--variant) → FALSE
|
|
510
|
+
*/
|
|
511
|
+
function hasContainerStyleConflict(terms) {
|
|
512
|
+
// Group container style queries by property (and container name)
|
|
513
|
+
const styleByProp = new Map();
|
|
514
|
+
for (const term of terms) {
|
|
515
|
+
if (term.kind !== 'state' ||
|
|
516
|
+
term.type !== 'container' ||
|
|
517
|
+
term.subtype !== 'style')
|
|
518
|
+
continue;
|
|
519
|
+
const key = `${term.containerName || '_'}:${term.property}`;
|
|
520
|
+
if (!styleByProp.has(key)) {
|
|
521
|
+
styleByProp.set(key, { positive: [], negated: [] });
|
|
522
|
+
}
|
|
523
|
+
const group = styleByProp.get(key);
|
|
524
|
+
if (term.negated) {
|
|
525
|
+
group.negated.push(term);
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
group.positive.push(term);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// Check each property for conflicts
|
|
532
|
+
for (const [, group] of styleByProp) {
|
|
533
|
+
// Multiple different values for same property in positive → conflict
|
|
534
|
+
// e.g., style(--variant: danger) & style(--variant: success)
|
|
535
|
+
const positiveValues = group.positive
|
|
536
|
+
.filter((c) => c.propertyValue !== undefined)
|
|
537
|
+
.map((c) => c.propertyValue);
|
|
538
|
+
const uniquePositiveValues = new Set(positiveValues);
|
|
539
|
+
if (uniquePositiveValues.size > 1) {
|
|
540
|
+
return true;
|
|
541
|
+
}
|
|
542
|
+
// Positive value + negated existence → conflict
|
|
543
|
+
// e.g., style(--variant: danger) & not style(--variant)
|
|
544
|
+
const hasPositiveValue = group.positive.some((c) => c.propertyValue !== undefined);
|
|
545
|
+
const hasNegatedExistence = group.negated.some((c) => c.propertyValue === undefined);
|
|
546
|
+
if (hasPositiveValue && hasNegatedExistence) {
|
|
547
|
+
return true;
|
|
548
|
+
}
|
|
549
|
+
// Positive value + negated same value → conflict
|
|
550
|
+
// e.g., style(--variant: danger) & not style(--variant: danger)
|
|
551
|
+
for (const pos of group.positive) {
|
|
552
|
+
if (pos.propertyValue !== undefined) {
|
|
553
|
+
for (const neg of group.negated) {
|
|
554
|
+
if (neg.propertyValue === pos.propertyValue) {
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
// ============================================================================
|
|
564
|
+
// Implied Negation Removal
|
|
565
|
+
// ============================================================================
|
|
566
|
+
/**
|
|
567
|
+
* Remove negations that are implied by positive terms.
|
|
568
|
+
*
|
|
569
|
+
* Key optimizations:
|
|
570
|
+
* 1. style(--variant: danger) implies NOT style(--variant: success)
|
|
571
|
+
* → If we have style(--variant: danger) & not style(--variant: success),
|
|
572
|
+
* the negation is redundant and can be removed.
|
|
573
|
+
*
|
|
574
|
+
* 2. [data-theme="dark"] implies NOT [data-theme="light"]
|
|
575
|
+
* → Same logic for attribute selectors.
|
|
576
|
+
*
|
|
577
|
+
* This produces cleaner CSS:
|
|
578
|
+
* Before: @container style(--variant: danger) and (not style(--variant: success))
|
|
579
|
+
* After: @container style(--variant: danger)
|
|
580
|
+
*/
|
|
581
|
+
function removeImpliedNegations(terms) {
|
|
582
|
+
// Build sets of positive container style properties with specific values
|
|
583
|
+
const positiveContainerStyles = new Map();
|
|
584
|
+
// key: "containerName:property", value: propertyValue (or undefined for existence)
|
|
585
|
+
// Build sets of positive modifier attributes with specific values
|
|
586
|
+
const positiveModifiers = new Map();
|
|
587
|
+
// key: "attribute", value: value (or undefined for boolean)
|
|
588
|
+
for (const term of terms) {
|
|
589
|
+
if (term.kind !== 'state' || term.negated)
|
|
590
|
+
continue;
|
|
591
|
+
if (term.type === 'container' && term.subtype === 'style') {
|
|
592
|
+
const key = `${term.containerName || '_'}:${term.property}`;
|
|
593
|
+
// Only track if we have a specific value (not just existence check)
|
|
594
|
+
if (term.propertyValue !== undefined) {
|
|
595
|
+
positiveContainerStyles.set(key, term.propertyValue);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (term.type === 'modifier' && term.value !== undefined) {
|
|
599
|
+
positiveModifiers.set(term.attribute, term.value);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
// Filter out redundant negations
|
|
603
|
+
return terms.filter((term) => {
|
|
604
|
+
if (term.kind !== 'state' || !term.negated)
|
|
605
|
+
return true;
|
|
606
|
+
// Check container style negations
|
|
607
|
+
if (term.type === 'container' && term.subtype === 'style') {
|
|
608
|
+
const key = `${term.containerName || '_'}:${term.property}`;
|
|
609
|
+
const positiveValue = positiveContainerStyles.get(key);
|
|
610
|
+
if (positiveValue !== undefined) {
|
|
611
|
+
// We have a positive style(--prop: X) for this property
|
|
612
|
+
if (term.propertyValue === undefined) {
|
|
613
|
+
// Negating existence: not style(--prop)
|
|
614
|
+
// But we have style(--prop: X), which implies existence → contradiction
|
|
615
|
+
// This should have been caught by hasContainerStyleConflict
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
if (term.propertyValue !== positiveValue) {
|
|
619
|
+
// Negating a different value: not style(--prop: Y)
|
|
620
|
+
// We have style(--prop: X), which implies not style(--prop: Y)
|
|
621
|
+
// → This negation is redundant!
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
// Check modifier negations
|
|
627
|
+
if (term.type === 'modifier') {
|
|
628
|
+
const positiveValue = positiveModifiers.get(term.attribute);
|
|
629
|
+
if (positiveValue !== undefined && term.value !== undefined) {
|
|
630
|
+
// We have [attr="X"] and this is not [attr="Y"]
|
|
631
|
+
if (term.value !== positiveValue) {
|
|
632
|
+
// [attr="X"] implies not [attr="Y"] → redundant
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return true;
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
// ============================================================================
|
|
641
|
+
// Deduplication
|
|
642
|
+
// ============================================================================
|
|
643
|
+
function deduplicateTerms(terms) {
|
|
644
|
+
const seen = new Set();
|
|
645
|
+
const result = [];
|
|
646
|
+
for (const term of terms) {
|
|
647
|
+
const id = getConditionUniqueId(term);
|
|
648
|
+
if (!seen.has(id)) {
|
|
649
|
+
seen.add(id);
|
|
650
|
+
result.push(term);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return result;
|
|
654
|
+
}
|
|
655
|
+
// ============================================================================
|
|
656
|
+
// Range Merging
|
|
657
|
+
// ============================================================================
|
|
658
|
+
/**
|
|
659
|
+
* Merge compatible range conditions
|
|
660
|
+
* e.g., @media(w >= 400px) & @media(w <= 800px) → @media(400px <= w <= 800px)
|
|
661
|
+
*/
|
|
662
|
+
function mergeRanges(terms) {
|
|
663
|
+
// Group media conditions by dimension
|
|
664
|
+
const mediaByDim = new Map();
|
|
665
|
+
const containerByDim = new Map();
|
|
666
|
+
terms.forEach((term, index) => {
|
|
667
|
+
if (term.kind !== 'state')
|
|
668
|
+
return;
|
|
669
|
+
if (term.type === 'media' &&
|
|
670
|
+
term.subtype === 'dimension' &&
|
|
671
|
+
!term.negated) {
|
|
672
|
+
const key = term.dimension || 'width';
|
|
673
|
+
if (!mediaByDim.has(key)) {
|
|
674
|
+
mediaByDim.set(key, { conditions: [], indices: [] });
|
|
675
|
+
}
|
|
676
|
+
const group = mediaByDim.get(key);
|
|
677
|
+
group.conditions.push(term);
|
|
678
|
+
group.indices.push(index);
|
|
679
|
+
}
|
|
680
|
+
if (term.type === 'container' &&
|
|
681
|
+
term.subtype === 'dimension' &&
|
|
682
|
+
!term.negated) {
|
|
683
|
+
const key = `${term.containerName || '_'}:${term.dimension || 'width'}`;
|
|
684
|
+
if (!containerByDim.has(key)) {
|
|
685
|
+
containerByDim.set(key, { conditions: [], indices: [] });
|
|
686
|
+
}
|
|
687
|
+
const group = containerByDim.get(key);
|
|
688
|
+
group.conditions.push(term);
|
|
689
|
+
group.indices.push(index);
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
// Track indices to remove
|
|
693
|
+
const indicesToRemove = new Set();
|
|
694
|
+
const mergedTerms = [];
|
|
695
|
+
// Merge media conditions
|
|
696
|
+
for (const [dim, group] of mediaByDim) {
|
|
697
|
+
if (group.conditions.length > 1) {
|
|
698
|
+
const merged = mergeMediaRanges(group.conditions);
|
|
699
|
+
if (merged) {
|
|
700
|
+
group.indices.forEach((i) => indicesToRemove.add(i));
|
|
701
|
+
mergedTerms.push(merged);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
// Merge container conditions
|
|
706
|
+
for (const [, group] of containerByDim) {
|
|
707
|
+
if (group.conditions.length > 1) {
|
|
708
|
+
const merged = mergeContainerRanges(group.conditions);
|
|
709
|
+
if (merged) {
|
|
710
|
+
group.indices.forEach((i) => indicesToRemove.add(i));
|
|
711
|
+
mergedTerms.push(merged);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
// Build result
|
|
716
|
+
const result = [];
|
|
717
|
+
terms.forEach((term, index) => {
|
|
718
|
+
if (!indicesToRemove.has(index)) {
|
|
719
|
+
result.push(term);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
result.push(...mergedTerms);
|
|
723
|
+
return result;
|
|
724
|
+
}
|
|
725
|
+
function mergeMediaRanges(conditions) {
|
|
726
|
+
if (conditions.length === 0)
|
|
727
|
+
return null;
|
|
728
|
+
let lowerBound;
|
|
729
|
+
let upperBound;
|
|
730
|
+
for (const cond of conditions) {
|
|
731
|
+
if (cond.lowerBound) {
|
|
732
|
+
if (!lowerBound ||
|
|
733
|
+
(cond.lowerBound.valueNumeric ?? -Infinity) >
|
|
734
|
+
(lowerBound.valueNumeric ?? -Infinity)) {
|
|
735
|
+
lowerBound = cond.lowerBound;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (cond.upperBound) {
|
|
739
|
+
if (!upperBound ||
|
|
740
|
+
(cond.upperBound.valueNumeric ?? Infinity) <
|
|
741
|
+
(upperBound.valueNumeric ?? Infinity)) {
|
|
742
|
+
upperBound = cond.upperBound;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
const base = conditions[0];
|
|
747
|
+
// Build a merged condition
|
|
748
|
+
const merged = {
|
|
749
|
+
kind: 'state',
|
|
750
|
+
type: 'media',
|
|
751
|
+
subtype: 'dimension',
|
|
752
|
+
negated: false,
|
|
753
|
+
raw: buildMergedRaw(base.dimension || 'width', lowerBound, upperBound),
|
|
754
|
+
uniqueId: '', // Will be recalculated
|
|
755
|
+
dimension: base.dimension,
|
|
756
|
+
lowerBound,
|
|
757
|
+
upperBound,
|
|
758
|
+
};
|
|
759
|
+
// Recalculate uniqueId
|
|
760
|
+
const parts = ['media', 'dim', merged.dimension];
|
|
761
|
+
if (lowerBound) {
|
|
762
|
+
parts.push(lowerBound.inclusive ? '>=' : '>');
|
|
763
|
+
parts.push(lowerBound.value);
|
|
764
|
+
}
|
|
765
|
+
if (upperBound) {
|
|
766
|
+
parts.push(upperBound.inclusive ? '<=' : '<');
|
|
767
|
+
parts.push(upperBound.value);
|
|
768
|
+
}
|
|
769
|
+
merged.uniqueId = parts.join(':');
|
|
770
|
+
return merged;
|
|
771
|
+
}
|
|
772
|
+
function mergeContainerRanges(conditions) {
|
|
773
|
+
if (conditions.length === 0)
|
|
774
|
+
return null;
|
|
775
|
+
let lowerBound;
|
|
776
|
+
let upperBound;
|
|
777
|
+
for (const cond of conditions) {
|
|
778
|
+
if (cond.lowerBound) {
|
|
779
|
+
if (!lowerBound ||
|
|
780
|
+
(cond.lowerBound.valueNumeric ?? -Infinity) >
|
|
781
|
+
(lowerBound.valueNumeric ?? -Infinity)) {
|
|
782
|
+
lowerBound = cond.lowerBound;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (cond.upperBound) {
|
|
786
|
+
if (!upperBound ||
|
|
787
|
+
(cond.upperBound.valueNumeric ?? Infinity) <
|
|
788
|
+
(upperBound.valueNumeric ?? Infinity)) {
|
|
789
|
+
upperBound = cond.upperBound;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
const base = conditions[0];
|
|
794
|
+
const merged = {
|
|
795
|
+
kind: 'state',
|
|
796
|
+
type: 'container',
|
|
797
|
+
subtype: 'dimension',
|
|
798
|
+
negated: false,
|
|
799
|
+
raw: buildMergedRaw(base.dimension || 'width', lowerBound, upperBound),
|
|
800
|
+
uniqueId: '', // Will be recalculated
|
|
801
|
+
containerName: base.containerName,
|
|
802
|
+
dimension: base.dimension,
|
|
803
|
+
lowerBound,
|
|
804
|
+
upperBound,
|
|
805
|
+
};
|
|
806
|
+
// Recalculate uniqueId
|
|
807
|
+
const name = merged.containerName || '_';
|
|
808
|
+
const parts = ['container', 'dim', name, merged.dimension];
|
|
809
|
+
if (lowerBound) {
|
|
810
|
+
parts.push(lowerBound.inclusive ? '>=' : '>');
|
|
811
|
+
parts.push(lowerBound.value);
|
|
812
|
+
}
|
|
813
|
+
if (upperBound) {
|
|
814
|
+
parts.push(upperBound.inclusive ? '<=' : '<');
|
|
815
|
+
parts.push(upperBound.value);
|
|
816
|
+
}
|
|
817
|
+
merged.uniqueId = parts.join(':');
|
|
818
|
+
return merged;
|
|
819
|
+
}
|
|
820
|
+
function buildMergedRaw(dimension, lowerBound, upperBound) {
|
|
821
|
+
if (lowerBound && upperBound) {
|
|
822
|
+
const lowerOp = lowerBound.inclusive ? '<=' : '<';
|
|
823
|
+
const upperOp = upperBound.inclusive ? '<=' : '<';
|
|
824
|
+
return `@media(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;
|
|
825
|
+
}
|
|
826
|
+
else if (upperBound) {
|
|
827
|
+
const op = upperBound.inclusive ? '<=' : '<';
|
|
828
|
+
return `@media(${dimension} ${op} ${upperBound.value})`;
|
|
829
|
+
}
|
|
830
|
+
else if (lowerBound) {
|
|
831
|
+
const op = lowerBound.inclusive ? '>=' : '>';
|
|
832
|
+
return `@media(${dimension} ${op} ${lowerBound.value})`;
|
|
833
|
+
}
|
|
834
|
+
return '@media()';
|
|
835
|
+
}
|
|
836
|
+
// ============================================================================
|
|
837
|
+
// Sorting
|
|
838
|
+
// ============================================================================
|
|
839
|
+
function sortTerms(terms) {
|
|
840
|
+
return [...terms].sort((a, b) => {
|
|
841
|
+
const idA = getConditionUniqueId(a);
|
|
842
|
+
const idB = getConditionUniqueId(b);
|
|
843
|
+
return idA.localeCompare(idB);
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
// ============================================================================
|
|
847
|
+
// Absorption
|
|
848
|
+
// ============================================================================
|
|
849
|
+
/**
|
|
850
|
+
* Apply absorption law for AND: A & (A | B) → A
|
|
851
|
+
*/
|
|
852
|
+
function applyAbsorptionAnd(terms) {
|
|
853
|
+
// Collect all unique IDs of simple terms
|
|
854
|
+
const simpleIds = new Set();
|
|
855
|
+
for (const term of terms) {
|
|
856
|
+
if (term.kind !== 'compound') {
|
|
857
|
+
simpleIds.add(getConditionUniqueId(term));
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
// Filter out OR terms that are absorbed
|
|
861
|
+
return terms.filter((term) => {
|
|
862
|
+
if (term.kind === 'compound' && term.operator === 'OR') {
|
|
863
|
+
// If any child of this OR is in simpleIds, absorb the whole OR
|
|
864
|
+
for (const child of term.children) {
|
|
865
|
+
if (simpleIds.has(getConditionUniqueId(child))) {
|
|
866
|
+
return false; // Absorb
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return true;
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Apply absorption law for OR: A | (A & B) → A
|
|
875
|
+
*/
|
|
876
|
+
function applyAbsorptionOr(terms) {
|
|
877
|
+
// Collect all unique IDs of simple terms
|
|
878
|
+
const simpleIds = new Set();
|
|
879
|
+
for (const term of terms) {
|
|
880
|
+
if (term.kind !== 'compound') {
|
|
881
|
+
simpleIds.add(getConditionUniqueId(term));
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
// Filter out AND terms that are absorbed
|
|
885
|
+
return terms.filter((term) => {
|
|
886
|
+
if (term.kind === 'compound' && term.operator === 'AND') {
|
|
887
|
+
// If any child of this AND is in simpleIds, absorb the whole AND
|
|
888
|
+
for (const child of term.children) {
|
|
889
|
+
if (simpleIds.has(getConditionUniqueId(child))) {
|
|
890
|
+
return false; // Absorb
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
return true;
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
|