@cube-dev/ui-kit 0.161.0 → 0.163.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +74 -0
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Button/Button.js +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -2
- package/dist/components/actions/use-anchored-menu.js.map +1 -1
- package/dist/components/actions/use-context-menu.js +1 -2
- package/dist/components/actions/use-context-menu.js.map +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/Item/Item.js +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Text.d.ts +28 -28
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/TreeNode.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.js +1 -1
- package/dist/components/data/DataTable/DataTable.js +1 -1
- package/dist/components/data/ItemTable/ItemTable.js +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
- package/dist/components/data/ItemTable/ItemTableToolbar.js +1 -2
- package/dist/components/data/ItemTable/ItemTableToolbar.js.map +1 -1
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/RowCollection.js +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +1 -1
- package/dist/components/data/TableBase/TableRow.js +1 -1
- package/dist/components/data/TableBase/TableView.js +2 -2
- package/dist/components/data/TableBase/TableView.js.map +1 -1
- package/dist/components/data/TableBase/column-menu.js +1 -1
- package/dist/components/data/TableBase/column-tint.js +1 -1
- package/dist/components/data/TableBase/row-menu.js +1 -1
- package/dist/components/data/TableBase/styled.js +1 -1
- package/dist/components/data/TableBase/types.js +1 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-column-order.js +1 -1
- package/dist/components/data/TableBase/use-container-width.js +1 -1
- package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
- package/dist/components/data/TableBase/use-scrollability.js +1 -1
- package/dist/components/data/TableBase/use-table-columns.js +1 -1
- package/dist/components/data/TableBase/use-table-search.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +1 -1
- package/dist/components/fields/Checkbox/Checkbox.js +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ColorInput/ColorInput.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.js +1 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +1 -1
- package/dist/components/fields/ComboBox/ComboBox.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DatePicker.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.d.ts +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.js +39 -23
- package/dist/components/fields/DatePicker/PeriodPicker.js.map +1 -1
- package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
- package/dist/components/fields/DatePicker/YearPicker.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/period.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.js +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +1 -2
- package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +1 -2
- package/dist/components/fields/FilterPicker/FilterPicker.js.map +1 -1
- package/dist/components/fields/Input/Input.js +1 -1
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -4
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js.map +1 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -3
- package/dist/components/fields/Picker/Picker.js.map +1 -1
- package/dist/components/fields/RadioGroup/Radio.d.ts +31 -9
- package/dist/components/fields/RadioGroup/Radio.js +57 -14
- package/dist/components/fields/RadioGroup/Radio.js.map +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.js +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -3
- package/dist/components/fields/Slider/HueSlider.js.map +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/SliderBase.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +1 -1
- package/dist/components/fields/Switch/Switch.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/color/ColorPanel.js +1 -1
- package/dist/components/fields/color/ColorSwatch.js +1 -1
- package/dist/components/fields/color/channels.js +1 -1
- package/dist/components/fields/color/color.js +1 -1
- package/dist/components/fields/color/context.js +1 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/Form/Field.js +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/form/Form/SubmitError.js +1 -1
- package/dist/components/form/Form/index.js +1 -1
- package/dist/components/form/Form/use-field/use-field-props.js +1 -1
- package/dist/components/form/Form/use-field/use-field.js +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Board/Board.js +1 -1
- package/dist/components/layout/Board/BoardProvider.js +1 -1
- package/dist/components/layout/Board/BoardResponsive.js +1 -1
- package/dist/components/layout/Board/Widget.js +1 -1
- package/dist/components/layout/Board/WidgetHost.js +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-store.js +1 -1
- package/dist/components/layout/Board/grid-core/calculate.js +1 -1
- package/dist/components/layout/Board/grid-core/collision.js +1 -1
- package/dist/components/layout/Board/grid-core/compactors.js +1 -1
- package/dist/components/layout/Board/grid-core/constraints.js +1 -1
- package/dist/components/layout/Board/grid-core/group-move.js +1 -1
- package/dist/components/layout/Board/grid-core/layout.js +1 -1
- package/dist/components/layout/Board/grid-core/sort.js +1 -1
- package/dist/components/layout/Board/index.js +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +1 -1
- package/dist/components/layout/Board/use-board-registry.js +1 -1
- package/dist/components/layout/Board/use-board-select-modifier-key.js +1 -1
- package/dist/components/layout/Board/use-board-selection.js +1 -1
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Pagination/Pagination.js +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -2
- package/dist/components/navigation/Tabs/TabPicker.js.map +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +13 -43
- package/dist/components/other/Calendar/Calendar.js.map +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +10 -30
- package/dist/components/other/Calendar/CalendarCell.js.map +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +9 -5
- package/dist/components/other/Calendar/CalendarGrid.js.map +1 -1
- package/dist/components/other/Calendar/CalendarHeader.js +62 -0
- package/dist/components/other/Calendar/CalendarHeader.js.map +1 -0
- package/dist/components/other/Calendar/CalendarPanel.js +196 -0
- package/dist/components/other/Calendar/CalendarPanel.js.map +1 -0
- package/dist/components/other/Calendar/PeriodCalendar.js +160 -196
- package/dist/components/other/Calendar/PeriodCalendar.js.map +1 -1
- package/dist/components/other/Calendar/PeriodGrid.js +144 -0
- package/dist/components/other/Calendar/PeriodGrid.js.map +1 -0
- package/dist/components/other/Calendar/RangeCalendar.js +11 -40
- package/dist/components/other/Calendar/RangeCalendar.js.map +1 -1
- package/dist/components/other/Calendar/styled.js +64 -0
- package/dist/components/other/Calendar/styled.js.map +1 -0
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -2
- package/dist/components/overlays/Modal/Overlay.js.map +1 -1
- package/dist/components/overlays/Modal/Popover.js +11 -13
- package/dist/components/overlays/Modal/Popover.js.map +1 -1
- package/dist/components/overlays/Modal/Tray.js +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +1 -2
- package/dist/components/overlays/Notifications/OverlayContainer.js.map +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useToast.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +59 -30
- package/dist/data/item-themes.js.map +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +2006 -1970
- package/dist/eslint-plugin/defaults.generated.js.map +1 -1
- package/dist/eslint-plugin/index.d.ts +6 -0
- package/dist/eslint-plugin/index.js +9 -5
- package/dist/eslint-plugin/index.js.map +1 -1
- package/dist/eslint-plugin/rules/no-redundant-default-prop.d.ts +17 -0
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js +17 -11
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js.map +1 -1
- package/dist/eslint-plugin/types.d.ts +22 -3
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locales/de-DE/uikit.js +15 -2
- package/dist/i18n/locales/en-US/uikit.js +15 -2
- package/dist/i18n/locales/en-US/uikit.json.d.ts +14 -1
- package/dist/i18n/locales/es-ES/uikit.js +15 -2
- package/dist/i18n/locales/es-MX/uikit.js +15 -2
- package/dist/i18n/locales/fr-FR/uikit.js +15 -2
- package/dist/i18n/locales/it-IT/uikit.js +15 -2
- package/dist/i18n/locales/ja-JP/uikit.js +15 -2
- package/dist/i18n/locales/nb-NO/uikit.js +15 -2
- package/dist/i18n/locales/pt-BR/uikit.js +15 -2
- package/dist/i18n/locales/pt-PT/uikit.js +15 -2
- package/dist/i18n/locales/sv-SE/uikit.js +15 -2
- package/dist/i18n/locales/vi-VN/uikit.js +15 -2
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/ArrowNarrowDownIcon.js +1 -1
- package/dist/icons/ArrowNarrowUpIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PipetteIcon.js +1 -1
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.js +1 -1
- package/dist/probe/canonicalize.js +1 -1
- package/dist/probe/css.js +1 -1
- package/dist/probe/index.js +1 -1
- package/dist/provider.js +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/color-theme.js +1 -1
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.js +1 -1
- package/dist/tokens/palette.js +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/disabledProps.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useBufferedValue.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +2 -2
- package/docs/components/fields/PeriodPicker.md +44 -4
- package/docs/components/fields/RadioGroup.md +39 -5
- package/docs/components/other/Calendar.md +187 -0
- package/package.json +4 -1
|
@@ -1,227 +1,191 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
2
|
-
import { _Title } from "../../content/Title.js";
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.163.0 | Cube Dev Team */
|
|
3
2
|
import { useProviderProps } from "../../../provider.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useI18n } from "../../../i18n/useI18n.js";
|
|
4
|
+
import { getQuarter } from "../../fields/DatePicker/period.js";
|
|
5
|
+
import { CalendarElement } from "./styled.js";
|
|
6
|
+
import { CalendarHeader } from "./CalendarHeader.js";
|
|
7
|
+
import { PeriodGrid } from "./PeriodGrid.js";
|
|
8
|
+
import { useMemo, useState } from "react";
|
|
11
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
import { useDateFormatter
|
|
13
|
-
import { CalendarDate, getLocalTimeZone, today } from "@internationalized/date";
|
|
10
|
+
import { useDateFormatter } from "react-aria";
|
|
11
|
+
import { CalendarDate, endOfMonth, endOfYear, getLocalTimeZone, toCalendarDate, today } from "@internationalized/date";
|
|
14
12
|
|
|
15
13
|
//#region src/components/other/Calendar/PeriodCalendar.tsx
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const PeriodHeaderElement = tasty({ styles: {
|
|
22
|
-
display: "flex",
|
|
23
|
-
placeContent: "center space-between",
|
|
24
|
-
placeItems: "center",
|
|
25
|
-
gap: "1.5x"
|
|
26
|
-
} });
|
|
27
|
-
const PeriodGridElement = tasty({ styles: {
|
|
28
|
-
display: "grid",
|
|
29
|
-
gap: "1bw",
|
|
30
|
-
padding: ".5x top"
|
|
31
|
-
} });
|
|
32
|
-
const PeriodCellElement = tasty({
|
|
33
|
-
as: "button",
|
|
34
|
-
"data-popover-keep": true,
|
|
35
|
-
styles: {
|
|
36
|
-
preset: "t3m",
|
|
37
|
-
display: "grid",
|
|
38
|
-
placeItems: "center",
|
|
39
|
-
height: "5x",
|
|
40
|
-
padding: "1x",
|
|
41
|
-
border: 0,
|
|
42
|
-
fill: {
|
|
43
|
-
"": "#primary.0",
|
|
44
|
-
":hover": "#primary.16",
|
|
45
|
-
pressed: "#primary.10",
|
|
46
|
-
selected: "#primary",
|
|
47
|
-
"selected & :hover": "#primary",
|
|
48
|
-
disabled: "#primary.0"
|
|
49
|
-
},
|
|
50
|
-
color: {
|
|
51
|
-
"": "#dark",
|
|
52
|
-
outside: "#dark.30",
|
|
53
|
-
selected: "#white",
|
|
54
|
-
disabled: "#dark.30"
|
|
55
|
-
},
|
|
56
|
-
outline: {
|
|
57
|
-
"": "1bw #primary-text.0",
|
|
58
|
-
focused: "1bw #primary-text"
|
|
59
|
-
},
|
|
60
|
-
outlineOffset: .5,
|
|
61
|
-
radius: true,
|
|
62
|
-
cursor: {
|
|
63
|
-
"": "pointer",
|
|
64
|
-
disabled: "not-allowed"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
});
|
|
14
|
+
/** The year grid shows a decade plus one adjacent year on either side. */
|
|
15
|
+
const YEAR_CELLS = 12;
|
|
16
|
+
/** Explicit so the panel keeps one width across all three period views. */
|
|
17
|
+
const PERIOD_GRID_STYLES = { width: "28x" };
|
|
18
|
+
/** picker → grid columns */
|
|
68
19
|
const COLUMNS = {
|
|
69
20
|
month: 3,
|
|
70
21
|
quarter: 4,
|
|
71
22
|
year: 3
|
|
72
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* The panel behind `MonthPicker`, `QuarterPicker` and `YearPicker`. The month
|
|
26
|
+
* and quarter panels drill up into a year list, so reaching a distant year
|
|
27
|
+
* never means clicking the arrow a dozen times.
|
|
28
|
+
*/
|
|
73
29
|
function PeriodCalendar(props) {
|
|
30
|
+
const { t } = useI18n();
|
|
74
31
|
props = useProviderProps(props);
|
|
75
32
|
let { picker, value, onChange, minValue, maxValue, isDateUnavailable, isDisabled, autoFocus } = props;
|
|
76
|
-
let { locale } = useLocale();
|
|
77
33
|
let monthFormatter = useDateFormatter({
|
|
78
34
|
month: "short",
|
|
79
35
|
timeZone: "UTC"
|
|
80
36
|
});
|
|
81
|
-
let selected = value
|
|
82
|
-
let
|
|
83
|
-
let
|
|
84
|
-
let [
|
|
85
|
-
let
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
|
|
37
|
+
let selected = value ? toCalendarDate(value) : null;
|
|
38
|
+
let todayDate = useMemo(() => today(getLocalTimeZone()), []);
|
|
39
|
+
let [anchor, setAnchor] = useState(() => selected ?? todayDate);
|
|
40
|
+
let [isYearView, setIsYearView] = useState(false);
|
|
41
|
+
let [autoFocusGrid, setAutoFocusGrid] = useState(!!autoFocus);
|
|
42
|
+
let showYearView = (next) => {
|
|
43
|
+
setAutoFocusGrid(true);
|
|
44
|
+
setIsYearView(next);
|
|
45
|
+
};
|
|
46
|
+
let view = picker === "year" || isYearView ? "year" : picker;
|
|
47
|
+
let yearStart = (year) => new CalendarDate(year, 1, 1);
|
|
48
|
+
let isPeriodDisabled = (start, end) => {
|
|
89
49
|
if (isDisabled) return true;
|
|
90
|
-
if (minValue &&
|
|
91
|
-
if (maxValue &&
|
|
92
|
-
return isDateUnavailable?.(
|
|
50
|
+
if (minValue && end.compare(minValue) < 0) return true;
|
|
51
|
+
if (maxValue && start.compare(maxValue) > 0) return true;
|
|
52
|
+
return isDateUnavailable?.(start) ?? false;
|
|
53
|
+
};
|
|
54
|
+
/** Header for the month and quarter panels — the year drills up to a list. */
|
|
55
|
+
let renderYearHeader = () => {
|
|
56
|
+
let prevYear = anchor.year - 1;
|
|
57
|
+
let nextYear = anchor.year + 1;
|
|
58
|
+
return /* @__PURE__ */ jsx(CalendarHeader, {
|
|
59
|
+
segments: [{
|
|
60
|
+
key: "year",
|
|
61
|
+
label: String(anchor.year),
|
|
62
|
+
isDisabled,
|
|
63
|
+
onPress: () => showYearView(true)
|
|
64
|
+
}],
|
|
65
|
+
prevButtonProps: {
|
|
66
|
+
"aria-label": t("calendar.previousYear", "Previous year"),
|
|
67
|
+
isDisabled: isPeriodDisabled(yearStart(prevYear), endOfYear(yearStart(prevYear))),
|
|
68
|
+
onPress: () => setAnchor(anchor.subtract({ years: 1 }))
|
|
69
|
+
},
|
|
70
|
+
nextButtonProps: {
|
|
71
|
+
"aria-label": t("calendar.nextYear", "Next year"),
|
|
72
|
+
isDisabled: isPeriodDisabled(yearStart(nextYear), endOfYear(yearStart(nextYear))),
|
|
73
|
+
onPress: () => setAnchor(anchor.add({ years: 1 }))
|
|
74
|
+
}
|
|
75
|
+
});
|
|
93
76
|
};
|
|
94
|
-
let
|
|
95
|
-
if (picker
|
|
96
|
-
|
|
77
|
+
let onKeyDown = (e) => {
|
|
78
|
+
if (isYearView && picker !== "year" && e.key === "Escape") {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
e.stopPropagation();
|
|
81
|
+
showYearView(false);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
let cells;
|
|
85
|
+
let focusedIndex;
|
|
86
|
+
let gridLabel;
|
|
87
|
+
let header;
|
|
88
|
+
let onCellPress;
|
|
89
|
+
let onCellFocus;
|
|
90
|
+
let onMoveFocus;
|
|
91
|
+
let onMovePage;
|
|
92
|
+
if (view === "year") {
|
|
93
|
+
let decadeStart = Math.floor(anchor.year / 10) * 10;
|
|
94
|
+
let firstYear = decadeStart - 1;
|
|
95
|
+
cells = Array.from({ length: YEAR_CELLS }, (_, index) => {
|
|
96
|
+
let year = firstYear + index;
|
|
97
|
+
let date = yearStart(year);
|
|
97
98
|
return {
|
|
98
|
-
key: `
|
|
99
|
-
label:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
key: `year-${year}`,
|
|
100
|
+
label: String(year),
|
|
101
|
+
isSelected: selected?.year === year,
|
|
102
|
+
isCurrent: todayDate.year === year,
|
|
103
|
+
isOutside: year < decadeStart || year > decadeStart + 9,
|
|
104
|
+
isDisabled: isPeriodDisabled(date, endOfYear(date))
|
|
104
105
|
};
|
|
105
106
|
});
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
focusedIndex = anchor.year - firstYear;
|
|
108
|
+
gridLabel = t("calendar.years", "Years");
|
|
109
|
+
header = /* @__PURE__ */ jsx(CalendarHeader, {
|
|
110
|
+
title: `${decadeStart} – ${decadeStart + 9}`,
|
|
111
|
+
prevButtonProps: {
|
|
112
|
+
"aria-label": t("calendar.previousYears", "Previous years"),
|
|
113
|
+
isDisabled: isPeriodDisabled(yearStart(decadeStart - 10), endOfYear(yearStart(decadeStart - 1))),
|
|
114
|
+
onPress: () => setAnchor(anchor.subtract({ years: 10 }))
|
|
115
|
+
},
|
|
116
|
+
nextButtonProps: {
|
|
117
|
+
"aria-label": t("calendar.nextYears", "Next years"),
|
|
118
|
+
isDisabled: isPeriodDisabled(yearStart(decadeStart + 10), endOfYear(yearStart(decadeStart + 19))),
|
|
119
|
+
onPress: () => setAnchor(anchor.add({ years: 10 }))
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
onCellPress = (index) => {
|
|
123
|
+
let year = firstYear + index;
|
|
124
|
+
if (picker === "year") onChange?.(yearStart(year));
|
|
125
|
+
else {
|
|
126
|
+
setAnchor(anchor.set({ year }));
|
|
127
|
+
showYearView(false);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
onCellFocus = (index) => setAnchor(anchor.set({ year: firstYear + index }));
|
|
131
|
+
onMoveFocus = (delta) => setAnchor(anchor.add({ years: delta }));
|
|
132
|
+
onMovePage = (delta) => setAnchor(anchor.add({ years: delta * 10 }));
|
|
133
|
+
} else if (view === "quarter") {
|
|
134
|
+
let quarterDate = (quarter) => new CalendarDate(anchor.year, (quarter - 1) * 3 + 1, 1);
|
|
135
|
+
cells = Array.from({ length: 4 }, (_, index) => {
|
|
136
|
+
let quarter = index + 1;
|
|
137
|
+
let date = quarterDate(quarter);
|
|
108
138
|
return {
|
|
109
|
-
key: `
|
|
110
|
-
label: `Q${
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
isDisabled: isPeriodDisabled(date)
|
|
114
|
-
isOutside: false
|
|
139
|
+
key: `quarter-${quarter}`,
|
|
140
|
+
label: `Q${quarter}`,
|
|
141
|
+
isSelected: selected != null && selected.year === anchor.year && getQuarter(selected.month) === quarter,
|
|
142
|
+
isCurrent: todayDate.year === anchor.year && getQuarter(todayDate.month) === quarter,
|
|
143
|
+
isDisabled: isPeriodDisabled(date, endOfMonth(date.add({ months: 2 })))
|
|
115
144
|
};
|
|
116
145
|
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
146
|
+
focusedIndex = getQuarter(anchor.month) - 1;
|
|
147
|
+
gridLabel = t("calendar.quarters", "Quarters");
|
|
148
|
+
header = renderYearHeader();
|
|
149
|
+
onCellPress = (index) => onChange?.(quarterDate(index + 1));
|
|
150
|
+
onCellFocus = (index) => setAnchor(quarterDate(index + 1));
|
|
151
|
+
onMoveFocus = (delta) => setAnchor(anchor.add({ months: delta * 3 }));
|
|
152
|
+
onMovePage = (delta) => setAnchor(anchor.add({ years: delta }));
|
|
153
|
+
} else {
|
|
154
|
+
let monthDate = (month) => new CalendarDate(anchor.year, month, 1);
|
|
155
|
+
cells = Array.from({ length: 12 }, (_, index) => {
|
|
156
|
+
let month = index + 1;
|
|
157
|
+
let date = monthDate(month);
|
|
120
158
|
return {
|
|
121
|
-
key: `
|
|
122
|
-
label:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
isDisabled: isPeriodDisabled(date)
|
|
126
|
-
isOutside: year < decadeStart || year > decadeStart + 9
|
|
159
|
+
key: `month-${month}`,
|
|
160
|
+
label: monthFormatter.format(date.toDate("UTC")),
|
|
161
|
+
isSelected: selected != null && selected.year === anchor.year && selected.month === month,
|
|
162
|
+
isCurrent: todayDate.year === anchor.year && todayDate.month === month,
|
|
163
|
+
isDisabled: isPeriodDisabled(date, endOfMonth(date))
|
|
127
164
|
};
|
|
128
165
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
maxValue,
|
|
139
|
-
isDateUnavailable,
|
|
140
|
-
isDisabled
|
|
141
|
-
]);
|
|
142
|
-
let title = picker === "year" ? `${decadeStart}-${decadeStart + 9}` : String(focusedYear);
|
|
143
|
-
let cellRefs = useRef([]);
|
|
144
|
-
let [focusedIndex, setFocusedIndex] = useState(() => {
|
|
145
|
-
let idx = cells.findIndex((cell) => cell.isSelected);
|
|
146
|
-
return idx >= 0 ? idx : 0;
|
|
147
|
-
});
|
|
148
|
-
useEffect(() => {
|
|
149
|
-
if (autoFocus) cellRefs.current[focusedIndex]?.focus();
|
|
150
|
-
}, []);
|
|
151
|
-
let moveFocus = (index) => {
|
|
152
|
-
let clamped = Math.max(0, Math.min(cells.length - 1, index));
|
|
153
|
-
setFocusedIndex(clamped);
|
|
154
|
-
cellRefs.current[clamped]?.focus();
|
|
155
|
-
};
|
|
156
|
-
let onKeyDown = (e) => {
|
|
157
|
-
switch (e.key) {
|
|
158
|
-
case "ArrowRight":
|
|
159
|
-
moveFocus(focusedIndex + 1);
|
|
160
|
-
break;
|
|
161
|
-
case "ArrowLeft":
|
|
162
|
-
moveFocus(focusedIndex - 1);
|
|
163
|
-
break;
|
|
164
|
-
case "ArrowDown":
|
|
165
|
-
moveFocus(focusedIndex + cols);
|
|
166
|
-
break;
|
|
167
|
-
case "ArrowUp":
|
|
168
|
-
moveFocus(focusedIndex - cols);
|
|
169
|
-
break;
|
|
170
|
-
case "Home":
|
|
171
|
-
moveFocus(0);
|
|
172
|
-
break;
|
|
173
|
-
case "End":
|
|
174
|
-
moveFocus(cells.length - 1);
|
|
175
|
-
break;
|
|
176
|
-
default: return;
|
|
177
|
-
}
|
|
178
|
-
e.preventDefault();
|
|
179
|
-
};
|
|
180
|
-
return /* @__PURE__ */ jsxs(PeriodCalendarElement, { children: [/* @__PURE__ */ jsxs(PeriodHeaderElement, { children: [/* @__PURE__ */ jsx(_Title, {
|
|
181
|
-
level: 6,
|
|
182
|
-
preset: "h6",
|
|
183
|
-
children: title
|
|
184
|
-
}), /* @__PURE__ */ jsxs(Space, {
|
|
185
|
-
gap: ".5x",
|
|
186
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
187
|
-
"data-popover-keep": true,
|
|
188
|
-
size: "xsmall",
|
|
189
|
-
"aria-label": "Previous",
|
|
190
|
-
icon: /* @__PURE__ */ jsx(LeftIcon, {}),
|
|
191
|
-
isDisabled,
|
|
192
|
-
onPress: () => setFocusedYear((year) => year - step)
|
|
193
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
194
|
-
"data-popover-keep": true,
|
|
195
|
-
size: "xsmall",
|
|
196
|
-
"aria-label": "Next",
|
|
197
|
-
icon: /* @__PURE__ */ jsx(RightIcon, {}),
|
|
198
|
-
isDisabled,
|
|
199
|
-
onPress: () => setFocusedYear((year) => year + step)
|
|
200
|
-
})]
|
|
201
|
-
})] }), /* @__PURE__ */ jsx(PeriodGridElement, {
|
|
202
|
-
role: "grid",
|
|
203
|
-
styles: { gridColumns: `repeat(${cols}, 1fr)` },
|
|
166
|
+
focusedIndex = anchor.month - 1;
|
|
167
|
+
gridLabel = t("calendar.months", "Months");
|
|
168
|
+
header = renderYearHeader();
|
|
169
|
+
onCellPress = (index) => onChange?.(monthDate(index + 1));
|
|
170
|
+
onCellFocus = (index) => setAnchor(monthDate(index + 1));
|
|
171
|
+
onMoveFocus = (delta) => setAnchor(anchor.add({ months: delta }));
|
|
172
|
+
onMovePage = (delta) => setAnchor(anchor.add({ years: delta }));
|
|
173
|
+
}
|
|
174
|
+
return /* @__PURE__ */ jsxs(CalendarElement, {
|
|
204
175
|
onKeyDown,
|
|
205
|
-
children:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
onFocus: () => setFocusedIndex(i),
|
|
219
|
-
onClick: () => {
|
|
220
|
-
if (!cell.isDisabled) onChange?.(cell.date);
|
|
221
|
-
},
|
|
222
|
-
children: cell.label
|
|
223
|
-
}, cell.key))
|
|
224
|
-
})] });
|
|
176
|
+
children: [header, /* @__PURE__ */ jsx(PeriodGrid, {
|
|
177
|
+
autoFocus: autoFocusGrid,
|
|
178
|
+
"aria-label": gridLabel,
|
|
179
|
+
cells,
|
|
180
|
+
styles: PERIOD_GRID_STYLES,
|
|
181
|
+
columns: COLUMNS[view],
|
|
182
|
+
focusedIndex,
|
|
183
|
+
onCellPress,
|
|
184
|
+
onCellFocus,
|
|
185
|
+
onMoveFocus,
|
|
186
|
+
onMovePage
|
|
187
|
+
}, view)]
|
|
188
|
+
});
|
|
225
189
|
}
|
|
226
190
|
|
|
227
191
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PeriodCalendar.js","names":["Title"],"sources":["../../../../src/components/other/Calendar/PeriodCalendar.tsx"],"sourcesContent":["import { CalendarDate, getLocalTimeZone, today } from '@internationalized/date';\nimport { tasty } from '@tenphi/tasty';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { DateValue, useDateFormatter, useLocale } from 'react-aria';\n\nimport { LeftIcon, RightIcon } from '../../../icons';\nimport { useProviderProps } from '../../../provider';\nimport { Button } from '../../actions';\nimport { Title } from '../../content/Title';\nimport {\n getQuarter,\n PickerType,\n snapToPeriod,\n} from '../../fields/DatePicker/period';\nimport { Space } from '../../layout/Space';\n\nconst PeriodCalendarElement = tasty({\n styles: {\n padding: '1x',\n gap: '1x',\n width: 'min 30x',\n },\n});\n\nconst PeriodHeaderElement = tasty({\n styles: {\n display: 'flex',\n placeContent: 'center space-between',\n placeItems: 'center',\n gap: '1.5x',\n },\n});\n\nconst PeriodGridElement = tasty({\n styles: {\n display: 'grid',\n gap: '1bw',\n padding: '.5x top',\n },\n});\n\nconst PeriodCellElement = tasty({\n as: 'button',\n 'data-popover-keep': true,\n styles: {\n preset: 't3m',\n display: 'grid',\n placeItems: 'center',\n height: '5x',\n padding: '1x',\n border: 0,\n fill: {\n '': '#primary.0',\n ':hover': '#primary.16',\n pressed: '#primary.10',\n\n selected: '#primary',\n 'selected & :hover': '#primary',\n\n disabled: '#primary.0',\n },\n color: {\n '': '#dark',\n outside: '#dark.30',\n selected: '#white',\n disabled: '#dark.30',\n },\n outline: {\n '': '1bw #primary-text.0',\n focused: '1bw #primary-text',\n },\n outlineOffset: 0.5,\n radius: true,\n cursor: {\n '': 'pointer',\n disabled: 'not-allowed',\n },\n },\n});\n\n// picker → grid columns\nconst COLUMNS: Record<'month' | 'quarter' | 'year', number> = {\n month: 3,\n quarter: 4,\n year: 3,\n};\n\nexport interface CubePeriodCalendarProps {\n /** Which non-day period this panel selects. */\n picker: 'month' | 'quarter' | 'year';\n value?: DateValue | null;\n onChange?: (date: CalendarDate) => void;\n minValue?: DateValue | null;\n maxValue?: DateValue | null;\n isDateUnavailable?: (date: DateValue) => boolean;\n isDisabled?: boolean;\n autoFocus?: boolean;\n}\n\ninterface Cell {\n key: string;\n label: string;\n date: CalendarDate;\n isSelected: boolean;\n isDisabled: boolean;\n isOutside: boolean;\n}\n\nexport function PeriodCalendar(props: CubePeriodCalendarProps) {\n props = useProviderProps(props);\n\n let {\n picker,\n value,\n onChange,\n minValue,\n maxValue,\n isDateUnavailable,\n isDisabled,\n autoFocus,\n } = props;\n\n let { locale } = useLocale();\n let monthFormatter = useDateFormatter({ month: 'short', timeZone: 'UTC' });\n\n let selected = value ?? null;\n let selectedYear = selected?.year ?? null;\n let selectedMonth = selected?.month ?? null;\n\n let [focusedYear, setFocusedYear] = useState(\n () => selectedYear ?? today(getLocalTimeZone()).year,\n );\n\n let cols = COLUMNS[picker];\n let step = picker === 'year' ? 10 : 1;\n let decadeStart = Math.floor(focusedYear / 10) * 10;\n\n let isPeriodDisabled = (date: CalendarDate) => {\n if (isDisabled) return true;\n if (minValue && date.compare(snapToPeriod(minValue, picker, locale)) < 0) {\n return true;\n }\n if (maxValue && date.compare(snapToPeriod(maxValue, picker, locale)) > 0) {\n return true;\n }\n\n return isDateUnavailable?.(date) ?? false;\n };\n\n let cells = useMemo<Cell[]>(() => {\n if (picker === 'month') {\n return Array.from({ length: 12 }, (_, m) => {\n let date = new CalendarDate(focusedYear, m + 1, 1);\n\n return {\n key: `m-${m}`,\n label: monthFormatter.format(new Date(Date.UTC(2021, m, 15))),\n date,\n isSelected: selectedYear === focusedYear && selectedMonth === m + 1,\n isDisabled: isPeriodDisabled(date),\n isOutside: false,\n };\n });\n }\n\n if (picker === 'quarter') {\n return Array.from({ length: 4 }, (_, q) => {\n let date = new CalendarDate(focusedYear, q * 3 + 1, 1);\n\n return {\n key: `q-${q}`,\n label: `Q${q + 1}`,\n date,\n isSelected:\n selectedYear === focusedYear &&\n selectedMonth != null &&\n getQuarter(selectedMonth) === q + 1,\n isDisabled: isPeriodDisabled(date),\n isOutside: false,\n };\n });\n }\n\n // year: render 12 cells — one leading + a decade + one trailing.\n return Array.from({ length: 12 }, (_, i) => {\n let year = decadeStart - 1 + i;\n let date = new CalendarDate(year, 1, 1);\n\n return {\n key: `y-${year}`,\n label: String(year),\n date,\n isSelected: selectedYear === year,\n isDisabled: isPeriodDisabled(date),\n isOutside: year < decadeStart || year > decadeStart + 9,\n };\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n picker,\n focusedYear,\n decadeStart,\n selectedYear,\n selectedMonth,\n monthFormatter,\n locale,\n minValue,\n maxValue,\n isDateUnavailable,\n isDisabled,\n ]);\n\n let title =\n picker === 'year'\n ? `${decadeStart}-${decadeStart + 9}`\n : String(focusedYear);\n\n let cellRefs = useRef<Array<HTMLButtonElement | null>>([]);\n let [focusedIndex, setFocusedIndex] = useState(() => {\n let idx = cells.findIndex((cell) => cell.isSelected);\n\n return idx >= 0 ? idx : 0;\n });\n\n useEffect(() => {\n if (autoFocus) {\n cellRefs.current[focusedIndex]?.focus();\n }\n // Focus only on mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n let moveFocus = (index: number) => {\n let clamped = Math.max(0, Math.min(cells.length - 1, index));\n setFocusedIndex(clamped);\n cellRefs.current[clamped]?.focus();\n };\n\n let onKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n moveFocus(focusedIndex + 1);\n break;\n case 'ArrowLeft':\n moveFocus(focusedIndex - 1);\n break;\n case 'ArrowDown':\n moveFocus(focusedIndex + cols);\n break;\n case 'ArrowUp':\n moveFocus(focusedIndex - cols);\n break;\n case 'Home':\n moveFocus(0);\n break;\n case 'End':\n moveFocus(cells.length - 1);\n break;\n default:\n return;\n }\n e.preventDefault();\n };\n\n return (\n <PeriodCalendarElement>\n <PeriodHeaderElement>\n <Title level={6} preset=\"h6\">\n {title}\n </Title>\n <Space gap=\".5x\">\n <Button\n data-popover-keep\n size=\"xsmall\"\n aria-label=\"Previous\"\n icon={<LeftIcon />}\n isDisabled={isDisabled}\n onPress={() => setFocusedYear((year) => year - step)}\n />\n <Button\n data-popover-keep\n size=\"xsmall\"\n aria-label=\"Next\"\n icon={<RightIcon />}\n isDisabled={isDisabled}\n onPress={() => setFocusedYear((year) => year + step)}\n />\n </Space>\n </PeriodHeaderElement>\n <PeriodGridElement\n role=\"grid\"\n styles={{ gridColumns: `repeat(${cols}, 1fr)` }}\n onKeyDown={onKeyDown}\n >\n {cells.map((cell, i) => (\n <PeriodCellElement\n key={cell.key}\n ref={(el: HTMLButtonElement | null) => {\n cellRefs.current[i] = el;\n }}\n type=\"button\"\n tabIndex={i === focusedIndex ? 0 : -1}\n disabled={cell.isDisabled}\n aria-pressed={cell.isSelected}\n mods={{\n selected: cell.isSelected,\n outside: cell.isOutside,\n disabled: cell.isDisabled,\n }}\n onFocus={() => setFocusedIndex(i)}\n onClick={() => {\n if (!cell.isDisabled) onChange?.(cell.date);\n }}\n >\n {cell.label}\n </PeriodCellElement>\n ))}\n </PeriodGridElement>\n </PeriodCalendarElement>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PeriodCalendar.js","names":[],"sources":["../../../../src/components/other/Calendar/PeriodCalendar.tsx"],"sourcesContent":["import {\n CalendarDate,\n endOfMonth,\n endOfYear,\n getLocalTimeZone,\n toCalendarDate,\n today,\n} from '@internationalized/date';\nimport { KeyboardEvent, ReactElement, useMemo, useState } from 'react';\nimport { DateValue, useDateFormatter } from 'react-aria';\n\nimport { useI18n } from '../../../i18n';\nimport { useProviderProps } from '../../../provider';\nimport { getQuarter } from '../../fields/DatePicker/period';\n\nimport { CalendarHeader } from './CalendarHeader';\nimport { CubePeriodGridCell, PeriodGrid } from './PeriodGrid';\nimport { CalendarElement } from './styled';\n\n/** The year grid shows a decade plus one adjacent year on either side. */\nconst YEAR_CELLS = 12;\n\n/** Explicit so the panel keeps one width across all three period views. */\nconst PERIOD_GRID_STYLES = { width: '28x' } as const;\n\nexport type CubePeriodCalendarPicker = 'month' | 'quarter' | 'year';\n\n/** picker → grid columns */\nconst COLUMNS: Record<CubePeriodCalendarPicker, number> = {\n month: 3,\n quarter: 4,\n year: 3,\n};\n\nexport interface CubePeriodCalendarProps {\n /** Which non-day period this panel selects. */\n picker: CubePeriodCalendarPicker;\n value?: DateValue | null;\n onChange?: (date: CalendarDate) => void;\n minValue?: DateValue | null;\n maxValue?: DateValue | null;\n isDateUnavailable?: (date: DateValue) => boolean;\n isDisabled?: boolean;\n autoFocus?: boolean;\n}\n\n/**\n * The panel behind `MonthPicker`, `QuarterPicker` and `YearPicker`. The month\n * and quarter panels drill up into a year list, so reaching a distant year\n * never means clicking the arrow a dozen times.\n */\nexport function PeriodCalendar(props: CubePeriodCalendarProps) {\n const { t } = useI18n();\n\n props = useProviderProps(props);\n\n let {\n picker,\n value,\n onChange,\n minValue,\n maxValue,\n isDateUnavailable,\n isDisabled,\n autoFocus,\n } = props;\n\n let monthFormatter = useDateFormatter({ month: 'short', timeZone: 'UTC' });\n\n let selected = value ? toCalendarDate(value) : null;\n let todayDate = useMemo(() => today(getLocalTimeZone()), []);\n\n // A date inside the period the keyboard currently focuses. Drives both the\n // roving tab stop and which year / decade the panel shows.\n let [anchor, setAnchor] = useState<CalendarDate>(() => selected ?? todayDate);\n let [isYearView, setIsYearView] = useState(false);\n // Switching panels always moves focus into the new grid — the button the\n // user just pressed is gone by then.\n let [autoFocusGrid, setAutoFocusGrid] = useState(!!autoFocus);\n\n let showYearView = (next: boolean) => {\n setAutoFocusGrid(true);\n setIsYearView(next);\n };\n\n let view: CubePeriodCalendarPicker =\n picker === 'year' || isYearView ? 'year' : picker;\n\n let yearStart = (year: number) => new CalendarDate(year, 1, 1);\n\n let isPeriodDisabled = (start: CalendarDate, end: CalendarDate) => {\n if (isDisabled) return true;\n if (minValue && end.compare(minValue) < 0) return true;\n if (maxValue && start.compare(maxValue) > 0) return true;\n\n return isDateUnavailable?.(start) ?? false;\n };\n\n /** Header for the month and quarter panels — the year drills up to a list. */\n let renderYearHeader = () => {\n let prevYear = anchor.year - 1;\n let nextYear = anchor.year + 1;\n\n return (\n <CalendarHeader\n segments={[\n {\n key: 'year',\n label: String(anchor.year),\n isDisabled,\n onPress: () => showYearView(true),\n },\n ]}\n prevButtonProps={{\n 'aria-label': t('calendar.previousYear', 'Previous year'),\n isDisabled: isPeriodDisabled(\n yearStart(prevYear),\n endOfYear(yearStart(prevYear)),\n ),\n onPress: () => setAnchor(anchor.subtract({ years: 1 })),\n }}\n nextButtonProps={{\n 'aria-label': t('calendar.nextYear', 'Next year'),\n isDisabled: isPeriodDisabled(\n yearStart(nextYear),\n endOfYear(yearStart(nextYear)),\n ),\n onPress: () => setAnchor(anchor.add({ years: 1 })),\n }}\n />\n );\n };\n\n let onKeyDown = (e: KeyboardEvent) => {\n // The year list is a detour, so `Escape` returns to the period list rather\n // than closing the surrounding popover.\n if (isYearView && picker !== 'year' && e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n showYearView(false);\n }\n };\n\n let cells: CubePeriodGridCell[];\n let focusedIndex: number;\n let gridLabel: string;\n let header: ReactElement;\n let onCellPress: (index: number) => void;\n let onCellFocus: (index: number) => void;\n let onMoveFocus: (delta: number) => void;\n let onMovePage: (delta: -1 | 1) => void;\n\n if (view === 'year') {\n let decadeStart = Math.floor(anchor.year / 10) * 10;\n let firstYear = decadeStart - 1;\n\n cells = Array.from({ length: YEAR_CELLS }, (_, index) => {\n let year = firstYear + index;\n let date = yearStart(year);\n\n return {\n key: `year-${year}`,\n label: String(year),\n isSelected: selected?.year === year,\n isCurrent: todayDate.year === year,\n isOutside: year < decadeStart || year > decadeStart + 9,\n isDisabled: isPeriodDisabled(date, endOfYear(date)),\n };\n });\n\n focusedIndex = anchor.year - firstYear;\n gridLabel = t('calendar.years', 'Years');\n\n header = (\n <CalendarHeader\n title={`${decadeStart} – ${decadeStart + 9}`}\n prevButtonProps={{\n 'aria-label': t('calendar.previousYears', 'Previous years'),\n isDisabled: isPeriodDisabled(\n yearStart(decadeStart - 10),\n endOfYear(yearStart(decadeStart - 1)),\n ),\n onPress: () => setAnchor(anchor.subtract({ years: 10 })),\n }}\n nextButtonProps={{\n 'aria-label': t('calendar.nextYears', 'Next years'),\n isDisabled: isPeriodDisabled(\n yearStart(decadeStart + 10),\n endOfYear(yearStart(decadeStart + 19)),\n ),\n onPress: () => setAnchor(anchor.add({ years: 10 })),\n }}\n />\n );\n\n onCellPress = (index) => {\n let year = firstYear + index;\n\n if (picker === 'year') {\n onChange?.(yearStart(year));\n } else {\n setAnchor(anchor.set({ year }));\n showYearView(false);\n }\n };\n onCellFocus = (index) => setAnchor(anchor.set({ year: firstYear + index }));\n onMoveFocus = (delta) => setAnchor(anchor.add({ years: delta }));\n onMovePage = (delta) => setAnchor(anchor.add({ years: delta * 10 }));\n } else if (view === 'quarter') {\n let quarterDate = (quarter: number) =>\n new CalendarDate(anchor.year, (quarter - 1) * 3 + 1, 1);\n\n cells = Array.from({ length: 4 }, (_, index) => {\n let quarter = index + 1;\n let date = quarterDate(quarter);\n\n return {\n key: `quarter-${quarter}`,\n label: `Q${quarter}`,\n isSelected:\n selected != null &&\n selected.year === anchor.year &&\n getQuarter(selected.month) === quarter,\n isCurrent:\n todayDate.year === anchor.year &&\n getQuarter(todayDate.month) === quarter,\n isDisabled: isPeriodDisabled(date, endOfMonth(date.add({ months: 2 }))),\n };\n });\n\n focusedIndex = getQuarter(anchor.month) - 1;\n gridLabel = t('calendar.quarters', 'Quarters');\n header = renderYearHeader();\n\n onCellPress = (index) => onChange?.(quarterDate(index + 1));\n onCellFocus = (index) => setAnchor(quarterDate(index + 1));\n onMoveFocus = (delta) => setAnchor(anchor.add({ months: delta * 3 }));\n onMovePage = (delta) => setAnchor(anchor.add({ years: delta }));\n } else {\n let monthDate = (month: number) => new CalendarDate(anchor.year, month, 1);\n\n cells = Array.from({ length: 12 }, (_, index) => {\n let month = index + 1;\n let date = monthDate(month);\n\n return {\n key: `month-${month}`,\n label: monthFormatter.format(date.toDate('UTC')),\n isSelected:\n selected != null &&\n selected.year === anchor.year &&\n selected.month === month,\n isCurrent: todayDate.year === anchor.year && todayDate.month === month,\n isDisabled: isPeriodDisabled(date, endOfMonth(date)),\n };\n });\n\n focusedIndex = anchor.month - 1;\n gridLabel = t('calendar.months', 'Months');\n header = renderYearHeader();\n\n onCellPress = (index) => onChange?.(monthDate(index + 1));\n onCellFocus = (index) => setAnchor(monthDate(index + 1));\n onMoveFocus = (delta) => setAnchor(anchor.add({ months: delta }));\n onMovePage = (delta) => setAnchor(anchor.add({ years: delta }));\n }\n\n return (\n <CalendarElement onKeyDown={onKeyDown}>\n {header}\n <PeriodGrid\n // Remount per view so focus follows the user into the new grid.\n key={view}\n autoFocus={autoFocusGrid}\n aria-label={gridLabel}\n cells={cells}\n styles={PERIOD_GRID_STYLES}\n columns={COLUMNS[view]}\n focusedIndex={focusedIndex}\n onCellPress={onCellPress}\n onCellFocus={onCellFocus}\n onMoveFocus={onMoveFocus}\n onMovePage={onMovePage}\n />\n </CalendarElement>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.163.0 | Cube Dev Team */
|
|
2
|
+
import { CALENDAR_CELL_STYLES } from "./styled.js";
|
|
3
|
+
import { tasty } from "@tenphi/tasty";
|
|
4
|
+
import { useLayoutEffect, useRef } from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/components/other/Calendar/PeriodGrid.tsx
|
|
8
|
+
const PeriodGridElement = tasty({
|
|
9
|
+
as: "table",
|
|
10
|
+
role: "grid",
|
|
11
|
+
styles: {
|
|
12
|
+
borderCollapse: "collapse",
|
|
13
|
+
borderSpacing: 0,
|
|
14
|
+
tableLayout: "fixed"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
const PeriodGridCellElement = tasty({
|
|
18
|
+
as: "td",
|
|
19
|
+
role: "gridcell",
|
|
20
|
+
styles: {
|
|
21
|
+
margin: 0,
|
|
22
|
+
padding: "2bw right bottom"
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const PeriodGridButtonElement = tasty({
|
|
26
|
+
as: "button",
|
|
27
|
+
"data-popover-keep": true,
|
|
28
|
+
styles: {
|
|
29
|
+
...CALENDAR_CELL_STYLES,
|
|
30
|
+
width: "100%",
|
|
31
|
+
height: "4x",
|
|
32
|
+
padding: "0 .5x"
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* A keyboard-navigable grid of calendar periods (months, quarters or years).
|
|
37
|
+
*
|
|
38
|
+
* The grid owns rendering, the roving tab stop and DOM focus; the owner owns
|
|
39
|
+
* the periods themselves. Arrow keys that leave the page are reported through
|
|
40
|
+
* `onMoveFocus` so the owner can page and keep focus on the adjacent period.
|
|
41
|
+
*/
|
|
42
|
+
function PeriodGrid(props) {
|
|
43
|
+
let { cells, columns, focusedIndex, autoFocus, styles, onCellPress, onCellFocus, onMoveFocus, onMovePage } = props;
|
|
44
|
+
let cellRefs = useRef([]);
|
|
45
|
+
let shouldFocusRef = useRef(!!autoFocus);
|
|
46
|
+
let safeIndex = Math.max(0, Math.min(cells.length - 1, focusedIndex));
|
|
47
|
+
cellRefs.current.length = cells.length;
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
if (shouldFocusRef.current) {
|
|
50
|
+
shouldFocusRef.current = false;
|
|
51
|
+
cellRefs.current[safeIndex]?.focus();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
let moveFocus = (delta) => {
|
|
55
|
+
shouldFocusRef.current = true;
|
|
56
|
+
let next = safeIndex + delta;
|
|
57
|
+
while (next >= 0 && next < cells.length && cells[next].isDisabled) next += delta;
|
|
58
|
+
if (next < 0 || next >= cells.length) onMoveFocus(delta);
|
|
59
|
+
else onCellFocus(next);
|
|
60
|
+
};
|
|
61
|
+
let focusEdge = (edge) => {
|
|
62
|
+
let step = edge === "start" ? 1 : -1;
|
|
63
|
+
let index = edge === "start" ? 0 : cells.length - 1;
|
|
64
|
+
while (index >= 0 && index < cells.length && cells[index].isDisabled) index += step;
|
|
65
|
+
if (index < 0 || index >= cells.length) return;
|
|
66
|
+
shouldFocusRef.current = true;
|
|
67
|
+
onCellFocus(index);
|
|
68
|
+
};
|
|
69
|
+
let onKeyDown = (e) => {
|
|
70
|
+
switch (e.key) {
|
|
71
|
+
case "ArrowRight":
|
|
72
|
+
moveFocus(1);
|
|
73
|
+
break;
|
|
74
|
+
case "ArrowLeft":
|
|
75
|
+
moveFocus(-1);
|
|
76
|
+
break;
|
|
77
|
+
case "ArrowDown":
|
|
78
|
+
moveFocus(columns);
|
|
79
|
+
break;
|
|
80
|
+
case "ArrowUp":
|
|
81
|
+
moveFocus(-columns);
|
|
82
|
+
break;
|
|
83
|
+
case "Home":
|
|
84
|
+
focusEdge("start");
|
|
85
|
+
break;
|
|
86
|
+
case "End":
|
|
87
|
+
focusEdge("end");
|
|
88
|
+
break;
|
|
89
|
+
case "PageUp":
|
|
90
|
+
shouldFocusRef.current = true;
|
|
91
|
+
onMovePage(-1);
|
|
92
|
+
break;
|
|
93
|
+
case "PageDown":
|
|
94
|
+
shouldFocusRef.current = true;
|
|
95
|
+
onMovePage(1);
|
|
96
|
+
break;
|
|
97
|
+
default: return;
|
|
98
|
+
}
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
e.stopPropagation();
|
|
101
|
+
};
|
|
102
|
+
let rows = [];
|
|
103
|
+
for (let i = 0; i < cells.length; i += columns) rows.push(cells.slice(i, i + columns));
|
|
104
|
+
return /* @__PURE__ */ jsx(PeriodGridElement, {
|
|
105
|
+
"aria-label": props["aria-label"],
|
|
106
|
+
styles,
|
|
107
|
+
onKeyDown,
|
|
108
|
+
children: /* @__PURE__ */ jsx("tbody", {
|
|
109
|
+
"data-element": "Body",
|
|
110
|
+
children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", {
|
|
111
|
+
role: "row",
|
|
112
|
+
"data-element": "Row",
|
|
113
|
+
children: row.map((cell, columnIndex) => {
|
|
114
|
+
let index = rowIndex * columns + columnIndex;
|
|
115
|
+
return /* @__PURE__ */ jsx(PeriodGridCellElement, {
|
|
116
|
+
"aria-selected": !!cell.isSelected,
|
|
117
|
+
children: /* @__PURE__ */ jsx(PeriodGridButtonElement, {
|
|
118
|
+
ref: (element) => {
|
|
119
|
+
cellRefs.current[index] = element;
|
|
120
|
+
},
|
|
121
|
+
type: "button",
|
|
122
|
+
tabIndex: index === safeIndex ? 0 : -1,
|
|
123
|
+
disabled: cell.isDisabled,
|
|
124
|
+
"aria-label": cell.ariaLabel,
|
|
125
|
+
mods: {
|
|
126
|
+
selected: cell.isSelected,
|
|
127
|
+
current: cell.isCurrent,
|
|
128
|
+
outside: cell.isOutside,
|
|
129
|
+
disabled: cell.isDisabled
|
|
130
|
+
},
|
|
131
|
+
onFocus: () => onCellFocus(index),
|
|
132
|
+
onClick: () => onCellPress(index),
|
|
133
|
+
children: cell.label
|
|
134
|
+
})
|
|
135
|
+
}, cell.key);
|
|
136
|
+
})
|
|
137
|
+
}, rowIndex))
|
|
138
|
+
})
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
export { PeriodGrid };
|
|
144
|
+
//# sourceMappingURL=PeriodGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PeriodGrid.js","names":[],"sources":["../../../../src/components/other/Calendar/PeriodGrid.tsx"],"sourcesContent":["import { Styles, tasty } from '@tenphi/tasty';\nimport { KeyboardEvent, useLayoutEffect, useRef } from 'react';\n\nimport { CALENDAR_CELL_STYLES } from './styled';\n\nconst PeriodGridElement = tasty({\n as: 'table',\n role: 'grid',\n styles: {\n borderCollapse: 'collapse',\n borderSpacing: 0,\n // Columns share the width evenly. The owner passes that width explicitly —\n // a percentage here would resolve against the popover's `max-content` box.\n tableLayout: 'fixed',\n },\n});\n\nconst PeriodGridCellElement = tasty({\n as: 'td',\n role: 'gridcell',\n styles: {\n margin: 0,\n padding: '2bw right bottom',\n },\n});\n\nconst PeriodGridButtonElement = tasty({\n as: 'button',\n 'data-popover-keep': true,\n styles: {\n ...CALENDAR_CELL_STYLES,\n width: '100%',\n height: '4x',\n padding: '0 .5x',\n },\n});\n\nexport interface CubePeriodGridCell {\n /** Stable identity of the cell, also used as the React key. */\n key: string;\n label: string;\n /** Overrides the accessible name when the visible label is ambiguous. */\n ariaLabel?: string;\n isSelected?: boolean;\n /** Whether the cell contains today. */\n isCurrent?: boolean;\n isDisabled?: boolean;\n /** Whether the cell belongs to a neighbouring page (e.g. an adjacent decade). */\n isOutside?: boolean;\n}\n\nexport interface CubePeriodGridProps {\n cells: CubePeriodGridCell[];\n columns: number;\n /** Index of the cell that holds the roving tab stop. */\n focusedIndex: number;\n autoFocus?: boolean;\n 'aria-label'?: string;\n styles?: Styles;\n onCellPress: (index: number) => void;\n /** Focus moved to another cell of the current page. */\n onCellFocus: (index: number) => void;\n /**\n * Focus moved past the edge of the current page by `delta` periods. The owner\n * moves its anchor, which in turn flips the page and the focused index.\n */\n onMoveFocus: (delta: number) => void;\n /** `PageUp` / `PageDown` — one page back or forward. */\n onMovePage: (delta: -1 | 1) => void;\n}\n\n/**\n * A keyboard-navigable grid of calendar periods (months, quarters or years).\n *\n * The grid owns rendering, the roving tab stop and DOM focus; the owner owns\n * the periods themselves. Arrow keys that leave the page are reported through\n * `onMoveFocus` so the owner can page and keep focus on the adjacent period.\n */\nexport function PeriodGrid(props: CubePeriodGridProps) {\n let {\n cells,\n columns,\n focusedIndex,\n autoFocus,\n styles,\n onCellPress,\n onCellFocus,\n onMoveFocus,\n onMovePage,\n } = props;\n\n let cellRefs = useRef<Array<HTMLButtonElement | null>>([]);\n // Set by the grid's own keyboard handling and by `autoFocus`, so paging with\n // the header buttons never steals focus into the grid.\n let shouldFocusRef = useRef(!!autoFocus);\n\n let safeIndex = Math.max(0, Math.min(cells.length - 1, focusedIndex));\n\n cellRefs.current.length = cells.length;\n\n useLayoutEffect(() => {\n if (shouldFocusRef.current) {\n shouldFocusRef.current = false;\n cellRefs.current[safeIndex]?.focus();\n }\n });\n\n let moveFocus = (delta: number) => {\n shouldFocusRef.current = true;\n\n let next = safeIndex + delta;\n\n // Disabled cells can't hold DOM focus, so step over them instead of\n // stranding the caret on an unreachable period.\n while (next >= 0 && next < cells.length && cells[next].isDisabled) {\n next += delta;\n }\n\n if (next < 0 || next >= cells.length) {\n onMoveFocus(delta);\n } else {\n onCellFocus(next);\n }\n };\n\n let focusEdge = (edge: 'start' | 'end') => {\n let step = edge === 'start' ? 1 : -1;\n let index = edge === 'start' ? 0 : cells.length - 1;\n\n while (index >= 0 && index < cells.length && cells[index].isDisabled) {\n index += step;\n }\n\n if (index < 0 || index >= cells.length) return;\n\n shouldFocusRef.current = true;\n onCellFocus(index);\n };\n\n let onKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n moveFocus(1);\n break;\n case 'ArrowLeft':\n moveFocus(-1);\n break;\n case 'ArrowDown':\n moveFocus(columns);\n break;\n case 'ArrowUp':\n moveFocus(-columns);\n break;\n case 'Home':\n focusEdge('start');\n break;\n case 'End':\n focusEdge('end');\n break;\n case 'PageUp':\n shouldFocusRef.current = true;\n onMovePage(-1);\n break;\n case 'PageDown':\n shouldFocusRef.current = true;\n onMovePage(1);\n break;\n default:\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n };\n\n let rows: CubePeriodGridCell[][] = [];\n\n for (let i = 0; i < cells.length; i += columns) {\n rows.push(cells.slice(i, i + columns));\n }\n\n return (\n <PeriodGridElement\n aria-label={props['aria-label']}\n styles={styles}\n onKeyDown={onKeyDown}\n >\n <tbody data-element=\"Body\">\n {rows.map((row, rowIndex) => (\n <tr key={rowIndex} role=\"row\" data-element=\"Row\">\n {row.map((cell, columnIndex) => {\n let index = rowIndex * columns + columnIndex;\n\n return (\n <PeriodGridCellElement\n key={cell.key}\n aria-selected={!!cell.isSelected}\n >\n <PeriodGridButtonElement\n ref={(element: HTMLButtonElement | null) => {\n cellRefs.current[index] = element;\n }}\n type=\"button\"\n tabIndex={index === safeIndex ? 0 : -1}\n disabled={cell.isDisabled}\n aria-label={cell.ariaLabel}\n mods={{\n selected: cell.isSelected,\n current: cell.isCurrent,\n outside: cell.isOutside,\n disabled: cell.isDisabled,\n }}\n onFocus={() => onCellFocus(index)}\n onClick={() => onCellPress(index)}\n >\n {cell.label}\n </PeriodGridButtonElement>\n </PeriodGridCellElement>\n );\n })}\n </tr>\n ))}\n </tbody>\n </PeriodGridElement>\n );\n}\n"],"mappings":"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"}
|