@povio/ui 0.0.2 → 0.0.4
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/package.json +70 -9
- package/src/assets/icons/AlignCenter.tsx +16 -0
- package/src/assets/icons/AlignLeft.tsx +16 -0
- package/src/assets/icons/AlignLeftRight.tsx +16 -0
- package/src/assets/icons/AlignRight.tsx +16 -0
- package/src/assets/icons/ArrowDropDown.tsx +16 -0
- package/src/assets/icons/ArrowDropUp.tsx +16 -0
- package/src/assets/icons/ArrowLeft.tsx +16 -0
- package/src/assets/icons/ArrowRight.tsx +16 -0
- package/src/assets/icons/Bold.tsx +16 -0
- package/src/assets/icons/BulletedList.tsx +16 -0
- package/src/assets/icons/Calendar.tsx +18 -0
- package/src/assets/icons/Check.tsx +18 -0
- package/src/assets/icons/CheckCircle.tsx +16 -0
- package/src/assets/icons/CheckboxCheckmark.tsx +19 -0
- package/src/assets/icons/CheckboxIndeterminate.tsx +19 -0
- package/src/assets/icons/ChevronDown.tsx +18 -0
- package/src/assets/icons/ChevronLeft.tsx +18 -0
- package/src/assets/icons/ChevronRight.tsx +18 -0
- package/src/assets/icons/ChevronUp.tsx +18 -0
- package/src/assets/icons/ChevronsLeft.tsx +24 -0
- package/src/assets/icons/ChevronsRight.tsx +24 -0
- package/src/assets/icons/Clock.tsx +16 -0
- package/src/assets/icons/Close.tsx +16 -0
- package/src/assets/icons/DateTime.tsx +20 -0
- package/src/assets/icons/Drag.tsx +16 -0
- package/src/assets/icons/File.tsx +18 -0
- package/src/assets/icons/Highlight.tsx +16 -0
- package/src/assets/icons/HighlightOn.tsx +26 -0
- package/src/assets/icons/Info.tsx +24 -0
- package/src/assets/icons/Italic.tsx +16 -0
- package/src/assets/icons/Link.tsx +16 -0
- package/src/assets/icons/Menu.tsx +18 -0
- package/src/assets/icons/NumberedList.tsx +16 -0
- package/src/assets/icons/PointerHorizontal.tsx +16 -0
- package/src/assets/icons/PointerVertical.tsx +16 -0
- package/src/assets/icons/Send.tsx +18 -0
- package/src/assets/icons/Strikethrough.tsx +16 -0
- package/src/assets/icons/TextColor.tsx +24 -0
- package/src/assets/icons/Today.tsx +16 -0
- package/src/assets/icons/Underlined.tsx +18 -0
- package/src/assets/icons/Upload.tsx +20 -0
- package/src/assets/icons/View.tsx +16 -0
- package/src/assets/icons/ViewOff.tsx +16 -0
- package/src/assets/icons/Warningfilled.tsx +18 -0
- package/src/assets/locales/en/translation.json +156 -0
- package/src/assets/locales/sl/translation.json +152 -0
- package/src/components/Menu/Menu.tsx +29 -0
- package/src/components/Menu/MenuDesktop.tsx +68 -0
- package/src/components/Menu/MenuItem.tsx +33 -0
- package/src/components/Menu/MenuMobile.tsx +81 -0
- package/src/components/Menu/MenuPopover.tsx +45 -0
- package/src/components/buttons/Button/Button.tsx +108 -0
- package/src/components/buttons/Button/button.cva.ts +678 -0
- package/src/components/buttons/IconButton/IconButton.tsx +25 -0
- package/src/components/buttons/InlineIconButton/InlineIconButton.tsx +27 -0
- package/src/components/buttons/PillButton/PillButton.tsx +70 -0
- package/src/components/buttons/PillButton/pillButton.cva.ts +88 -0
- package/src/components/buttons/SplitButton/SplitButton.tsx +61 -0
- package/src/components/buttons/TextButton/TextButton.tsx +29 -0
- package/src/components/buttons/ToggleButton/ToggleButton.tsx +28 -0
- package/src/components/buttons/shared/ButtonContent.tsx +61 -0
- package/src/components/buttons/shared/buttonContent.cva.ts +18 -0
- package/src/components/inputs/Checkbox/Checkbox.tsx +101 -0
- package/src/components/inputs/Checkbox/CheckboxCheckmark.tsx +47 -0
- package/src/components/inputs/Checkbox/checkbox.cva.ts +51 -0
- package/src/components/inputs/DateTime/DatePicker/DatePicker.tsx +269 -0
- package/src/components/inputs/DateTime/DateRangePicker/DateRangePicker.tsx +808 -0
- package/src/components/inputs/DateTime/DateTimePicker/DateTimePicker.tsx +291 -0
- package/src/components/inputs/DateTime/TimePicker/TimePicker.tsx +255 -0
- package/src/components/inputs/DateTime/shared/Calendar.tsx +104 -0
- package/src/components/inputs/DateTime/shared/CalendarCell.tsx +247 -0
- package/src/components/inputs/DateTime/shared/CalendarGrid.tsx +102 -0
- package/src/components/inputs/DateTime/shared/CalendarHeader.tsx +110 -0
- package/src/components/inputs/DateTime/shared/CalendarSelectHeader.tsx +228 -0
- package/src/components/inputs/DateTime/shared/DateField.tsx +83 -0
- package/src/components/inputs/DateTime/shared/DatePickerInput.tsx +170 -0
- package/src/components/inputs/DateTime/shared/DateSegmentItem.tsx +65 -0
- package/src/components/inputs/DateTime/shared/DateTimeDialog.tsx +87 -0
- package/src/components/inputs/DateTime/shared/DateTimeDialogFooter.tsx +42 -0
- package/src/components/inputs/DateTime/shared/MonthPicker.tsx +91 -0
- package/src/components/inputs/DateTime/shared/RangeCalendar.tsx +160 -0
- package/src/components/inputs/DateTime/shared/TimeField.tsx +36 -0
- package/src/components/inputs/DateTime/shared/TimePickerForm.tsx +222 -0
- package/src/components/inputs/DateTime/shared/TimePickerInput.tsx +114 -0
- package/src/components/inputs/DateTime/shared/YearPicker.tsx +100 -0
- package/src/components/inputs/File/FileUpload.tsx +285 -0
- package/src/components/inputs/File/FileUploadContainer.tsx +16 -0
- package/src/components/inputs/File/InputUpload.tsx +196 -0
- package/src/components/inputs/File/fileUpload.types.ts +100 -0
- package/src/components/inputs/File/index.ts +15 -0
- package/src/components/inputs/File/inputUpload.types.ts +41 -0
- package/src/components/inputs/File/shared/FileCard.tsx +72 -0
- package/src/components/inputs/File/shared/FileCardList.tsx +30 -0
- package/src/components/inputs/File/shared/FileProgressBar.tsx +25 -0
- package/src/components/inputs/File/shared/FileUploadContent.tsx +99 -0
- package/src/components/inputs/File/shared/FileUploadContentEmpty.tsx +94 -0
- package/src/components/inputs/File/shared/FileUploadContentError.tsx +170 -0
- package/src/components/inputs/File/shared/FileUploadContentFilled.tsx +179 -0
- package/src/components/inputs/File/shared/FileUploadContentLoading.tsx +115 -0
- package/src/components/inputs/File/shared/InputUploadContent.tsx +68 -0
- package/src/components/inputs/File/shared/InputUploadFilled.tsx +32 -0
- package/src/components/inputs/File/shared/fileUpload.cva.ts +59 -0
- package/src/components/inputs/File/shared/inputUploadButton.cva.ts +48 -0
- package/src/components/inputs/FormField/FormField.tsx +69 -0
- package/src/components/inputs/FormField/FormFieldError.tsx +21 -0
- package/src/components/inputs/FormField/FormFieldHeader.tsx +75 -0
- package/src/components/inputs/FormField/FormFieldHeaderClose.tsx +23 -0
- package/src/components/inputs/FormField/FormFieldLabel.tsx +41 -0
- package/src/components/inputs/Input/NumberInput/NumberInput.tsx +180 -0
- package/src/components/inputs/Input/PasswordInput/PasswordInput.tsx +34 -0
- package/src/components/inputs/Input/TextArea/TextArea.tsx +166 -0
- package/src/components/inputs/Input/TextInput/TextInput.tsx +181 -0
- package/src/components/inputs/Input/shared/InputContent.tsx +154 -0
- package/src/components/inputs/Inputs/Form.tsx +129 -0
- package/src/components/inputs/Inputs/InputItem.tsx +127 -0
- package/src/components/inputs/Inputs/Inputs.tsx +43 -0
- package/src/components/inputs/RadioGroup/RadioGroup.tsx +139 -0
- package/src/components/inputs/RadioGroup/radio.cva.ts +51 -0
- package/src/components/inputs/Selection/Autocomplete/Autocomplete.tsx +61 -0
- package/src/components/inputs/Selection/Autocomplete/QueryAutocomplete.tsx +58 -0
- package/src/components/inputs/Selection/Select/Select.tsx +59 -0
- package/src/components/inputs/Selection/shared/SelectBase.tsx +69 -0
- package/src/components/inputs/Selection/shared/SelectDesktop.tsx +236 -0
- package/src/components/inputs/Selection/shared/SelectInput.tsx +278 -0
- package/src/components/inputs/Selection/shared/SelectListBox.tsx +121 -0
- package/src/components/inputs/Selection/shared/SelectListBoxItem.tsx +79 -0
- package/src/components/inputs/Selection/shared/SelectListBoxItemSelectAll.tsx +40 -0
- package/src/components/inputs/Selection/shared/SelectListBoxLoadingItem.tsx +52 -0
- package/src/components/inputs/Selection/shared/SelectListBoxSelectionBar.tsx +39 -0
- package/src/components/inputs/Selection/shared/SelectMobile.tsx +169 -0
- package/src/components/inputs/Selection/shared/select.context.tsx +316 -0
- package/src/components/inputs/Selection/shared/select.types.ts +75 -0
- package/src/components/inputs/Selection/shared/useSelectItems.tsx +127 -0
- package/src/components/inputs/Slider/Slider.tsx +174 -0
- package/src/components/inputs/TextEditor/TextEditor.tsx +239 -0
- package/src/components/inputs/TextEditor/Toolbar/ColorPicker.tsx +34 -0
- package/src/components/inputs/TextEditor/Toolbar/ColorPickerDropdown.tsx +74 -0
- package/src/components/inputs/TextEditor/Toolbar/HyperlinkAction.tsx +87 -0
- package/src/components/inputs/TextEditor/Toolbar/TextAlignSelect.tsx +64 -0
- package/src/components/inputs/TextEditor/Toolbar/TextColorSelect.tsx +30 -0
- package/src/components/inputs/TextEditor/Toolbar/TextEditorToolbar.tsx +40 -0
- package/src/components/inputs/TextEditor/Toolbar/TextHighlightSelect.tsx +39 -0
- package/src/components/inputs/TextEditor/Toolbar/TextListActions.tsx +57 -0
- package/src/components/inputs/TextEditor/Toolbar/TextMarksActions.tsx +79 -0
- package/src/components/inputs/TextEditor/Toolbar/TextStyleSelect.tsx +73 -0
- package/src/components/inputs/TextEditor/textEditor.types.ts +43 -0
- package/src/components/inputs/Toggle/Toggle.tsx +80 -0
- package/src/components/inputs/Toggle/toggle.cva.ts +48 -0
- package/src/components/inputs/shared/CheckContent.tsx +26 -0
- package/src/components/inputs/shared/InputClear.tsx +29 -0
- package/src/components/inputs/shared/form.types.ts +28 -0
- package/src/components/inputs/shared/input.cva.ts +182 -0
- package/src/components/inputs/shared/label.cva.ts +146 -0
- package/src/components/outline.clsx.ts +9 -0
- package/src/components/overlays/ActionModal/ActionModal.tsx +93 -0
- package/src/components/overlays/BottomSheet/BottomSheet.tsx +270 -0
- package/src/components/overlays/Drawer/Drawer.tsx +93 -0
- package/src/components/overlays/Modal/Modal.tsx +63 -0
- package/src/components/overlays/Modal/modal.cva.ts +55 -0
- package/src/components/overlays/ResponsivePopover/ResponsivePopover.tsx +77 -0
- package/src/components/overlays/Tooltip/Tooltip.tsx +47 -0
- package/src/components/overlays/Tooltip/TooltipEllipsis.tsx +35 -0
- package/src/components/segment/Segment.tsx +121 -0
- package/src/components/segment/SegmentItem.tsx +41 -0
- package/src/components/segment/segment.types.ts +44 -0
- package/src/components/shared/pagination/Pagination.tsx +75 -0
- package/src/components/shared/pagination/PaginationList.tsx +174 -0
- package/src/components/shared/pagination/minWidth.cva.ts +13 -0
- package/src/components/status/Alert/Alert.tsx +58 -0
- package/src/components/status/Alert/alert.cva.ts +66 -0
- package/src/components/status/Loader/Loader.tsx +32 -0
- package/src/components/status/Loader/loader.cva.ts +29 -0
- package/src/components/status/Toast/Toast.tsx +86 -0
- package/src/components/status/Toast/toast.cva.ts +154 -0
- package/src/components/status/Toast/useToast.tsx +77 -0
- package/src/components/status/shared/status.cva.ts +60 -0
- package/src/components/table/CellText.tsx +23 -0
- package/src/components/table/ColumnConfig.tsx +145 -0
- package/src/components/table/HeaderText.tsx +18 -0
- package/src/components/table/InfiniteTable.tsx +51 -0
- package/src/components/table/PaginatedTable.tsx +38 -0
- package/src/components/table/Table.tsx +456 -0
- package/src/components/table/table.cva.ts +47 -0
- package/src/components/text/Link/Link.tsx +21 -0
- package/src/components/text/Link/link.cva.ts +21 -0
- package/src/components/text/Tag/Tag.tsx +59 -0
- package/src/components/text/Tag/tag.cva.ts +62 -0
- package/src/components/text/Typography/Typography.tsx +33 -0
- package/src/components/text/Typography/typography.cva.ts +102 -0
- package/src/config/confirmation.context.tsx +133 -0
- package/src/config/i18n.ts +12 -0
- package/src/config/router.context.tsx +66 -0
- package/src/config/uiConfig.context.tsx +89 -0
- package/src/config/uiStyle.context.tsx +100 -0
- package/src/helpers/dynamicColumns.ts +567 -0
- package/src/helpers/dynamicInputs.ts +392 -0
- package/src/hooks/useAutosave.ts +109 -0
- package/src/hooks/useBreakpoint.ts +26 -0
- package/src/hooks/useDebounceCallback.ts +35 -0
- package/src/hooks/useDeepCompare.ts +27 -0
- package/src/hooks/useFilters.ts +154 -0
- package/src/hooks/useForm.ts +54 -0
- package/src/hooks/useFormAutosave.ts +100 -0
- package/src/hooks/useIntersectionObserver.ts +33 -0
- package/src/hooks/useLocalStorage.ts +81 -0
- package/src/hooks/useLongPressRepeat.ts +40 -0
- package/src/hooks/usePagination.ts +41 -0
- package/src/hooks/useScrollableListBox.ts +35 -0
- package/src/hooks/useSingletonMutation.ts +30 -0
- package/src/hooks/useSorting.ts +39 -0
- package/src/hooks/useStateAndRef.ts +20 -0
- package/src/hooks/useTableColumnConfig.ts +86 -0
- package/src/hooks/useTableNav.ts +615 -0
- package/src/hooks/useTranslationMemo.ts +17 -0
- package/src/index.ts +252 -0
- package/src/types/{common.d.ts → common.ts} +15 -4
- package/src/types/i18next.d.ts +11 -0
- package/src/types/react-query.ts +48 -0
- package/src/types/table.d.ts +17 -0
- package/src/utils/array.utils.spec.ts +16 -0
- package/src/utils/array.utils.ts +9 -0
- package/src/utils/compoundMapper.spec.ts +91 -0
- package/src/utils/compoundMapper.ts +42 -0
- package/src/utils/date-time.utils.spec.ts +48 -0
- package/src/utils/date-time.utils.ts +85 -0
- package/src/utils/date.utils.spec.ts +12 -0
- package/src/utils/date.utils.ts +9 -0
- package/src/utils/dom.utils.ts +16 -0
- package/src/utils/file.utils.ts +73 -0
- package/src/utils/isEqual.ts +153 -0
- package/src/utils/logger.ts +19 -0
- package/src/utils/object.utils.ts +62 -0
- package/src/utils/queries.utils.ts +10 -0
- package/src/utils/rest/interceptors/logging.interceptor.ts +16 -0
- package/src/utils/rest/interceptors/response.interceptor.ts +27 -0
- package/src/utils/rest/interceptors/rest-interceptor.ts +22 -0
- package/src/utils/rest/rest-client.ts +125 -0
- package/src/utils/rest/rest.utils.ts +65 -0
- package/src/utils/routing.utils.ts +12 -0
- package/src/utils/string.utils.ts +9 -0
- package/src/utils/vendor/error-handling.ts +170 -0
- package/src/utils/zod.utils.ts +95 -0
- package/index.js +0 -61206
- package/povio-ui-0.0.2.tgz +0 -0
- package/src/assets/icons/AlignCenter.d.ts +0 -2
- package/src/assets/icons/AlignLeft.d.ts +0 -2
- package/src/assets/icons/AlignLeftRight.d.ts +0 -2
- package/src/assets/icons/AlignRight.d.ts +0 -2
- package/src/assets/icons/ArrowDropDown.d.ts +0 -2
- package/src/assets/icons/ArrowDropUp.d.ts +0 -2
- package/src/assets/icons/ArrowLeft.d.ts +0 -2
- package/src/assets/icons/ArrowRight.d.ts +0 -2
- package/src/assets/icons/Bold.d.ts +0 -2
- package/src/assets/icons/BulletedList.d.ts +0 -2
- package/src/assets/icons/Calendar.d.ts +0 -2
- package/src/assets/icons/Check.d.ts +0 -2
- package/src/assets/icons/CheckCircle.d.ts +0 -2
- package/src/assets/icons/CheckboxCheckmark.d.ts +0 -2
- package/src/assets/icons/CheckboxIndeterminate.d.ts +0 -2
- package/src/assets/icons/ChevronDown.d.ts +0 -2
- package/src/assets/icons/ChevronLeft.d.ts +0 -2
- package/src/assets/icons/ChevronRight.d.ts +0 -2
- package/src/assets/icons/ChevronUp.d.ts +0 -2
- package/src/assets/icons/ChevronsLeft.d.ts +0 -2
- package/src/assets/icons/ChevronsRight.d.ts +0 -2
- package/src/assets/icons/Clock.d.ts +0 -2
- package/src/assets/icons/Close.d.ts +0 -2
- package/src/assets/icons/DateTime.d.ts +0 -2
- package/src/assets/icons/Drag.d.ts +0 -2
- package/src/assets/icons/File.d.ts +0 -2
- package/src/assets/icons/Highlight.d.ts +0 -2
- package/src/assets/icons/HighlightOn.d.ts +0 -6
- package/src/assets/icons/Info.d.ts +0 -2
- package/src/assets/icons/Italic.d.ts +0 -2
- package/src/assets/icons/Link.d.ts +0 -2
- package/src/assets/icons/Menu.d.ts +0 -2
- package/src/assets/icons/NumberedList.d.ts +0 -2
- package/src/assets/icons/PointerHorizontal.d.ts +0 -2
- package/src/assets/icons/PointerVertical.d.ts +0 -2
- package/src/assets/icons/Send.d.ts +0 -2
- package/src/assets/icons/Strikethrough.d.ts +0 -2
- package/src/assets/icons/TextColor.d.ts +0 -6
- package/src/assets/icons/Today.d.ts +0 -2
- package/src/assets/icons/Underlined.d.ts +0 -2
- package/src/assets/icons/Upload.d.ts +0 -2
- package/src/assets/icons/View.d.ts +0 -2
- package/src/assets/icons/ViewOff.d.ts +0 -2
- package/src/assets/icons/Warningfilled.d.ts +0 -2
- package/src/components/Menu/Menu.d.ts +0 -14
- package/src/components/Menu/MenuDesktop.d.ts +0 -2
- package/src/components/Menu/MenuItem.d.ts +0 -5
- package/src/components/Menu/MenuMobile.d.ts +0 -2
- package/src/components/Menu/MenuPopover.d.ts +0 -5
- package/src/components/buttons/Button/Button.d.ts +0 -27
- package/src/components/buttons/Button/button.cva.d.ts +0 -30
- package/src/components/buttons/IconButton/IconButton.d.ts +0 -10
- package/src/components/buttons/InlineIconButton/InlineIconButton.d.ts +0 -11
- package/src/components/buttons/PillButton/PillButton.d.ts +0 -11
- package/src/components/buttons/PillButton/pillButton.cva.d.ts +0 -14
- package/src/components/buttons/SplitButton/SplitButton.d.ts +0 -10
- package/src/components/buttons/TextButton/TextButton.d.ts +0 -11
- package/src/components/buttons/ToggleButton/ToggleButton.d.ts +0 -9
- package/src/components/buttons/shared/ButtonContent.d.ts +0 -16
- package/src/components/buttons/shared/buttonContent.cva.d.ts +0 -6
- package/src/components/inputs/Checkbox/Checkbox.d.ts +0 -17
- package/src/components/inputs/Checkbox/CheckboxCheckmark.d.ts +0 -9
- package/src/components/inputs/Checkbox/checkbox.cva.d.ts +0 -11
- package/src/components/inputs/DateTime/DatePicker/DatePicker.d.ts +0 -24
- package/src/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +0 -32
- package/src/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +0 -22
- package/src/components/inputs/DateTime/TimePicker/TimePicker.d.ts +0 -20
- package/src/components/inputs/DateTime/shared/Calendar.d.ts +0 -20
- package/src/components/inputs/DateTime/shared/CalendarCell.d.ts +0 -20
- package/src/components/inputs/DateTime/shared/CalendarGrid.d.ts +0 -25
- package/src/components/inputs/DateTime/shared/CalendarHeader.d.ts +0 -16
- package/src/components/inputs/DateTime/shared/CalendarSelectHeader.d.ts +0 -17
- package/src/components/inputs/DateTime/shared/DateField.d.ts +0 -12
- package/src/components/inputs/DateTime/shared/DatePickerInput.d.ts +0 -20
- package/src/components/inputs/DateTime/shared/DateSegmentItem.d.ts +0 -11
- package/src/components/inputs/DateTime/shared/DateTimeDialog.d.ts +0 -15
- package/src/components/inputs/DateTime/shared/DateTimeDialogFooter.d.ts +0 -7
- package/src/components/inputs/DateTime/shared/MonthPicker.d.ts +0 -7
- package/src/components/inputs/DateTime/shared/RangeCalendar.d.ts +0 -26
- package/src/components/inputs/DateTime/shared/TimeField.d.ts +0 -12
- package/src/components/inputs/DateTime/shared/TimePickerForm.d.ts +0 -10
- package/src/components/inputs/DateTime/shared/TimePickerInput.d.ts +0 -18
- package/src/components/inputs/DateTime/shared/YearPicker.d.ts +0 -8
- package/src/components/inputs/File/FileUpload.d.ts +0 -4
- package/src/components/inputs/File/FileUploadContainer.d.ts +0 -3
- package/src/components/inputs/File/InputUpload.d.ts +0 -4
- package/src/components/inputs/File/fileUpload.types.d.ts +0 -79
- package/src/components/inputs/File/index.d.ts +0 -9
- package/src/components/inputs/File/inputUpload.types.d.ts +0 -30
- package/src/components/inputs/File/shared/FileCard.d.ts +0 -9
- package/src/components/inputs/File/shared/FileCardList.d.ts +0 -9
- package/src/components/inputs/File/shared/FileProgressBar.d.ts +0 -3
- package/src/components/inputs/File/shared/FileUploadContent.d.ts +0 -10
- package/src/components/inputs/File/shared/FileUploadContentEmpty.d.ts +0 -9
- package/src/components/inputs/File/shared/FileUploadContentError.d.ts +0 -11
- package/src/components/inputs/File/shared/FileUploadContentFilled.d.ts +0 -11
- package/src/components/inputs/File/shared/FileUploadContentLoading.d.ts +0 -9
- package/src/components/inputs/File/shared/InputUploadContent.d.ts +0 -8
- package/src/components/inputs/File/shared/InputUploadFilled.d.ts +0 -7
- package/src/components/inputs/File/shared/fileUpload.cva.d.ts +0 -11
- package/src/components/inputs/File/shared/inputUploadButton.cva.d.ts +0 -10
- package/src/components/inputs/FormField/FormField.d.ts +0 -17
- package/src/components/inputs/FormField/FormFieldError.d.ts +0 -7
- package/src/components/inputs/FormField/FormFieldHeader.d.ts +0 -14
- package/src/components/inputs/FormField/FormFieldHeaderClose.d.ts +0 -5
- package/src/components/inputs/FormField/FormFieldLabel.d.ts +0 -11
- package/src/components/inputs/Input/NumberInput/NumberInput.d.ts +0 -18
- package/src/components/inputs/Input/PasswordInput/PasswordInput.d.ts +0 -7
- package/src/components/inputs/Input/TextArea/TextArea.d.ts +0 -17
- package/src/components/inputs/Input/TextInput/TextInput.d.ts +0 -19
- package/src/components/inputs/Input/shared/InputContent.d.ts +0 -27
- package/src/components/inputs/Inputs/Form.d.ts +0 -26
- package/src/components/inputs/Inputs/InputItem.d.ts +0 -73
- package/src/components/inputs/Inputs/Inputs.d.ts +0 -10
- package/src/components/inputs/RadioGroup/RadioGroup.d.ts +0 -18
- package/src/components/inputs/RadioGroup/radio.cva.d.ts +0 -11
- package/src/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +0 -8
- package/src/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +0 -19
- package/src/components/inputs/Selection/Select/Select.d.ts +0 -8
- package/src/components/inputs/Selection/shared/SelectBase.d.ts +0 -24
- package/src/components/inputs/Selection/shared/SelectDesktop.d.ts +0 -5
- package/src/components/inputs/Selection/shared/SelectInput.d.ts +0 -15
- package/src/components/inputs/Selection/shared/SelectListBox.d.ts +0 -9
- package/src/components/inputs/Selection/shared/SelectListBoxItem.d.ts +0 -8
- package/src/components/inputs/Selection/shared/SelectListBoxItemSelectAll.d.ts +0 -4
- package/src/components/inputs/Selection/shared/SelectListBoxLoadingItem.d.ts +0 -6
- package/src/components/inputs/Selection/shared/SelectListBoxSelectionBar.d.ts +0 -5
- package/src/components/inputs/Selection/shared/SelectMobile.d.ts +0 -5
- package/src/components/inputs/Selection/shared/select.context.d.ts +0 -30
- package/src/components/inputs/Selection/shared/select.types.d.ts +0 -55
- package/src/components/inputs/Selection/shared/useSelectItems.d.ts +0 -23
- package/src/components/inputs/Slider/Slider.d.ts +0 -18
- package/src/components/inputs/TextEditor/TextEditor.d.ts +0 -20
- package/src/components/inputs/TextEditor/Toolbar/ColorPicker.d.ts +0 -7
- package/src/components/inputs/TextEditor/Toolbar/ColorPickerDropdown.d.ts +0 -10
- package/src/components/inputs/TextEditor/Toolbar/HyperlinkAction.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextAlignSelect.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextColorSelect.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextEditorToolbar.d.ts +0 -6
- package/src/components/inputs/TextEditor/Toolbar/TextHighlightSelect.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextListActions.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextMarksActions.d.ts +0 -2
- package/src/components/inputs/TextEditor/Toolbar/TextStyleSelect.d.ts +0 -2
- package/src/components/inputs/TextEditor/textEditor.types.d.ts +0 -5
- package/src/components/inputs/Toggle/Toggle.d.ts +0 -14
- package/src/components/inputs/Toggle/toggle.cva.d.ts +0 -10
- package/src/components/inputs/shared/CheckContent.d.ts +0 -7
- package/src/components/inputs/shared/InputClear.d.ts +0 -6
- package/src/components/inputs/shared/form.types.d.ts +0 -12
- package/src/components/inputs/shared/input.cva.d.ts +0 -22
- package/src/components/inputs/shared/label.cva.d.ts +0 -10
- package/src/components/outline.clsx.d.ts +0 -2
- package/src/components/overlays/ActionModal/ActionModal.d.ts +0 -19
- package/src/components/overlays/BottomSheet/BottomSheet.d.ts +0 -21
- package/src/components/overlays/Drawer/Drawer.d.ts +0 -13
- package/src/components/overlays/Modal/Modal.d.ts +0 -11
- package/src/components/overlays/Modal/modal.cva.d.ts +0 -12
- package/src/components/overlays/ResponsivePopover/ResponsivePopover.d.ts +0 -10
- package/src/components/overlays/Tooltip/Tooltip.d.ts +0 -9
- package/src/components/overlays/Tooltip/TooltipEllipsis.d.ts +0 -7
- package/src/components/segment/Segment.d.ts +0 -4
- package/src/components/segment/SegmentItem.d.ts +0 -2
- package/src/components/segment/segment.types.d.ts +0 -34
- package/src/components/shared/pagination/Pagination.d.ts +0 -9
- package/src/components/shared/pagination/PaginationList.d.ts +0 -15
- package/src/components/shared/pagination/minWidth.cva.d.ts +0 -3
- package/src/components/status/Alert/Alert.d.ts +0 -11
- package/src/components/status/Alert/alert.cva.d.ts +0 -7
- package/src/components/status/Loader/Loader.d.ts +0 -5
- package/src/components/status/Loader/loader.cva.d.ts +0 -9
- package/src/components/status/Toast/Toast.d.ts +0 -14
- package/src/components/status/Toast/toast.cva.d.ts +0 -18
- package/src/components/status/Toast/useToast.d.ts +0 -12
- package/src/components/status/shared/status.cva.d.ts +0 -8
- package/src/components/table/CellText.d.ts +0 -7
- package/src/components/table/ColumnConfig.d.ts +0 -10
- package/src/components/table/HeaderText.d.ts +0 -5
- package/src/components/table/InfiniteTable.d.ts +0 -9
- package/src/components/table/PaginatedTable.d.ts +0 -11
- package/src/components/table/Table.d.ts +0 -37
- package/src/components/table/table.cva.d.ts +0 -15
- package/src/components/text/Link/Link.d.ts +0 -7
- package/src/components/text/Link/link.cva.d.ts +0 -6
- package/src/components/text/Tag/Tag.d.ts +0 -10
- package/src/components/text/Tag/tag.cva.d.ts +0 -6
- package/src/components/text/Typography/Typography.d.ts +0 -11
- package/src/components/text/Typography/typography.cva.d.ts +0 -8
- package/src/config/confirmation.context.d.ts +0 -20
- package/src/config/i18n.d.ts +0 -315
- package/src/config/router.context.d.ts +0 -20
- package/src/config/uiConfig.context.d.ts +0 -28
- package/src/config/uiStyle.context.d.ts +0 -84
- package/src/helpers/dynamicColumns.d.ts +0 -44
- package/src/helpers/dynamicInputs.d.ts +0 -83
- package/src/hooks/useAutosave.d.ts +0 -9
- package/src/hooks/useBreakpoint.d.ts +0 -3
- package/src/hooks/useDebounceCallback.d.ts +0 -6
- package/src/hooks/useDeepCompare.d.ts +0 -4
- package/src/hooks/useFilters.d.ts +0 -7
- package/src/hooks/useForm.d.ts +0 -18
- package/src/hooks/useFormAutosave.d.ts +0 -13
- package/src/hooks/useIntersectionObserver.d.ts +0 -7
- package/src/hooks/useLocalStorage.d.ts +0 -13
- package/src/hooks/useLongPressRepeat.d.ts +0 -9
- package/src/hooks/usePagination.d.ts +0 -7
- package/src/hooks/useScrollableListBox.d.ts +0 -3
- package/src/hooks/useSingletonMutation.d.ts +0 -2
- package/src/hooks/useSorting.d.ts +0 -6
- package/src/hooks/useStateAndRef.d.ts +0 -4
- package/src/hooks/useTableColumnConfig.d.ts +0 -16
- package/src/hooks/useTableNav.d.ts +0 -84
- package/src/hooks/useTranslationMemo.d.ts +0 -4
- package/src/index.d.ts +0 -205
- package/src/types/react-query.d.ts +0 -6
- package/src/utils/array.utils.d.ts +0 -3
- package/src/utils/array.utils.spec.d.ts +0 -1
- package/src/utils/compoundMapper.d.ts +0 -19
- package/src/utils/compoundMapper.spec.d.ts +0 -1
- package/src/utils/date-time.utils.d.ts +0 -14
- package/src/utils/date-time.utils.spec.d.ts +0 -1
- package/src/utils/date.utils.d.ts +0 -3
- package/src/utils/date.utils.spec.d.ts +0 -1
- package/src/utils/dom.utils.d.ts +0 -5
- package/src/utils/file.utils.d.ts +0 -9
- package/src/utils/isEqual.d.ts +0 -1
- package/src/utils/logger.d.ts +0 -7
- package/src/utils/object.utils.d.ts +0 -10
- package/src/utils/queries.utils.d.ts +0 -4
- package/src/utils/rest/interceptors/logging.interceptor.d.ts +0 -2
- package/src/utils/rest/interceptors/response.interceptor.d.ts +0 -2
- package/src/utils/rest/interceptors/rest-interceptor.d.ts +0 -8
- package/src/utils/rest/rest-client.d.ts +0 -29
- package/src/utils/rest/rest.utils.d.ts +0 -10
- package/src/utils/routing.utils.d.ts +0 -3
- package/src/utils/string.utils.d.ts +0 -4
- package/src/utils/vendor/error-handling.d.ts +0 -21
- package/src/utils/zod.utils.d.ts +0 -19
- package/vite.config.d.ts +0 -2
- /package/{styles → src/styles}/editor.css +0 -0
- /package/{styles → src/styles}/index.css +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ColumnDef, ColumnOrderState, VisibilityState } from "@tanstack/react-table";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
|
|
4
|
+
function sortByKeyOrder<TData, TValue>(data: ColumnDef<TData, TValue>[], orderedKeys: ColumnOrderState = []) {
|
|
5
|
+
return [...data].sort((a, b) => {
|
|
6
|
+
return (
|
|
7
|
+
orderedKeys.findIndex((key) => key === (a.id ?? (a as unknown as { accessorKey: string }).accessorKey)) -
|
|
8
|
+
orderedKeys.findIndex((key) => key === (b.id ?? (b as unknown as { accessorKey: string }).accessorKey))
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface UseTableColumnConfigOptions {
|
|
14
|
+
visibleColumns?: VisibilityState;
|
|
15
|
+
columnOrder?: ColumnOrderState;
|
|
16
|
+
onVisibilityChange?: (value: VisibilityState) => void;
|
|
17
|
+
onOrderChange?: (value: ColumnOrderState) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function useTableColumnConfig<TData, TValue>(
|
|
21
|
+
defaultColumns: ColumnDef<TData, TValue>[],
|
|
22
|
+
options: UseTableColumnConfigOptions = {},
|
|
23
|
+
) {
|
|
24
|
+
// Always keep internal state
|
|
25
|
+
const [internalVisibleColumns, setInternalVisibleColumns] = useState<VisibilityState>(() =>
|
|
26
|
+
defaultColumns
|
|
27
|
+
.map((col) => ({ [col.id ?? (col as unknown as { accessorKey: string }).accessorKey]: true }))
|
|
28
|
+
.reduce((acc, cur) => ({ ...cur, ...acc }), {}),
|
|
29
|
+
);
|
|
30
|
+
const [internalColumnOrder, setInternalColumnOrder] = useState<ColumnOrderState>(() =>
|
|
31
|
+
defaultColumns.map((col) => col.id ?? (col as unknown as { accessorKey: string }).accessorKey),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Sync in from outside if provided
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (options.visibleColumns) {
|
|
37
|
+
setInternalVisibleColumns(options.visibleColumns);
|
|
38
|
+
}
|
|
39
|
+
}, [options.visibleColumns]);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (options.columnOrder) {
|
|
43
|
+
setInternalColumnOrder(options.columnOrder);
|
|
44
|
+
}
|
|
45
|
+
}, [options.columnOrder]);
|
|
46
|
+
|
|
47
|
+
// Handlers always update internal state and call parent callback if provided
|
|
48
|
+
const handleVisibilityChange = useCallback(
|
|
49
|
+
(value: VisibilityState) => {
|
|
50
|
+
setInternalVisibleColumns(value);
|
|
51
|
+
options?.onVisibilityChange?.(value);
|
|
52
|
+
},
|
|
53
|
+
[options],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const handleOrderChange = useCallback(
|
|
57
|
+
(value: ColumnOrderState) => {
|
|
58
|
+
setInternalColumnOrder(value);
|
|
59
|
+
options?.onOrderChange?.(value);
|
|
60
|
+
},
|
|
61
|
+
[options],
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Compute columns
|
|
65
|
+
const configColumns = useMemo(
|
|
66
|
+
() => sortByKeyOrder(defaultColumns, internalColumnOrder),
|
|
67
|
+
[defaultColumns, internalColumnOrder],
|
|
68
|
+
);
|
|
69
|
+
const columns = useMemo(
|
|
70
|
+
() =>
|
|
71
|
+
configColumns.filter(
|
|
72
|
+
(col) =>
|
|
73
|
+
internalVisibleColumns?.[(col as { id: string }).id ?? (col as { accessorKey: string }).accessorKey] ?? true,
|
|
74
|
+
),
|
|
75
|
+
[configColumns, internalVisibleColumns],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
configColumns,
|
|
80
|
+
columns,
|
|
81
|
+
visibleColumns: internalVisibleColumns,
|
|
82
|
+
columnOrder: internalColumnOrder,
|
|
83
|
+
onVisibilityChange: handleVisibilityChange,
|
|
84
|
+
onOrderChange: handleOrderChange,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
// oxlint-disable @typescript-eslint/no-unsafe-enum-comparison
|
|
2
|
+
// oxlint-disable @typescript-eslint/unbound-method
|
|
3
|
+
|
|
4
|
+
import type { KeyboardEvent } from "react";
|
|
5
|
+
|
|
6
|
+
import { logger } from "#ui/utils/logger";
|
|
7
|
+
|
|
8
|
+
type FocusableElement = HTMLElement | SVGElement;
|
|
9
|
+
|
|
10
|
+
const enum Keys {
|
|
11
|
+
Enter = "Enter",
|
|
12
|
+
Escape = "Escape",
|
|
13
|
+
Shift = "Shift",
|
|
14
|
+
Control = "Control",
|
|
15
|
+
Home = "Home",
|
|
16
|
+
End = "End",
|
|
17
|
+
Backspace = "Backspace",
|
|
18
|
+
/** Page Keys */
|
|
19
|
+
PageUp = "PageUp",
|
|
20
|
+
PageDown = "PageDown",
|
|
21
|
+
/** Arrow Keys */
|
|
22
|
+
ArrowLeft = "ArrowLeft",
|
|
23
|
+
ArrowUp = "ArrowUp",
|
|
24
|
+
ArrowRight = "ArrowRight",
|
|
25
|
+
ArrowDown = "ArrowDown",
|
|
26
|
+
F2 = "F2",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const Selectors = {
|
|
30
|
+
Cell: '[role="cell"],[role="gridcell"],[role="columnheader"],[role="rowheader"],td,th',
|
|
31
|
+
Row: '[role="row"],tr',
|
|
32
|
+
RowGroup: '[role="rowgroup"],thead,tbody,tfoot',
|
|
33
|
+
/** Selector from here: https://github.com/Shopify/polaris/blob/main/polaris-react/src/utilities/focus.ts#L10 */
|
|
34
|
+
Focusable:
|
|
35
|
+
'a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not([aria-disabled="true"]):not([tabindex="-1"]):not(:disabled),*[tabindex]',
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
type Config =
|
|
39
|
+
| {
|
|
40
|
+
/** Enable debug logs */
|
|
41
|
+
debug?: boolean;
|
|
42
|
+
/** CSS Selectors being used to find Rows, Row Groups, Cells and Focusable elements */
|
|
43
|
+
selectors?: Partial<typeof Selectors>;
|
|
44
|
+
/** How many rows to move when pressing page up/down - Default goes to first/last row */
|
|
45
|
+
pageUpDown?: number;
|
|
46
|
+
}
|
|
47
|
+
| undefined;
|
|
48
|
+
|
|
49
|
+
class DataGridNav {
|
|
50
|
+
private selectors: Record<keyof typeof Selectors, string>;
|
|
51
|
+
readonly pageUpDown: number | undefined;
|
|
52
|
+
private keys: string[] = [];
|
|
53
|
+
private disabled: boolean;
|
|
54
|
+
readonly debug: boolean;
|
|
55
|
+
private activeCell: HTMLElement | null = null;
|
|
56
|
+
|
|
57
|
+
constructor();
|
|
58
|
+
constructor(config: Config);
|
|
59
|
+
constructor(config: Config = {}) {
|
|
60
|
+
const { selectors = {}, pageUpDown, debug = false } = config;
|
|
61
|
+
this.selectors = { ...Selectors, ...selectors };
|
|
62
|
+
this.pageUpDown = pageUpDown;
|
|
63
|
+
this.keys = [];
|
|
64
|
+
this.debug = debug;
|
|
65
|
+
this.disabled = false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private debugLog = (functionName: string, message: string) => {
|
|
69
|
+
if (this.debug) {
|
|
70
|
+
logger.info(`[${functionName}]: ${message}`);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Disables the keyboard listener in cases
|
|
76
|
+
* that elements inside the grid need to use
|
|
77
|
+
* arrows keys etc., like select dropdowns
|
|
78
|
+
*/
|
|
79
|
+
public disable() {
|
|
80
|
+
this.disabled = true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Enables the keyboard listeners
|
|
85
|
+
*/
|
|
86
|
+
public enable() {
|
|
87
|
+
this.disabled = false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// oxlint-disable-next-line class-methods-use-this
|
|
91
|
+
private isFocusable(el: Element): el is FocusableElement {
|
|
92
|
+
return el instanceof HTMLElement || el instanceof SVGElement;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public getActiveCell(): HTMLElement | null {
|
|
96
|
+
return this.activeCell;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Used as a keyboard listener for key up */
|
|
100
|
+
public tableKeyUp() {
|
|
101
|
+
// TODO: have a cleanup as user can press key
|
|
102
|
+
// and then move to another tab, and get back to the same tab
|
|
103
|
+
// so this will not be empty (the bug exists with .pop)
|
|
104
|
+
this.keys = [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Used as a keyboard listener for key down */
|
|
108
|
+
public tableKeyDown(e: KeyboardEvent) {
|
|
109
|
+
this.debugLog("tableKeyDown", `Key pressed: ${e.key}`);
|
|
110
|
+
if (this.disabled) {
|
|
111
|
+
this.debugLog("tableKeyDown", "interaction is disabled");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Avoid page scrolling etc.
|
|
116
|
+
* Enable default behavior for:
|
|
117
|
+
* Tab, Shift + Tab
|
|
118
|
+
* TODO: Actually it will be better to just prevent
|
|
119
|
+
* in ArrowKeys and PageKeys maybe?
|
|
120
|
+
* Or should the consumer stop propagation?!
|
|
121
|
+
* Cannot work with preventDefault as it will
|
|
122
|
+
* first capture the event from an input in cell for example
|
|
123
|
+
*/
|
|
124
|
+
if (Keys.ArrowDown === e.key || Keys.ArrowUp === e.key || Keys.ArrowLeft === e.key || Keys.ArrowRight === e.key) {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Add key to the stack if it's
|
|
130
|
+
* not the same with the last (long press)
|
|
131
|
+
*/
|
|
132
|
+
if (this.keys.length === 0 || this.keys[this.keys.length - 1] !== e.key) {
|
|
133
|
+
this.keys.push(e.key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Need to check if we are inside a grid cell
|
|
138
|
+
* or not to enable/disable Grid Navigation
|
|
139
|
+
*/
|
|
140
|
+
if (!(e.target instanceof Element)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const cell = e.target.parentElement?.closest(`${this.selectors.Cell},${this.selectors.Row}`);
|
|
144
|
+
|
|
145
|
+
if (!cell) {
|
|
146
|
+
this.debugLog("tableKeyDown", "cell not found");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (cell.matches(this.selectors.Cell)) {
|
|
151
|
+
this.debugLog("tableKeyDown", "event captured in cell");
|
|
152
|
+
this.cellNavigation(e);
|
|
153
|
+
} else {
|
|
154
|
+
this.debugLog("tableKeyDown", "event captured in cell");
|
|
155
|
+
this.gridNavigation(e);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Handles the navigation inside a cell
|
|
161
|
+
*/
|
|
162
|
+
public cellNavigation(e: KeyboardEvent) {
|
|
163
|
+
if (!(e.target instanceof Element)) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Keys: Escape
|
|
169
|
+
* Restore grid navigation
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
// oxlint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
173
|
+
if (e.key === Keys.Escape) {
|
|
174
|
+
const cell = e.target.closest(this.selectors.Cell);
|
|
175
|
+
if (cell && this.isFocusable(cell)) {
|
|
176
|
+
cell.focus();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Keys: ArrowRight, ArrowDown
|
|
183
|
+
* Move to the next focusable cell, or the first one
|
|
184
|
+
*
|
|
185
|
+
* Arrow Down disabled:
|
|
186
|
+
* https://github.com/w3c/aria-practices/issues/2739#issuecomment-1613538972
|
|
187
|
+
*/
|
|
188
|
+
// oxlint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
189
|
+
if (e.key === Keys.ArrowRight || e.key === Keys.ArrowDown) {
|
|
190
|
+
const cell = e.target.closest(this.selectors.Cell);
|
|
191
|
+
if (!cell) {
|
|
192
|
+
this.debugLog("cellNavigation", "cell not found");
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const focusableWidgets = [...cell.querySelectorAll(this.selectors.Focusable)];
|
|
197
|
+
|
|
198
|
+
const widgetIdx = focusableWidgets.findIndex((el) => el === e.target);
|
|
199
|
+
|
|
200
|
+
const nextFocusable = widgetIdx === focusableWidgets.length - 1 ? 0 : widgetIdx + 1;
|
|
201
|
+
const widgetToFocus = focusableWidgets[nextFocusable];
|
|
202
|
+
if (this.isFocusable(widgetToFocus)) {
|
|
203
|
+
widgetToFocus.focus();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Keys: ArrowLeft, ArrowUp
|
|
211
|
+
* Move to the previous focusable cell, or the last one
|
|
212
|
+
*
|
|
213
|
+
* Arrow Up disabled:
|
|
214
|
+
* https://github.com/w3c/aria-practices/issues/2739#issuecomment-1613538972
|
|
215
|
+
*/
|
|
216
|
+
// oxlint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
217
|
+
if (e.key === Keys.ArrowLeft || e.key === Keys.ArrowUp) {
|
|
218
|
+
const cell = e.target.closest(this.selectors.Cell);
|
|
219
|
+
|
|
220
|
+
if (!cell) {
|
|
221
|
+
this.debugLog("cellNavigation", "cell not found");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const focusableWidgets = [...cell.querySelectorAll(this.selectors.Focusable)];
|
|
226
|
+
|
|
227
|
+
const widgetIdx = focusableWidgets.findIndex((el) => el === e.target);
|
|
228
|
+
|
|
229
|
+
const previousFocusable = widgetIdx === 0 ? focusableWidgets.length - 1 : widgetIdx - 1;
|
|
230
|
+
const widgetToFocus = focusableWidgets[previousFocusable];
|
|
231
|
+
if (this.isFocusable(widgetToFocus)) {
|
|
232
|
+
widgetToFocus.focus();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Handles the navigation outside a cell
|
|
239
|
+
* on the grid level
|
|
240
|
+
*/
|
|
241
|
+
public gridNavigation(e: KeyboardEvent) {
|
|
242
|
+
const { target } = e;
|
|
243
|
+
if (!(e.target instanceof Element)) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (!(target instanceof Element)) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (this.keys.length === 1) {
|
|
251
|
+
/**
|
|
252
|
+
* Keys: Enter
|
|
253
|
+
* Should move focus inside the cell to the first focusable element:
|
|
254
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/grid/#gridNav_inside
|
|
255
|
+
*/
|
|
256
|
+
|
|
257
|
+
// step into the html element and append char
|
|
258
|
+
if (/^[a-zA-Z0-9]$/.test(e.key)) {
|
|
259
|
+
const cell = e.target.querySelector(this.selectors.Focusable);
|
|
260
|
+
|
|
261
|
+
if (cell && this.isFocusable(cell) && cell instanceof HTMLInputElement) {
|
|
262
|
+
cell.focus();
|
|
263
|
+
cell.value = `${cell.value}${e.key}`;
|
|
264
|
+
e.preventDefault();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// we remove the value of the input
|
|
271
|
+
if (e.key === Keys.Backspace) {
|
|
272
|
+
const cell = e.target.querySelector(this.selectors.Focusable);
|
|
273
|
+
|
|
274
|
+
if (cell && this.isFocusable(cell) && cell instanceof HTMLInputElement) {
|
|
275
|
+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
276
|
+
if (nativeInputValueSetter) {
|
|
277
|
+
nativeInputValueSetter.call(cell, "");
|
|
278
|
+
const ev = new Event("input", { bubbles: true });
|
|
279
|
+
cell.dispatchEvent(ev);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// just go into the focusable element
|
|
287
|
+
if (e.key === Keys.Enter) {
|
|
288
|
+
const cell = e.target.querySelector(this.selectors.Focusable);
|
|
289
|
+
|
|
290
|
+
if (cell && this.isFocusable(cell)) {
|
|
291
|
+
if (cell.getAttribute("data-type") === "select-trigger") {
|
|
292
|
+
cell.click();
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
cell.focus();
|
|
297
|
+
e.preventDefault();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Keys: ArrowLeft, ArrowRight
|
|
305
|
+
* Should move focus to the next/previous cell
|
|
306
|
+
*/
|
|
307
|
+
if (e.key === Keys.ArrowLeft || e.key === Keys.ArrowRight) {
|
|
308
|
+
const direction = e.key === Keys.ArrowLeft ? "prev" : "next";
|
|
309
|
+
// Get the closest cell we are currently in
|
|
310
|
+
const cell = e.target.closest(this.selectors.Cell);
|
|
311
|
+
|
|
312
|
+
let nextCell: HTMLElement | null = null;
|
|
313
|
+
|
|
314
|
+
if (direction === "next" && cell?.nextElementSibling instanceof HTMLElement) {
|
|
315
|
+
nextCell = cell.nextElementSibling;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (direction === "prev" && cell?.previousElementSibling instanceof HTMLElement) {
|
|
319
|
+
nextCell = cell.previousElementSibling;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (nextCell && this.isFocusable(nextCell)) {
|
|
323
|
+
nextCell.focus();
|
|
324
|
+
e.preventDefault();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Keys: Up,Down
|
|
330
|
+
* Should move focus to the same column of the next/previous row
|
|
331
|
+
*/
|
|
332
|
+
if (e.key === Keys.ArrowDown || e.key === Keys.ArrowUp) {
|
|
333
|
+
this.verticalCellNavigation(e);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Keys: PageUp, PageDown
|
|
339
|
+
* Should move focus to the first/last row
|
|
340
|
+
* or a predefined number of rows if user provides a value
|
|
341
|
+
*/
|
|
342
|
+
if (e.key === Keys.PageUp || e.key === Keys.PageDown) {
|
|
343
|
+
this.pageCellNavigation(e);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Keys: Home, End
|
|
349
|
+
* Should move focus to the first/last cell of the current row
|
|
350
|
+
*/
|
|
351
|
+
if (e.key === Keys.Home || e.key === Keys.End) {
|
|
352
|
+
const row = e.target.closest(this.selectors.Row)!;
|
|
353
|
+
const rowChildren = [...(row?.children || [])];
|
|
354
|
+
if (e.key === Keys.End) {
|
|
355
|
+
rowChildren.reverse();
|
|
356
|
+
}
|
|
357
|
+
this.focusOnFirstCell(rowChildren);
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
/**
|
|
361
|
+
* Keys: Control + Home, Control + End
|
|
362
|
+
* Should move focus to the first/last cell of the first/last row
|
|
363
|
+
*/
|
|
364
|
+
const [firstKey, secondKey] = this.keys;
|
|
365
|
+
if (
|
|
366
|
+
firstKey === "Control" &&
|
|
367
|
+
// oxlint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
368
|
+
(secondKey === Keys.Home || secondKey === Keys.End)
|
|
369
|
+
) {
|
|
370
|
+
const row = e.target.closest(this.selectors.Row)!;
|
|
371
|
+
const siblings = row.parentElement?.children;
|
|
372
|
+
|
|
373
|
+
if (!siblings) {
|
|
374
|
+
this.debugLog("cellNavigation", "siblings not found");
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const rowToFocus = secondKey === Keys.Home ? siblings[0] : siblings[siblings.length - 1];
|
|
379
|
+
const rowChildren = [...(rowToFocus?.children || [])];
|
|
380
|
+
if (secondKey === Keys.End) {
|
|
381
|
+
rowChildren.reverse();
|
|
382
|
+
}
|
|
383
|
+
this.focusOnFirstCell(rowChildren);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private pageCellNavigation(e: KeyboardEvent) {
|
|
389
|
+
if (!(e.target instanceof Element)) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const row = e.target.closest(this.selectors.Row)!;
|
|
393
|
+
const cell = e.target.closest(this.selectors.Cell)!;
|
|
394
|
+
|
|
395
|
+
if (row && cell) {
|
|
396
|
+
const position = this.getColumnIndex(cell);
|
|
397
|
+
|
|
398
|
+
if (position === undefined) {
|
|
399
|
+
this.debugLog("cellNavigation", "position not found");
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
const direction = e.key === Keys.PageUp ? "prev" : "next";
|
|
403
|
+
const siblings = row.parentElement?.children;
|
|
404
|
+
|
|
405
|
+
if (!siblings) {
|
|
406
|
+
this.debugLog("cellNavigation", "siblings not found");
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// If pageUpDown is defined, we should move that number of rows, or to the closest possible
|
|
411
|
+
let destinationRow: Element | ChildNode;
|
|
412
|
+
if (this.pageUpDown) {
|
|
413
|
+
const methodClbk = direction === "prev" ? "previousSibling" : "nextSibling";
|
|
414
|
+
let sibling = row[methodClbk];
|
|
415
|
+
if (sibling === null) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
let lastVisitedSibling = sibling;
|
|
420
|
+
|
|
421
|
+
for (let i = 0; i < this.pageUpDown - 1 && sibling; i++) {
|
|
422
|
+
sibling = sibling[methodClbk];
|
|
423
|
+
if (sibling) {
|
|
424
|
+
lastVisitedSibling = sibling;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
destinationRow = sibling || lastVisitedSibling;
|
|
428
|
+
} else {
|
|
429
|
+
destinationRow = direction === "prev" ? siblings[0] : siblings[siblings.length - 1];
|
|
430
|
+
}
|
|
431
|
+
if (!destinationRow || !(destinationRow instanceof Element)) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const child = destinationRow.children[position];
|
|
436
|
+
if (child && this.isFocusable(child)) {
|
|
437
|
+
child.focus();
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private verticalCellNavigation(e: KeyboardEvent) {
|
|
443
|
+
if (!(e.target instanceof Element)) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const row = e.target.closest(this.selectors.Row)!;
|
|
447
|
+
const cell = e.target.closest(this.selectors.Cell)!;
|
|
448
|
+
|
|
449
|
+
if (row && cell) {
|
|
450
|
+
const cellPosition = this.getColumnIndex(cell);
|
|
451
|
+
const rowPosition = this.getRowIndex(row);
|
|
452
|
+
this.debugLog("gridNavigation", `Initial row position: ${rowPosition}`);
|
|
453
|
+
this.debugLog("gridNavigation", `Initial cell position: ${cellPosition}`);
|
|
454
|
+
if (cellPosition === undefined || rowPosition === undefined) {
|
|
455
|
+
this.debugLog("verticalCellNavigation", "row or cell position not found");
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const direction = e.key === Keys.ArrowUp ? "prev" : "next";
|
|
460
|
+
|
|
461
|
+
/** Find previous rowgroup and focus on the proper cell */
|
|
462
|
+
if (rowPosition === 0 && direction === "prev") {
|
|
463
|
+
const currentRowGroup = row.parentElement?.closest(this.selectors.RowGroup);
|
|
464
|
+
const siblingRowGroups = [...(currentRowGroup?.parentElement?.children || [])];
|
|
465
|
+
const currentRowGroupIdx = siblingRowGroups.findIndex((el) => el === currentRowGroup);
|
|
466
|
+
if (currentRowGroupIdx !== 0) {
|
|
467
|
+
const previousRowGroup = siblingRowGroups[currentRowGroupIdx - 1];
|
|
468
|
+
const rows = [...previousRowGroup.querySelectorAll(this.selectors.Row)];
|
|
469
|
+
const child = rows[rows.length - 1].children[cellPosition];
|
|
470
|
+
if (child && this.isFocusable(child)) {
|
|
471
|
+
child.focus();
|
|
472
|
+
}
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const siblingRows = [...(row.parentElement?.querySelectorAll(this.selectors.Row) || [])];
|
|
478
|
+
/** Find next rowgroup and focus on the proper cell */
|
|
479
|
+
if (rowPosition === siblingRows.length - 1 && direction === "next") {
|
|
480
|
+
const currentRowGroup = row.parentElement?.closest(this.selectors.RowGroup);
|
|
481
|
+
const siblingRowGroups = [...(currentRowGroup?.parentElement?.children || [])];
|
|
482
|
+
const currentRowGroupIdx = siblingRowGroups.findIndex((el) => el === currentRowGroup);
|
|
483
|
+
if (currentRowGroupIdx !== siblingRowGroups.length - 1) {
|
|
484
|
+
const nextRowGroup = siblingRowGroups[currentRowGroupIdx + 1];
|
|
485
|
+
const rows = [...nextRowGroup.querySelectorAll(this.selectors.Row)];
|
|
486
|
+
const child = rows[0].children[cellPosition];
|
|
487
|
+
if (child && this.isFocusable(child)) {
|
|
488
|
+
child.focus();
|
|
489
|
+
}
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/** Navigation in the same rowgroup */
|
|
496
|
+
const destinationRow = this.findUntil(direction, row, this.selectors.Row);
|
|
497
|
+
if (!destinationRow) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const child = destinationRow.children[cellPosition];
|
|
502
|
+
if (child && this.isFocusable(child)) {
|
|
503
|
+
child.focus();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Sending a row `Element` and then the first cell will be focused.
|
|
510
|
+
*
|
|
511
|
+
* If you want to focus the last cell then the row children can be passed in
|
|
512
|
+
* reversed order
|
|
513
|
+
*/
|
|
514
|
+
private focusOnFirstCell(el: Element[]) {
|
|
515
|
+
// oxlint-disable-next-line @typescript-eslint/prefer-for-of
|
|
516
|
+
for (let i = 0; i < el.length; i++) {
|
|
517
|
+
const child = el[i];
|
|
518
|
+
if (this.isFocusable(child)) {
|
|
519
|
+
child.focus();
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Get the column index of a `cell` based on the first `row` parent.
|
|
527
|
+
* `cellIndex` could be used, but it's not supported in HTML tables.
|
|
528
|
+
*/
|
|
529
|
+
private getColumnIndex(cell: Element) {
|
|
530
|
+
let position = 0;
|
|
531
|
+
const siblings = cell?.parentNode?.children;
|
|
532
|
+
if (!siblings) {
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
while (cell !== siblings[position] && siblings[position] !== undefined) {
|
|
537
|
+
position++;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Cell position find was not possible, maybe should log here
|
|
541
|
+
if (siblings[position] === undefined) {
|
|
542
|
+
this.debugLog("getColumnIndex", "position finding was not successful");
|
|
543
|
+
return undefined;
|
|
544
|
+
}
|
|
545
|
+
return position;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Get the row index of a `row` based
|
|
550
|
+
* on its sibling rows
|
|
551
|
+
*/
|
|
552
|
+
private getRowIndex(row: Element) {
|
|
553
|
+
let position = 0;
|
|
554
|
+
const siblings = row?.parentNode?.children;
|
|
555
|
+
if (!siblings) {
|
|
556
|
+
return undefined;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
while (row !== siblings[position] && siblings[position] !== undefined) {
|
|
560
|
+
position++;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Cell position find was not possible
|
|
564
|
+
if (siblings[position] === undefined) {
|
|
565
|
+
this.debugLog("getRowIndex", "position finding was not successful");
|
|
566
|
+
return undefined;
|
|
567
|
+
}
|
|
568
|
+
return position;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Equivalent to prevUntil/nextUntil in jQuery
|
|
573
|
+
* https://api.jquery.com/prevUntil/
|
|
574
|
+
*/
|
|
575
|
+
// oxlint-disable-next-line class-methods-use-this
|
|
576
|
+
private findUntil(
|
|
577
|
+
direction: "next" | "prev",
|
|
578
|
+
el: Element | ChildNode,
|
|
579
|
+
matchSelector: string,
|
|
580
|
+
exitSelector?: string,
|
|
581
|
+
): FocusableElement | null {
|
|
582
|
+
let element: ChildNode = el;
|
|
583
|
+
const method = direction === "next" ? "nextSibling" : "previousSibling";
|
|
584
|
+
|
|
585
|
+
while (element[method]) {
|
|
586
|
+
const sibling = element[method];
|
|
587
|
+
if (!sibling) {
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
if (exitSelector && sibling instanceof Element && sibling.matches(exitSelector)) {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (sibling instanceof Element && sibling.matches(matchSelector)) {
|
|
595
|
+
return sibling as FocusableElement;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
element = sibling;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export function useTableNav(options?: Config) {
|
|
606
|
+
const nav = new DataGridNav(options);
|
|
607
|
+
|
|
608
|
+
return {
|
|
609
|
+
listeners: {
|
|
610
|
+
onKeyDown: (e: KeyboardEvent) => nav.tableKeyDown(e),
|
|
611
|
+
onKeyUp: () => nav.tableKeyUp(),
|
|
612
|
+
},
|
|
613
|
+
tableNav: nav,
|
|
614
|
+
};
|
|
615
|
+
}
|