@danske/sapphire-react-lab 0.106.2 → 0.107.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/build/cjs/index.js +2557 -64
- package/build/cjs/index.js.map +1 -1
- package/build/esm/core/src/BreakpointProvider/useBreakpointContext.js +11 -0
- package/build/esm/core/src/BreakpointProvider/useBreakpointContext.js.map +1 -0
- package/build/esm/core/src/Flex/src/Flex.js +64 -0
- package/build/esm/core/src/Flex/src/Flex.js.map +1 -0
- package/build/esm/core/src/Grid/src/Grid.js +55 -0
- package/build/esm/core/src/Grid/src/Grid.js.map +1 -0
- package/build/esm/core/src/Icon/src/Icon.js +37 -0
- package/build/esm/core/src/Icon/src/Icon.js.map +1 -0
- package/build/esm/core/src/ListBox/i18n/da-DK.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/de-DE.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/en-US.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/fi-FI.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/index.js.map +1 -0
- package/build/esm/core/src/ListBox/i18n/nb-NO.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/pl-PL.json.js +7 -0
- package/build/esm/core/src/ListBox/i18n/sv-SE.json.js +7 -0
- package/build/esm/core/src/ListBox/src/ListBoxContext.js +8 -0
- package/build/esm/core/src/ListBox/src/ListBoxContext.js.map +1 -0
- package/build/esm/core/src/ListBox/src/ListBoxEmptyState.js +26 -0
- package/build/esm/core/src/ListBox/src/ListBoxEmptyState.js.map +1 -0
- package/build/esm/core/src/ListBox/src/ListBoxItemSkeleton.js +37 -0
- package/build/esm/core/src/ListBox/src/ListBoxItemSkeleton.js.map +1 -0
- package/build/esm/core/src/ListBox/src/ListBoxOption.js +105 -0
- package/build/esm/core/src/ListBox/src/ListBoxOption.js.map +1 -0
- package/build/esm/core/src/ListBox/src/ListBoxSection.js +86 -0
- package/build/esm/core/src/ListBox/src/ListBoxSection.js.map +1 -0
- package/build/esm/core/src/ListBox/src/StatelessListBox.js +162 -0
- package/build/esm/core/src/ListBox/src/StatelessListBox.js.map +1 -0
- package/build/esm/core/src/Pagination/src/usePaginationContext.js +8 -0
- package/build/esm/core/src/Pagination/src/usePaginationContext.js.map +1 -0
- package/build/esm/core/src/Popover/src/Popover.js +62 -0
- package/build/esm/core/src/Popover/src/Popover.js.map +1 -0
- package/build/esm/core/src/Radio/src/RadioBox.js +58 -0
- package/build/esm/core/src/Radio/src/RadioBox.js.map +1 -0
- package/build/esm/core/src/Separator/src/Separator.js +32 -0
- package/build/esm/core/src/Separator/src/Separator.js.map +1 -0
- package/build/esm/core/src/Skeleton/src/Skeleton.js +19 -0
- package/build/esm/core/src/Skeleton/src/Skeleton.js.map +1 -0
- package/build/esm/core/src/Skeleton/src/SkeletonCircle.js +39 -0
- package/build/esm/core/src/Skeleton/src/SkeletonCircle.js.map +1 -0
- package/build/esm/core/src/Skeleton/src/SkeletonText.js +59 -0
- package/build/esm/core/src/Skeleton/src/SkeletonText.js.map +1 -0
- package/build/esm/core/src/Skeleton/src/animation.js +4 -0
- package/build/esm/core/src/Skeleton/src/animation.js.map +1 -0
- package/build/esm/core/src/ThemeRoot/src/ThemeRoot.js +42 -0
- package/build/esm/core/src/ThemeRoot/src/ThemeRoot.js.map +1 -0
- package/build/esm/core/src/View/src/View.js +60 -0
- package/build/esm/core/src/View/src/View.js.map +1 -0
- package/build/esm/core/src/utils/SapphireStyleProps.js +48 -0
- package/build/esm/core/src/utils/SapphireStyleProps.js.map +1 -0
- package/build/esm/core/src/utils/useCollectionFocusProxy.js +53 -0
- package/build/esm/core/src/utils/useCollectionFocusProxy.js.map +1 -0
- package/build/esm/core/src/utils/usePreventTouchEnd.js +16 -0
- package/build/esm/core/src/utils/usePreventTouchEnd.js.map +1 -0
- package/build/esm/core/src/utils/useSapphireStyleProps.js +179 -0
- package/build/esm/core/src/utils/useSapphireStyleProps.js.map +1 -0
- package/build/esm/core/src/utils/useSapphireTextStyleProps.js +9 -0
- package/build/esm/core/src/utils/useSapphireTextStyleProps.js.map +1 -0
- package/build/esm/core/src/utils/useScrollCheck.js +38 -0
- package/build/esm/core/src/utils/useScrollCheck.js.map +1 -0
- package/build/esm/core/src/utils/useThemeCheck.js +14 -0
- package/build/esm/core/src/utils/useThemeCheck.js.map +1 -0
- package/build/esm/core/src/utils/virtualization/ListWithLoadingStateLayout.js +158 -0
- package/build/esm/core/src/utils/virtualization/ListWithLoadingStateLayout.js.map +1 -0
- package/build/esm/core/src/utils/virtualization/VariableWidthListLayout.js +69 -0
- package/build/esm/core/src/utils/virtualization/VariableWidthListLayout.js.map +1 -0
- package/build/esm/core/src/utils/virtualization/VirtualizerWithLoadingSkeleton.js +40 -0
- package/build/esm/core/src/utils/virtualization/VirtualizerWithLoadingSkeleton.js.map +1 -0
- package/build/esm/core/src/utils/virtualization/useListWithLoadingStateLayout.js +35 -0
- package/build/esm/core/src/utils/virtualization/useListWithLoadingStateLayout.js.map +1 -0
- package/build/esm/index.js +23 -20
- package/build/esm/index.js.map +1 -1
- package/build/esm/lab/src/Accordion/index.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/Accordion.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/AccordionContext.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/AccordionHeading.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/AccordionItem.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/AccordionPanel.js.map +1 -0
- package/build/esm/lab/src/Accordion/src/utils.js.map +1 -0
- package/build/esm/lab/src/Alert/src/Alert.js.map +1 -0
- package/build/esm/lab/src/Amount/src/Amount.js.map +1 -0
- package/build/esm/lab/src/Amount/src/useGroupAmount.js.map +1 -0
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/da-DK.json.js +2 -2
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/de-DE.json.js +2 -2
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/en-US.json.js +2 -2
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/fi-FI.json.js +2 -2
- package/build/esm/lab/src/Autocomplete/i18n/index.js +20 -0
- package/build/esm/lab/src/Autocomplete/i18n/index.js.map +1 -0
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/nb-NO.json.js +2 -2
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/pl-PL.json.js +2 -2
- package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/sv-SE.json.js +2 -2
- package/build/esm/lab/src/Autocomplete/src/Autocomplete.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItem.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItemLink.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItemStatic.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbOverflowMenu.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/Breadcrumbs.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbsSeparator.js.map +1 -0
- package/build/esm/lab/src/Breadcrumbs/src/useBreadcrumbThreshold.js.map +1 -0
- package/build/esm/lab/src/DataGrid/index.js +9 -0
- package/build/esm/lab/src/DataGrid/index.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/DataGrid.js +463 -0
- package/build/esm/lab/src/DataGrid/src/DataGrid.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/DataGridCellContext.js +6 -0
- package/build/esm/lab/src/DataGrid/src/DataGridCellContext.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/EditableCellContent.js +125 -0
- package/build/esm/lab/src/DataGrid/src/EditableCellContent.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/createDataGridColumnHelper.js +15 -0
- package/build/esm/lab/src/DataGrid/src/createDataGridColumnHelper.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/useGridKeyboardNavigation.js +417 -0
- package/build/esm/lab/src/DataGrid/src/useGridKeyboardNavigation.js.map +1 -0
- package/build/esm/lab/src/DataGrid/src/useMeasureColumnWidths.js +55 -0
- package/build/esm/lab/src/DataGrid/src/useMeasureColumnWidths.js.map +1 -0
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/da-DK.json.js +2 -2
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/de-DE.json.js +2 -2
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/en-US.json.js +2 -2
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/fi-FI.json.js +2 -2
- package/build/esm/lab/src/FileDropzone/i18n/index.js.map +1 -0
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/nb-NO.json.js +2 -2
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/pl-PL.json.js +2 -2
- package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/sv-SE.json.js +2 -2
- package/build/esm/lab/src/FileDropzone/src/FileDropzone.js.map +1 -0
- package/build/esm/lab/src/FileDropzone/src/FileTrigger.js.map +1 -0
- package/build/esm/lab/src/FileDropzone/src/utils.js.map +1 -0
- package/build/esm/lab/src/Filtering/src/FilterDropdown.js.map +1 -0
- package/build/esm/{Filtering → lab/src/Filtering}/src/SearchableSelectFilter.js +2 -0
- package/build/esm/lab/src/Filtering/src/SearchableSelectFilter.js.map +1 -0
- package/build/esm/lab/src/Flag/src/Flag.js.map +1 -0
- package/build/esm/lab/src/LabeledValue/src/LabeledValue.js.map +1 -0
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/da-DK.json.js +2 -2
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/de-DE.json.js +2 -2
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/en-US.json.js +2 -2
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/fi-FI.json.js +2 -2
- package/build/esm/lab/src/NumberField/i18n/index.js.map +1 -0
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/nb-NO.json.js +2 -2
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/pl-PL.json.js +2 -2
- package/build/esm/{NumberField → lab/src/NumberField}/i18n/sv-SE.json.js +2 -2
- package/build/esm/lab/src/NumberField/src/NumberField.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/StepperButton.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/cursorHelpers.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/formatHelpers.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/keyboardHelpers.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/useAutofillStyle.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/useNumberFieldFormatting.js.map +1 -0
- package/build/esm/lab/src/NumberField/src/useSapphireNumberField.js.map +1 -0
- package/build/esm/lab/src/ProgressIndicator/src/ProgressIndicator.js.map +1 -0
- package/build/esm/lab/src/Sidebar/index.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Body.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/ExpandableItem.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Header.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Item.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/List.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Panel.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/ResponsiveSidebarContext.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/SecondarySidebarContext.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Section.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/Sidebar.js.map +1 -0
- package/build/esm/lab/src/Sidebar/src/useSidebar.js.map +1 -0
- package/build/esm/lab/src/Slider/index.js.map +1 -0
- package/build/esm/lab/src/Slider/src/Slider.js.map +1 -0
- package/build/esm/lab/src/TagGroup/src/Tag.js.map +1 -0
- package/build/esm/lab/src/TagGroup/src/TagGroup.js.map +1 -0
- package/build/esm/lab/src/TagGroup/src/TagItem.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/da-DK.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/da-DK.json.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/de-DE.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/de-DE.json.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/en-US.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/en-US.json.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/fi-FI.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/fi-FI.json.js.map +1 -0
- package/build/esm/lab/src/TimeField/i18n/index.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/nb-NO.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/nb-NO.json.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/pl-PL.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/pl-PL.json.js.map +1 -0
- package/build/esm/{TimeField → lab/src/TimeField}/i18n/sv-SE.json.js +2 -2
- package/build/esm/lab/src/TimeField/i18n/sv-SE.json.js.map +1 -0
- package/build/esm/lab/src/TimeField/src/TimeField.js.map +1 -0
- package/build/esm/lab/src/TimeField/src/TimeFieldSegment.js.map +1 -0
- package/build/esm/lab/src/TruncateOverflow/src/TruncateOverflow.js +46 -0
- package/build/esm/lab/src/TruncateOverflow/src/TruncateOverflow.js.map +1 -0
- package/build/index.d.ts +553 -10
- package/package.json +8 -8
- package/build/esm/Accordion/index.js.map +0 -1
- package/build/esm/Accordion/src/Accordion.js.map +0 -1
- package/build/esm/Accordion/src/AccordionContext.js.map +0 -1
- package/build/esm/Accordion/src/AccordionHeading.js.map +0 -1
- package/build/esm/Accordion/src/AccordionItem.js.map +0 -1
- package/build/esm/Accordion/src/AccordionPanel.js.map +0 -1
- package/build/esm/Accordion/src/utils.js.map +0 -1
- package/build/esm/Alert/src/Alert.js.map +0 -1
- package/build/esm/Amount/src/Amount.js.map +0 -1
- package/build/esm/Amount/src/useGroupAmount.js.map +0 -1
- package/build/esm/Autocomplete/i18n/index.js.map +0 -1
- package/build/esm/Autocomplete/src/Autocomplete.js.map +0 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItem.js.map +0 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemLink.js.map +0 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js.map +0 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbOverflowMenu.js.map +0 -1
- package/build/esm/Breadcrumbs/src/Breadcrumbs.js.map +0 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbsSeparator.js.map +0 -1
- package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js.map +0 -1
- package/build/esm/FileDropzone/i18n/index.js.map +0 -1
- package/build/esm/FileDropzone/src/FileDropzone.js.map +0 -1
- package/build/esm/FileDropzone/src/FileTrigger.js.map +0 -1
- package/build/esm/FileDropzone/src/utils.js.map +0 -1
- package/build/esm/Filtering/src/FilterDropdown.js.map +0 -1
- package/build/esm/Filtering/src/SearchableSelectFilter.js.map +0 -1
- package/build/esm/Flag/src/Flag.js.map +0 -1
- package/build/esm/LabeledValue/src/LabeledValue.js.map +0 -1
- package/build/esm/NumberField/i18n/index.js.map +0 -1
- package/build/esm/NumberField/src/NumberField.js.map +0 -1
- package/build/esm/NumberField/src/StepperButton.js.map +0 -1
- package/build/esm/NumberField/src/cursorHelpers.js.map +0 -1
- package/build/esm/NumberField/src/formatHelpers.js.map +0 -1
- package/build/esm/NumberField/src/keyboardHelpers.js.map +0 -1
- package/build/esm/NumberField/src/useAutofillStyle.js.map +0 -1
- package/build/esm/NumberField/src/useNumberFieldFormatting.js.map +0 -1
- package/build/esm/NumberField/src/useSapphireNumberField.js.map +0 -1
- package/build/esm/ProgressIndicator/src/ProgressIndicator.js.map +0 -1
- package/build/esm/Sidebar/index.js.map +0 -1
- package/build/esm/Sidebar/src/Body.js.map +0 -1
- package/build/esm/Sidebar/src/ExpandableItem.js.map +0 -1
- package/build/esm/Sidebar/src/Header.js.map +0 -1
- package/build/esm/Sidebar/src/Item.js.map +0 -1
- package/build/esm/Sidebar/src/List.js.map +0 -1
- package/build/esm/Sidebar/src/Panel.js.map +0 -1
- package/build/esm/Sidebar/src/ResponsiveSidebarContext.js.map +0 -1
- package/build/esm/Sidebar/src/SecondarySidebarContext.js.map +0 -1
- package/build/esm/Sidebar/src/Section.js.map +0 -1
- package/build/esm/Sidebar/src/Sidebar.js.map +0 -1
- package/build/esm/Sidebar/src/useSidebar.js.map +0 -1
- package/build/esm/Slider/index.js.map +0 -1
- package/build/esm/Slider/src/Slider.js.map +0 -1
- package/build/esm/TagGroup/src/Tag.js.map +0 -1
- package/build/esm/TagGroup/src/TagGroup.js.map +0 -1
- package/build/esm/TagGroup/src/TagItem.js.map +0 -1
- package/build/esm/TimeField/i18n/index.js.map +0 -1
- package/build/esm/TimeField/src/TimeField.js.map +0 -1
- package/build/esm/TimeField/src/TimeFieldSegment.js.map +0 -1
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/da-DK.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/de-DE.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/en-US.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/fi-FI.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/index.js +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/nb-NO.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/pl-PL.json.js.map +0 -0
- /package/build/esm/{TimeField → core/src/ListBox}/i18n/sv-SE.json.js.map +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/index.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/Accordion.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionContext.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionHeading.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionItem.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionPanel.js +0 -0
- /package/build/esm/{Accordion → lab/src/Accordion}/src/utils.js +0 -0
- /package/build/esm/{Alert → lab/src/Alert}/src/Alert.js +0 -0
- /package/build/esm/{Amount → lab/src/Amount}/src/Amount.js +0 -0
- /package/build/esm/{Amount → lab/src/Amount}/src/useGroupAmount.js +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/da-DK.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/de-DE.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/en-US.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/fi-FI.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/nb-NO.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/pl-PL.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/sv-SE.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/Autocomplete}/src/Autocomplete.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItem.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItemLink.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItemStatic.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbOverflowMenu.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/Breadcrumbs.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbsSeparator.js +0 -0
- /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/useBreadcrumbThreshold.js +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/da-DK.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/de-DE.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/en-US.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/fi-FI.json.js.map +0 -0
- /package/build/esm/{Autocomplete → lab/src/FileDropzone}/i18n/index.js +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/nb-NO.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/pl-PL.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/sv-SE.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/FileDropzone.js +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/FileTrigger.js +0 -0
- /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/utils.js +0 -0
- /package/build/esm/{Filtering → lab/src/Filtering}/src/FilterDropdown.js +0 -0
- /package/build/esm/{Flag → lab/src/Flag}/src/Flag.js +0 -0
- /package/build/esm/{LabeledValue → lab/src/LabeledValue}/src/LabeledValue.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/da-DK.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/de-DE.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/en-US.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/fi-FI.json.js.map +0 -0
- /package/build/esm/{FileDropzone → lab/src/NumberField}/i18n/index.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/nb-NO.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/pl-PL.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/i18n/sv-SE.json.js.map +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/NumberField.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/StepperButton.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/cursorHelpers.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/formatHelpers.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/keyboardHelpers.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/useAutofillStyle.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/useNumberFieldFormatting.js +0 -0
- /package/build/esm/{NumberField → lab/src/NumberField}/src/useSapphireNumberField.js +0 -0
- /package/build/esm/{ProgressIndicator → lab/src/ProgressIndicator}/src/ProgressIndicator.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/index.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Body.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/ExpandableItem.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Header.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Item.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/List.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Panel.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/ResponsiveSidebarContext.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/SecondarySidebarContext.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Section.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Sidebar.js +0 -0
- /package/build/esm/{Sidebar → lab/src/Sidebar}/src/useSidebar.js +0 -0
- /package/build/esm/{Slider → lab/src/Slider}/index.js +0 -0
- /package/build/esm/{Slider → lab/src/Slider}/src/Slider.js +0 -0
- /package/build/esm/{TagGroup → lab/src/TagGroup}/src/Tag.js +0 -0
- /package/build/esm/{TagGroup → lab/src/TagGroup}/src/TagGroup.js +0 -0
- /package/build/esm/{TagGroup → lab/src/TagGroup}/src/TagItem.js +0 -0
- /package/build/esm/{NumberField → lab/src/TimeField}/i18n/index.js +0 -0
- /package/build/esm/{TimeField → lab/src/TimeField}/src/TimeField.js +0 -0
- /package/build/esm/{TimeField → lab/src/TimeField}/src/TimeFieldSegment.js +0 -0
package/build/cjs/index.js
CHANGED
|
@@ -59,6 +59,33 @@ var styles$a = require('@danske/sapphire-css/components/dateField/dateField.modu
|
|
|
59
59
|
var useTimeField = require('react-aria/useTimeField');
|
|
60
60
|
var useTimeFieldState = require('react-stately/useTimeFieldState');
|
|
61
61
|
var useDateField = require('react-aria/useDateField');
|
|
62
|
+
var styles$b = require('@danske/sapphire-css/components/truncate-overflow/truncate-overflow.module.css');
|
|
63
|
+
var useOverlayTriggerState = require('react-stately/useOverlayTriggerState');
|
|
64
|
+
var styles$c = require('@danske/sapphire-css/components/table/table.module.css');
|
|
65
|
+
var reactTable = require('@tanstack/react-table');
|
|
66
|
+
var reactVirtual = require('@tanstack/react-virtual');
|
|
67
|
+
var useLoadMore = require('react-aria/private/utils/useLoadMore');
|
|
68
|
+
var useFocusVisible = require('react-aria/private/interactions/useFocusVisible');
|
|
69
|
+
var styles$g = require('@danske/sapphire-css/components/radio/radio.module.css');
|
|
70
|
+
var sapphireReactContext = require('@danske/sapphire-react-context');
|
|
71
|
+
var VirtualizerItem = require('react-aria/private/virtualizer/VirtualizerItem');
|
|
72
|
+
var styles$e = require('@danske/sapphire-css/components/listbox/listbox.module.css');
|
|
73
|
+
var iconStyles = require('@danske/sapphire-css/components/icon/icon.module.css');
|
|
74
|
+
var styles$d = require('@danske/sapphire-css/components/skeleton/skeleton.module.css');
|
|
75
|
+
var popoverStyles = require('@danske/sapphire-css/components/popover/popover.module.css');
|
|
76
|
+
var ariaHideOutside = require('react-aria/private/overlays/ariaHideOutside');
|
|
77
|
+
var avatarStyles = require('@danske/sapphire-css/components/avatar/avatar.module.css');
|
|
78
|
+
require('@danske/sapphire-css/themes/default');
|
|
79
|
+
require('@danske/sapphire-css/themes/default-dark');
|
|
80
|
+
require('@danske/sapphire-css/themes/realkredit');
|
|
81
|
+
var themes = require('@danske/sapphire-css/themes');
|
|
82
|
+
require('react-dom');
|
|
83
|
+
var surfaceStyles = require('@danske/sapphire-css/components/surface/surface.module.css');
|
|
84
|
+
require('react-aria/PortalProvider');
|
|
85
|
+
var useVirtualizerItem = require('react-aria/private/virtualizer/useVirtualizerItem');
|
|
86
|
+
var styles$f = require('@danske/sapphire-css/components/separator/separator.module.css');
|
|
87
|
+
var useVirtualizerState = require('react-stately/useVirtualizerState');
|
|
88
|
+
var Virtualizer = require('react-aria/private/virtualizer/Virtualizer');
|
|
62
89
|
|
|
63
90
|
const AccordionContext = React.createContext({
|
|
64
91
|
sidePadding: void 0,
|
|
@@ -354,47 +381,47 @@ const Amount = ({
|
|
|
354
381
|
);
|
|
355
382
|
};
|
|
356
383
|
|
|
357
|
-
var da$
|
|
384
|
+
var da$4 = {
|
|
358
385
|
"listbox-suggestions": "Forslag"
|
|
359
386
|
};
|
|
360
387
|
|
|
361
|
-
var en$
|
|
388
|
+
var en$4 = {
|
|
362
389
|
"listbox-suggestions": "Suggestions"
|
|
363
390
|
};
|
|
364
391
|
|
|
365
|
-
var de$
|
|
392
|
+
var de$4 = {
|
|
366
393
|
"listbox-suggestions": "Vorschläge"
|
|
367
394
|
};
|
|
368
395
|
|
|
369
|
-
var fi$
|
|
396
|
+
var fi$4 = {
|
|
370
397
|
"listbox-suggestions": "Ehdotukset"
|
|
371
398
|
};
|
|
372
399
|
|
|
373
|
-
var no$
|
|
400
|
+
var no$4 = {
|
|
374
401
|
"listbox-suggestions": "Forslag"
|
|
375
402
|
};
|
|
376
403
|
|
|
377
|
-
var pl$
|
|
404
|
+
var pl$4 = {
|
|
378
405
|
"listbox-suggestions": "Sugestie"
|
|
379
406
|
};
|
|
380
407
|
|
|
381
|
-
var se$
|
|
408
|
+
var se$4 = {
|
|
382
409
|
"listbox-suggestions": "Förslag"
|
|
383
410
|
};
|
|
384
411
|
|
|
385
|
-
var intlMessages$
|
|
386
|
-
"da-DK": da$
|
|
387
|
-
"en-US": en$
|
|
388
|
-
"de-DE": de$
|
|
389
|
-
"fi-FI": fi$
|
|
390
|
-
"nb-NO": no$
|
|
391
|
-
"pl-PL": pl$
|
|
392
|
-
"sv-SE": se$
|
|
412
|
+
var intlMessages$4 = {
|
|
413
|
+
"da-DK": da$4,
|
|
414
|
+
"en-US": en$4,
|
|
415
|
+
"de-DE": de$4,
|
|
416
|
+
"fi-FI": fi$4,
|
|
417
|
+
"nb-NO": no$4,
|
|
418
|
+
"pl-PL": pl$4,
|
|
419
|
+
"sv-SE": se$4
|
|
393
420
|
};
|
|
394
421
|
|
|
395
422
|
function Autocomplete(props) {
|
|
396
423
|
sapphireReact.useThemeCheck();
|
|
397
|
-
const formatMessage = i18n.useMessageFormatter(intlMessages$
|
|
424
|
+
const formatMessage = i18n.useMessageFormatter(intlMessages$4);
|
|
398
425
|
const {
|
|
399
426
|
inputValue,
|
|
400
427
|
renderInput,
|
|
@@ -795,56 +822,56 @@ const convertFileListToFileDropItems = (fileList) => {
|
|
|
795
822
|
}));
|
|
796
823
|
};
|
|
797
824
|
|
|
798
|
-
var da$
|
|
825
|
+
var da$3 = {
|
|
799
826
|
"dropzone-heading-default": "Træk filer hertil, eller klik for at vælge",
|
|
800
827
|
"dropzone-heading-default-single": "Træk fil her, eller klik for at vælge",
|
|
801
828
|
"dropzone-heading-dropping": "Slip fil"
|
|
802
829
|
};
|
|
803
830
|
|
|
804
|
-
var en$
|
|
831
|
+
var en$3 = {
|
|
805
832
|
"dropzone-heading-default": "Drag files here or click to select",
|
|
806
833
|
"dropzone-heading-default-single": "Drag a file here or click to select",
|
|
807
834
|
"dropzone-heading-dropping": "Drop file"
|
|
808
835
|
};
|
|
809
836
|
|
|
810
|
-
var de$
|
|
837
|
+
var de$3 = {
|
|
811
838
|
"dropzone-heading-default": "Ziehen Sie Dateien hierher oder klicken Sie, um sie auszuwählen",
|
|
812
839
|
"dropzone-heading-default-single": "Ziehen Sie die Datei hierher oder klicken Sie, um sie auszuwählen",
|
|
813
840
|
"dropzone-heading-dropping": "Datei ablegen"
|
|
814
841
|
};
|
|
815
842
|
|
|
816
|
-
var fi$
|
|
843
|
+
var fi$3 = {
|
|
817
844
|
"dropzone-heading-default": "Vedä tiedostoja tähän tai valitse napsauttamalla",
|
|
818
845
|
"dropzone-heading-default-single": "Vedä tiedosto tähän tai valitse napsauttamalla",
|
|
819
846
|
"dropzone-heading-dropping": "Pudota tiedosto"
|
|
820
847
|
};
|
|
821
848
|
|
|
822
|
-
var no$
|
|
849
|
+
var no$3 = {
|
|
823
850
|
"dropzone-heading-default": "Dra filer her eller klikk for å velge",
|
|
824
851
|
"dropzone-heading-default-single": "Dra fil her eller klikk for å velge",
|
|
825
852
|
"dropzone-heading-dropping": "Slipp fil"
|
|
826
853
|
};
|
|
827
854
|
|
|
828
|
-
var pl$
|
|
855
|
+
var pl$3 = {
|
|
829
856
|
"dropzone-heading-default": "Przeciągnij pliki tutaj lub kliknij, aby wybrać",
|
|
830
857
|
"dropzone-heading-default-single": "Przeciągnij plik tutaj lub kliknij, aby wybrać",
|
|
831
858
|
"dropzone-heading-dropping": "Upuść plik"
|
|
832
859
|
};
|
|
833
860
|
|
|
834
|
-
var se$
|
|
861
|
+
var se$3 = {
|
|
835
862
|
"dropzone-heading-default": "Dra filer hit eller klicka för att välja",
|
|
836
863
|
"dropzone-heading-default-single": "Dra fil hit eller klicka för att välja",
|
|
837
864
|
"dropzone-heading-dropping": "Släpp filen"
|
|
838
865
|
};
|
|
839
866
|
|
|
840
|
-
var intlMessages$
|
|
841
|
-
"da-DK": da$
|
|
842
|
-
"en-US": en$
|
|
843
|
-
"de-DE": de$
|
|
844
|
-
"fi-FI": fi$
|
|
845
|
-
"nb-NO": no$
|
|
846
|
-
"pl-PL": pl$
|
|
847
|
-
"sv-SE": se$
|
|
867
|
+
var intlMessages$3 = {
|
|
868
|
+
"da-DK": da$3,
|
|
869
|
+
"en-US": en$3,
|
|
870
|
+
"de-DE": de$3,
|
|
871
|
+
"fi-FI": fi$3,
|
|
872
|
+
"nb-NO": no$3,
|
|
873
|
+
"pl-PL": pl$3,
|
|
874
|
+
"sv-SE": se$3
|
|
848
875
|
};
|
|
849
876
|
|
|
850
877
|
const FileDropzone = React.forwardRef(function DropzoneWrapper(props, forwardedRef) {
|
|
@@ -861,7 +888,7 @@ const FileDropzone = React.forwardRef(function DropzoneWrapper(props, forwardedR
|
|
|
861
888
|
} = props;
|
|
862
889
|
const id = useId.useId();
|
|
863
890
|
const paragraphId = props["aria-label"] ? void 0 : id;
|
|
864
|
-
const format = i18n.useMessageFormatter(intlMessages$
|
|
891
|
+
const format = i18n.useMessageFormatter(intlMessages$3);
|
|
865
892
|
const pressableRef = useObjectRef.useObjectRef(forwardedRef);
|
|
866
893
|
const { hoverProps, isHovered } = useHover.useHover({ isDisabled });
|
|
867
894
|
const { styleProps } = sapphireReact.useSapphireStyleProps(props);
|
|
@@ -1136,61 +1163,61 @@ function LabeledValue({
|
|
|
1136
1163
|
|
|
1137
1164
|
var increment$6 = "øge";
|
|
1138
1165
|
var decrement$6 = "formindske";
|
|
1139
|
-
var da$
|
|
1166
|
+
var da$2 = {
|
|
1140
1167
|
increment: increment$6,
|
|
1141
1168
|
decrement: decrement$6
|
|
1142
1169
|
};
|
|
1143
1170
|
|
|
1144
1171
|
var increment$5 = "Increase";
|
|
1145
1172
|
var decrement$5 = "Decrease";
|
|
1146
|
-
var en$
|
|
1173
|
+
var en$2 = {
|
|
1147
1174
|
increment: increment$5,
|
|
1148
1175
|
decrement: decrement$5
|
|
1149
1176
|
};
|
|
1150
1177
|
|
|
1151
1178
|
var increment$4 = "erhöhen";
|
|
1152
1179
|
var decrement$4 = "verringern";
|
|
1153
|
-
var de$
|
|
1180
|
+
var de$2 = {
|
|
1154
1181
|
increment: increment$4,
|
|
1155
1182
|
decrement: decrement$4
|
|
1156
1183
|
};
|
|
1157
1184
|
|
|
1158
1185
|
var increment$3 = "lisääntyä";
|
|
1159
1186
|
var decrement$3 = "vähentää";
|
|
1160
|
-
var fi$
|
|
1187
|
+
var fi$2 = {
|
|
1161
1188
|
increment: increment$3,
|
|
1162
1189
|
decrement: decrement$3
|
|
1163
1190
|
};
|
|
1164
1191
|
|
|
1165
1192
|
var increment$2 = "øke";
|
|
1166
1193
|
var decrement$2 = "avta";
|
|
1167
|
-
var no$
|
|
1194
|
+
var no$2 = {
|
|
1168
1195
|
increment: increment$2,
|
|
1169
1196
|
decrement: decrement$2
|
|
1170
1197
|
};
|
|
1171
1198
|
|
|
1172
1199
|
var increment$1 = "zwiększyć";
|
|
1173
1200
|
var decrement$1 = "zmniejszenie";
|
|
1174
|
-
var pl$
|
|
1201
|
+
var pl$2 = {
|
|
1175
1202
|
increment: increment$1,
|
|
1176
1203
|
decrement: decrement$1
|
|
1177
1204
|
};
|
|
1178
1205
|
|
|
1179
1206
|
var increment = "öka";
|
|
1180
1207
|
var decrement = "minska";
|
|
1181
|
-
var se$
|
|
1208
|
+
var se$2 = {
|
|
1182
1209
|
increment: increment,
|
|
1183
1210
|
decrement: decrement
|
|
1184
1211
|
};
|
|
1185
1212
|
|
|
1186
|
-
var intlMessages$
|
|
1187
|
-
"da-DK": da$
|
|
1188
|
-
"en-US": en$
|
|
1189
|
-
"de-DE": de$
|
|
1190
|
-
"fi-FI": fi$
|
|
1191
|
-
"nb-NO": no$
|
|
1192
|
-
"pl-PL": pl$
|
|
1193
|
-
"sv-SE": se$
|
|
1213
|
+
var intlMessages$2 = {
|
|
1214
|
+
"da-DK": da$2,
|
|
1215
|
+
"en-US": en$2,
|
|
1216
|
+
"de-DE": de$2,
|
|
1217
|
+
"fi-FI": fi$2,
|
|
1218
|
+
"nb-NO": no$2,
|
|
1219
|
+
"pl-PL": pl$2,
|
|
1220
|
+
"sv-SE": se$2
|
|
1194
1221
|
};
|
|
1195
1222
|
|
|
1196
1223
|
const StepperButton = ({
|
|
@@ -1666,7 +1693,7 @@ const NumberField = React.forwardRef(function NumberField2(props, ref) {
|
|
|
1666
1693
|
}, [affix]);
|
|
1667
1694
|
sapphireReact.useThemeCheck();
|
|
1668
1695
|
const inputRef = useObjectRef.useObjectRef(props.inputRef);
|
|
1669
|
-
const formatMessage = i18n.useMessageFormatter(intlMessages$
|
|
1696
|
+
const formatMessage = i18n.useMessageFormatter(intlMessages$2);
|
|
1670
1697
|
const {
|
|
1671
1698
|
inputProps,
|
|
1672
1699
|
labelProps,
|
|
@@ -2586,48 +2613,48 @@ const EditableSegment = ({ segment, state }) => {
|
|
|
2586
2613
|
};
|
|
2587
2614
|
|
|
2588
2615
|
var clear$6 = "Nulstil";
|
|
2589
|
-
var da = {
|
|
2616
|
+
var da$1 = {
|
|
2590
2617
|
clear: clear$6
|
|
2591
2618
|
};
|
|
2592
2619
|
|
|
2593
2620
|
var clear$5 = "Clear";
|
|
2594
|
-
var en = {
|
|
2621
|
+
var en$1 = {
|
|
2595
2622
|
clear: clear$5
|
|
2596
2623
|
};
|
|
2597
2624
|
|
|
2598
2625
|
var clear$4 = "Zurücksetzen";
|
|
2599
|
-
var de = {
|
|
2626
|
+
var de$1 = {
|
|
2600
2627
|
clear: clear$4
|
|
2601
2628
|
};
|
|
2602
2629
|
|
|
2603
2630
|
var clear$3 = "Nollaa";
|
|
2604
|
-
var fi = {
|
|
2631
|
+
var fi$1 = {
|
|
2605
2632
|
clear: clear$3
|
|
2606
2633
|
};
|
|
2607
2634
|
|
|
2608
2635
|
var clear$2 = "Nullstill";
|
|
2609
|
-
var no = {
|
|
2636
|
+
var no$1 = {
|
|
2610
2637
|
clear: clear$2
|
|
2611
2638
|
};
|
|
2612
2639
|
|
|
2613
2640
|
var clear$1 = "Zresetuj";
|
|
2614
|
-
var pl = {
|
|
2641
|
+
var pl$1 = {
|
|
2615
2642
|
clear: clear$1
|
|
2616
2643
|
};
|
|
2617
2644
|
|
|
2618
2645
|
var clear = "Återställ";
|
|
2619
|
-
var se = {
|
|
2646
|
+
var se$1 = {
|
|
2620
2647
|
clear: clear
|
|
2621
2648
|
};
|
|
2622
2649
|
|
|
2623
|
-
var intlMessages = {
|
|
2624
|
-
"da-DK": da,
|
|
2625
|
-
"en-US": en,
|
|
2626
|
-
"de-DE": de,
|
|
2627
|
-
"fi-FI": fi,
|
|
2628
|
-
"nb-NO": no,
|
|
2629
|
-
"pl-PL": pl,
|
|
2630
|
-
"sv-SE": se
|
|
2650
|
+
var intlMessages$1 = {
|
|
2651
|
+
"da-DK": da$1,
|
|
2652
|
+
"en-US": en$1,
|
|
2653
|
+
"de-DE": de$1,
|
|
2654
|
+
"fi-FI": fi$1,
|
|
2655
|
+
"nb-NO": no$1,
|
|
2656
|
+
"pl-PL": pl$1,
|
|
2657
|
+
"sv-SE": se$1
|
|
2631
2658
|
};
|
|
2632
2659
|
|
|
2633
2660
|
const isAnySegmentModified = (segments) => segments.map(({ type, isPlaceholder }) => {
|
|
@@ -2646,7 +2673,7 @@ function _TimeField({
|
|
|
2646
2673
|
sapphireReact.useThemeCheck();
|
|
2647
2674
|
const timeFieldRef = useObjectRef.useObjectRef(ref);
|
|
2648
2675
|
const { locale } = I18nProvider.useLocale();
|
|
2649
|
-
const formatMessage = i18n.useMessageFormatter(intlMessages);
|
|
2676
|
+
const formatMessage = i18n.useMessageFormatter(intlMessages$1);
|
|
2650
2677
|
const state = useTimeFieldState.useTimeFieldState({
|
|
2651
2678
|
...otherProps,
|
|
2652
2679
|
locale,
|
|
@@ -2704,6 +2731,2469 @@ function _TimeField({
|
|
|
2704
2731
|
}
|
|
2705
2732
|
const TimeField = React.forwardRef(_TimeField);
|
|
2706
2733
|
|
|
2734
|
+
const TruncateOverflow = React.forwardRef(({ children, tooltip: tooltipProp, ...props }, forwardedRef) => {
|
|
2735
|
+
const ref = useObjectRef.useObjectRef(forwardedRef);
|
|
2736
|
+
const { styleProps, filteredProps } = sapphireReact.useSapphireStyleProps(props);
|
|
2737
|
+
const [needsTooltip, setNeedsTooltip] = React.useState(false);
|
|
2738
|
+
const [content, setContent] = React.useState(
|
|
2739
|
+
typeof children === "string" ? children : ""
|
|
2740
|
+
);
|
|
2741
|
+
const tooltip = tooltipProp ?? content;
|
|
2742
|
+
React.useEffect(() => {
|
|
2743
|
+
const elem = ref.current;
|
|
2744
|
+
if (!elem) return;
|
|
2745
|
+
const hasOverflow = elem.scrollWidth > elem.clientWidth || elem.scrollHeight > elem.clientHeight;
|
|
2746
|
+
setNeedsTooltip(hasOverflow);
|
|
2747
|
+
setContent(
|
|
2748
|
+
typeof children === "string" ? children : elem.textContent?.trim() ?? ""
|
|
2749
|
+
);
|
|
2750
|
+
});
|
|
2751
|
+
return needsTooltip && tooltip ? /* @__PURE__ */ React.createElement(sapphireReact.Tooltip, { title: tooltip }, (triggerProps) => /* @__PURE__ */ React.createElement(
|
|
2752
|
+
"span",
|
|
2753
|
+
{
|
|
2754
|
+
...mergeProps.mergeProps(triggerProps, filteredProps),
|
|
2755
|
+
ref: mergeRefs.mergeRefs(
|
|
2756
|
+
ref,
|
|
2757
|
+
triggerProps.ref
|
|
2758
|
+
),
|
|
2759
|
+
className: clsx(
|
|
2760
|
+
styles$b["sapphire-truncate-overflow"],
|
|
2761
|
+
styleProps.className
|
|
2762
|
+
),
|
|
2763
|
+
style: styleProps.style
|
|
2764
|
+
},
|
|
2765
|
+
children
|
|
2766
|
+
)) : /* @__PURE__ */ React.createElement("span", { ref, className: styles$b["sapphire-truncate-overflow"] }, children);
|
|
2767
|
+
});
|
|
2768
|
+
TruncateOverflow.displayName = "TruncateOverflow";
|
|
2769
|
+
|
|
2770
|
+
const DataGridCellContext = React.createContext(null);
|
|
2771
|
+
|
|
2772
|
+
const EditableCellContent = React.forwardRef(function EditableCellContent2(props, ref) {
|
|
2773
|
+
const {
|
|
2774
|
+
children,
|
|
2775
|
+
renderEditor,
|
|
2776
|
+
onSubmit,
|
|
2777
|
+
onCancel,
|
|
2778
|
+
editButtonLabel,
|
|
2779
|
+
saveButtonLabel
|
|
2780
|
+
} = props;
|
|
2781
|
+
const [isEditing, setIsEditing] = React.useState(false);
|
|
2782
|
+
const [cellPosition, setCellPosition] = React.useState({ width: 0, offset: 0 });
|
|
2783
|
+
const cellContext = React.useContext(DataGridCellContext);
|
|
2784
|
+
if (!cellContext) {
|
|
2785
|
+
throw new Error(
|
|
2786
|
+
"DataGrid.EditableCellContent is meant to be rendered inside DataGrid columns."
|
|
2787
|
+
);
|
|
2788
|
+
}
|
|
2789
|
+
const cellRef = cellContext.ref;
|
|
2790
|
+
const formRef = React.useRef(null);
|
|
2791
|
+
const handleSubmit = React.useCallback(
|
|
2792
|
+
(e) => {
|
|
2793
|
+
e.preventDefault();
|
|
2794
|
+
const result = onSubmit?.(e);
|
|
2795
|
+
if (result !== false) {
|
|
2796
|
+
setIsEditing(false);
|
|
2797
|
+
}
|
|
2798
|
+
},
|
|
2799
|
+
[onSubmit, setIsEditing]
|
|
2800
|
+
);
|
|
2801
|
+
const cancel = React.useCallback(() => {
|
|
2802
|
+
setIsEditing(false);
|
|
2803
|
+
onCancel?.();
|
|
2804
|
+
}, [setIsEditing, onCancel]);
|
|
2805
|
+
const popoverState = useOverlayTriggerState.useOverlayTriggerState({
|
|
2806
|
+
isOpen: isEditing,
|
|
2807
|
+
onOpenChange: (isOpen) => {
|
|
2808
|
+
if (!isOpen) {
|
|
2809
|
+
formRef.current?.requestSubmit();
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
});
|
|
2813
|
+
React.useLayoutEffect(() => {
|
|
2814
|
+
if (isEditing && cellRef.current) {
|
|
2815
|
+
const width = cellRef.current.clientWidth;
|
|
2816
|
+
const offset = -cellRef.current.offsetHeight - 1;
|
|
2817
|
+
setCellPosition({ width, offset });
|
|
2818
|
+
}
|
|
2819
|
+
}, [isEditing]);
|
|
2820
|
+
React.useEffect(() => {
|
|
2821
|
+
if (isEditing) {
|
|
2822
|
+
const onKeyDown = (e) => {
|
|
2823
|
+
if (e.key === "Escape") {
|
|
2824
|
+
e.stopPropagation();
|
|
2825
|
+
e.preventDefault();
|
|
2826
|
+
cancel();
|
|
2827
|
+
}
|
|
2828
|
+
};
|
|
2829
|
+
window.addEventListener("keydown", onKeyDown);
|
|
2830
|
+
return () => {
|
|
2831
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
2832
|
+
};
|
|
2833
|
+
}
|
|
2834
|
+
}, [isEditing, cancel]);
|
|
2835
|
+
return /* @__PURE__ */ React.createElement(
|
|
2836
|
+
"span",
|
|
2837
|
+
{
|
|
2838
|
+
ref,
|
|
2839
|
+
className: clsx(styles$c["sapphire-table__cell-container--editable"])
|
|
2840
|
+
},
|
|
2841
|
+
children,
|
|
2842
|
+
/* @__PURE__ */ React.createElement(
|
|
2843
|
+
sapphireReact.IconButton,
|
|
2844
|
+
{
|
|
2845
|
+
"aria-label": editButtonLabel ?? "Edit",
|
|
2846
|
+
variant: "tertiary",
|
|
2847
|
+
size: "sm",
|
|
2848
|
+
onPress: () => setIsEditing(true),
|
|
2849
|
+
UNSAFE_className: clsx(styles$c["sapphire-table__edit-button"])
|
|
2850
|
+
},
|
|
2851
|
+
/* @__PURE__ */ React.createElement(react.EditAlt, null)
|
|
2852
|
+
),
|
|
2853
|
+
/* @__PURE__ */ React.createElement(
|
|
2854
|
+
sapphireReact.Popover,
|
|
2855
|
+
{
|
|
2856
|
+
state: popoverState,
|
|
2857
|
+
triggerRef: cellRef,
|
|
2858
|
+
placement: "bottom start",
|
|
2859
|
+
offset: cellPosition.offset,
|
|
2860
|
+
isKeyboardDismissDisabled: true,
|
|
2861
|
+
padded: true,
|
|
2862
|
+
UNSAFE_style: { minWidth: `${cellPosition.width}px` }
|
|
2863
|
+
},
|
|
2864
|
+
/* @__PURE__ */ React.createElement(
|
|
2865
|
+
"form",
|
|
2866
|
+
{
|
|
2867
|
+
ref: formRef,
|
|
2868
|
+
onSubmit: handleSubmit,
|
|
2869
|
+
className: clsx(styles$c["sapphire-table__edit-cell-popover"])
|
|
2870
|
+
},
|
|
2871
|
+
renderEditor(),
|
|
2872
|
+
/* @__PURE__ */ React.createElement(
|
|
2873
|
+
sapphireReact.IconButton,
|
|
2874
|
+
{
|
|
2875
|
+
size: "md",
|
|
2876
|
+
type: "submit",
|
|
2877
|
+
variant: "tertiary",
|
|
2878
|
+
"aria-label": saveButtonLabel ?? "Save"
|
|
2879
|
+
},
|
|
2880
|
+
/* @__PURE__ */ React.createElement(react.Checkmark, null)
|
|
2881
|
+
)
|
|
2882
|
+
)
|
|
2883
|
+
)
|
|
2884
|
+
);
|
|
2885
|
+
});
|
|
2886
|
+
|
|
2887
|
+
function useMeasureColumnWidths({
|
|
2888
|
+
data,
|
|
2889
|
+
table,
|
|
2890
|
+
enabled: shouldAutoMeasure,
|
|
2891
|
+
tableRef
|
|
2892
|
+
}) {
|
|
2893
|
+
const [measuredColumnWidths, setMeasuredColumnWidths] = React.useState(null);
|
|
2894
|
+
const columnKey = table.getVisibleLeafColumns().map((c) => c.id).join(",");
|
|
2895
|
+
React.useLayoutEffect(() => {
|
|
2896
|
+
if (shouldAutoMeasure) {
|
|
2897
|
+
setMeasuredColumnWidths(null);
|
|
2898
|
+
}
|
|
2899
|
+
}, [columnKey, shouldAutoMeasure]);
|
|
2900
|
+
React.useLayoutEffect(() => {
|
|
2901
|
+
if (!shouldAutoMeasure || measuredColumnWidths !== null) return;
|
|
2902
|
+
if (data.length === 0) return;
|
|
2903
|
+
const tableEl = tableRef.current;
|
|
2904
|
+
if (!tableEl) return;
|
|
2905
|
+
let rafId;
|
|
2906
|
+
let cancelled = false;
|
|
2907
|
+
const measureColumnWidths = () => {
|
|
2908
|
+
if (cancelled) return;
|
|
2909
|
+
const bodyRows = tableEl.querySelectorAll("tbody tr:not([aria-hidden])");
|
|
2910
|
+
if (bodyRows.length === 0) {
|
|
2911
|
+
rafId = requestAnimationFrame(measureColumnWidths);
|
|
2912
|
+
return;
|
|
2913
|
+
}
|
|
2914
|
+
const headerCells = tableEl.querySelectorAll("thead th");
|
|
2915
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
2916
|
+
const widths = {};
|
|
2917
|
+
visibleColumns.forEach((col, i) => {
|
|
2918
|
+
const thEl = headerCells[i];
|
|
2919
|
+
if (thEl) {
|
|
2920
|
+
widths[col.id] = thEl.getBoundingClientRect().width;
|
|
2921
|
+
}
|
|
2922
|
+
});
|
|
2923
|
+
if (Object.keys(widths).length > 0 && !cancelled) {
|
|
2924
|
+
setMeasuredColumnWidths(widths);
|
|
2925
|
+
}
|
|
2926
|
+
};
|
|
2927
|
+
rafId = requestAnimationFrame(measureColumnWidths);
|
|
2928
|
+
return () => {
|
|
2929
|
+
cancelled = true;
|
|
2930
|
+
cancelAnimationFrame(rafId);
|
|
2931
|
+
};
|
|
2932
|
+
}, [shouldAutoMeasure, measuredColumnWidths, data.length, table]);
|
|
2933
|
+
return {
|
|
2934
|
+
measuredColumnWidths
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
const INTERACTIVE_SELECTOR = [
|
|
2939
|
+
"a[href]",
|
|
2940
|
+
"button:not([disabled])",
|
|
2941
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
2942
|
+
"select:not([disabled])",
|
|
2943
|
+
"textarea:not([disabled])"
|
|
2944
|
+
].join(", ");
|
|
2945
|
+
const GRID_ROW_ATTR = "data-grid-row";
|
|
2946
|
+
const DATA_INDEX_ATTR = "data-index";
|
|
2947
|
+
function buildGrid(table) {
|
|
2948
|
+
const grid = [];
|
|
2949
|
+
const thead = table.querySelector("thead");
|
|
2950
|
+
if (thead) {
|
|
2951
|
+
thead.querySelectorAll(":scope > tr").forEach((tr) => {
|
|
2952
|
+
const cells = rowCells(tr);
|
|
2953
|
+
if (cells.length > 0) grid.push(cells);
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
2956
|
+
const tbody = table.querySelector("tbody");
|
|
2957
|
+
if (tbody) {
|
|
2958
|
+
tbody.querySelectorAll(`:scope > tr[${GRID_ROW_ATTR}]`).forEach((tr) => {
|
|
2959
|
+
const cells = rowCells(tr);
|
|
2960
|
+
if (cells.length > 0) grid.push(cells);
|
|
2961
|
+
});
|
|
2962
|
+
}
|
|
2963
|
+
return grid;
|
|
2964
|
+
}
|
|
2965
|
+
function rowCells(tr) {
|
|
2966
|
+
const cells = [];
|
|
2967
|
+
tr.querySelectorAll(":scope > th, :scope > td").forEach(
|
|
2968
|
+
(cell) => {
|
|
2969
|
+
cells.push({ element: cell, focusTarget: getFocusTarget(cell) });
|
|
2970
|
+
}
|
|
2971
|
+
);
|
|
2972
|
+
return cells;
|
|
2973
|
+
}
|
|
2974
|
+
function getFocusTarget(cell) {
|
|
2975
|
+
const interactive = cell.querySelectorAll(INTERACTIVE_SELECTOR);
|
|
2976
|
+
return interactive.length === 1 ? interactive[0] : cell;
|
|
2977
|
+
}
|
|
2978
|
+
function isEditableTarget(target) {
|
|
2979
|
+
if (target instanceof HTMLTextAreaElement) return true;
|
|
2980
|
+
if (target instanceof HTMLSelectElement) return true;
|
|
2981
|
+
if (target instanceof HTMLInputElement && target.type !== "checkbox" && target.type !== "radio" && target.type !== "button")
|
|
2982
|
+
return true;
|
|
2983
|
+
return target instanceof HTMLElement && target.isContentEditable;
|
|
2984
|
+
}
|
|
2985
|
+
function getDataIndexOfCell(cell) {
|
|
2986
|
+
const tr = cell.closest("tr");
|
|
2987
|
+
const raw = tr?.getAttribute(DATA_INDEX_ATTR);
|
|
2988
|
+
if (raw == null) return null;
|
|
2989
|
+
const n = parseInt(raw, 10);
|
|
2990
|
+
return isNaN(n) ? null : n;
|
|
2991
|
+
}
|
|
2992
|
+
function findGridRowByDataIndex(grid, dataIndex) {
|
|
2993
|
+
for (let r = grid.length - 1; r >= 0; r--) {
|
|
2994
|
+
const tr = grid[r][0]?.element.closest("tr");
|
|
2995
|
+
if (tr?.getAttribute(DATA_INDEX_ATTR) === String(dataIndex)) return r;
|
|
2996
|
+
}
|
|
2997
|
+
return -1;
|
|
2998
|
+
}
|
|
2999
|
+
function getVisiblePageSize(scrollContainer, table) {
|
|
3000
|
+
const fallback = 7;
|
|
3001
|
+
if (!scrollContainer) return fallback;
|
|
3002
|
+
const containerHeight = scrollContainer.clientHeight;
|
|
3003
|
+
if (containerHeight <= 0) return fallback;
|
|
3004
|
+
const firstBodyRow = table.querySelector(
|
|
3005
|
+
`tbody > tr[${GRID_ROW_ATTR}]`
|
|
3006
|
+
);
|
|
3007
|
+
if (!firstBodyRow) return fallback;
|
|
3008
|
+
const rowHeight = firstBodyRow.getBoundingClientRect().height;
|
|
3009
|
+
if (rowHeight <= 0) return fallback;
|
|
3010
|
+
return Math.max(1, Math.floor(containerHeight / rowHeight));
|
|
3011
|
+
}
|
|
3012
|
+
function countHeaderRows(grid) {
|
|
3013
|
+
let count = 0;
|
|
3014
|
+
for (const row of grid) {
|
|
3015
|
+
const tr = row[0]?.element.closest("tr");
|
|
3016
|
+
if (tr?.closest("thead")) count++;
|
|
3017
|
+
else break;
|
|
3018
|
+
}
|
|
3019
|
+
return count;
|
|
3020
|
+
}
|
|
3021
|
+
function useGridKeyboardNavigation({
|
|
3022
|
+
tableRef,
|
|
3023
|
+
enabled = true,
|
|
3024
|
+
scrollContainerRef,
|
|
3025
|
+
rowItemCount,
|
|
3026
|
+
onScrollToRowIndex
|
|
3027
|
+
}) {
|
|
3028
|
+
const activeCoordsRef = React.useRef({ row: 0, col: 0 });
|
|
3029
|
+
const pendingFocusRef = React.useRef(null);
|
|
3030
|
+
const [focusedRowIndex, setFocusedRowIndex] = React.useState(null);
|
|
3031
|
+
const syncTabIndices = () => {
|
|
3032
|
+
const table = tableRef.current;
|
|
3033
|
+
if (!table || !enabled) return;
|
|
3034
|
+
const grid = buildGrid(table);
|
|
3035
|
+
if (grid.length === 0) return;
|
|
3036
|
+
let { row, col } = activeCoordsRef.current;
|
|
3037
|
+
const activeEl = table.ownerDocument.activeElement;
|
|
3038
|
+
if (activeEl && table.contains(activeEl)) {
|
|
3039
|
+
const focusedCell = activeEl.closest?.(
|
|
3040
|
+
"th, td"
|
|
3041
|
+
);
|
|
3042
|
+
if (focusedCell) {
|
|
3043
|
+
for (let r = 0; r < grid.length; r++) {
|
|
3044
|
+
for (let c = 0; c < grid[r].length; c++) {
|
|
3045
|
+
if (grid[r][c].element === focusedCell) {
|
|
3046
|
+
row = r;
|
|
3047
|
+
col = c;
|
|
3048
|
+
break;
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
const clampedRow = clamp(row, 0, grid.length - 1);
|
|
3055
|
+
const clampedCol = clamp(col, 0, grid[clampedRow].length - 1);
|
|
3056
|
+
activeCoordsRef.current = { row: clampedRow, col: clampedCol };
|
|
3057
|
+
for (let r = 0; r < grid.length; r++) {
|
|
3058
|
+
for (let c = 0; c < grid[r].length; c++) {
|
|
3059
|
+
const { element, focusTarget } = grid[r][c];
|
|
3060
|
+
const isActive = r === clampedRow && c === clampedCol;
|
|
3061
|
+
element.setAttribute("tabindex", "-1");
|
|
3062
|
+
element.querySelectorAll(INTERACTIVE_SELECTOR).forEach((child) => {
|
|
3063
|
+
child.setAttribute("tabindex", "-1");
|
|
3064
|
+
});
|
|
3065
|
+
if (isActive) {
|
|
3066
|
+
focusTarget.setAttribute("tabindex", "0");
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
};
|
|
3071
|
+
React.useLayoutEffect(() => {
|
|
3072
|
+
if (!enabled) return;
|
|
3073
|
+
const table = tableRef.current;
|
|
3074
|
+
if (!table) return;
|
|
3075
|
+
const pending = pendingFocusRef.current;
|
|
3076
|
+
if (pending) {
|
|
3077
|
+
const grid = buildGrid(table);
|
|
3078
|
+
const gridRow = findNearestGridRowByDataIndex(grid, pending.dataIndex);
|
|
3079
|
+
if (gridRow >= 0) {
|
|
3080
|
+
pendingFocusRef.current = null;
|
|
3081
|
+
const col = clamp(pending.col, 0, grid[gridRow].length - 1);
|
|
3082
|
+
activeCoordsRef.current = { row: gridRow, col };
|
|
3083
|
+
syncTabIndices();
|
|
3084
|
+
grid[gridRow][col].focusTarget.focus();
|
|
3085
|
+
return;
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
syncTabIndices();
|
|
3089
|
+
});
|
|
3090
|
+
const navigateTo = (targetRow, targetCol) => {
|
|
3091
|
+
const table = tableRef.current;
|
|
3092
|
+
if (!table) return;
|
|
3093
|
+
const grid = buildGrid(table);
|
|
3094
|
+
if (grid.length === 0) return;
|
|
3095
|
+
const row = clamp(targetRow, 0, grid.length - 1);
|
|
3096
|
+
const col = clamp(targetCol, 0, grid[row].length - 1);
|
|
3097
|
+
activeCoordsRef.current = { row, col };
|
|
3098
|
+
syncTabIndices();
|
|
3099
|
+
const cell = grid[row]?.[col];
|
|
3100
|
+
if (cell) {
|
|
3101
|
+
cell.focusTarget.focus({ preventScroll: true });
|
|
3102
|
+
cell.element.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
3103
|
+
}
|
|
3104
|
+
};
|
|
3105
|
+
const navigateToDataIndex = (dataIndex, col) => {
|
|
3106
|
+
const table = tableRef.current;
|
|
3107
|
+
if (!table) return;
|
|
3108
|
+
const grid = buildGrid(table);
|
|
3109
|
+
const gridRow = findGridRowByDataIndex(grid, dataIndex);
|
|
3110
|
+
if (gridRow >= 0) {
|
|
3111
|
+
const clampedCol = clamp(col, 0, grid[gridRow].length - 1);
|
|
3112
|
+
activeCoordsRef.current = { row: gridRow, col: clampedCol };
|
|
3113
|
+
syncTabIndices();
|
|
3114
|
+
grid[gridRow][clampedCol].focusTarget.focus({ preventScroll: true });
|
|
3115
|
+
grid[gridRow][clampedCol].element.scrollIntoView?.({
|
|
3116
|
+
block: "nearest",
|
|
3117
|
+
inline: "nearest"
|
|
3118
|
+
});
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
if (onScrollToRowIndex) {
|
|
3122
|
+
onScrollToRowIndex(dataIndex);
|
|
3123
|
+
pendingFocusRef.current = { dataIndex, col };
|
|
3124
|
+
}
|
|
3125
|
+
};
|
|
3126
|
+
const onKeyDown = (e) => {
|
|
3127
|
+
if (!enabled) return;
|
|
3128
|
+
const table = tableRef.current;
|
|
3129
|
+
if (!table) return;
|
|
3130
|
+
if (isEditableTarget(e.target)) return;
|
|
3131
|
+
const grid = buildGrid(table);
|
|
3132
|
+
if (grid.length === 0) return;
|
|
3133
|
+
const cell = e.target.closest?.(
|
|
3134
|
+
"th, td"
|
|
3135
|
+
);
|
|
3136
|
+
if (!cell || !table.contains(cell)) return;
|
|
3137
|
+
let curRow = -1;
|
|
3138
|
+
let curCol = -1;
|
|
3139
|
+
outer: for (let r = 0; r < grid.length; r++) {
|
|
3140
|
+
for (let c = 0; c < grid[r].length; c++) {
|
|
3141
|
+
if (grid[r][c].element === cell) {
|
|
3142
|
+
curRow = r;
|
|
3143
|
+
curCol = c;
|
|
3144
|
+
break outer;
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
if (curRow < 0) return;
|
|
3149
|
+
const curDataIndex = getDataIndexOfCell(cell);
|
|
3150
|
+
const headerRows = countHeaderRows(grid);
|
|
3151
|
+
const isBodyRow = curDataIndex != null;
|
|
3152
|
+
const maxRow = grid.length - 1;
|
|
3153
|
+
let targetRow = curRow;
|
|
3154
|
+
let targetCol = curCol;
|
|
3155
|
+
let handled = true;
|
|
3156
|
+
switch (e.key) {
|
|
3157
|
+
case "ArrowRight":
|
|
3158
|
+
targetCol = Math.min(curCol + 1, grid[curRow].length - 1);
|
|
3159
|
+
break;
|
|
3160
|
+
case "ArrowLeft":
|
|
3161
|
+
targetCol = Math.max(curCol - 1, 0);
|
|
3162
|
+
break;
|
|
3163
|
+
case "ArrowDown":
|
|
3164
|
+
if (isBodyRow && rowItemCount != null) {
|
|
3165
|
+
const nextDataIndex = findNextNavigableDataIndex(
|
|
3166
|
+
grid,
|
|
3167
|
+
curDataIndex,
|
|
3168
|
+
1,
|
|
3169
|
+
rowItemCount
|
|
3170
|
+
);
|
|
3171
|
+
if (nextDataIndex != null) {
|
|
3172
|
+
e.preventDefault();
|
|
3173
|
+
navigateToDataIndex(nextDataIndex, curCol);
|
|
3174
|
+
return;
|
|
3175
|
+
}
|
|
3176
|
+
} else {
|
|
3177
|
+
targetRow = Math.min(curRow + 1, maxRow);
|
|
3178
|
+
}
|
|
3179
|
+
break;
|
|
3180
|
+
case "ArrowUp":
|
|
3181
|
+
if (isBodyRow) {
|
|
3182
|
+
const prevDataIndex = findNextNavigableDataIndex(
|
|
3183
|
+
grid,
|
|
3184
|
+
curDataIndex,
|
|
3185
|
+
-1,
|
|
3186
|
+
rowItemCount ?? curDataIndex
|
|
3187
|
+
);
|
|
3188
|
+
if (prevDataIndex != null) {
|
|
3189
|
+
e.preventDefault();
|
|
3190
|
+
navigateToDataIndex(prevDataIndex, curCol);
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
targetRow = Math.max(headerRows - 1, 0);
|
|
3194
|
+
} else {
|
|
3195
|
+
targetRow = Math.max(curRow - 1, 0);
|
|
3196
|
+
}
|
|
3197
|
+
break;
|
|
3198
|
+
case "Home":
|
|
3199
|
+
if (e.ctrlKey || e.metaKey) {
|
|
3200
|
+
targetRow = 0;
|
|
3201
|
+
targetCol = 0;
|
|
3202
|
+
} else {
|
|
3203
|
+
targetCol = 0;
|
|
3204
|
+
}
|
|
3205
|
+
break;
|
|
3206
|
+
case "End":
|
|
3207
|
+
if (e.ctrlKey || e.metaKey) {
|
|
3208
|
+
targetRow = maxRow;
|
|
3209
|
+
targetCol = grid[maxRow].length - 1;
|
|
3210
|
+
} else {
|
|
3211
|
+
targetCol = grid[curRow].length - 1;
|
|
3212
|
+
}
|
|
3213
|
+
break;
|
|
3214
|
+
case "PageDown":
|
|
3215
|
+
case "PageUp": {
|
|
3216
|
+
const pageSize = getVisiblePageSize(
|
|
3217
|
+
scrollContainerRef?.current ?? null,
|
|
3218
|
+
table
|
|
3219
|
+
);
|
|
3220
|
+
const direction = e.key === "PageDown" ? 1 : -1;
|
|
3221
|
+
if (isBodyRow && rowItemCount != null) {
|
|
3222
|
+
let target = curDataIndex;
|
|
3223
|
+
let stepsUsed = 0;
|
|
3224
|
+
for (let i = 0; i < pageSize; i++) {
|
|
3225
|
+
const next = findNextNavigableDataIndex(
|
|
3226
|
+
grid,
|
|
3227
|
+
target,
|
|
3228
|
+
direction,
|
|
3229
|
+
rowItemCount
|
|
3230
|
+
);
|
|
3231
|
+
if (next == null) break;
|
|
3232
|
+
target = next;
|
|
3233
|
+
stepsUsed++;
|
|
3234
|
+
}
|
|
3235
|
+
const hasRemainingSteps = stepsUsed < pageSize;
|
|
3236
|
+
if (direction === -1 && hasRemainingSteps) {
|
|
3237
|
+
targetRow = 0;
|
|
3238
|
+
break;
|
|
3239
|
+
}
|
|
3240
|
+
if (target !== curDataIndex) {
|
|
3241
|
+
e.preventDefault();
|
|
3242
|
+
navigateToDataIndex(target, curCol);
|
|
3243
|
+
return;
|
|
3244
|
+
}
|
|
3245
|
+
}
|
|
3246
|
+
targetRow = clamp(curRow + direction * pageSize, 0, maxRow);
|
|
3247
|
+
break;
|
|
3248
|
+
}
|
|
3249
|
+
default:
|
|
3250
|
+
handled = false;
|
|
3251
|
+
}
|
|
3252
|
+
if (handled) {
|
|
3253
|
+
e.preventDefault();
|
|
3254
|
+
targetCol = Math.min(targetCol, grid[targetRow].length - 1);
|
|
3255
|
+
navigateTo(targetRow, targetCol);
|
|
3256
|
+
}
|
|
3257
|
+
};
|
|
3258
|
+
const onFocus = (e) => {
|
|
3259
|
+
if (!enabled) return;
|
|
3260
|
+
const table = tableRef.current;
|
|
3261
|
+
if (!table) return;
|
|
3262
|
+
const cell = e.target.closest?.(
|
|
3263
|
+
"th, td"
|
|
3264
|
+
);
|
|
3265
|
+
if (!cell || !table.contains(cell)) return;
|
|
3266
|
+
if (focusedRowIndex != null && !table.contains(e.relatedTarget) && useFocusVisible.getInteractionModality() !== "pointer") {
|
|
3267
|
+
onScrollToRowIndex?.(focusedRowIndex, { align: "start" });
|
|
3268
|
+
}
|
|
3269
|
+
const grid = buildGrid(table);
|
|
3270
|
+
for (let r = 0; r < grid.length; r++) {
|
|
3271
|
+
for (let c = 0; c < grid[r].length; c++) {
|
|
3272
|
+
if (grid[r][c].element === cell) {
|
|
3273
|
+
activeCoordsRef.current = { row: r, col: c };
|
|
3274
|
+
syncTabIndices();
|
|
3275
|
+
const dataIndex = getDataIndexOfCell(cell);
|
|
3276
|
+
if (dataIndex !== focusedRowIndex) {
|
|
3277
|
+
setFocusedRowIndex(dataIndex);
|
|
3278
|
+
}
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
};
|
|
3284
|
+
const rangeExtractor = React.useCallback(
|
|
3285
|
+
(range) => {
|
|
3286
|
+
const indices = reactVirtual.defaultRangeExtractor(range);
|
|
3287
|
+
if (focusedRowIndex != null && !indices.includes(focusedRowIndex)) {
|
|
3288
|
+
indices.push(focusedRowIndex);
|
|
3289
|
+
indices.sort((a, b) => a - b);
|
|
3290
|
+
}
|
|
3291
|
+
return indices;
|
|
3292
|
+
},
|
|
3293
|
+
[focusedRowIndex]
|
|
3294
|
+
);
|
|
3295
|
+
return {
|
|
3296
|
+
gridKeyboardNavigationProps: { onKeyDown, onFocus },
|
|
3297
|
+
rangeExtractor
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
function clamp(value, min, max) {
|
|
3301
|
+
return Math.min(Math.max(value, min), max);
|
|
3302
|
+
}
|
|
3303
|
+
function findNextNavigableDataIndex(grid, fromDataIndex, direction, rowItemCount) {
|
|
3304
|
+
const navigable = /* @__PURE__ */ new Set();
|
|
3305
|
+
const nonNavigable = /* @__PURE__ */ new Set();
|
|
3306
|
+
const table = grid[0]?.[0]?.element.closest("table");
|
|
3307
|
+
if (table) {
|
|
3308
|
+
const tbody = table.querySelector("tbody");
|
|
3309
|
+
if (tbody) {
|
|
3310
|
+
tbody.querySelectorAll(":scope > tr[data-index]").forEach((tr) => {
|
|
3311
|
+
const idx = parseInt(tr.getAttribute(DATA_INDEX_ATTR), 10);
|
|
3312
|
+
if (isNaN(idx)) return;
|
|
3313
|
+
if (tr.hasAttribute(GRID_ROW_ATTR)) {
|
|
3314
|
+
navigable.add(idx);
|
|
3315
|
+
} else {
|
|
3316
|
+
nonNavigable.add(idx);
|
|
3317
|
+
}
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
let candidate = fromDataIndex + direction;
|
|
3322
|
+
while (candidate >= 0 && candidate < rowItemCount) {
|
|
3323
|
+
if (nonNavigable.has(candidate)) {
|
|
3324
|
+
candidate += direction;
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
3327
|
+
return candidate;
|
|
3328
|
+
}
|
|
3329
|
+
return null;
|
|
3330
|
+
}
|
|
3331
|
+
function findNearestGridRowByDataIndex(grid, targetDataIndex) {
|
|
3332
|
+
let bestRow = -1;
|
|
3333
|
+
let bestDist = Infinity;
|
|
3334
|
+
for (let r = 0; r < grid.length; r++) {
|
|
3335
|
+
const tr = grid[r][0]?.element.closest("tr");
|
|
3336
|
+
const raw = tr?.getAttribute(DATA_INDEX_ATTR);
|
|
3337
|
+
if (raw == null) continue;
|
|
3338
|
+
const idx = parseInt(raw, 10);
|
|
3339
|
+
if (isNaN(idx)) continue;
|
|
3340
|
+
const dist = Math.abs(idx - targetDataIndex);
|
|
3341
|
+
if (dist < bestDist) {
|
|
3342
|
+
bestDist = dist;
|
|
3343
|
+
bestRow = r;
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
return bestRow;
|
|
3347
|
+
}
|
|
3348
|
+
|
|
3349
|
+
const isHiddenHandler = {
|
|
3350
|
+
styleProp: "display",
|
|
3351
|
+
convertValue: (value) => value ? "none" : void 0
|
|
3352
|
+
};
|
|
3353
|
+
const commonStyleHandlers = {
|
|
3354
|
+
margin: "margin",
|
|
3355
|
+
marginLeft: "marginLeft",
|
|
3356
|
+
marginRight: "marginRight",
|
|
3357
|
+
marginTop: "marginTop",
|
|
3358
|
+
marginBottom: "marginBottom",
|
|
3359
|
+
marginX: {
|
|
3360
|
+
styleProps: ["marginLeft", "marginRight"]
|
|
3361
|
+
},
|
|
3362
|
+
marginY: {
|
|
3363
|
+
styleProps: ["marginTop", "marginBottom"]
|
|
3364
|
+
},
|
|
3365
|
+
width: "width",
|
|
3366
|
+
height: "height",
|
|
3367
|
+
minWidth: "minWidth",
|
|
3368
|
+
minHeight: "minHeight",
|
|
3369
|
+
maxWidth: "maxWidth",
|
|
3370
|
+
maxHeight: "maxHeight",
|
|
3371
|
+
flex: "flex",
|
|
3372
|
+
flexGrow: "flexGrow",
|
|
3373
|
+
flexShrink: "flexShrink",
|
|
3374
|
+
flexBasis: "flexBasis",
|
|
3375
|
+
justifySelf: "justifySelf",
|
|
3376
|
+
alignSelf: "alignSelf",
|
|
3377
|
+
order: "order",
|
|
3378
|
+
gridArea: "gridArea",
|
|
3379
|
+
gridColumn: "gridColumn",
|
|
3380
|
+
gridColumnEnd: "gridColumnEnd",
|
|
3381
|
+
gridColumnStart: "gridColumnStart",
|
|
3382
|
+
gridRow: "gridRow",
|
|
3383
|
+
gridRowEnd: "gridRowEnd",
|
|
3384
|
+
gridRowStart: "gridRowStart",
|
|
3385
|
+
position: "position",
|
|
3386
|
+
zIndex: "zIndex",
|
|
3387
|
+
top: "top",
|
|
3388
|
+
bottom: "bottom",
|
|
3389
|
+
left: "left",
|
|
3390
|
+
right: "right",
|
|
3391
|
+
inset: "inset",
|
|
3392
|
+
isHidden: isHiddenHandler
|
|
3393
|
+
};
|
|
3394
|
+
|
|
3395
|
+
function useBreakpointContext() {
|
|
3396
|
+
return React.useContext(
|
|
3397
|
+
sapphireReactContext.BreakpointContext
|
|
3398
|
+
);
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
const isSapphireToken = (obj) => "value" in obj;
|
|
3402
|
+
const resolveResponsiveValue = (matchedBreakpoints, value) => {
|
|
3403
|
+
if (value && typeof value === "object") {
|
|
3404
|
+
if (isSapphireToken(value)) {
|
|
3405
|
+
return value.value;
|
|
3406
|
+
}
|
|
3407
|
+
for (const breakpoint of matchedBreakpoints) {
|
|
3408
|
+
if (breakpoint === "base") {
|
|
3409
|
+
continue;
|
|
3410
|
+
}
|
|
3411
|
+
const breakpointValue = value[breakpoint];
|
|
3412
|
+
if (breakpointValue != null) {
|
|
3413
|
+
if (typeof breakpointValue === "object" && isSapphireToken(breakpointValue)) {
|
|
3414
|
+
return breakpointValue.value;
|
|
3415
|
+
}
|
|
3416
|
+
return breakpointValue;
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
const baseValue = value.base;
|
|
3420
|
+
if (baseValue != null) {
|
|
3421
|
+
if (typeof baseValue === "object" && isSapphireToken(baseValue)) {
|
|
3422
|
+
return baseValue.value;
|
|
3423
|
+
}
|
|
3424
|
+
return baseValue;
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
return value;
|
|
3428
|
+
};
|
|
3429
|
+
const useResolveResponsiveValue = () => {
|
|
3430
|
+
const breakpointContext = useBreakpointContext();
|
|
3431
|
+
const matchedBreakpoints = breakpointContext?.matchedBreakpoints || ["base"];
|
|
3432
|
+
return (value) => resolveResponsiveValue(matchedBreakpoints, value);
|
|
3433
|
+
};
|
|
3434
|
+
const generateRulePart = (containerBreakpointValue, className, key, breakpointResponsiveValue, container) => {
|
|
3435
|
+
const kebabCaseKey = key.replace(
|
|
3436
|
+
/[A-Z]/g,
|
|
3437
|
+
(match) => `-${match.toLowerCase()}`
|
|
3438
|
+
);
|
|
3439
|
+
const value = breakpointResponsiveValue && typeof breakpointResponsiveValue === "object" && isSapphireToken(breakpointResponsiveValue) ? breakpointResponsiveValue.value : breakpointResponsiveValue;
|
|
3440
|
+
return `
|
|
3441
|
+
@container ${typeof container === "string" ? container : ""} (min-width: ${containerBreakpointValue}px) {
|
|
3442
|
+
.${className} {
|
|
3443
|
+
${kebabCaseKey}: ${value};
|
|
3444
|
+
}
|
|
3445
|
+
}`;
|
|
3446
|
+
};
|
|
3447
|
+
const useContainerStyleProps = (props, handlers) => {
|
|
3448
|
+
const uniqueId = useId.useId().replace(/:/g, "_");
|
|
3449
|
+
const elementClassName = `container-query-${uniqueId}`;
|
|
3450
|
+
const breakpointContext = useBreakpointContext();
|
|
3451
|
+
let stylesString = "";
|
|
3452
|
+
Object.keys(props).forEach((_key) => {
|
|
3453
|
+
const key = _key;
|
|
3454
|
+
const responsiveValue = props[key];
|
|
3455
|
+
if (!responsiveValue || !isContainerResponsiveProp(responsiveValue)) {
|
|
3456
|
+
return;
|
|
3457
|
+
}
|
|
3458
|
+
const breakpoints = [
|
|
3459
|
+
0,
|
|
3460
|
+
// `value.base` should be mapped to min-width: 0px and should always be first in the stylesheet.
|
|
3461
|
+
...Object.keys(responsiveValue).filter(
|
|
3462
|
+
(breakpointKey) => !["base", "container"].includes(breakpointKey)
|
|
3463
|
+
)
|
|
3464
|
+
];
|
|
3465
|
+
breakpoints.forEach((breakpointKey) => {
|
|
3466
|
+
const isDesignTokenBreakpoint = isNaN(Number(breakpointKey));
|
|
3467
|
+
const containerBreakpointValue = isDesignTokenBreakpoint ? (
|
|
3468
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain -- we are confident it's a BreakpointKey
|
|
3469
|
+
breakpointContext?.breakpoints?.[breakpointKey]
|
|
3470
|
+
) : Number(breakpointKey);
|
|
3471
|
+
const value = isDesignTokenBreakpoint ? responsiveValue[breakpointKey] : breakpointKey === 0 ? responsiveValue.base : responsiveValue[containerBreakpointValue];
|
|
3472
|
+
Object.entries(
|
|
3473
|
+
normalizeHandler(handlers[key], value ?? void 0)
|
|
3474
|
+
).forEach(([styleProp, styleValue]) => {
|
|
3475
|
+
stylesString += generateRulePart(
|
|
3476
|
+
containerBreakpointValue,
|
|
3477
|
+
elementClassName,
|
|
3478
|
+
styleProp,
|
|
3479
|
+
styleValue,
|
|
3480
|
+
responsiveValue.container
|
|
3481
|
+
);
|
|
3482
|
+
});
|
|
3483
|
+
});
|
|
3484
|
+
});
|
|
3485
|
+
const getOrCreateStylesheet = React.useCallback(() => {
|
|
3486
|
+
const stylesheetElementId = "container-query-stylesheet-" + uniqueId;
|
|
3487
|
+
let containerQueryStylesheetElement = document.getElementById(stylesheetElementId);
|
|
3488
|
+
if (!containerQueryStylesheetElement) {
|
|
3489
|
+
containerQueryStylesheetElement = document.createElement("style");
|
|
3490
|
+
containerQueryStylesheetElement.id = stylesheetElementId;
|
|
3491
|
+
document.head.appendChild(containerQueryStylesheetElement);
|
|
3492
|
+
}
|
|
3493
|
+
return containerQueryStylesheetElement;
|
|
3494
|
+
}, [uniqueId]);
|
|
3495
|
+
React.useEffect(() => {
|
|
3496
|
+
if (!stylesString) {
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
const styleSheet = getOrCreateStylesheet();
|
|
3500
|
+
const cssRuleNode = document.createTextNode(stylesString);
|
|
3501
|
+
styleSheet.appendChild(cssRuleNode);
|
|
3502
|
+
return () => {
|
|
3503
|
+
styleSheet.remove();
|
|
3504
|
+
};
|
|
3505
|
+
}, [stylesString, getOrCreateStylesheet]);
|
|
3506
|
+
return {
|
|
3507
|
+
containerStylesClassName: stylesString ? elementClassName : ""
|
|
3508
|
+
};
|
|
3509
|
+
};
|
|
3510
|
+
function isContainerResponsiveProp(prop) {
|
|
3511
|
+
return prop && typeof prop === "object" && "container" in prop;
|
|
3512
|
+
}
|
|
3513
|
+
const useSapphireStyleProps = ({ UNSAFE_className, UNSAFE_style, ...props }, handlers = commonStyleHandlers) => {
|
|
3514
|
+
const resolveResponsiveValue2 = useResolveResponsiveValue();
|
|
3515
|
+
const { containerStylesClassName } = useContainerStyleProps(
|
|
3516
|
+
props,
|
|
3517
|
+
handlers
|
|
3518
|
+
);
|
|
3519
|
+
const derivedStyle = {};
|
|
3520
|
+
const filteredProps = {};
|
|
3521
|
+
Object.keys(props).forEach((key) => {
|
|
3522
|
+
if (["style", "className"].includes(key) && typeof process !== "undefined" && process.env?.NODE_ENV === "development") {
|
|
3523
|
+
return console.warn(
|
|
3524
|
+
"Passing 'style' or 'className' props will have no effect. Please use supported style props directly or use UNSAFE_style or UNSAFE_className if you have no other options than applying style directly to the component."
|
|
3525
|
+
);
|
|
3526
|
+
}
|
|
3527
|
+
const currentProp = props[key];
|
|
3528
|
+
const handler = handlers[key];
|
|
3529
|
+
if (handler !== void 0 && currentProp !== null) {
|
|
3530
|
+
if (!isContainerResponsiveProp(currentProp)) {
|
|
3531
|
+
const resolvedResponsiveValue = resolveResponsiveValue2(
|
|
3532
|
+
// @ts-expect-error: TS2590: Expression produces a union type that is too complex to represent.
|
|
3533
|
+
currentProp
|
|
3534
|
+
);
|
|
3535
|
+
Object.assign(
|
|
3536
|
+
derivedStyle,
|
|
3537
|
+
normalizeHandler(handler, resolvedResponsiveValue)
|
|
3538
|
+
);
|
|
3539
|
+
}
|
|
3540
|
+
} else {
|
|
3541
|
+
filteredProps[key] = currentProp;
|
|
3542
|
+
}
|
|
3543
|
+
});
|
|
3544
|
+
return {
|
|
3545
|
+
styleProps: {
|
|
3546
|
+
style: { ...UNSAFE_style, ...derivedStyle },
|
|
3547
|
+
className: clsx(UNSAFE_className, containerStylesClassName)
|
|
3548
|
+
},
|
|
3549
|
+
filteredProps
|
|
3550
|
+
};
|
|
3551
|
+
};
|
|
3552
|
+
function normalizeHandler(handler, value) {
|
|
3553
|
+
const result = {};
|
|
3554
|
+
if (value == void 0) {
|
|
3555
|
+
return result;
|
|
3556
|
+
}
|
|
3557
|
+
if (typeof handler === "object") {
|
|
3558
|
+
if ("convertValue" in handler) {
|
|
3559
|
+
value = handler.convertValue(value);
|
|
3560
|
+
}
|
|
3561
|
+
const styleProps = "styleProps" in handler ? handler.styleProps : [handler.styleProp];
|
|
3562
|
+
styleProps.forEach((styleProp) => {
|
|
3563
|
+
result[styleProp] = value;
|
|
3564
|
+
});
|
|
3565
|
+
} else {
|
|
3566
|
+
result[handler] = value;
|
|
3567
|
+
}
|
|
3568
|
+
return result;
|
|
3569
|
+
}
|
|
3570
|
+
|
|
3571
|
+
({
|
|
3572
|
+
...commonStyleHandlers});
|
|
3573
|
+
|
|
3574
|
+
const ListBoxContext = React.createContext(
|
|
3575
|
+
null
|
|
3576
|
+
);
|
|
3577
|
+
|
|
3578
|
+
const getAnimationDelay = (order) => order ? `${order * 80}ms` : void 0;
|
|
3579
|
+
|
|
3580
|
+
const isFixedWidthType = (props) => {
|
|
3581
|
+
return props.widthType === "fixed";
|
|
3582
|
+
};
|
|
3583
|
+
const SkeletonText = (props) => {
|
|
3584
|
+
useThemeCheck();
|
|
3585
|
+
const {
|
|
3586
|
+
index,
|
|
3587
|
+
widthType = "randomPct",
|
|
3588
|
+
UNSAFE_className,
|
|
3589
|
+
UNSAFE_style,
|
|
3590
|
+
children,
|
|
3591
|
+
minWidth = 50,
|
|
3592
|
+
maxWidth = 100,
|
|
3593
|
+
...rest
|
|
3594
|
+
} = props;
|
|
3595
|
+
const animationDelay = getAnimationDelay(index);
|
|
3596
|
+
const { styleProps } = useSapphireStyleProps({
|
|
3597
|
+
UNSAFE_className,
|
|
3598
|
+
UNSAFE_style
|
|
3599
|
+
});
|
|
3600
|
+
const skeletonWidth = React.useMemo(() => {
|
|
3601
|
+
if (isFixedWidthType(props)) {
|
|
3602
|
+
return props.width;
|
|
3603
|
+
}
|
|
3604
|
+
const calculatedWidth = Math.random() * (maxWidth - minWidth) + minWidth;
|
|
3605
|
+
return widthType === "randomPct" ? `${calculatedWidth}%` : calculatedWidth;
|
|
3606
|
+
}, []);
|
|
3607
|
+
return /* @__PURE__ */ React.createElement(
|
|
3608
|
+
"span",
|
|
3609
|
+
{
|
|
3610
|
+
...rest,
|
|
3611
|
+
style: {
|
|
3612
|
+
width: skeletonWidth,
|
|
3613
|
+
animationDelay,
|
|
3614
|
+
...styleProps.style
|
|
3615
|
+
},
|
|
3616
|
+
className: clsx(
|
|
3617
|
+
styles$d["sapphire-skeleton"],
|
|
3618
|
+
styles$d["sapphire-skeleton--text"],
|
|
3619
|
+
styleProps.className
|
|
3620
|
+
)
|
|
3621
|
+
}
|
|
3622
|
+
);
|
|
3623
|
+
};
|
|
3624
|
+
|
|
3625
|
+
const SkeletonCircle = ({
|
|
3626
|
+
index,
|
|
3627
|
+
children,
|
|
3628
|
+
...rest
|
|
3629
|
+
}) => {
|
|
3630
|
+
useThemeCheck();
|
|
3631
|
+
const { styleProps } = useSapphireStyleProps(rest);
|
|
3632
|
+
const animationDelay = getAnimationDelay(index);
|
|
3633
|
+
return /* @__PURE__ */ React.createElement(
|
|
3634
|
+
"div",
|
|
3635
|
+
{
|
|
3636
|
+
...rest,
|
|
3637
|
+
style: {
|
|
3638
|
+
animationDelay,
|
|
3639
|
+
...styleProps.style
|
|
3640
|
+
},
|
|
3641
|
+
className: clsx(
|
|
3642
|
+
styles$d["sapphire-skeleton"],
|
|
3643
|
+
styles$d["sapphire-skeleton--circle"],
|
|
3644
|
+
styleProps.className
|
|
3645
|
+
)
|
|
3646
|
+
}
|
|
3647
|
+
);
|
|
3648
|
+
};
|
|
3649
|
+
|
|
3650
|
+
const Skeleton = {
|
|
3651
|
+
Circle: SkeletonCircle,
|
|
3652
|
+
Text: SkeletonText};
|
|
3653
|
+
|
|
3654
|
+
const ListBoxItemSkeleton = ({
|
|
3655
|
+
index,
|
|
3656
|
+
primaryText = true,
|
|
3657
|
+
secondaryText = false,
|
|
3658
|
+
icon = false,
|
|
3659
|
+
iconSize = "lg"
|
|
3660
|
+
}) => /* @__PURE__ */ React.createElement(
|
|
3661
|
+
"div",
|
|
3662
|
+
{
|
|
3663
|
+
className: clsx(
|
|
3664
|
+
styles$e["sapphire-listbox__item"],
|
|
3665
|
+
styles$e["js-hover"],
|
|
3666
|
+
styles$e["js-focus"]
|
|
3667
|
+
)
|
|
3668
|
+
},
|
|
3669
|
+
/* @__PURE__ */ React.createElement("div", { className: styles$e["sapphire-listbox__content"] }, icon && /* @__PURE__ */ React.createElement("div", { className: styles$e["sapphire-listbox__icon"] }, /* @__PURE__ */ React.createElement(
|
|
3670
|
+
"div",
|
|
3671
|
+
{
|
|
3672
|
+
className: clsx(iconStyles["sapphire-icon"], {
|
|
3673
|
+
[iconStyles["sapphire-icon--sm"]]: iconSize === "sm",
|
|
3674
|
+
[iconStyles["sapphire-icon--md"]]: iconSize === "md",
|
|
3675
|
+
[iconStyles["sapphire-icon--lg"]]: iconSize === "lg",
|
|
3676
|
+
[iconStyles["sapphire-icon--xl"]]: iconSize === "xl"
|
|
3677
|
+
})
|
|
3678
|
+
},
|
|
3679
|
+
icon === true ? /* @__PURE__ */ React.createElement(Skeleton.Circle, { index }) : icon
|
|
3680
|
+
)), /* @__PURE__ */ React.createElement("div", { className: styles$e["sapphire-listbox__text-container"] }, /* @__PURE__ */ React.createElement("div", { className: styles$e["sapphire-listbox__primary-text"] }, primaryText === true ? /* @__PURE__ */ React.createElement(Skeleton.Text, { index }) : primaryText), secondaryText && /* @__PURE__ */ React.createElement("div", { className: styles$e["sapphire-listbox__secondary-text"] }, secondaryText === true ? /* @__PURE__ */ React.createElement(Skeleton.Text, { index }) : secondaryText)))
|
|
3681
|
+
);
|
|
3682
|
+
|
|
3683
|
+
const Icon = React.forwardRef(function Icon2({
|
|
3684
|
+
size = "md",
|
|
3685
|
+
color = "inherit",
|
|
3686
|
+
"aria-label": ariaLabel,
|
|
3687
|
+
...props
|
|
3688
|
+
}, ref) {
|
|
3689
|
+
useThemeCheck();
|
|
3690
|
+
const { styleProps } = useSapphireStyleProps(props);
|
|
3691
|
+
const colorClass = color === "inherit" ? void 0 : iconStyles[`sapphire-icon--${color}`];
|
|
3692
|
+
return React.cloneElement(utils.getWrappedElement(props.children), {
|
|
3693
|
+
ref,
|
|
3694
|
+
role: "img",
|
|
3695
|
+
...ariaLabel ? { "aria-label": ariaLabel } : { "aria-hidden": true },
|
|
3696
|
+
className: clsx(
|
|
3697
|
+
iconStyles["sapphire-icon"],
|
|
3698
|
+
styleProps.className,
|
|
3699
|
+
iconStyles[`sapphire-icon--${size}`],
|
|
3700
|
+
colorClass
|
|
3701
|
+
),
|
|
3702
|
+
style: styleProps.style
|
|
3703
|
+
});
|
|
3704
|
+
});
|
|
3705
|
+
|
|
3706
|
+
const flexStylePropsHandler = {
|
|
3707
|
+
...commonStyleHandlers,
|
|
3708
|
+
flexDirection: "flexDirection",
|
|
3709
|
+
flexWrap: "flexWrap",
|
|
3710
|
+
flexFlow: "flexFlow",
|
|
3711
|
+
justifyContent: { styleProp: "justifyContent", convertValue: flexAlignValue },
|
|
3712
|
+
alignItems: { styleProp: "alignItems", convertValue: flexAlignValue },
|
|
3713
|
+
alignContent: { styleProp: "alignContent", convertValue: flexAlignValue },
|
|
3714
|
+
gap: "gap",
|
|
3715
|
+
columnGap: "columnGap",
|
|
3716
|
+
rowGap: "rowGap",
|
|
3717
|
+
padding: "padding",
|
|
3718
|
+
paddingLeft: "paddingLeft",
|
|
3719
|
+
paddingRight: "paddingRight",
|
|
3720
|
+
paddingTop: "paddingTop",
|
|
3721
|
+
paddingBottom: "paddingBottom",
|
|
3722
|
+
container: "container",
|
|
3723
|
+
containerType: "containerType",
|
|
3724
|
+
containerName: "containerName"
|
|
3725
|
+
};
|
|
3726
|
+
React.forwardRef(function Flex2(props, ref) {
|
|
3727
|
+
useThemeCheck();
|
|
3728
|
+
const { children, elementType, ...otherProps } = props;
|
|
3729
|
+
const { styleProps, filteredProps } = useSapphireStyleProps(otherProps, flexStylePropsHandler);
|
|
3730
|
+
const style = {
|
|
3731
|
+
...styleProps.style,
|
|
3732
|
+
display: "flex"
|
|
3733
|
+
};
|
|
3734
|
+
const ElementType2 = elementType || "div";
|
|
3735
|
+
return /* @__PURE__ */ React.createElement(
|
|
3736
|
+
ElementType2,
|
|
3737
|
+
{
|
|
3738
|
+
...filteredProps,
|
|
3739
|
+
...filterDOMProps.filterDOMProps(props, { global: true }),
|
|
3740
|
+
style,
|
|
3741
|
+
ref,
|
|
3742
|
+
className: styleProps.className
|
|
3743
|
+
},
|
|
3744
|
+
children
|
|
3745
|
+
);
|
|
3746
|
+
});
|
|
3747
|
+
function flexAlignValue(value) {
|
|
3748
|
+
if (value === "start") {
|
|
3749
|
+
return "flex-start";
|
|
3750
|
+
}
|
|
3751
|
+
if (value === "end") {
|
|
3752
|
+
return "flex-end";
|
|
3753
|
+
}
|
|
3754
|
+
return value;
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3757
|
+
const gridStylePropsHandler = {
|
|
3758
|
+
...commonStyleHandlers,
|
|
3759
|
+
gridAutoFlow: "gridAutoFlow",
|
|
3760
|
+
gridAutoColumns: "gridAutoColumns",
|
|
3761
|
+
gridAutoRows: "gridAutoRows",
|
|
3762
|
+
gridTemplateAreas: "gridTemplateAreas",
|
|
3763
|
+
gridTemplateColumns: "gridTemplateColumns",
|
|
3764
|
+
gridTemplateRows: "gridTemplateRows",
|
|
3765
|
+
gap: "gap",
|
|
3766
|
+
columnGap: "columnGap",
|
|
3767
|
+
rowGap: "rowGap",
|
|
3768
|
+
justifyItems: "justifyItems",
|
|
3769
|
+
justifyContent: "justifyContent",
|
|
3770
|
+
alignItems: "alignItems",
|
|
3771
|
+
alignContent: "alignContent",
|
|
3772
|
+
padding: "padding",
|
|
3773
|
+
paddingLeft: "paddingLeft",
|
|
3774
|
+
paddingRight: "paddingRight",
|
|
3775
|
+
paddingTop: "paddingTop",
|
|
3776
|
+
paddingBottom: "paddingBottom"
|
|
3777
|
+
};
|
|
3778
|
+
React.forwardRef(function Grid2(props, ref) {
|
|
3779
|
+
useThemeCheck();
|
|
3780
|
+
const { children, ...otherProps } = props;
|
|
3781
|
+
const { styleProps, filteredProps } = useSapphireStyleProps(otherProps, gridStylePropsHandler);
|
|
3782
|
+
const style = {
|
|
3783
|
+
...styleProps.style,
|
|
3784
|
+
display: "grid"
|
|
3785
|
+
};
|
|
3786
|
+
return /* @__PURE__ */ React.createElement(
|
|
3787
|
+
"div",
|
|
3788
|
+
{
|
|
3789
|
+
...filteredProps,
|
|
3790
|
+
...filterDOMProps.filterDOMProps(props, { global: true }),
|
|
3791
|
+
style,
|
|
3792
|
+
ref,
|
|
3793
|
+
className: styleProps.className
|
|
3794
|
+
},
|
|
3795
|
+
children
|
|
3796
|
+
);
|
|
3797
|
+
});
|
|
3798
|
+
|
|
3799
|
+
const viewStylePropHandlers = {
|
|
3800
|
+
...commonStyleHandlers,
|
|
3801
|
+
...flexStylePropsHandler,
|
|
3802
|
+
...gridStylePropsHandler,
|
|
3803
|
+
display: "display",
|
|
3804
|
+
color: "color",
|
|
3805
|
+
backgroundColor: "backgroundColor",
|
|
3806
|
+
border: "border",
|
|
3807
|
+
borderWidth: "borderWidth",
|
|
3808
|
+
borderColor: "borderColor",
|
|
3809
|
+
borderStyle: "borderStyle",
|
|
3810
|
+
borderLeft: "borderLeft",
|
|
3811
|
+
borderLeftWidth: "borderLeftWidth",
|
|
3812
|
+
borderLeftColor: "borderLeftColor",
|
|
3813
|
+
borderLeftStyle: "borderLeftStyle",
|
|
3814
|
+
borderRight: "borderRight",
|
|
3815
|
+
borderRightWidth: "borderRightWidth",
|
|
3816
|
+
borderRightColor: "borderRightColor",
|
|
3817
|
+
borderRightStyle: "borderRightStyle",
|
|
3818
|
+
borderTop: "borderTop",
|
|
3819
|
+
borderTopWidth: "borderTopWidth",
|
|
3820
|
+
borderTopColor: "borderTopColor",
|
|
3821
|
+
borderTopStyle: "borderTopStyle",
|
|
3822
|
+
borderBottom: "borderBottom",
|
|
3823
|
+
borderBottomWidth: "borderBottomWidth",
|
|
3824
|
+
borderBottomColor: "borderBottomColor",
|
|
3825
|
+
borderBottomStyle: "borderBottomStyle",
|
|
3826
|
+
borderRadius: "borderRadius",
|
|
3827
|
+
borderTopLeftRadius: "borderTopLeftRadius",
|
|
3828
|
+
borderTopRightRadius: "borderTopRightRadius",
|
|
3829
|
+
borderBottomLeftRadius: "borderBottomLeftRadius",
|
|
3830
|
+
borderBottomRightRadius: "borderBottomRightRadius",
|
|
3831
|
+
boxShadow: "boxShadow",
|
|
3832
|
+
container: "container",
|
|
3833
|
+
containerType: "containerType",
|
|
3834
|
+
containerName: "containerName",
|
|
3835
|
+
overflow: "overflow",
|
|
3836
|
+
overflowX: "overflowX",
|
|
3837
|
+
overflowY: "overflowY"
|
|
3838
|
+
};
|
|
3839
|
+
React.forwardRef(function View2({ elementType: ElementType = "div", children, ...otherProps }, ref) {
|
|
3840
|
+
useThemeCheck();
|
|
3841
|
+
const { styleProps, filteredProps } = useSapphireStyleProps(otherProps, viewStylePropHandlers);
|
|
3842
|
+
return /* @__PURE__ */ React.createElement(ElementType, { ...filteredProps, ...styleProps, ref }, children);
|
|
3843
|
+
});
|
|
3844
|
+
|
|
3845
|
+
React.forwardRef(function ThemeRoot2({ children, variant, noSurface = false, ...props }, ref) {
|
|
3846
|
+
const themeContext = React.useContext(sapphireReactContext.ThemeContext);
|
|
3847
|
+
if (typeof themeContext.theme === "undefined") {
|
|
3848
|
+
throw new Error(
|
|
3849
|
+
"<ThemeRoot> must be rendered inside a <SapphireProvider>."
|
|
3850
|
+
);
|
|
3851
|
+
}
|
|
3852
|
+
const { styleProps } = useSapphireStyleProps(props, viewStylePropHandlers);
|
|
3853
|
+
const theme = themeContext.theme;
|
|
3854
|
+
const themeVariant = variant || themeContext.themeVariant;
|
|
3855
|
+
const themeClassName = theme?.themeClassName;
|
|
3856
|
+
const colorScheme = themeClassName?.includes("dark") ? "dark" : "light";
|
|
3857
|
+
return /* @__PURE__ */ React.createElement(
|
|
3858
|
+
"div",
|
|
3859
|
+
{
|
|
3860
|
+
className: clsx(
|
|
3861
|
+
themeClassName,
|
|
3862
|
+
themeVariant === "secondary" ? theme?.themeSecondaryModifierClassName : themeVariant === "tertiary" ? theme?.themeTertiaryModifierClassName : themeVariant === "contrast" ? theme?.themeContrastModifierClassName : null,
|
|
3863
|
+
styleProps.className,
|
|
3864
|
+
!noSurface && surfaceStyles["sapphire-surface"]
|
|
3865
|
+
),
|
|
3866
|
+
style: { ...styleProps.style, colorScheme },
|
|
3867
|
+
ref,
|
|
3868
|
+
...filterDOMProps.filterDOMProps(props, { global: true })
|
|
3869
|
+
},
|
|
3870
|
+
children
|
|
3871
|
+
);
|
|
3872
|
+
});
|
|
3873
|
+
|
|
3874
|
+
const ListBoxOption = ({
|
|
3875
|
+
item
|
|
3876
|
+
}) => {
|
|
3877
|
+
const ref = React.useRef(null);
|
|
3878
|
+
const {
|
|
3879
|
+
state,
|
|
3880
|
+
shouldUseVirtualFocus,
|
|
3881
|
+
disableSelectedStyles,
|
|
3882
|
+
containerMaxWidth
|
|
3883
|
+
} = React.useContext(ListBoxContext);
|
|
3884
|
+
const {
|
|
3885
|
+
optionProps,
|
|
3886
|
+
isDisabled,
|
|
3887
|
+
isFocused: isVirtuallyFocused,
|
|
3888
|
+
isPressed
|
|
3889
|
+
} = useListBox.useOption({ key: item.key }, state, ref);
|
|
3890
|
+
const { focusProps, isFocusVisible: isFocusRingVisible } = useFocusRing.useFocusRing();
|
|
3891
|
+
const { hoverProps, isHovered } = useHover.useHover({ isDisabled });
|
|
3892
|
+
usePreventTouchEnd(ref);
|
|
3893
|
+
const rightIcon = item.props.rightIcon || item.props.icon;
|
|
3894
|
+
return /* @__PURE__ */ React.createElement(
|
|
3895
|
+
"div",
|
|
3896
|
+
{
|
|
3897
|
+
...mergeProps.mergeProps(
|
|
3898
|
+
optionProps,
|
|
3899
|
+
hoverProps,
|
|
3900
|
+
shouldUseVirtualFocus ? {} : focusProps
|
|
3901
|
+
),
|
|
3902
|
+
ref,
|
|
3903
|
+
className: clsx(
|
|
3904
|
+
styles$e["sapphire-listbox__item"],
|
|
3905
|
+
styles$e["js-hover"],
|
|
3906
|
+
styles$e["js-focus"],
|
|
3907
|
+
{
|
|
3908
|
+
[styles$e["is-disabled"]]: isDisabled,
|
|
3909
|
+
[styles$e["is-focus"]]: shouldUseVirtualFocus ? isVirtuallyFocused && useFocusVisible.isFocusVisible() : isFocusRingVisible,
|
|
3910
|
+
[styles$e["is-hover"]]: isHovered,
|
|
3911
|
+
[styles$e["is-active"]]: isPressed
|
|
3912
|
+
}
|
|
3913
|
+
)
|
|
3914
|
+
},
|
|
3915
|
+
/* @__PURE__ */ React.createElement(
|
|
3916
|
+
"div",
|
|
3917
|
+
{
|
|
3918
|
+
className: clsx(styles$e["sapphire-listbox__content"]),
|
|
3919
|
+
style: containerMaxWidth !== void 0 ? {
|
|
3920
|
+
maxWidth: `calc(${containerMaxWidth}px - 2 * ${themes.tokens.size.iconSm})`
|
|
3921
|
+
} : void 0
|
|
3922
|
+
},
|
|
3923
|
+
!disableSelectedStyles && /* @__PURE__ */ React.createElement(
|
|
3924
|
+
"div",
|
|
3925
|
+
{
|
|
3926
|
+
className: clsx(styles$e["sapphire-listbox__checkmark"]),
|
|
3927
|
+
style: {
|
|
3928
|
+
visibility: state.selectionManager.selectedKeys.has(item.key) ? "visible" : "hidden"
|
|
3929
|
+
}
|
|
3930
|
+
},
|
|
3931
|
+
/* @__PURE__ */ React.createElement(Icon, { size: "sm", color: "informative" }, /* @__PURE__ */ React.createElement(react.Checkmark, null))
|
|
3932
|
+
),
|
|
3933
|
+
item.props.leftIcon && /* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__icon"]) }, /* @__PURE__ */ React.createElement(Icon, { size: "sm" }, item.props.leftIcon)),
|
|
3934
|
+
/* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__text-container"]) }, /* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__primary-text"]) }, item.rendered), item.props.secondaryText && /* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__secondary-text"]) }, item.props.secondaryText)),
|
|
3935
|
+
rightIcon ? /* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__icon"]) }, /* @__PURE__ */ React.createElement(Icon, { size: "sm" }, rightIcon)) : item.props.avatar && /* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__icon"]) }, /* @__PURE__ */ React.createElement(
|
|
3936
|
+
"div",
|
|
3937
|
+
{
|
|
3938
|
+
className: clsx(
|
|
3939
|
+
avatarStyles["sapphire-avatar"],
|
|
3940
|
+
avatarStyles["sapphire-avatar--sm"]
|
|
3941
|
+
)
|
|
3942
|
+
},
|
|
3943
|
+
item.props.avatar
|
|
3944
|
+
))
|
|
3945
|
+
)
|
|
3946
|
+
);
|
|
3947
|
+
};
|
|
3948
|
+
|
|
3949
|
+
const useThemeCheck = () => {
|
|
3950
|
+
const themeContext = React.useContext(sapphireReactContext.ThemeContext);
|
|
3951
|
+
if (typeof themeContext.theme === void 0) {
|
|
3952
|
+
throw new Error(
|
|
3953
|
+
"A Sapphire component must be rendered inside a <SapphireProvider>."
|
|
3954
|
+
);
|
|
3955
|
+
}
|
|
3956
|
+
};
|
|
3957
|
+
|
|
3958
|
+
const Separator = React.forwardRef(function Separator2(props, ref) {
|
|
3959
|
+
useThemeCheck();
|
|
3960
|
+
const { orientation = "horizontal", ...otherProps } = props;
|
|
3961
|
+
const { styleProps, filteredProps } = useSapphireStyleProps(otherProps);
|
|
3962
|
+
return /* @__PURE__ */ React.createElement(
|
|
3963
|
+
reactAriaComponents.Separator,
|
|
3964
|
+
{
|
|
3965
|
+
ref,
|
|
3966
|
+
...filteredProps,
|
|
3967
|
+
...filterDOMProps.filterDOMProps(props, { global: true }),
|
|
3968
|
+
style: styleProps.style,
|
|
3969
|
+
className: clsx(styles$f["sapphire-separator"], styleProps.className),
|
|
3970
|
+
orientation
|
|
3971
|
+
}
|
|
3972
|
+
);
|
|
3973
|
+
});
|
|
3974
|
+
|
|
3975
|
+
function ListBoxSection({
|
|
3976
|
+
item,
|
|
3977
|
+
layoutInfo,
|
|
3978
|
+
virtualizer,
|
|
3979
|
+
childrenViews,
|
|
3980
|
+
children
|
|
3981
|
+
}) {
|
|
3982
|
+
useThemeCheck();
|
|
3983
|
+
const { groupProps, headingProps } = useListBox.useListBoxSection({
|
|
3984
|
+
"aria-label": item["aria-label"],
|
|
3985
|
+
heading: item.rendered
|
|
3986
|
+
});
|
|
3987
|
+
const headerLayoutInfo = childrenViews && childrenViews.find((c) => c.viewType === "header")?.layoutInfo;
|
|
3988
|
+
const dividerLayoutInfo = childrenViews && childrenViews.find((c) => c.viewType === "divider")?.layoutInfo;
|
|
3989
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, headerLayoutInfo && /* @__PURE__ */ React.createElement(
|
|
3990
|
+
"div",
|
|
3991
|
+
{
|
|
3992
|
+
role: "presentation",
|
|
3993
|
+
style: VirtualizerItem.layoutInfoToStyle(headerLayoutInfo, "ltr")
|
|
3994
|
+
},
|
|
3995
|
+
item.prevKey && /* @__PURE__ */ React.createElement(
|
|
3996
|
+
Separator,
|
|
3997
|
+
{
|
|
3998
|
+
UNSAFE_className: styles$e["sapphire-listbox__separator"]
|
|
3999
|
+
}
|
|
4000
|
+
),
|
|
4001
|
+
item.rendered && /* @__PURE__ */ React.createElement(
|
|
4002
|
+
SectionHeader,
|
|
4003
|
+
{
|
|
4004
|
+
item,
|
|
4005
|
+
headerLayoutInfo,
|
|
4006
|
+
headingProps,
|
|
4007
|
+
virtualizer
|
|
4008
|
+
}
|
|
4009
|
+
)
|
|
4010
|
+
), layoutInfo && /* @__PURE__ */ React.createElement(
|
|
4011
|
+
"div",
|
|
4012
|
+
{
|
|
4013
|
+
...groupProps,
|
|
4014
|
+
key: layoutInfo.key,
|
|
4015
|
+
style: VirtualizerItem.layoutInfoToStyle(layoutInfo, "ltr"),
|
|
4016
|
+
className: styles$e["sapphire-listbox__section"]
|
|
4017
|
+
},
|
|
4018
|
+
children
|
|
4019
|
+
), dividerLayoutInfo && /* @__PURE__ */ React.createElement(
|
|
4020
|
+
"div",
|
|
4021
|
+
{
|
|
4022
|
+
role: "presentation",
|
|
4023
|
+
style: VirtualizerItem.layoutInfoToStyle(dividerLayoutInfo, "ltr")
|
|
4024
|
+
},
|
|
4025
|
+
/* @__PURE__ */ React.createElement(Separator, { UNSAFE_className: styles$e["sapphire-listbox__separator"] })
|
|
4026
|
+
));
|
|
4027
|
+
}
|
|
4028
|
+
const SectionHeader = ({
|
|
4029
|
+
item,
|
|
4030
|
+
headerLayoutInfo,
|
|
4031
|
+
headingProps,
|
|
4032
|
+
virtualizer
|
|
4033
|
+
}) => {
|
|
4034
|
+
const headerRef = React.useRef(null);
|
|
4035
|
+
useVirtualizerItem.useVirtualizerItem({
|
|
4036
|
+
layoutInfo: headerLayoutInfo,
|
|
4037
|
+
virtualizer,
|
|
4038
|
+
ref: headerRef
|
|
4039
|
+
});
|
|
4040
|
+
return /* @__PURE__ */ React.createElement(
|
|
4041
|
+
"div",
|
|
4042
|
+
{
|
|
4043
|
+
...headingProps,
|
|
4044
|
+
ref: headerRef,
|
|
4045
|
+
className: styles$e["sapphire-listbox__section-header"]
|
|
4046
|
+
},
|
|
4047
|
+
item.rendered
|
|
4048
|
+
);
|
|
4049
|
+
};
|
|
4050
|
+
|
|
4051
|
+
class VariableWidthListLayout extends useVirtualizerState.ListLayout {
|
|
4052
|
+
/**
|
|
4053
|
+
* content width of items are stored here, if the content width is bigger than the Virtualizer's
|
|
4054
|
+
* visible rect's width.
|
|
4055
|
+
*/
|
|
4056
|
+
keyToWidth = /* @__PURE__ */ new Map();
|
|
4057
|
+
visibleContentWidth = 0;
|
|
4058
|
+
constructor(options) {
|
|
4059
|
+
super(options);
|
|
4060
|
+
}
|
|
4061
|
+
buildItem(node, x, y) {
|
|
4062
|
+
const previousLayoutNode = this.layoutNodes.get(node.key);
|
|
4063
|
+
const layoutNode = super.buildItem(node, x, y);
|
|
4064
|
+
if (this.visibleContentWidth) {
|
|
4065
|
+
layoutNode.layoutInfo.rect.width = this.visibleContentWidth;
|
|
4066
|
+
}
|
|
4067
|
+
if (previousLayoutNode && previousLayoutNode.node === node && !previousLayoutNode.layoutInfo.estimatedSize) {
|
|
4068
|
+
layoutNode.layoutInfo.estimatedSize = false;
|
|
4069
|
+
}
|
|
4070
|
+
return layoutNode;
|
|
4071
|
+
}
|
|
4072
|
+
/**
|
|
4073
|
+
* Allows for overriding buildCollection in a sub-class
|
|
4074
|
+
*/
|
|
4075
|
+
doBuildCollection() {
|
|
4076
|
+
return super.buildCollection();
|
|
4077
|
+
}
|
|
4078
|
+
buildCollection() {
|
|
4079
|
+
this.visibleContentWidth = this.getVisibleContentWidth();
|
|
4080
|
+
const layoutNodes = this.doBuildCollection();
|
|
4081
|
+
this.contentSize.width = this.visibleContentWidth;
|
|
4082
|
+
return layoutNodes;
|
|
4083
|
+
}
|
|
4084
|
+
shouldInvalidate(newRect, oldRect) {
|
|
4085
|
+
return super.shouldInvalidate(newRect, oldRect) || this.getVisibleContentWidth() !== this.visibleContentWidth;
|
|
4086
|
+
}
|
|
4087
|
+
shouldInvalidateEverything(invalidationContext) {
|
|
4088
|
+
return super.shouldInvalidateEverything(invalidationContext) || // in buildChild, if invalidateEverything is false and y is not changed, it will reuse the existing layoutInfo.
|
|
4089
|
+
// which can be problematic, if it was created in a time when the visible content width was different.
|
|
4090
|
+
// A more efficient approach (instead of rebuilding the whole collection), might be to set layout width to
|
|
4091
|
+
// visibleContentWidth, in getVisibleLayoutInfos, if mutation is ok.
|
|
4092
|
+
// UPDATE: using getFinalLayoutInfo seems to be a legitimate last minute way to mutate layout infos.
|
|
4093
|
+
this.contentSize?.width !== this.visibleContentWidth;
|
|
4094
|
+
}
|
|
4095
|
+
updateItemSize(key, size) {
|
|
4096
|
+
const changed = super.updateItemSize(key, size);
|
|
4097
|
+
const layoutNode = this.layoutNodes.get(key);
|
|
4098
|
+
if (!layoutNode) return false;
|
|
4099
|
+
const layoutInfo = layoutNode.layoutInfo;
|
|
4100
|
+
if (layoutInfo && size.width > this.contentSize.width) {
|
|
4101
|
+
this.keyToWidth.set(key, size.width);
|
|
4102
|
+
this.contentSize.width = size.width;
|
|
4103
|
+
return true;
|
|
4104
|
+
} else {
|
|
4105
|
+
return changed;
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
getVisibleContentWidth() {
|
|
4109
|
+
return this.virtualizer ? Math.max(
|
|
4110
|
+
this.virtualizer.visibleRect.width,
|
|
4111
|
+
...Array.from(this.keyToWidth.values())
|
|
4112
|
+
) : 0;
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
|
|
4116
|
+
class ListWithLoadingStateLayout extends VariableWidthListLayout {
|
|
4117
|
+
options;
|
|
4118
|
+
constructor(options) {
|
|
4119
|
+
super(options);
|
|
4120
|
+
this.options = options;
|
|
4121
|
+
this.loaderSize = options.loadingRowsCount * (options.rowHeight ?? options.estimatedRowHeight ?? 50);
|
|
4122
|
+
}
|
|
4123
|
+
doBuildCollection() {
|
|
4124
|
+
let nodes = [];
|
|
4125
|
+
if (this.options.loadingState === "loading" || this.collection.size === 0) {
|
|
4126
|
+
this.contentSize.height = 0;
|
|
4127
|
+
} else {
|
|
4128
|
+
nodes = super.doBuildCollection();
|
|
4129
|
+
}
|
|
4130
|
+
if (this.options.loadingState) {
|
|
4131
|
+
const loaderNode = this.buildLoader();
|
|
4132
|
+
nodes.push(loaderNode);
|
|
4133
|
+
this.contentSize.height = this.contentSize.height + loaderNode.layoutInfo.rect.height;
|
|
4134
|
+
}
|
|
4135
|
+
if (!this.options.loadingState && this.collection.size === 0) {
|
|
4136
|
+
const emptyStateNode = this.buildEmptyState();
|
|
4137
|
+
nodes.push(emptyStateNode);
|
|
4138
|
+
this.contentSize.height = emptyStateNode.layoutInfo.rect.height;
|
|
4139
|
+
}
|
|
4140
|
+
return nodes;
|
|
4141
|
+
}
|
|
4142
|
+
/**
|
|
4143
|
+
* Adds the section header node (which is rendered as a divider and
|
|
4144
|
+
* optional heading text)
|
|
4145
|
+
*/
|
|
4146
|
+
buildSection(node, x, y) {
|
|
4147
|
+
const headerNode = {
|
|
4148
|
+
type: "header",
|
|
4149
|
+
key: node.key + ":header",
|
|
4150
|
+
parentKey: node.key,
|
|
4151
|
+
value: null,
|
|
4152
|
+
level: node.level,
|
|
4153
|
+
index: node.index,
|
|
4154
|
+
hasChildNodes: false,
|
|
4155
|
+
childNodes: [],
|
|
4156
|
+
rendered: node.rendered,
|
|
4157
|
+
textValue: node.textValue
|
|
4158
|
+
};
|
|
4159
|
+
this.headingSize = node.rendered ? this.options.headingHeight : 0;
|
|
4160
|
+
const header = this.buildSectionHeader(headerNode, x, y);
|
|
4161
|
+
header.node = headerNode;
|
|
4162
|
+
header.layoutInfo.parentKey = node.key;
|
|
4163
|
+
this.layoutNodes.set(headerNode.key, header);
|
|
4164
|
+
header.layoutInfo.rect.height += // if first item is the section, we don't show the divider
|
|
4165
|
+
node.prevKey ? this.options.sectionDividerHeight : 0;
|
|
4166
|
+
y += header.layoutInfo.rect.height;
|
|
4167
|
+
const section = super.buildSection(node, x, y);
|
|
4168
|
+
section.children.unshift(header);
|
|
4169
|
+
if (node.nextKey && node.index !== void 0) {
|
|
4170
|
+
const nextNode = this.nextNodeAtLevel(node.level, node.index);
|
|
4171
|
+
if (nextNode && nextNode.type !== "section") {
|
|
4172
|
+
const dividerRect = new useVirtualizerState.Rect(
|
|
4173
|
+
0,
|
|
4174
|
+
section.layoutInfo.rect.maxY,
|
|
4175
|
+
this.virtualizer?.visibleRect.width,
|
|
4176
|
+
this.options.sectionDividerHeight
|
|
4177
|
+
);
|
|
4178
|
+
const layoutInfo = new useVirtualizerState.LayoutInfo(
|
|
4179
|
+
"divider",
|
|
4180
|
+
`${node.key}:divider`,
|
|
4181
|
+
dividerRect
|
|
4182
|
+
);
|
|
4183
|
+
layoutInfo.parentKey = node.key;
|
|
4184
|
+
const layoutNode = {
|
|
4185
|
+
layoutInfo,
|
|
4186
|
+
validRect: layoutInfo.rect.intersection(this.validRect)
|
|
4187
|
+
};
|
|
4188
|
+
this.layoutNodes.set(layoutInfo.key, layoutNode);
|
|
4189
|
+
section.children?.push(layoutNode);
|
|
4190
|
+
section.layoutInfo.rect.height += dividerRect.height;
|
|
4191
|
+
y += dividerRect.height;
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
return section;
|
|
4195
|
+
}
|
|
4196
|
+
nextNodeAtLevel(level, startAt) {
|
|
4197
|
+
for (const item of this.collection) {
|
|
4198
|
+
if (item.level === level && item.index && item.index > startAt) {
|
|
4199
|
+
return item;
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
/**
|
|
4204
|
+
* Builds loader node (containing all loading rows at the end of the view)
|
|
4205
|
+
*/
|
|
4206
|
+
buildLoader() {
|
|
4207
|
+
const rect = new useVirtualizerState.Rect(
|
|
4208
|
+
0,
|
|
4209
|
+
this.contentSize.height,
|
|
4210
|
+
this.virtualizer?.visibleRect.width,
|
|
4211
|
+
this.loaderSize ?? 0
|
|
4212
|
+
);
|
|
4213
|
+
const previousLayoutNode = this.layoutNodes.get("loader");
|
|
4214
|
+
if (previousLayoutNode?.layoutInfo.rect.y === rect.y) {
|
|
4215
|
+
return previousLayoutNode;
|
|
4216
|
+
}
|
|
4217
|
+
const layoutNode = {
|
|
4218
|
+
layoutInfo: new useVirtualizerState.LayoutInfo("loader", "loader", rect),
|
|
4219
|
+
validRect: rect
|
|
4220
|
+
};
|
|
4221
|
+
layoutNode.layoutInfo.estimatedSize = true;
|
|
4222
|
+
this.layoutNodes.set("loader", layoutNode);
|
|
4223
|
+
return layoutNode;
|
|
4224
|
+
}
|
|
4225
|
+
/**
|
|
4226
|
+
* Builds empty state node
|
|
4227
|
+
*/
|
|
4228
|
+
buildEmptyState() {
|
|
4229
|
+
const rect = new useVirtualizerState.Rect(
|
|
4230
|
+
0,
|
|
4231
|
+
this.contentSize.height,
|
|
4232
|
+
this.virtualizer?.visibleRect.width,
|
|
4233
|
+
this.options.rowHeight ?? this.options.estimatedRowHeight ?? 50
|
|
4234
|
+
);
|
|
4235
|
+
const previousLayoutNode = this.layoutNodes.get("empty-state");
|
|
4236
|
+
if (previousLayoutNode?.layoutInfo.rect.y === rect.y) {
|
|
4237
|
+
return previousLayoutNode;
|
|
4238
|
+
}
|
|
4239
|
+
const layoutNode = {
|
|
4240
|
+
layoutInfo: new useVirtualizerState.LayoutInfo("empty-state", "empty-state", rect),
|
|
4241
|
+
validRect: rect
|
|
4242
|
+
};
|
|
4243
|
+
layoutNode.layoutInfo.estimatedSize = true;
|
|
4244
|
+
this.layoutNodes.set("empty-state", layoutNode);
|
|
4245
|
+
return layoutNode;
|
|
4246
|
+
}
|
|
4247
|
+
/**
|
|
4248
|
+
* estimatedSize is set to false by default after size is updated, assuming item
|
|
4249
|
+
* height is not dynamic. In some cases (including loading skeleton rows) the height can
|
|
4250
|
+
* change as custom loading skeleton render can be passed as a prop. Setting estimatedSize to
|
|
4251
|
+
* true makes sure size is calculated and updated if needed after each render.
|
|
4252
|
+
* See useVirtualizerItem code for more details.
|
|
4253
|
+
*/
|
|
4254
|
+
updateItemSize(key, size) {
|
|
4255
|
+
const result = super.updateItemSize(key, size);
|
|
4256
|
+
if (this.canNodeHaveVariableHeight(key)) {
|
|
4257
|
+
const loaderLayoutInfo = this.virtualizer?.getVisibleLayoutInfos().get(key);
|
|
4258
|
+
if (loaderLayoutInfo) {
|
|
4259
|
+
loaderLayoutInfo.estimatedSize = true;
|
|
4260
|
+
}
|
|
4261
|
+
}
|
|
4262
|
+
return result;
|
|
4263
|
+
}
|
|
4264
|
+
canNodeHaveVariableHeight(key) {
|
|
4265
|
+
return key === "loader";
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
|
|
4269
|
+
function useListWithLoadingStateLayout({
|
|
4270
|
+
loadingState,
|
|
4271
|
+
loadingSkeletonRowsCount,
|
|
4272
|
+
sectionDividerHeight = 5,
|
|
4273
|
+
headingHeight = 34
|
|
4274
|
+
// default css height
|
|
4275
|
+
}) {
|
|
4276
|
+
const layout = React.useMemo(
|
|
4277
|
+
() => new ListWithLoadingStateLayout({
|
|
4278
|
+
/**
|
|
4279
|
+
* The estimated height is an average between the min and max height
|
|
4280
|
+
* of list items built with our own exports. Which is the only way
|
|
4281
|
+
* to render InteractiveList items.
|
|
4282
|
+
*/
|
|
4283
|
+
estimatedRowHeight: 60,
|
|
4284
|
+
loadingState,
|
|
4285
|
+
sectionDividerHeight,
|
|
4286
|
+
headingHeight,
|
|
4287
|
+
loadingRowsCount: loadingSkeletonRowsCount
|
|
4288
|
+
}),
|
|
4289
|
+
[
|
|
4290
|
+
loadingState,
|
|
4291
|
+
loadingSkeletonRowsCount,
|
|
4292
|
+
sectionDividerHeight,
|
|
4293
|
+
headingHeight
|
|
4294
|
+
]
|
|
4295
|
+
);
|
|
4296
|
+
return layout;
|
|
4297
|
+
}
|
|
4298
|
+
|
|
4299
|
+
const LoadingRendererContext = React.createContext({
|
|
4300
|
+
loadingSkeletonRowsCount: NaN,
|
|
4301
|
+
renderLoadingSkeleton: () => {
|
|
4302
|
+
throw new Error("Illegal state.");
|
|
4303
|
+
}
|
|
4304
|
+
});
|
|
4305
|
+
function _VirtualizerWithLoading({
|
|
4306
|
+
renderLoadingSkeleton,
|
|
4307
|
+
loadingSkeletonRowsCount,
|
|
4308
|
+
emptyState,
|
|
4309
|
+
...props
|
|
4310
|
+
}, ref) {
|
|
4311
|
+
return /* @__PURE__ */ React.createElement(
|
|
4312
|
+
LoadingRendererContext.Provider,
|
|
4313
|
+
{
|
|
4314
|
+
value: { renderLoadingSkeleton, loadingSkeletonRowsCount }
|
|
4315
|
+
},
|
|
4316
|
+
/* @__PURE__ */ React.createElement(Virtualizer.Virtualizer, { ...props, ref: useObjectRef.useObjectRef(ref) }, (kind, item) => {
|
|
4317
|
+
if (kind === "loader") {
|
|
4318
|
+
return /* @__PURE__ */ React.createElement(LoadingRendererContext.Consumer, null, ({ renderLoadingSkeleton: renderLoadingSkeleton2, loadingSkeletonRowsCount: loadingSkeletonRowsCount2 }) => Array.from(Array(loadingSkeletonRowsCount2)).map(
|
|
4319
|
+
(_, index) => renderLoadingSkeleton2(index)
|
|
4320
|
+
));
|
|
4321
|
+
}
|
|
4322
|
+
if (!!emptyState && kind === "empty-state") {
|
|
4323
|
+
return emptyState;
|
|
4324
|
+
}
|
|
4325
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, props.children(kind, item));
|
|
4326
|
+
})
|
|
4327
|
+
);
|
|
4328
|
+
}
|
|
4329
|
+
const VirtualizerWithLoadingSkeleton = React.forwardRef(
|
|
4330
|
+
_VirtualizerWithLoading
|
|
4331
|
+
);
|
|
4332
|
+
|
|
4333
|
+
const useCollectionFocusProxy = ({
|
|
4334
|
+
state,
|
|
4335
|
+
focusProxyRef,
|
|
4336
|
+
collectionRef
|
|
4337
|
+
}) => {
|
|
4338
|
+
React.useEffect(
|
|
4339
|
+
() => {
|
|
4340
|
+
const proxy = focusProxyRef?.current;
|
|
4341
|
+
if (proxy) {
|
|
4342
|
+
const onKeyDown = (event) => {
|
|
4343
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
4344
|
+
event.preventDefault();
|
|
4345
|
+
event.stopPropagation();
|
|
4346
|
+
state.selectionManager.setFocused(true);
|
|
4347
|
+
collectionRef.current?.dispatchEvent(
|
|
4348
|
+
new KeyboardEvent(event.type, event)
|
|
4349
|
+
);
|
|
4350
|
+
} else if (event.key === "Enter" && state.selectionManager?.focusedKey != null) {
|
|
4351
|
+
forwardEventToFocusedItem(event);
|
|
4352
|
+
event.preventDefault();
|
|
4353
|
+
event.currentTarget?.addEventListener(
|
|
4354
|
+
"keyup",
|
|
4355
|
+
(event2) => {
|
|
4356
|
+
if (event2.key === "Enter" && state.selectionManager.focusedKey != null) {
|
|
4357
|
+
forwardEventToFocusedItem(event2);
|
|
4358
|
+
}
|
|
4359
|
+
},
|
|
4360
|
+
{ once: true, capture: true }
|
|
4361
|
+
);
|
|
4362
|
+
}
|
|
4363
|
+
function forwardEventToFocusedItem(event2) {
|
|
4364
|
+
if (state.selectionManager.focusedKey != null) {
|
|
4365
|
+
collectionRef.current?.querySelector(
|
|
4366
|
+
`[data-key="${state.selectionManager.focusedKey}"]`
|
|
4367
|
+
)?.dispatchEvent(new KeyboardEvent(event2.type, event2));
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
};
|
|
4371
|
+
proxy.addEventListener("keydown", onKeyDown);
|
|
4372
|
+
return () => {
|
|
4373
|
+
proxy.removeEventListener("keydown", onKeyDown);
|
|
4374
|
+
};
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
/* with no dependency here, event listeners are reattached on each render, but that's the case when unmemoized
|
|
4378
|
+
event handlers are passed to elements too (e.g., when using any react-aria hook) */
|
|
4379
|
+
);
|
|
4380
|
+
};
|
|
4381
|
+
|
|
4382
|
+
const ListBoxEmptyState = ({
|
|
4383
|
+
children
|
|
4384
|
+
}) => /* @__PURE__ */ React.createElement(
|
|
4385
|
+
"div",
|
|
4386
|
+
{
|
|
4387
|
+
className: clsx(
|
|
4388
|
+
styles$e["sapphire-listbox__item"],
|
|
4389
|
+
styles$e["sapphire-listbox__item--empty"]
|
|
4390
|
+
)
|
|
4391
|
+
},
|
|
4392
|
+
/* @__PURE__ */ React.createElement("div", { className: clsx(styles$e["sapphire-listbox__content"]) }, /* @__PURE__ */ React.createElement(
|
|
4393
|
+
"div",
|
|
4394
|
+
{
|
|
4395
|
+
role: "presentation",
|
|
4396
|
+
className: styles$e["sapphire-listbox__primary-text"]
|
|
4397
|
+
},
|
|
4398
|
+
children
|
|
4399
|
+
))
|
|
4400
|
+
);
|
|
4401
|
+
|
|
4402
|
+
var empty$6 = "Ingen resultater";
|
|
4403
|
+
var da = {
|
|
4404
|
+
empty: empty$6
|
|
4405
|
+
};
|
|
4406
|
+
|
|
4407
|
+
var empty$5 = "No results";
|
|
4408
|
+
var en = {
|
|
4409
|
+
empty: empty$5
|
|
4410
|
+
};
|
|
4411
|
+
|
|
4412
|
+
var empty$4 = "Keine Ergebnisse";
|
|
4413
|
+
var de = {
|
|
4414
|
+
empty: empty$4
|
|
4415
|
+
};
|
|
4416
|
+
|
|
4417
|
+
var empty$3 = "Ei tuloksia";
|
|
4418
|
+
var fi = {
|
|
4419
|
+
empty: empty$3
|
|
4420
|
+
};
|
|
4421
|
+
|
|
4422
|
+
var empty$2 = "Ingen resultater";
|
|
4423
|
+
var no = {
|
|
4424
|
+
empty: empty$2
|
|
4425
|
+
};
|
|
4426
|
+
|
|
4427
|
+
var empty$1 = "Brak wyników";
|
|
4428
|
+
var pl = {
|
|
4429
|
+
empty: empty$1
|
|
4430
|
+
};
|
|
4431
|
+
|
|
4432
|
+
var empty = "Inga resultat";
|
|
4433
|
+
var se = {
|
|
4434
|
+
empty: empty
|
|
4435
|
+
};
|
|
4436
|
+
|
|
4437
|
+
var intlMessages = {
|
|
4438
|
+
"da-DK": da,
|
|
4439
|
+
"en-US": en,
|
|
4440
|
+
"de-DE": de,
|
|
4441
|
+
"fi-FI": fi,
|
|
4442
|
+
"nb-NO": no,
|
|
4443
|
+
"pl-PL": pl,
|
|
4444
|
+
"sv-SE": se
|
|
4445
|
+
};
|
|
4446
|
+
|
|
4447
|
+
const _StatelessListBox = ({
|
|
4448
|
+
loadingState,
|
|
4449
|
+
loadingSkeletonRowsCount = 4,
|
|
4450
|
+
state,
|
|
4451
|
+
renderLoadingSkeleton = (index) => /* @__PURE__ */ React.createElement(ListBoxItemSkeleton, { key: index, index }),
|
|
4452
|
+
onLoadMore,
|
|
4453
|
+
hasScrollDividers = false,
|
|
4454
|
+
connectedInputRef,
|
|
4455
|
+
shouldUseVirtualFocus = Boolean(connectedInputRef),
|
|
4456
|
+
disableSelectedStyles = false,
|
|
4457
|
+
negativeSideMargin,
|
|
4458
|
+
emptyState: emptyStateProp,
|
|
4459
|
+
...otherProps
|
|
4460
|
+
}, ref) => {
|
|
4461
|
+
const { styleProps } = useSapphireStyleProps(otherProps);
|
|
4462
|
+
const listBoxRef = useObjectRef.useObjectRef(ref);
|
|
4463
|
+
const { listBoxProps } = useListBox.useListBox(
|
|
4464
|
+
{
|
|
4465
|
+
...otherProps,
|
|
4466
|
+
shouldUseVirtualFocus,
|
|
4467
|
+
isVirtualized: true
|
|
4468
|
+
},
|
|
4469
|
+
state,
|
|
4470
|
+
listBoxRef
|
|
4471
|
+
);
|
|
4472
|
+
const formatMessage = i18n.useMessageFormatter(intlMessages);
|
|
4473
|
+
const emptyState = emptyStateProp === null ? null : /* @__PURE__ */ React.createElement(ListBoxEmptyState, null, emptyStateProp || formatMessage("empty"));
|
|
4474
|
+
const layout = useListWithLoadingStateLayout({
|
|
4475
|
+
loadingState,
|
|
4476
|
+
loadingSkeletonRowsCount,
|
|
4477
|
+
sectionDividerHeight: 5,
|
|
4478
|
+
headingHeight: 34
|
|
4479
|
+
});
|
|
4480
|
+
useCollectionFocusProxy({
|
|
4481
|
+
state,
|
|
4482
|
+
focusProxyRef: connectedInputRef,
|
|
4483
|
+
collectionRef: listBoxRef
|
|
4484
|
+
});
|
|
4485
|
+
const { scrollCheckProps, isScrolled, isScrollable } = useScrollCheck(listBoxRef);
|
|
4486
|
+
const constrainWidth = styleProps.style?.maxWidth !== void 0 || styleProps.style?.width !== void 0;
|
|
4487
|
+
const [containerMaxWidth, setContainerMaxWidth] = React.useState(void 0);
|
|
4488
|
+
React.useLayoutEffect(() => {
|
|
4489
|
+
setContainerMaxWidth(
|
|
4490
|
+
constrainWidth && listBoxRef.current ? listBoxRef.current.offsetWidth : void 0
|
|
4491
|
+
);
|
|
4492
|
+
}, [constrainWidth]);
|
|
4493
|
+
const renderWrapper = React.useCallback(
|
|
4494
|
+
(parent, reusableView, children, renderChildren) => {
|
|
4495
|
+
if (reusableView.viewType === "section" && reusableView.content) {
|
|
4496
|
+
return /* @__PURE__ */ React.createElement(
|
|
4497
|
+
ListBoxSection,
|
|
4498
|
+
{
|
|
4499
|
+
key: reusableView.key,
|
|
4500
|
+
item: reusableView.content,
|
|
4501
|
+
layoutInfo: reusableView.layoutInfo,
|
|
4502
|
+
virtualizer: reusableView.virtualizer,
|
|
4503
|
+
childrenViews: children
|
|
4504
|
+
},
|
|
4505
|
+
renderChildren(children.filter((c) => c.viewType === "item"))
|
|
4506
|
+
);
|
|
4507
|
+
}
|
|
4508
|
+
return /* @__PURE__ */ React.createElement(
|
|
4509
|
+
VirtualizerItem.VirtualizerItem,
|
|
4510
|
+
{
|
|
4511
|
+
key: reusableView.key,
|
|
4512
|
+
layoutInfo: reusableView.layoutInfo,
|
|
4513
|
+
virtualizer: reusableView.virtualizer,
|
|
4514
|
+
parent: parent?.layoutInfo
|
|
4515
|
+
},
|
|
4516
|
+
reusableView.rendered
|
|
4517
|
+
);
|
|
4518
|
+
},
|
|
4519
|
+
[]
|
|
4520
|
+
);
|
|
4521
|
+
return /* @__PURE__ */ React.createElement(
|
|
4522
|
+
ListBoxContext.Provider,
|
|
4523
|
+
{
|
|
4524
|
+
value: {
|
|
4525
|
+
state,
|
|
4526
|
+
shouldUseVirtualFocus,
|
|
4527
|
+
disableSelectedStyles,
|
|
4528
|
+
containerMaxWidth
|
|
4529
|
+
}
|
|
4530
|
+
},
|
|
4531
|
+
/* @__PURE__ */ React.createElement(
|
|
4532
|
+
VirtualizerWithLoadingSkeleton,
|
|
4533
|
+
{
|
|
4534
|
+
...mergeProps.mergeProps(listBoxProps, scrollCheckProps),
|
|
4535
|
+
onLoadMore,
|
|
4536
|
+
scrollDirection: "vertical",
|
|
4537
|
+
autoFocus: Boolean(otherProps.autoFocus),
|
|
4538
|
+
layout,
|
|
4539
|
+
collection: state.collection,
|
|
4540
|
+
persistedKeys: new Set(
|
|
4541
|
+
[
|
|
4542
|
+
...state.selectionManager.selectedKeys,
|
|
4543
|
+
state.selectionManager.focusedKey
|
|
4544
|
+
].filter((key) => key !== null)
|
|
4545
|
+
),
|
|
4546
|
+
className: clsx(
|
|
4547
|
+
styles$e["sapphire-listbox"],
|
|
4548
|
+
{
|
|
4549
|
+
[styles$e["sapphire-listbox--selection"]]: !disableSelectedStyles
|
|
4550
|
+
},
|
|
4551
|
+
styleProps.className
|
|
4552
|
+
),
|
|
4553
|
+
style: {
|
|
4554
|
+
...styleProps.style,
|
|
4555
|
+
padding: void 0,
|
|
4556
|
+
...negativeSideMargin ? {
|
|
4557
|
+
marginLeft: typeof negativeSideMargin === "string" ? `calc(${negativeSideMargin} * -1)` : `-${negativeSideMargin}px`,
|
|
4558
|
+
marginRight: typeof negativeSideMargin === "string" ? `calc(${negativeSideMargin} * -1)` : `-${negativeSideMargin}px`
|
|
4559
|
+
} : {},
|
|
4560
|
+
// Should be moved to css when we are a little more sure about what we want, and specially
|
|
4561
|
+
// when/if we need the same feature in Sapphire Angular.
|
|
4562
|
+
borderTop: hasScrollDividers && isScrolled ? `${themes.tokens.size.borderSm} solid ${themes.tokens.color.borderSecondary}` : "",
|
|
4563
|
+
borderBottom: hasScrollDividers && isScrollable ? `${themes.tokens.size.borderSm} solid ${themes.tokens.color.borderSecondary}` : ""
|
|
4564
|
+
},
|
|
4565
|
+
renderWrapper,
|
|
4566
|
+
renderLoadingSkeleton,
|
|
4567
|
+
loadingSkeletonRowsCount,
|
|
4568
|
+
emptyState,
|
|
4569
|
+
ref: listBoxRef,
|
|
4570
|
+
"aria-busy": loadingState && true
|
|
4571
|
+
},
|
|
4572
|
+
(kind, item) => {
|
|
4573
|
+
const node = item;
|
|
4574
|
+
if (kind === "item") {
|
|
4575
|
+
return /* @__PURE__ */ React.createElement(ListBoxOption, { key: node.key, item: node });
|
|
4576
|
+
}
|
|
4577
|
+
return null;
|
|
4578
|
+
}
|
|
4579
|
+
)
|
|
4580
|
+
);
|
|
4581
|
+
};
|
|
4582
|
+
React.forwardRef(_StatelessListBox);
|
|
4583
|
+
|
|
4584
|
+
React.forwardRef(function Popover2({
|
|
4585
|
+
children,
|
|
4586
|
+
padded,
|
|
4587
|
+
defaultMaxWidth,
|
|
4588
|
+
maxHeight,
|
|
4589
|
+
state,
|
|
4590
|
+
restoreFocus = false,
|
|
4591
|
+
...props
|
|
4592
|
+
}, forwardedRef) {
|
|
4593
|
+
const ref = useObjectRef.useObjectRef(forwardedRef);
|
|
4594
|
+
const { styleProps } = useSapphireStyleProps({ ...props, maxHeight });
|
|
4595
|
+
React.useEffect(() => {
|
|
4596
|
+
if (state && state.isOpen && props.isNonModal) {
|
|
4597
|
+
return ariaHideOutside.ariaHideOutside([
|
|
4598
|
+
props.triggerRef?.current,
|
|
4599
|
+
ref?.current
|
|
4600
|
+
]);
|
|
4601
|
+
}
|
|
4602
|
+
}, [state?.isOpen, props.isNonModal, ref, props.triggerRef]);
|
|
4603
|
+
const popover = /* @__PURE__ */ React.createElement(
|
|
4604
|
+
reactAriaComponents.Popover,
|
|
4605
|
+
{
|
|
4606
|
+
...props,
|
|
4607
|
+
ref,
|
|
4608
|
+
style: styleProps.style,
|
|
4609
|
+
className: clsx(styleProps.className, popoverStyles["sapphire-popover"], {
|
|
4610
|
+
[popoverStyles["sapphire-popover--padded"]]: padded,
|
|
4611
|
+
[popoverStyles["sapphire-popover--max-width"]]: defaultMaxWidth
|
|
4612
|
+
})
|
|
4613
|
+
},
|
|
4614
|
+
/* @__PURE__ */ React.createElement(
|
|
4615
|
+
"div",
|
|
4616
|
+
{
|
|
4617
|
+
className: popoverStyles["sapphire-popover__content"],
|
|
4618
|
+
role: "presentation"
|
|
4619
|
+
},
|
|
4620
|
+
/* @__PURE__ */ React.createElement(
|
|
4621
|
+
FocusScope.FocusScope,
|
|
4622
|
+
{
|
|
4623
|
+
autoFocus: !props.isNonModal,
|
|
4624
|
+
contain: !props.isNonModal,
|
|
4625
|
+
restoreFocus
|
|
4626
|
+
},
|
|
4627
|
+
children
|
|
4628
|
+
)
|
|
4629
|
+
)
|
|
4630
|
+
);
|
|
4631
|
+
if (state) {
|
|
4632
|
+
return /* @__PURE__ */ React.createElement(reactAriaComponents.OverlayTriggerStateContext.Provider, { value: state }, popover);
|
|
4633
|
+
}
|
|
4634
|
+
return popover;
|
|
4635
|
+
});
|
|
4636
|
+
|
|
4637
|
+
const useScrollCheck = (ref) => {
|
|
4638
|
+
const [isScrollable, setScrollable] = React.useState(false);
|
|
4639
|
+
const [isScrolled, setScrolled] = React.useState(false);
|
|
4640
|
+
const onScroll = () => {
|
|
4641
|
+
if (ref.current?.scrollTop === 0) {
|
|
4642
|
+
setScrolled(false);
|
|
4643
|
+
} else {
|
|
4644
|
+
setScrolled(true);
|
|
4645
|
+
}
|
|
4646
|
+
};
|
|
4647
|
+
React.useLayoutEffect(() => {
|
|
4648
|
+
const bodyElement = ref.current;
|
|
4649
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
4650
|
+
if (bodyElement) {
|
|
4651
|
+
setScrollable(bodyElement?.scrollHeight > bodyElement.offsetHeight);
|
|
4652
|
+
}
|
|
4653
|
+
});
|
|
4654
|
+
if (bodyElement) {
|
|
4655
|
+
resizeObserver.observe(bodyElement);
|
|
4656
|
+
}
|
|
4657
|
+
return () => {
|
|
4658
|
+
if (bodyElement) {
|
|
4659
|
+
resizeObserver.unobserve(bodyElement);
|
|
4660
|
+
}
|
|
4661
|
+
};
|
|
4662
|
+
}, []);
|
|
4663
|
+
React.useEffect(() => {
|
|
4664
|
+
if (ref.current) {
|
|
4665
|
+
setScrollable(ref.current?.scrollHeight > ref.current.offsetHeight);
|
|
4666
|
+
}
|
|
4667
|
+
});
|
|
4668
|
+
return { isScrollable, isScrolled, scrollCheckProps: { onScroll } };
|
|
4669
|
+
};
|
|
4670
|
+
|
|
4671
|
+
const usePreventTouchEnd = (ref) => React.useEffect(() => {
|
|
4672
|
+
ref.current?.addEventListener(
|
|
4673
|
+
"touchend",
|
|
4674
|
+
(e) => {
|
|
4675
|
+
if (e.currentTarget?.getAttribute("type") !== "submit" && typeof e.currentTarget?.getAttribute("href") !== "string") {
|
|
4676
|
+
e.preventDefault();
|
|
4677
|
+
}
|
|
4678
|
+
},
|
|
4679
|
+
{ passive: false }
|
|
4680
|
+
);
|
|
4681
|
+
}, []);
|
|
4682
|
+
|
|
4683
|
+
const RadioBox = React.forwardRef(function RadioBox2(props, ref) {
|
|
4684
|
+
[props, ref] = reactAriaComponents.useContextProps(props, ref, reactAriaComponents.CheckboxContext);
|
|
4685
|
+
const {
|
|
4686
|
+
elementType: CustomElement = "div",
|
|
4687
|
+
size,
|
|
4688
|
+
isDisabled,
|
|
4689
|
+
isHovered,
|
|
4690
|
+
isFocusVisible,
|
|
4691
|
+
isPressed,
|
|
4692
|
+
isSelected,
|
|
4693
|
+
label,
|
|
4694
|
+
role,
|
|
4695
|
+
children,
|
|
4696
|
+
slot,
|
|
4697
|
+
...otherProps
|
|
4698
|
+
} = props;
|
|
4699
|
+
const { styleProps, filteredProps } = useSapphireStyleProps(otherProps);
|
|
4700
|
+
const ariaProps = role === "checkbox" ? { role, "aria-checked": isSelected } : { role };
|
|
4701
|
+
return /* @__PURE__ */ React.createElement(
|
|
4702
|
+
CustomElement,
|
|
4703
|
+
{
|
|
4704
|
+
...filteredProps,
|
|
4705
|
+
...ariaProps,
|
|
4706
|
+
ref,
|
|
4707
|
+
className: clsx(
|
|
4708
|
+
styles$g["sapphire-radio"],
|
|
4709
|
+
{
|
|
4710
|
+
[styles$g["sapphire-radio--checked"]]: isSelected,
|
|
4711
|
+
[styles$g["sapphire-radio--md"]]: size === "md",
|
|
4712
|
+
[styles$g["is-hover"]]: isHovered,
|
|
4713
|
+
[styles$g["is-focus"]]: isFocusVisible,
|
|
4714
|
+
[styles$g["is-active"]]: isPressed
|
|
4715
|
+
},
|
|
4716
|
+
styles$g["js-focus"],
|
|
4717
|
+
styleProps.className
|
|
4718
|
+
),
|
|
4719
|
+
style: styleProps.style
|
|
4720
|
+
},
|
|
4721
|
+
children,
|
|
4722
|
+
/* @__PURE__ */ React.createElement("span", { className: clsx(styles$g["sapphire-radio__box"]) }),
|
|
4723
|
+
label && /* @__PURE__ */ React.createElement("span", { className: clsx(styles$g["sapphire-radio__label"]) }, label)
|
|
4724
|
+
);
|
|
4725
|
+
});
|
|
4726
|
+
|
|
4727
|
+
const PaginationContext = React.createContext({
|
|
4728
|
+
scrollableRef: void 0
|
|
4729
|
+
});
|
|
4730
|
+
|
|
4731
|
+
const DEFAULT_ROW_HEIGHTS = {
|
|
4732
|
+
sm: 40,
|
|
4733
|
+
md: 48,
|
|
4734
|
+
lg: 56,
|
|
4735
|
+
xl: 64
|
|
4736
|
+
};
|
|
4737
|
+
const SELECTION_COLUMN_ID = "__selection";
|
|
4738
|
+
function DataGrid({
|
|
4739
|
+
"aria-label": ariaLabel,
|
|
4740
|
+
columns,
|
|
4741
|
+
data,
|
|
4742
|
+
cellSpacing = "md",
|
|
4743
|
+
sortDescriptor,
|
|
4744
|
+
onSortChange,
|
|
4745
|
+
defaultSortDescriptor,
|
|
4746
|
+
selectionMode = "none",
|
|
4747
|
+
disallowEmptySelection,
|
|
4748
|
+
getRowId,
|
|
4749
|
+
selectedRowIds: selectedRowsProp,
|
|
4750
|
+
defaultSelectedRowIds,
|
|
4751
|
+
onSelectionChange,
|
|
4752
|
+
emptyState,
|
|
4753
|
+
loadingState,
|
|
4754
|
+
loadingSkeletonRowsCount = 3,
|
|
4755
|
+
hideLastDivider,
|
|
4756
|
+
enableRowVirtualization,
|
|
4757
|
+
estimatedRowHeight,
|
|
4758
|
+
rowExpansion,
|
|
4759
|
+
expandedRowIds,
|
|
4760
|
+
defaultExpandedRowIds,
|
|
4761
|
+
onExpandedRowsChange,
|
|
4762
|
+
onLoadMore,
|
|
4763
|
+
onRowAction,
|
|
4764
|
+
isDisabled,
|
|
4765
|
+
disabledBehavior = "all",
|
|
4766
|
+
layout = "auto",
|
|
4767
|
+
footer,
|
|
4768
|
+
stickyHeader = "auto",
|
|
4769
|
+
stickyFooter = "auto",
|
|
4770
|
+
context,
|
|
4771
|
+
...otherProps
|
|
4772
|
+
}) {
|
|
4773
|
+
sapphireReact.useThemeCheck();
|
|
4774
|
+
const { styleProps, filteredProps } = sapphireReact.useSapphireStyleProps(otherProps);
|
|
4775
|
+
const [sorting, setSorting] = useControlledState.useControlledState(
|
|
4776
|
+
toSortingState(sortDescriptor),
|
|
4777
|
+
toSortingState(defaultSortDescriptor) ?? [],
|
|
4778
|
+
(sortingState) => {
|
|
4779
|
+
onSortChange?.(fromSortingState(sortingState));
|
|
4780
|
+
}
|
|
4781
|
+
);
|
|
4782
|
+
const [rowSelection, setRowSelection] = useControlledState.useControlledState(
|
|
4783
|
+
toBooleanMap(selectedRowsProp),
|
|
4784
|
+
toBooleanMap(defaultSelectedRowIds) ?? {},
|
|
4785
|
+
(state) => {
|
|
4786
|
+
onSelectionChange?.(
|
|
4787
|
+
fromBooleanMap(state),
|
|
4788
|
+
pendingSelectionInteraction.current
|
|
4789
|
+
);
|
|
4790
|
+
}
|
|
4791
|
+
);
|
|
4792
|
+
const pendingSelectionInteraction = React.useRef("select");
|
|
4793
|
+
const handleRowSelectionChange = (updater) => {
|
|
4794
|
+
const newValue = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
4795
|
+
if (!disallowEmptySelection || Object.values(newValue).filter(Boolean).length > 0) {
|
|
4796
|
+
setRowSelection(newValue);
|
|
4797
|
+
pendingSelectionInteraction.current = "select";
|
|
4798
|
+
}
|
|
4799
|
+
};
|
|
4800
|
+
const [expanded, setExpanded] = useControlledState.useControlledState(
|
|
4801
|
+
toBooleanMap(expandedRowIds),
|
|
4802
|
+
toBooleanMap(defaultExpandedRowIds) ?? {},
|
|
4803
|
+
(expandedState) => {
|
|
4804
|
+
onExpandedRowsChange?.(
|
|
4805
|
+
expandedState === true ? [] : fromBooleanMap(expandedState)
|
|
4806
|
+
);
|
|
4807
|
+
}
|
|
4808
|
+
);
|
|
4809
|
+
const contextRef = React.useRef(context);
|
|
4810
|
+
contextRef.current = context;
|
|
4811
|
+
const allColumns = React.useMemo(() => {
|
|
4812
|
+
const result = [];
|
|
4813
|
+
if (selectionMode !== "none") {
|
|
4814
|
+
result.push({
|
|
4815
|
+
id: SELECTION_COLUMN_ID,
|
|
4816
|
+
header: selectionMode === "multiple" ? ({ table: table2 }) => /* @__PURE__ */ React.createElement(
|
|
4817
|
+
sapphireReact.Checkbox,
|
|
4818
|
+
{
|
|
4819
|
+
"aria-label": "Select all",
|
|
4820
|
+
isSelected: table2.getIsAllRowsSelected(),
|
|
4821
|
+
isIndeterminate: table2.getIsSomeRowsSelected(),
|
|
4822
|
+
isDisabled: isDisabled === true,
|
|
4823
|
+
onChange: (isSelected) => {
|
|
4824
|
+
pendingSelectionInteraction.current = "select-all";
|
|
4825
|
+
table2.toggleAllRowsSelected(isSelected);
|
|
4826
|
+
}
|
|
4827
|
+
}
|
|
4828
|
+
) : () => null,
|
|
4829
|
+
cell: ({ row }) => {
|
|
4830
|
+
const checkboxProps = {
|
|
4831
|
+
"aria-label": "Select",
|
|
4832
|
+
// TODO(i18n)
|
|
4833
|
+
isSelected: row.getIsSelected(),
|
|
4834
|
+
isDisabled: !row.getCanSelect(),
|
|
4835
|
+
onChange: (isSelected) => row.toggleSelected(isSelected)
|
|
4836
|
+
};
|
|
4837
|
+
return selectionMode === "single" && disallowEmptySelection ? /* @__PURE__ */ React.createElement(RadioBox, { role: "checkbox", ...checkboxProps }) : /* @__PURE__ */ React.createElement(sapphireReact.Checkbox, { ...checkboxProps });
|
|
4838
|
+
},
|
|
4839
|
+
renderLoadingSkeleton: (i) => /* @__PURE__ */ React.createElement(sapphireReact.Skeleton.From, { index: i, margin: "auto" }, /* @__PURE__ */ React.createElement(sapphireReact.Checkbox, null))
|
|
4840
|
+
});
|
|
4841
|
+
}
|
|
4842
|
+
result.push(
|
|
4843
|
+
...columns.map(({ header, cell, footer: footer2, ...column }) => {
|
|
4844
|
+
return {
|
|
4845
|
+
...column,
|
|
4846
|
+
header: typeof header === "function" ? () => header({ context: contextRef.current }) : header,
|
|
4847
|
+
footer: typeof footer2 === "function" ? () => footer2({ context: contextRef.current }) : footer2,
|
|
4848
|
+
cell: ({ row, getValue }) => {
|
|
4849
|
+
const value = getValue();
|
|
4850
|
+
if (!cell) {
|
|
4851
|
+
return value;
|
|
4852
|
+
}
|
|
4853
|
+
return cell({
|
|
4854
|
+
rowData: row.original,
|
|
4855
|
+
value,
|
|
4856
|
+
rowIndex: row.index,
|
|
4857
|
+
context: contextRef.current
|
|
4858
|
+
});
|
|
4859
|
+
}
|
|
4860
|
+
};
|
|
4861
|
+
})
|
|
4862
|
+
);
|
|
4863
|
+
return result;
|
|
4864
|
+
}, [
|
|
4865
|
+
selectionMode,
|
|
4866
|
+
disallowEmptySelection,
|
|
4867
|
+
isDisabled,
|
|
4868
|
+
disabledBehavior,
|
|
4869
|
+
columns
|
|
4870
|
+
]);
|
|
4871
|
+
const table = reactTable.useReactTable({
|
|
4872
|
+
data,
|
|
4873
|
+
columns: allColumns,
|
|
4874
|
+
state: { sorting, rowSelection, expanded },
|
|
4875
|
+
defaultColumn: {
|
|
4876
|
+
enableSorting: false,
|
|
4877
|
+
// TODO(decision): should sorting be enabled or disabled by default?
|
|
4878
|
+
size: void 0
|
|
4879
|
+
},
|
|
4880
|
+
getRowId,
|
|
4881
|
+
getSubRows: rowExpansion?.type === "subRows" ? rowExpansion.getSubRows : void 0,
|
|
4882
|
+
getCoreRowModel: reactTable.getCoreRowModel(),
|
|
4883
|
+
getSortedRowModel: reactTable.getSortedRowModel(),
|
|
4884
|
+
getExpandedRowModel: reactTable.getExpandedRowModel(),
|
|
4885
|
+
// sorting
|
|
4886
|
+
enableMultiSort: false,
|
|
4887
|
+
sortDescFirst: false,
|
|
4888
|
+
// TODO(decision): should it be an option?
|
|
4889
|
+
manualSorting: sortDescriptor !== void 0,
|
|
4890
|
+
onSortingChange: setSorting,
|
|
4891
|
+
// row selection
|
|
4892
|
+
enableRowSelection: selectionMode === "none" ? false : isDisabled !== void 0 ? (tanStackRow) => {
|
|
4893
|
+
const disabled = typeof isDisabled === "function" ? isDisabled?.(tanStackRow.original) : isDisabled;
|
|
4894
|
+
return !disabled;
|
|
4895
|
+
} : true,
|
|
4896
|
+
enableMultiRowSelection: selectionMode === "multiple",
|
|
4897
|
+
onRowSelectionChange: handleRowSelectionChange,
|
|
4898
|
+
// row expansion
|
|
4899
|
+
onExpandedChange: setExpanded
|
|
4900
|
+
});
|
|
4901
|
+
const containerRef = React.useRef(null);
|
|
4902
|
+
const tableRef = React.useRef(null);
|
|
4903
|
+
const { measuredColumnWidths } = useMeasureColumnWidths({
|
|
4904
|
+
table,
|
|
4905
|
+
data,
|
|
4906
|
+
tableRef,
|
|
4907
|
+
enabled: Boolean(enableRowVirtualization && layout === "auto")
|
|
4908
|
+
});
|
|
4909
|
+
const rows = table.getRowModel().rows;
|
|
4910
|
+
const rowItems = [];
|
|
4911
|
+
if (loadingState !== "loading") {
|
|
4912
|
+
for (const row of rows) {
|
|
4913
|
+
const disabled = typeof isDisabled === "function" ? isDisabled?.(row.original) : isDisabled ?? false;
|
|
4914
|
+
const expandedView = rowExpansion?.type === "expandedView" ? rowExpansion.getExpandedView(row.original, row.index) : void 0;
|
|
4915
|
+
rowItems.push({
|
|
4916
|
+
type: "data",
|
|
4917
|
+
row,
|
|
4918
|
+
hasExpandedView: Boolean(expandedView),
|
|
4919
|
+
disabled
|
|
4920
|
+
});
|
|
4921
|
+
if (expandedView && row.getIsExpanded()) {
|
|
4922
|
+
rowItems.push({
|
|
4923
|
+
type: "expandedView",
|
|
4924
|
+
row,
|
|
4925
|
+
expandedView
|
|
4926
|
+
});
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
if (loadingState) {
|
|
4931
|
+
for (let skeletonIndex = 0; skeletonIndex < loadingSkeletonRowsCount; skeletonIndex++) {
|
|
4932
|
+
rowItems.push({ type: "skeleton", skeletonIndex });
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
const { gridKeyboardNavigationProps, rangeExtractor } = useGridKeyboardNavigation({
|
|
4936
|
+
tableRef,
|
|
4937
|
+
enabled: true,
|
|
4938
|
+
scrollContainerRef: containerRef,
|
|
4939
|
+
rowItemCount: rowItems.length,
|
|
4940
|
+
onScrollToRowIndex: enableRowVirtualization ? (...args) => {
|
|
4941
|
+
virtualizer.scrollToIndex(...args);
|
|
4942
|
+
} : void 0
|
|
4943
|
+
});
|
|
4944
|
+
const virtualizer = reactVirtual.useVirtualizer({
|
|
4945
|
+
count: rowItems.length,
|
|
4946
|
+
getScrollElement: () => containerRef.current,
|
|
4947
|
+
estimateSize: () => estimatedRowHeight ?? DEFAULT_ROW_HEIGHTS[cellSpacing],
|
|
4948
|
+
overscan: 5,
|
|
4949
|
+
enabled: enableRowVirtualization,
|
|
4950
|
+
rangeExtractor
|
|
4951
|
+
});
|
|
4952
|
+
const virtualRows = enableRowVirtualization ? virtualizer.getVirtualItems() : null;
|
|
4953
|
+
const topGap = (virtualRows?.[1]?.start || 0) - (virtualRows?.[0]?.end || 0);
|
|
4954
|
+
const bottomGap = (virtualRows?.[virtualRows.length - 2]?.end || 0) - (virtualRows?.[virtualRows.length - 1]?.start || 0);
|
|
4955
|
+
const virtualPaddingTop = virtualRows?.length ? virtualRows[0].start + topGap : 0;
|
|
4956
|
+
const virtualPaddingBottom = virtualRows?.length ? virtualizer.getTotalSize() - virtualRows[virtualRows.length - 1].end + bottomGap : 0;
|
|
4957
|
+
const renderedRowItems = virtualRows ? virtualRows.map((vi) => ({ rowItem: rowItems[vi.index], index: vi.index })).filter(({ rowItem }) => !!rowItem) : rowItems.map((rowItem, index) => ({ rowItem, index }));
|
|
4958
|
+
const columnCount = table.getVisibleLeafColumns().length;
|
|
4959
|
+
const hasFooterRow = columns.some((col) => col.footer != null);
|
|
4960
|
+
useLoadMore.useLoadMore(
|
|
4961
|
+
{ isLoading: !!loadingState, onLoadMore, items: data },
|
|
4962
|
+
containerRef
|
|
4963
|
+
);
|
|
4964
|
+
const columnSizeVars = Object.fromEntries(
|
|
4965
|
+
table.getVisibleLeafColumns().flatMap((col) => {
|
|
4966
|
+
const columnDef = col.columnDef;
|
|
4967
|
+
const width = measuredColumnWidths?.[col.id] ?? columnDef.sizing?.width;
|
|
4968
|
+
if (width === void 0) return [];
|
|
4969
|
+
const cssValue = typeof width === "number" ? `${width}px` : width;
|
|
4970
|
+
return [[`--col-${col.id}-width`, cssValue]];
|
|
4971
|
+
})
|
|
4972
|
+
);
|
|
4973
|
+
return /* @__PURE__ */ React.createElement(
|
|
4974
|
+
sapphireReact.Table.Container,
|
|
4975
|
+
{
|
|
4976
|
+
ref: containerRef,
|
|
4977
|
+
hideLastDivider: hideLastDivider || data.length === 0 && !loadingState,
|
|
4978
|
+
stickyHeader,
|
|
4979
|
+
stickyFooter,
|
|
4980
|
+
UNSAFE_style: styleProps.style,
|
|
4981
|
+
UNSAFE_className: styleProps.className,
|
|
4982
|
+
footer: footer ? /* @__PURE__ */ React.createElement(PaginationContext.Provider, { value: { scrollableRef: containerRef } }, footer) : void 0,
|
|
4983
|
+
...filteredProps
|
|
4984
|
+
},
|
|
4985
|
+
/* @__PURE__ */ React.createElement(
|
|
4986
|
+
sapphireReact.Table,
|
|
4987
|
+
{
|
|
4988
|
+
ref: tableRef,
|
|
4989
|
+
role: "grid",
|
|
4990
|
+
"aria-label": ariaLabel,
|
|
4991
|
+
cellSpacing,
|
|
4992
|
+
"aria-busy": Boolean(loadingState) || void 0,
|
|
4993
|
+
layout: layout === "fixed" || measuredColumnWidths !== null ? "fixed" : "auto",
|
|
4994
|
+
UNSAFE_style: columnSizeVars,
|
|
4995
|
+
...gridKeyboardNavigationProps
|
|
4996
|
+
},
|
|
4997
|
+
/* @__PURE__ */ React.createElement("colgroup", null, table.getVisibleLeafColumns().map((col) => {
|
|
4998
|
+
const varName = `--col-${col.id}-width`;
|
|
4999
|
+
return /* @__PURE__ */ React.createElement(
|
|
5000
|
+
"col",
|
|
5001
|
+
{
|
|
5002
|
+
key: col.id,
|
|
5003
|
+
style: columnSizeVars[varName] ? { width: `var(${varName})` } : void 0
|
|
5004
|
+
}
|
|
5005
|
+
);
|
|
5006
|
+
})),
|
|
5007
|
+
/* @__PURE__ */ React.createElement(sapphireReact.Table.Header, null, table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ React.createElement(sapphireReact.Table.HeaderRow, { key: headerGroup.id }, headerGroup.headers.map((header) => {
|
|
5008
|
+
const columnDef = header.column.columnDef;
|
|
5009
|
+
return /* @__PURE__ */ React.createElement(
|
|
5010
|
+
sapphireReact.Table.HeaderCell,
|
|
5011
|
+
{
|
|
5012
|
+
key: header.id,
|
|
5013
|
+
allowsSorting: header.column.getCanSort(),
|
|
5014
|
+
sortDirection: mapSortDirection(
|
|
5015
|
+
header.column.getIsSorted()
|
|
5016
|
+
),
|
|
5017
|
+
onPress: header.column.getToggleSortingHandler(),
|
|
5018
|
+
align: columnDef.align,
|
|
5019
|
+
variant: header.column.id === SELECTION_COLUMN_ID ? "selection" : "normal",
|
|
5020
|
+
minWidth: columnDef.sizing?.minWidth,
|
|
5021
|
+
maxWidth: columnDef.sizing?.maxWidth
|
|
5022
|
+
},
|
|
5023
|
+
header.isPlaceholder ? null : reactTable.flexRender(columnDef.header, header.getContext())
|
|
5024
|
+
);
|
|
5025
|
+
})))),
|
|
5026
|
+
/* @__PURE__ */ React.createElement(sapphireReact.Table.Body, null, virtualPaddingTop > 0 && /* @__PURE__ */ React.createElement("tr", { "aria-hidden": true, style: { height: virtualPaddingTop } }, /* @__PURE__ */ React.createElement("td", { colSpan: columnCount })), renderedRowItems.map(({ rowItem, index: itemIndex }) => {
|
|
5027
|
+
if (rowItem.type === "skeleton") {
|
|
5028
|
+
const { skeletonIndex: i } = rowItem;
|
|
5029
|
+
return /* @__PURE__ */ React.createElement(sapphireReact.Table.Row, { key: `skeleton-${i}`, "aria-hidden": true }, table.getVisibleLeafColumns().map((col) => {
|
|
5030
|
+
const columnDef = col.columnDef;
|
|
5031
|
+
const renderLoadingSkeleton = columnDef.renderLoadingSkeleton ?? ((i2) => /* @__PURE__ */ React.createElement(sapphireReact.Skeleton.Text, { index: i2, widthType: "randomPct" }));
|
|
5032
|
+
return /* @__PURE__ */ React.createElement(
|
|
5033
|
+
sapphireReact.Table.Cell,
|
|
5034
|
+
{
|
|
5035
|
+
key: col.id,
|
|
5036
|
+
align: columnDef.align,
|
|
5037
|
+
overflow: "none",
|
|
5038
|
+
variant: col.id === SELECTION_COLUMN_ID ? "selection" : "normal"
|
|
5039
|
+
},
|
|
5040
|
+
renderLoadingSkeleton(i)
|
|
5041
|
+
);
|
|
5042
|
+
}));
|
|
5043
|
+
}
|
|
5044
|
+
if (rowItem.type === "expandedView") {
|
|
5045
|
+
const { row: row2 } = rowItem;
|
|
5046
|
+
return /* @__PURE__ */ React.createElement(
|
|
5047
|
+
sapphireReact.Table.Row,
|
|
5048
|
+
{
|
|
5049
|
+
key: `${row2.id}-expanded-view`,
|
|
5050
|
+
"data-index": itemIndex,
|
|
5051
|
+
ref: (element) => {
|
|
5052
|
+
virtualizer.measureElement(element);
|
|
5053
|
+
}
|
|
5054
|
+
},
|
|
5055
|
+
/* @__PURE__ */ React.createElement(sapphireReact.Table.Cell, { colSpan: columnCount, overflow: "none" }, rowItem.expandedView)
|
|
5056
|
+
);
|
|
5057
|
+
}
|
|
5058
|
+
const { row, disabled } = rowItem;
|
|
5059
|
+
const canExpand = row.getCanExpand() || rowItem.hasExpandedView;
|
|
5060
|
+
const toggleRowExpansion = canExpand ? () => row?.toggleExpanded() : void 0;
|
|
5061
|
+
const toggleRowSelection = row.getCanSelect() ? () => row?.toggleSelected() : void 0;
|
|
5062
|
+
const rowAction = onRowAction ? () => onRowAction(row.original) : void 0;
|
|
5063
|
+
const isRowActionDisabled = disabled && disabledBehavior !== "selection";
|
|
5064
|
+
const onAction = !isRowActionDisabled ? rowAction ?? toggleRowExpansion ?? toggleRowSelection : void 0;
|
|
5065
|
+
const firstUserColumnId = row.getVisibleCells().find((c) => c.column.id !== SELECTION_COLUMN_ID)?.column.id;
|
|
5066
|
+
return /* @__PURE__ */ React.createElement(
|
|
5067
|
+
sapphireReact.Table.Row,
|
|
5068
|
+
{
|
|
5069
|
+
key: row.id,
|
|
5070
|
+
isDisabled: isRowActionDisabled,
|
|
5071
|
+
isSelected: selectionMode !== "none" ? row.getIsSelected() : void 0,
|
|
5072
|
+
"aria-selected": selectionMode !== "none" ? row.getIsSelected() : void 0,
|
|
5073
|
+
onAction: onAction && ((e) => {
|
|
5074
|
+
if (e.pointerType === "keyboard" && e.key === " " && toggleRowSelection) {
|
|
5075
|
+
toggleRowSelection();
|
|
5076
|
+
} else {
|
|
5077
|
+
onAction?.();
|
|
5078
|
+
}
|
|
5079
|
+
}),
|
|
5080
|
+
triggerActionOnPressStart: onAction === toggleRowSelection,
|
|
5081
|
+
isExpanded: row.getIsExpanded() && rowExpansion?.type === "expandedView",
|
|
5082
|
+
"aria-level": rowExpansion != null ? row.depth + 1 : void 0,
|
|
5083
|
+
"data-grid-row": isRowActionDisabled ? void 0 : "",
|
|
5084
|
+
"data-index": itemIndex,
|
|
5085
|
+
ref: (element) => {
|
|
5086
|
+
virtualizer.measureElement(element);
|
|
5087
|
+
}
|
|
5088
|
+
},
|
|
5089
|
+
row.getVisibleCells().map((cell) => {
|
|
5090
|
+
const columnDef = cell.column.columnDef;
|
|
5091
|
+
const isTreeColumn = rowExpansion != null && cell.column.id === firstUserColumnId;
|
|
5092
|
+
return /* @__PURE__ */ React.createElement(
|
|
5093
|
+
DataGridCell,
|
|
5094
|
+
{
|
|
5095
|
+
key: cell.id,
|
|
5096
|
+
align: columnDef.align,
|
|
5097
|
+
isRowHeader: columnDef.isRowHeader,
|
|
5098
|
+
variant: cell.column.id === SELECTION_COLUMN_ID ? "selection" : isTreeColumn ? "tree" : "normal"
|
|
5099
|
+
},
|
|
5100
|
+
isTreeColumn && canExpand && /* @__PURE__ */ React.createElement(
|
|
5101
|
+
sapphireReact.Table.ToggleExpandButton,
|
|
5102
|
+
{
|
|
5103
|
+
isExpanded: row.getIsExpanded(),
|
|
5104
|
+
onPress: toggleRowExpansion,
|
|
5105
|
+
isDisabled: isRowActionDisabled
|
|
5106
|
+
}
|
|
5107
|
+
),
|
|
5108
|
+
reactTable.flexRender(columnDef.cell, cell.getContext())
|
|
5109
|
+
);
|
|
5110
|
+
})
|
|
5111
|
+
);
|
|
5112
|
+
}), virtualPaddingBottom > 0 && /* @__PURE__ */ React.createElement("tr", { "aria-hidden": true, style: { height: virtualPaddingBottom } }, /* @__PURE__ */ React.createElement("td", { colSpan: columnCount })), !loadingState && data.length === 0 && emptyState != null && /* @__PURE__ */ React.createElement(sapphireReact.Table.Row, null, /* @__PURE__ */ React.createElement(sapphireReact.Table.Cell, { colSpan: columnCount, overflow: "none" }, emptyState))),
|
|
5113
|
+
hasFooterRow && table.getFooterGroups().map((footerGroup) => /* @__PURE__ */ React.createElement(sapphireReact.Table.Footer, { key: footerGroup.id }, /* @__PURE__ */ React.createElement(sapphireReact.Table.Row, null, footerGroup.headers.map((footer2) => {
|
|
5114
|
+
const columnDef = footer2.column.columnDef;
|
|
5115
|
+
return /* @__PURE__ */ React.createElement(
|
|
5116
|
+
sapphireReact.Table.Cell,
|
|
5117
|
+
{
|
|
5118
|
+
key: footer2.id,
|
|
5119
|
+
role: "gridcell",
|
|
5120
|
+
align: columnDef.align,
|
|
5121
|
+
overflow: "none"
|
|
5122
|
+
},
|
|
5123
|
+
footer2.isPlaceholder ? null : reactTable.flexRender(columnDef.footer, footer2.getContext())
|
|
5124
|
+
);
|
|
5125
|
+
}))))
|
|
5126
|
+
)
|
|
5127
|
+
);
|
|
5128
|
+
}
|
|
5129
|
+
function DataGridCell({
|
|
5130
|
+
align,
|
|
5131
|
+
isRowHeader,
|
|
5132
|
+
children,
|
|
5133
|
+
variant
|
|
5134
|
+
}) {
|
|
5135
|
+
const ref = React.useRef(null);
|
|
5136
|
+
return /* @__PURE__ */ React.createElement(DataGridCellContext.Provider, { value: { ref } }, /* @__PURE__ */ React.createElement(
|
|
5137
|
+
sapphireReact.Table.Cell,
|
|
5138
|
+
{
|
|
5139
|
+
ref,
|
|
5140
|
+
role: isRowHeader ? "rowheader" : "gridcell",
|
|
5141
|
+
align,
|
|
5142
|
+
overflow: "none",
|
|
5143
|
+
variant
|
|
5144
|
+
},
|
|
5145
|
+
children
|
|
5146
|
+
));
|
|
5147
|
+
}
|
|
5148
|
+
function fromBooleanMap(state) {
|
|
5149
|
+
return Object.entries(state).filter(([, isExpanded]) => isExpanded).map(([id]) => id);
|
|
5150
|
+
}
|
|
5151
|
+
function toBooleanMap(ids) {
|
|
5152
|
+
return ids?.reduce((acc, id) => {
|
|
5153
|
+
acc[id] = true;
|
|
5154
|
+
return acc;
|
|
5155
|
+
}, {});
|
|
5156
|
+
}
|
|
5157
|
+
function toSortingState(sorting) {
|
|
5158
|
+
return sorting ? [
|
|
5159
|
+
{
|
|
5160
|
+
id: sorting.column,
|
|
5161
|
+
desc: sorting.direction === "descending"
|
|
5162
|
+
}
|
|
5163
|
+
] : void 0;
|
|
5164
|
+
}
|
|
5165
|
+
function fromSortingState(sorting) {
|
|
5166
|
+
return sorting[0] ? {
|
|
5167
|
+
column: sorting[0].id,
|
|
5168
|
+
direction: sorting[0].desc ? "descending" : "ascending"
|
|
5169
|
+
} : void 0;
|
|
5170
|
+
}
|
|
5171
|
+
function mapSortDirection(tanStackSortDirection) {
|
|
5172
|
+
if (tanStackSortDirection === "asc") {
|
|
5173
|
+
return "ascending";
|
|
5174
|
+
} else if (tanStackSortDirection === "desc") {
|
|
5175
|
+
return "descending";
|
|
5176
|
+
}
|
|
5177
|
+
return void 0;
|
|
5178
|
+
}
|
|
5179
|
+
|
|
5180
|
+
function createDataGridColumnHelper(_options) {
|
|
5181
|
+
const helper = {
|
|
5182
|
+
accessor: (accessorKeyOrFn, column) => {
|
|
5183
|
+
if (typeof accessorKeyOrFn === "function") {
|
|
5184
|
+
return { ...column, accessorFn: accessorKeyOrFn };
|
|
5185
|
+
}
|
|
5186
|
+
return { ...column, accessorKey: accessorKeyOrFn };
|
|
5187
|
+
},
|
|
5188
|
+
display: (column) => column
|
|
5189
|
+
};
|
|
5190
|
+
return helper;
|
|
5191
|
+
}
|
|
5192
|
+
|
|
5193
|
+
const _DataGrid = Object.assign(DataGrid, {
|
|
5194
|
+
EditableCellContent
|
|
5195
|
+
});
|
|
5196
|
+
|
|
2707
5197
|
Object.defineProperty(exports, "useLocale", {
|
|
2708
5198
|
enumerable: true,
|
|
2709
5199
|
get: function () { return I18nProvider.useLocale; }
|
|
@@ -2715,6 +5205,7 @@ exports.Amount = Amount;
|
|
|
2715
5205
|
exports.Autocomplete = Autocomplete;
|
|
2716
5206
|
exports.BreadcrumbItem = BreadcrumbItem;
|
|
2717
5207
|
exports.Breadcrumbs = Breadcrumbs;
|
|
5208
|
+
exports.DataGrid = _DataGrid;
|
|
2718
5209
|
exports.FileDropzone = FileDropzone;
|
|
2719
5210
|
exports.FileTrigger = FileTrigger;
|
|
2720
5211
|
exports.FilterDropdown = FilterDropdown;
|
|
@@ -2728,4 +5219,6 @@ exports.Slider = _Slider;
|
|
|
2728
5219
|
exports.TagGroup = TagGroup;
|
|
2729
5220
|
exports.TagItem = TagItem;
|
|
2730
5221
|
exports.TimeField = TimeField;
|
|
5222
|
+
exports.TruncateOverflow = TruncateOverflow;
|
|
5223
|
+
exports.createDataGridColumnHelper = createDataGridColumnHelper;
|
|
2731
5224
|
//# sourceMappingURL=index.js.map
|