@danske/sapphire-react-lab 0.106.3 → 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.
Files changed (327) hide show
  1. package/build/cjs/index.js +2557 -64
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/core/src/BreakpointProvider/useBreakpointContext.js +11 -0
  4. package/build/esm/core/src/BreakpointProvider/useBreakpointContext.js.map +1 -0
  5. package/build/esm/core/src/Flex/src/Flex.js +64 -0
  6. package/build/esm/core/src/Flex/src/Flex.js.map +1 -0
  7. package/build/esm/core/src/Grid/src/Grid.js +55 -0
  8. package/build/esm/core/src/Grid/src/Grid.js.map +1 -0
  9. package/build/esm/core/src/Icon/src/Icon.js +37 -0
  10. package/build/esm/core/src/Icon/src/Icon.js.map +1 -0
  11. package/build/esm/core/src/ListBox/i18n/da-DK.json.js +7 -0
  12. package/build/esm/core/src/ListBox/i18n/de-DE.json.js +7 -0
  13. package/build/esm/core/src/ListBox/i18n/en-US.json.js +7 -0
  14. package/build/esm/core/src/ListBox/i18n/fi-FI.json.js +7 -0
  15. package/build/esm/core/src/ListBox/i18n/index.js.map +1 -0
  16. package/build/esm/core/src/ListBox/i18n/nb-NO.json.js +7 -0
  17. package/build/esm/core/src/ListBox/i18n/pl-PL.json.js +7 -0
  18. package/build/esm/core/src/ListBox/i18n/sv-SE.json.js +7 -0
  19. package/build/esm/core/src/ListBox/src/ListBoxContext.js +8 -0
  20. package/build/esm/core/src/ListBox/src/ListBoxContext.js.map +1 -0
  21. package/build/esm/core/src/ListBox/src/ListBoxEmptyState.js +26 -0
  22. package/build/esm/core/src/ListBox/src/ListBoxEmptyState.js.map +1 -0
  23. package/build/esm/core/src/ListBox/src/ListBoxItemSkeleton.js +37 -0
  24. package/build/esm/core/src/ListBox/src/ListBoxItemSkeleton.js.map +1 -0
  25. package/build/esm/core/src/ListBox/src/ListBoxOption.js +105 -0
  26. package/build/esm/core/src/ListBox/src/ListBoxOption.js.map +1 -0
  27. package/build/esm/core/src/ListBox/src/ListBoxSection.js +86 -0
  28. package/build/esm/core/src/ListBox/src/ListBoxSection.js.map +1 -0
  29. package/build/esm/core/src/ListBox/src/StatelessListBox.js +162 -0
  30. package/build/esm/core/src/ListBox/src/StatelessListBox.js.map +1 -0
  31. package/build/esm/core/src/Pagination/src/usePaginationContext.js +8 -0
  32. package/build/esm/core/src/Pagination/src/usePaginationContext.js.map +1 -0
  33. package/build/esm/core/src/Popover/src/Popover.js +62 -0
  34. package/build/esm/core/src/Popover/src/Popover.js.map +1 -0
  35. package/build/esm/core/src/Radio/src/RadioBox.js +58 -0
  36. package/build/esm/core/src/Radio/src/RadioBox.js.map +1 -0
  37. package/build/esm/core/src/Separator/src/Separator.js +32 -0
  38. package/build/esm/core/src/Separator/src/Separator.js.map +1 -0
  39. package/build/esm/core/src/Skeleton/src/Skeleton.js +19 -0
  40. package/build/esm/core/src/Skeleton/src/Skeleton.js.map +1 -0
  41. package/build/esm/core/src/Skeleton/src/SkeletonCircle.js +39 -0
  42. package/build/esm/core/src/Skeleton/src/SkeletonCircle.js.map +1 -0
  43. package/build/esm/core/src/Skeleton/src/SkeletonText.js +59 -0
  44. package/build/esm/core/src/Skeleton/src/SkeletonText.js.map +1 -0
  45. package/build/esm/core/src/Skeleton/src/animation.js +4 -0
  46. package/build/esm/core/src/Skeleton/src/animation.js.map +1 -0
  47. package/build/esm/core/src/ThemeRoot/src/ThemeRoot.js +42 -0
  48. package/build/esm/core/src/ThemeRoot/src/ThemeRoot.js.map +1 -0
  49. package/build/esm/core/src/View/src/View.js +60 -0
  50. package/build/esm/core/src/View/src/View.js.map +1 -0
  51. package/build/esm/core/src/utils/SapphireStyleProps.js +48 -0
  52. package/build/esm/core/src/utils/SapphireStyleProps.js.map +1 -0
  53. package/build/esm/core/src/utils/useCollectionFocusProxy.js +53 -0
  54. package/build/esm/core/src/utils/useCollectionFocusProxy.js.map +1 -0
  55. package/build/esm/core/src/utils/usePreventTouchEnd.js +16 -0
  56. package/build/esm/core/src/utils/usePreventTouchEnd.js.map +1 -0
  57. package/build/esm/core/src/utils/useSapphireStyleProps.js +179 -0
  58. package/build/esm/core/src/utils/useSapphireStyleProps.js.map +1 -0
  59. package/build/esm/core/src/utils/useSapphireTextStyleProps.js +9 -0
  60. package/build/esm/core/src/utils/useSapphireTextStyleProps.js.map +1 -0
  61. package/build/esm/core/src/utils/useScrollCheck.js +38 -0
  62. package/build/esm/core/src/utils/useScrollCheck.js.map +1 -0
  63. package/build/esm/core/src/utils/useThemeCheck.js +14 -0
  64. package/build/esm/core/src/utils/useThemeCheck.js.map +1 -0
  65. package/build/esm/core/src/utils/virtualization/ListWithLoadingStateLayout.js +158 -0
  66. package/build/esm/core/src/utils/virtualization/ListWithLoadingStateLayout.js.map +1 -0
  67. package/build/esm/core/src/utils/virtualization/VariableWidthListLayout.js +69 -0
  68. package/build/esm/core/src/utils/virtualization/VariableWidthListLayout.js.map +1 -0
  69. package/build/esm/core/src/utils/virtualization/VirtualizerWithLoadingSkeleton.js +40 -0
  70. package/build/esm/core/src/utils/virtualization/VirtualizerWithLoadingSkeleton.js.map +1 -0
  71. package/build/esm/core/src/utils/virtualization/useListWithLoadingStateLayout.js +35 -0
  72. package/build/esm/core/src/utils/virtualization/useListWithLoadingStateLayout.js.map +1 -0
  73. package/build/esm/index.js +23 -20
  74. package/build/esm/index.js.map +1 -1
  75. package/build/esm/lab/src/Accordion/index.js.map +1 -0
  76. package/build/esm/lab/src/Accordion/src/Accordion.js.map +1 -0
  77. package/build/esm/lab/src/Accordion/src/AccordionContext.js.map +1 -0
  78. package/build/esm/lab/src/Accordion/src/AccordionHeading.js.map +1 -0
  79. package/build/esm/lab/src/Accordion/src/AccordionItem.js.map +1 -0
  80. package/build/esm/lab/src/Accordion/src/AccordionPanel.js.map +1 -0
  81. package/build/esm/lab/src/Accordion/src/utils.js.map +1 -0
  82. package/build/esm/lab/src/Alert/src/Alert.js.map +1 -0
  83. package/build/esm/lab/src/Amount/src/Amount.js.map +1 -0
  84. package/build/esm/lab/src/Amount/src/useGroupAmount.js.map +1 -0
  85. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/da-DK.json.js +2 -2
  86. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/de-DE.json.js +2 -2
  87. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/en-US.json.js +2 -2
  88. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/fi-FI.json.js +2 -2
  89. package/build/esm/lab/src/Autocomplete/i18n/index.js +20 -0
  90. package/build/esm/lab/src/Autocomplete/i18n/index.js.map +1 -0
  91. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/nb-NO.json.js +2 -2
  92. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/pl-PL.json.js +2 -2
  93. package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/sv-SE.json.js +2 -2
  94. package/build/esm/lab/src/Autocomplete/src/Autocomplete.js.map +1 -0
  95. package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItem.js.map +1 -0
  96. package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItemLink.js.map +1 -0
  97. package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbItemStatic.js.map +1 -0
  98. package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbOverflowMenu.js.map +1 -0
  99. package/build/esm/lab/src/Breadcrumbs/src/Breadcrumbs.js.map +1 -0
  100. package/build/esm/lab/src/Breadcrumbs/src/BreadcrumbsSeparator.js.map +1 -0
  101. package/build/esm/lab/src/Breadcrumbs/src/useBreadcrumbThreshold.js.map +1 -0
  102. package/build/esm/lab/src/DataGrid/index.js +9 -0
  103. package/build/esm/lab/src/DataGrid/index.js.map +1 -0
  104. package/build/esm/lab/src/DataGrid/src/DataGrid.js +463 -0
  105. package/build/esm/lab/src/DataGrid/src/DataGrid.js.map +1 -0
  106. package/build/esm/lab/src/DataGrid/src/DataGridCellContext.js +6 -0
  107. package/build/esm/lab/src/DataGrid/src/DataGridCellContext.js.map +1 -0
  108. package/build/esm/lab/src/DataGrid/src/EditableCellContent.js +125 -0
  109. package/build/esm/lab/src/DataGrid/src/EditableCellContent.js.map +1 -0
  110. package/build/esm/lab/src/DataGrid/src/createDataGridColumnHelper.js +15 -0
  111. package/build/esm/lab/src/DataGrid/src/createDataGridColumnHelper.js.map +1 -0
  112. package/build/esm/lab/src/DataGrid/src/useGridKeyboardNavigation.js +417 -0
  113. package/build/esm/lab/src/DataGrid/src/useGridKeyboardNavigation.js.map +1 -0
  114. package/build/esm/lab/src/DataGrid/src/useMeasureColumnWidths.js +55 -0
  115. package/build/esm/lab/src/DataGrid/src/useMeasureColumnWidths.js.map +1 -0
  116. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/da-DK.json.js +2 -2
  117. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/de-DE.json.js +2 -2
  118. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/en-US.json.js +2 -2
  119. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/fi-FI.json.js +2 -2
  120. package/build/esm/lab/src/FileDropzone/i18n/index.js.map +1 -0
  121. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/nb-NO.json.js +2 -2
  122. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/pl-PL.json.js +2 -2
  123. package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/sv-SE.json.js +2 -2
  124. package/build/esm/lab/src/FileDropzone/src/FileDropzone.js.map +1 -0
  125. package/build/esm/lab/src/FileDropzone/src/FileTrigger.js.map +1 -0
  126. package/build/esm/lab/src/FileDropzone/src/utils.js.map +1 -0
  127. package/build/esm/lab/src/Filtering/src/FilterDropdown.js.map +1 -0
  128. package/build/esm/{Filtering → lab/src/Filtering}/src/SearchableSelectFilter.js +2 -0
  129. package/build/esm/lab/src/Filtering/src/SearchableSelectFilter.js.map +1 -0
  130. package/build/esm/lab/src/Flag/src/Flag.js.map +1 -0
  131. package/build/esm/lab/src/LabeledValue/src/LabeledValue.js.map +1 -0
  132. package/build/esm/{NumberField → lab/src/NumberField}/i18n/da-DK.json.js +2 -2
  133. package/build/esm/{NumberField → lab/src/NumberField}/i18n/de-DE.json.js +2 -2
  134. package/build/esm/{NumberField → lab/src/NumberField}/i18n/en-US.json.js +2 -2
  135. package/build/esm/{NumberField → lab/src/NumberField}/i18n/fi-FI.json.js +2 -2
  136. package/build/esm/lab/src/NumberField/i18n/index.js.map +1 -0
  137. package/build/esm/{NumberField → lab/src/NumberField}/i18n/nb-NO.json.js +2 -2
  138. package/build/esm/{NumberField → lab/src/NumberField}/i18n/pl-PL.json.js +2 -2
  139. package/build/esm/{NumberField → lab/src/NumberField}/i18n/sv-SE.json.js +2 -2
  140. package/build/esm/lab/src/NumberField/src/NumberField.js.map +1 -0
  141. package/build/esm/lab/src/NumberField/src/StepperButton.js.map +1 -0
  142. package/build/esm/lab/src/NumberField/src/cursorHelpers.js.map +1 -0
  143. package/build/esm/lab/src/NumberField/src/formatHelpers.js.map +1 -0
  144. package/build/esm/lab/src/NumberField/src/keyboardHelpers.js.map +1 -0
  145. package/build/esm/lab/src/NumberField/src/useAutofillStyle.js.map +1 -0
  146. package/build/esm/lab/src/NumberField/src/useNumberFieldFormatting.js.map +1 -0
  147. package/build/esm/lab/src/NumberField/src/useSapphireNumberField.js.map +1 -0
  148. package/build/esm/lab/src/ProgressIndicator/src/ProgressIndicator.js.map +1 -0
  149. package/build/esm/lab/src/Sidebar/index.js.map +1 -0
  150. package/build/esm/lab/src/Sidebar/src/Body.js.map +1 -0
  151. package/build/esm/lab/src/Sidebar/src/ExpandableItem.js.map +1 -0
  152. package/build/esm/lab/src/Sidebar/src/Header.js.map +1 -0
  153. package/build/esm/lab/src/Sidebar/src/Item.js.map +1 -0
  154. package/build/esm/lab/src/Sidebar/src/List.js.map +1 -0
  155. package/build/esm/lab/src/Sidebar/src/Panel.js.map +1 -0
  156. package/build/esm/lab/src/Sidebar/src/ResponsiveSidebarContext.js.map +1 -0
  157. package/build/esm/lab/src/Sidebar/src/SecondarySidebarContext.js.map +1 -0
  158. package/build/esm/lab/src/Sidebar/src/Section.js.map +1 -0
  159. package/build/esm/lab/src/Sidebar/src/Sidebar.js.map +1 -0
  160. package/build/esm/lab/src/Sidebar/src/useSidebar.js.map +1 -0
  161. package/build/esm/lab/src/Slider/index.js.map +1 -0
  162. package/build/esm/lab/src/Slider/src/Slider.js.map +1 -0
  163. package/build/esm/lab/src/TagGroup/src/Tag.js.map +1 -0
  164. package/build/esm/lab/src/TagGroup/src/TagGroup.js.map +1 -0
  165. package/build/esm/lab/src/TagGroup/src/TagItem.js.map +1 -0
  166. package/build/esm/{TimeField → lab/src/TimeField}/i18n/da-DK.json.js +2 -2
  167. package/build/esm/lab/src/TimeField/i18n/da-DK.json.js.map +1 -0
  168. package/build/esm/{TimeField → lab/src/TimeField}/i18n/de-DE.json.js +2 -2
  169. package/build/esm/lab/src/TimeField/i18n/de-DE.json.js.map +1 -0
  170. package/build/esm/{TimeField → lab/src/TimeField}/i18n/en-US.json.js +2 -2
  171. package/build/esm/lab/src/TimeField/i18n/en-US.json.js.map +1 -0
  172. package/build/esm/{TimeField → lab/src/TimeField}/i18n/fi-FI.json.js +2 -2
  173. package/build/esm/lab/src/TimeField/i18n/fi-FI.json.js.map +1 -0
  174. package/build/esm/lab/src/TimeField/i18n/index.js.map +1 -0
  175. package/build/esm/{TimeField → lab/src/TimeField}/i18n/nb-NO.json.js +2 -2
  176. package/build/esm/lab/src/TimeField/i18n/nb-NO.json.js.map +1 -0
  177. package/build/esm/{TimeField → lab/src/TimeField}/i18n/pl-PL.json.js +2 -2
  178. package/build/esm/lab/src/TimeField/i18n/pl-PL.json.js.map +1 -0
  179. package/build/esm/{TimeField → lab/src/TimeField}/i18n/sv-SE.json.js +2 -2
  180. package/build/esm/lab/src/TimeField/i18n/sv-SE.json.js.map +1 -0
  181. package/build/esm/lab/src/TimeField/src/TimeField.js.map +1 -0
  182. package/build/esm/lab/src/TimeField/src/TimeFieldSegment.js.map +1 -0
  183. package/build/esm/lab/src/TruncateOverflow/src/TruncateOverflow.js +46 -0
  184. package/build/esm/lab/src/TruncateOverflow/src/TruncateOverflow.js.map +1 -0
  185. package/build/index.d.ts +551 -8
  186. package/package.json +7 -5
  187. package/build/esm/Accordion/index.js.map +0 -1
  188. package/build/esm/Accordion/src/Accordion.js.map +0 -1
  189. package/build/esm/Accordion/src/AccordionContext.js.map +0 -1
  190. package/build/esm/Accordion/src/AccordionHeading.js.map +0 -1
  191. package/build/esm/Accordion/src/AccordionItem.js.map +0 -1
  192. package/build/esm/Accordion/src/AccordionPanel.js.map +0 -1
  193. package/build/esm/Accordion/src/utils.js.map +0 -1
  194. package/build/esm/Alert/src/Alert.js.map +0 -1
  195. package/build/esm/Amount/src/Amount.js.map +0 -1
  196. package/build/esm/Amount/src/useGroupAmount.js.map +0 -1
  197. package/build/esm/Autocomplete/i18n/index.js.map +0 -1
  198. package/build/esm/Autocomplete/src/Autocomplete.js.map +0 -1
  199. package/build/esm/Breadcrumbs/src/BreadcrumbItem.js.map +0 -1
  200. package/build/esm/Breadcrumbs/src/BreadcrumbItemLink.js.map +0 -1
  201. package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js.map +0 -1
  202. package/build/esm/Breadcrumbs/src/BreadcrumbOverflowMenu.js.map +0 -1
  203. package/build/esm/Breadcrumbs/src/Breadcrumbs.js.map +0 -1
  204. package/build/esm/Breadcrumbs/src/BreadcrumbsSeparator.js.map +0 -1
  205. package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js.map +0 -1
  206. package/build/esm/FileDropzone/i18n/index.js.map +0 -1
  207. package/build/esm/FileDropzone/src/FileDropzone.js.map +0 -1
  208. package/build/esm/FileDropzone/src/FileTrigger.js.map +0 -1
  209. package/build/esm/FileDropzone/src/utils.js.map +0 -1
  210. package/build/esm/Filtering/src/FilterDropdown.js.map +0 -1
  211. package/build/esm/Filtering/src/SearchableSelectFilter.js.map +0 -1
  212. package/build/esm/Flag/src/Flag.js.map +0 -1
  213. package/build/esm/LabeledValue/src/LabeledValue.js.map +0 -1
  214. package/build/esm/NumberField/i18n/index.js.map +0 -1
  215. package/build/esm/NumberField/src/NumberField.js.map +0 -1
  216. package/build/esm/NumberField/src/StepperButton.js.map +0 -1
  217. package/build/esm/NumberField/src/cursorHelpers.js.map +0 -1
  218. package/build/esm/NumberField/src/formatHelpers.js.map +0 -1
  219. package/build/esm/NumberField/src/keyboardHelpers.js.map +0 -1
  220. package/build/esm/NumberField/src/useAutofillStyle.js.map +0 -1
  221. package/build/esm/NumberField/src/useNumberFieldFormatting.js.map +0 -1
  222. package/build/esm/NumberField/src/useSapphireNumberField.js.map +0 -1
  223. package/build/esm/ProgressIndicator/src/ProgressIndicator.js.map +0 -1
  224. package/build/esm/Sidebar/index.js.map +0 -1
  225. package/build/esm/Sidebar/src/Body.js.map +0 -1
  226. package/build/esm/Sidebar/src/ExpandableItem.js.map +0 -1
  227. package/build/esm/Sidebar/src/Header.js.map +0 -1
  228. package/build/esm/Sidebar/src/Item.js.map +0 -1
  229. package/build/esm/Sidebar/src/List.js.map +0 -1
  230. package/build/esm/Sidebar/src/Panel.js.map +0 -1
  231. package/build/esm/Sidebar/src/ResponsiveSidebarContext.js.map +0 -1
  232. package/build/esm/Sidebar/src/SecondarySidebarContext.js.map +0 -1
  233. package/build/esm/Sidebar/src/Section.js.map +0 -1
  234. package/build/esm/Sidebar/src/Sidebar.js.map +0 -1
  235. package/build/esm/Sidebar/src/useSidebar.js.map +0 -1
  236. package/build/esm/Slider/index.js.map +0 -1
  237. package/build/esm/Slider/src/Slider.js.map +0 -1
  238. package/build/esm/TagGroup/src/Tag.js.map +0 -1
  239. package/build/esm/TagGroup/src/TagGroup.js.map +0 -1
  240. package/build/esm/TagGroup/src/TagItem.js.map +0 -1
  241. package/build/esm/TimeField/i18n/index.js.map +0 -1
  242. package/build/esm/TimeField/src/TimeField.js.map +0 -1
  243. package/build/esm/TimeField/src/TimeFieldSegment.js.map +0 -1
  244. /package/build/esm/{TimeField → core/src/ListBox}/i18n/da-DK.json.js.map +0 -0
  245. /package/build/esm/{TimeField → core/src/ListBox}/i18n/de-DE.json.js.map +0 -0
  246. /package/build/esm/{TimeField → core/src/ListBox}/i18n/en-US.json.js.map +0 -0
  247. /package/build/esm/{TimeField → core/src/ListBox}/i18n/fi-FI.json.js.map +0 -0
  248. /package/build/esm/{TimeField → core/src/ListBox}/i18n/index.js +0 -0
  249. /package/build/esm/{TimeField → core/src/ListBox}/i18n/nb-NO.json.js.map +0 -0
  250. /package/build/esm/{TimeField → core/src/ListBox}/i18n/pl-PL.json.js.map +0 -0
  251. /package/build/esm/{TimeField → core/src/ListBox}/i18n/sv-SE.json.js.map +0 -0
  252. /package/build/esm/{Accordion → lab/src/Accordion}/index.js +0 -0
  253. /package/build/esm/{Accordion → lab/src/Accordion}/src/Accordion.js +0 -0
  254. /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionContext.js +0 -0
  255. /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionHeading.js +0 -0
  256. /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionItem.js +0 -0
  257. /package/build/esm/{Accordion → lab/src/Accordion}/src/AccordionPanel.js +0 -0
  258. /package/build/esm/{Accordion → lab/src/Accordion}/src/utils.js +0 -0
  259. /package/build/esm/{Alert → lab/src/Alert}/src/Alert.js +0 -0
  260. /package/build/esm/{Amount → lab/src/Amount}/src/Amount.js +0 -0
  261. /package/build/esm/{Amount → lab/src/Amount}/src/useGroupAmount.js +0 -0
  262. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/da-DK.json.js.map +0 -0
  263. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/de-DE.json.js.map +0 -0
  264. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/en-US.json.js.map +0 -0
  265. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/fi-FI.json.js.map +0 -0
  266. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/nb-NO.json.js.map +0 -0
  267. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/pl-PL.json.js.map +0 -0
  268. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/i18n/sv-SE.json.js.map +0 -0
  269. /package/build/esm/{Autocomplete → lab/src/Autocomplete}/src/Autocomplete.js +0 -0
  270. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItem.js +0 -0
  271. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItemLink.js +0 -0
  272. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbItemStatic.js +0 -0
  273. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbOverflowMenu.js +0 -0
  274. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/Breadcrumbs.js +0 -0
  275. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/BreadcrumbsSeparator.js +0 -0
  276. /package/build/esm/{Breadcrumbs → lab/src/Breadcrumbs}/src/useBreadcrumbThreshold.js +0 -0
  277. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/da-DK.json.js.map +0 -0
  278. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/de-DE.json.js.map +0 -0
  279. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/en-US.json.js.map +0 -0
  280. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/fi-FI.json.js.map +0 -0
  281. /package/build/esm/{Autocomplete → lab/src/FileDropzone}/i18n/index.js +0 -0
  282. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/nb-NO.json.js.map +0 -0
  283. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/pl-PL.json.js.map +0 -0
  284. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/i18n/sv-SE.json.js.map +0 -0
  285. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/FileDropzone.js +0 -0
  286. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/FileTrigger.js +0 -0
  287. /package/build/esm/{FileDropzone → lab/src/FileDropzone}/src/utils.js +0 -0
  288. /package/build/esm/{Filtering → lab/src/Filtering}/src/FilterDropdown.js +0 -0
  289. /package/build/esm/{Flag → lab/src/Flag}/src/Flag.js +0 -0
  290. /package/build/esm/{LabeledValue → lab/src/LabeledValue}/src/LabeledValue.js +0 -0
  291. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/da-DK.json.js.map +0 -0
  292. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/de-DE.json.js.map +0 -0
  293. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/en-US.json.js.map +0 -0
  294. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/fi-FI.json.js.map +0 -0
  295. /package/build/esm/{FileDropzone → lab/src/NumberField}/i18n/index.js +0 -0
  296. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/nb-NO.json.js.map +0 -0
  297. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/pl-PL.json.js.map +0 -0
  298. /package/build/esm/{NumberField → lab/src/NumberField}/i18n/sv-SE.json.js.map +0 -0
  299. /package/build/esm/{NumberField → lab/src/NumberField}/src/NumberField.js +0 -0
  300. /package/build/esm/{NumberField → lab/src/NumberField}/src/StepperButton.js +0 -0
  301. /package/build/esm/{NumberField → lab/src/NumberField}/src/cursorHelpers.js +0 -0
  302. /package/build/esm/{NumberField → lab/src/NumberField}/src/formatHelpers.js +0 -0
  303. /package/build/esm/{NumberField → lab/src/NumberField}/src/keyboardHelpers.js +0 -0
  304. /package/build/esm/{NumberField → lab/src/NumberField}/src/useAutofillStyle.js +0 -0
  305. /package/build/esm/{NumberField → lab/src/NumberField}/src/useNumberFieldFormatting.js +0 -0
  306. /package/build/esm/{NumberField → lab/src/NumberField}/src/useSapphireNumberField.js +0 -0
  307. /package/build/esm/{ProgressIndicator → lab/src/ProgressIndicator}/src/ProgressIndicator.js +0 -0
  308. /package/build/esm/{Sidebar → lab/src/Sidebar}/index.js +0 -0
  309. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Body.js +0 -0
  310. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/ExpandableItem.js +0 -0
  311. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Header.js +0 -0
  312. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Item.js +0 -0
  313. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/List.js +0 -0
  314. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Panel.js +0 -0
  315. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/ResponsiveSidebarContext.js +0 -0
  316. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/SecondarySidebarContext.js +0 -0
  317. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Section.js +0 -0
  318. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/Sidebar.js +0 -0
  319. /package/build/esm/{Sidebar → lab/src/Sidebar}/src/useSidebar.js +0 -0
  320. /package/build/esm/{Slider → lab/src/Slider}/index.js +0 -0
  321. /package/build/esm/{Slider → lab/src/Slider}/src/Slider.js +0 -0
  322. /package/build/esm/{TagGroup → lab/src/TagGroup}/src/Tag.js +0 -0
  323. /package/build/esm/{TagGroup → lab/src/TagGroup}/src/TagGroup.js +0 -0
  324. /package/build/esm/{TagGroup → lab/src/TagGroup}/src/TagItem.js +0 -0
  325. /package/build/esm/{NumberField → lab/src/TimeField}/i18n/index.js +0 -0
  326. /package/build/esm/{TimeField → lab/src/TimeField}/src/TimeField.js +0 -0
  327. /package/build/esm/{TimeField → lab/src/TimeField}/src/TimeFieldSegment.js +0 -0
@@ -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$3 = {
384
+ var da$4 = {
358
385
  "listbox-suggestions": "Forslag"
359
386
  };
360
387
 
361
- var en$3 = {
388
+ var en$4 = {
362
389
  "listbox-suggestions": "Suggestions"
363
390
  };
364
391
 
365
- var de$3 = {
392
+ var de$4 = {
366
393
  "listbox-suggestions": "Vorschläge"
367
394
  };
368
395
 
369
- var fi$3 = {
396
+ var fi$4 = {
370
397
  "listbox-suggestions": "Ehdotukset"
371
398
  };
372
399
 
373
- var no$3 = {
400
+ var no$4 = {
374
401
  "listbox-suggestions": "Forslag"
375
402
  };
376
403
 
377
- var pl$3 = {
404
+ var pl$4 = {
378
405
  "listbox-suggestions": "Sugestie"
379
406
  };
380
407
 
381
- var se$3 = {
408
+ var se$4 = {
382
409
  "listbox-suggestions": "Förslag"
383
410
  };
384
411
 
385
- var intlMessages$3 = {
386
- "da-DK": da$3,
387
- "en-US": en$3,
388
- "de-DE": de$3,
389
- "fi-FI": fi$3,
390
- "nb-NO": no$3,
391
- "pl-PL": pl$3,
392
- "sv-SE": se$3
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$3);
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$2 = {
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$2 = {
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$2 = {
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$2 = {
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$2 = {
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$2 = {
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$2 = {
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$2 = {
841
- "da-DK": da$2,
842
- "en-US": en$2,
843
- "de-DE": de$2,
844
- "fi-FI": fi$2,
845
- "nb-NO": no$2,
846
- "pl-PL": pl$2,
847
- "sv-SE": se$2
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$2);
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$1 = {
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$1 = {
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$1 = {
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$1 = {
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$1 = {
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$1 = {
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$1 = {
1208
+ var se$2 = {
1182
1209
  increment: increment,
1183
1210
  decrement: decrement
1184
1211
  };
1185
1212
 
1186
- var intlMessages$1 = {
1187
- "da-DK": da$1,
1188
- "en-US": en$1,
1189
- "de-DE": de$1,
1190
- "fi-FI": fi$1,
1191
- "nb-NO": no$1,
1192
- "pl-PL": pl$1,
1193
- "sv-SE": se$1
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$1);
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