@persona/design-system 0.10.10 → 0.10.12

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 (356) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/AdvancedFilterRuleRow.d.mts +5 -2
  3. package/dist/AdvancedFilterRulesPopover.d.mts +6 -2
  4. package/dist/ArrayValueControl.d.mts +1 -1
  5. package/dist/{Badge-BCdsVKuj.mjs → Badge-B2AJMf3d.mjs} +2 -2
  6. package/dist/{Badge-BCdsVKuj.mjs.map → Badge-B2AJMf3d.mjs.map} +1 -1
  7. package/dist/BooleanValueControl.d.mts +1 -1
  8. package/dist/{Breadcrumbs-CMf3Uvow.mjs → Breadcrumbs-DRs9eo1o.mjs} +5 -5
  9. package/dist/Breadcrumbs-DRs9eo1o.mjs.map +1 -0
  10. package/dist/{CardV2-CrV6eEQb.mjs → CardV2-DO-8COfu.mjs} +11 -8
  11. package/dist/CardV2-DO-8COfu.mjs.map +1 -0
  12. package/dist/ChartFrame.d.mts +61 -0
  13. package/dist/ChartLegend.d.mts +60 -0
  14. package/dist/ChartPopover.d.mts +155 -0
  15. package/dist/{Checkbox-Dr4LMKHV.mjs → Checkbox-BAh-wF_F.mjs} +5 -5
  16. package/dist/Checkbox-BAh-wF_F.mjs.map +1 -0
  17. package/dist/{CheckboxGroupField-Bpu2j6G2.d.mts → CheckboxGroupField-XSVAmESI.d.mts} +2 -2
  18. package/dist/CheckboxGroupField.d.mts +1 -1
  19. package/dist/ChoicesValueControl.d.mts +1 -1
  20. package/dist/{Combobox-Gb_j1dg6.mjs → Combobox-BNjYEAmv.mjs} +313 -138
  21. package/dist/Combobox-BNjYEAmv.mjs.map +1 -0
  22. package/dist/Combobox-DbcSss15.d.mts +12 -0
  23. package/dist/Combobox.d.mts +3 -3
  24. package/dist/{ComboboxBase-BPXqJHaQ.d.mts → ComboboxBase-CrFweFGi.d.mts} +61 -21
  25. package/dist/ComboboxBase.d.mts +2 -2
  26. package/dist/{ComboboxMultiSelect-BwkkSymj.d.mts → ComboboxMultiSelect-Cp5GBGQj.d.mts} +10 -6
  27. package/dist/ComboboxMultiSelect.d.mts +2 -2
  28. package/dist/{ComboboxSingleSelect-CdNNJNkp.d.mts → ComboboxSingleSelect-u7fK3Yvy.d.mts} +8 -6
  29. package/dist/ComboboxSingleSelect.d.mts +2 -2
  30. package/dist/{DataTable-BE9inUi-.d.mts → DataTable-C1mdfmQa.d.mts} +17 -7
  31. package/dist/{DataTable-CIZJ1vO8.mjs → DataTable-DdSY9mzT.mjs} +36 -23
  32. package/dist/DataTable-DdSY9mzT.mjs.map +1 -0
  33. package/dist/DataTable.d.mts +1 -1
  34. package/dist/{DatePicker-C9redLBr.mjs → DatePicker-DiilpYQg.mjs} +5 -5
  35. package/dist/{DatePicker-C9redLBr.mjs.map → DatePicker-DiilpYQg.mjs.map} +1 -1
  36. package/dist/DateRangeValueControl.d.mts +1 -1
  37. package/dist/DateValueControl.d.mts +1 -1
  38. package/dist/{DropdownButton-DpLG-cIj.mjs → DropdownButton-BxZ5hn0X.mjs} +3 -3
  39. package/dist/{DropdownButton-DpLG-cIj.mjs.map → DropdownButton-BxZ5hn0X.mjs.map} +1 -1
  40. package/dist/DropdownButton.d.mts +1 -1
  41. package/dist/{DropdownMenu-B6D4stkF.d.mts → DropdownMenu-CQR0U-zM.d.mts} +2 -2
  42. package/dist/{DropdownMenu-c8XK2Lr4.mjs → DropdownMenu-Ip75l4Th.mjs} +21 -2
  43. package/dist/DropdownMenu-Ip75l4Th.mjs.map +1 -0
  44. package/dist/DropdownMenu.d.mts +1 -1
  45. package/dist/{FieldRegistry-C2NVPhMO.d.mts → FieldRegistry-CJwGpUVK.d.mts} +2 -2
  46. package/dist/FieldRegistry.d.mts +1 -1
  47. package/dist/{FilterBar-BE_gBM0H.d.mts → FilterBar-CA4mDAXK.d.mts} +13 -5
  48. package/dist/FilterBar.d.mts +1 -1
  49. package/dist/FilterPickerMenu.d.mts +2 -2
  50. package/dist/FilterPill.d.mts +1 -1
  51. package/dist/FilterPopover.d.mts +1 -1
  52. package/dist/FloatValueControl.d.mts +3 -2
  53. package/dist/{FloatingToolbar-DLRaE0o7.mjs → FloatingToolbar-BA8Fqmrz.mjs} +35 -38
  54. package/dist/FloatingToolbar-BA8Fqmrz.mjs.map +1 -0
  55. package/dist/{FormControl-BztNXLn6.mjs → FormControl-BoKGiWdQ.mjs} +2 -2
  56. package/dist/{FormControl-BztNXLn6.mjs.map → FormControl-BoKGiWdQ.mjs.map} +1 -1
  57. package/dist/{FormField-Cf1VMvoa.mjs → FormField-yYJFkJ6R.mjs} +13 -13
  58. package/dist/{FormField-Cf1VMvoa.mjs.map → FormField-yYJFkJ6R.mjs.map} +1 -1
  59. package/dist/{HoverCopyableField-XHC_n9tp.mjs → HoverCopyableField-X2XfKTTh.mjs} +10 -5
  60. package/dist/HoverCopyableField-X2XfKTTh.mjs.map +1 -0
  61. package/dist/{IconButton-DxHB2g80.mjs → IconButton-Bj1fry_K.mjs} +4 -3
  62. package/dist/IconButton-Bj1fry_K.mjs.map +1 -0
  63. package/dist/IndexTableLayout.d.mts +11 -3
  64. package/dist/InlineCombobox.d.mts +1 -1
  65. package/dist/InlineInput.d.mts +1 -1
  66. package/dist/{Input-RHXujO9u.mjs → Input-DcbzPaax.mjs} +2 -2
  67. package/dist/{Input-RHXujO9u.mjs.map → Input-DcbzPaax.mjs.map} +1 -1
  68. package/dist/IntegerValueControl.d.mts +3 -2
  69. package/dist/{Link-D_kCyLYX.mjs → Link-B29ZMN6m.mjs} +3 -3
  70. package/dist/Link-B29ZMN6m.mjs.map +1 -0
  71. package/dist/{ListBox-BZp6exb8.mjs → ListBox-4rTgr3IJ.mjs} +6 -6
  72. package/dist/{ListBox-BZp6exb8.mjs.map → ListBox-4rTgr3IJ.mjs.map} +1 -1
  73. package/dist/{ListBox-DpFcM-dM.d.mts → ListBox-ZDaitaXR.d.mts} +2 -2
  74. package/dist/ListBox.d.mts +1 -1
  75. package/dist/{ListBoxField-DL6Zk8TU.d.mts → ListBoxField-CGvVWKyL.d.mts} +4 -4
  76. package/dist/ListBoxField.d.mts +1 -1
  77. package/dist/{LoadingShimmer-oPIv2ESr.mjs → LoadingShimmer-BVVdBeN-.mjs} +18 -20
  78. package/dist/LoadingShimmer-BVVdBeN-.mjs.map +1 -0
  79. package/dist/{LogicRow-BakOUtzx.d.mts → LogicRow-Bzp5o1sL.d.mts} +2 -2
  80. package/dist/LogicRow.d.mts +1 -1
  81. package/dist/{Menu-D6OrKCTC.d.mts → Menu-DviYNrFd.d.mts} +2 -2
  82. package/dist/Menu.d.mts +1 -1
  83. package/dist/{Modal-De5_bPJ_.mjs → Modal-CiPFqr0L.mjs} +52 -23
  84. package/dist/{Modal-De5_bPJ_.mjs.map → Modal-CiPFqr0L.mjs.map} +1 -1
  85. package/dist/{PageHeader-7_Hf6rHl.mjs → PageHeader-6KvtGED-.mjs} +2 -2
  86. package/dist/{PageHeader-7_Hf6rHl.mjs.map → PageHeader-6KvtGED-.mjs.map} +1 -1
  87. package/dist/{PageLayout-DjtGrvJa.mjs → PageLayout-CPiVnS_r.mjs} +3 -1
  88. package/dist/PageLayout-CPiVnS_r.mjs.map +1 -0
  89. package/dist/{Pagination-DMH2IaV0.mjs → Pagination-CqFvnlXc.mjs} +4 -4
  90. package/dist/{Pagination-DMH2IaV0.mjs.map → Pagination-CqFvnlXc.mjs.map} +1 -1
  91. package/dist/{Pii-24D_nSRQ.mjs → Pii-jSYND7Cn.mjs} +2 -2
  92. package/dist/{Pii-24D_nSRQ.mjs.map → Pii-jSYND7Cn.mjs.map} +1 -1
  93. package/dist/{PillShell-B7Bm-dsE.d.mts → PillShell-Bkyu5FXB.d.mts} +2 -2
  94. package/dist/PillShell.d.mts +1 -1
  95. package/dist/{Popover-DordjYNM.mjs → Popover-CVX-dfYb.mjs} +48 -18
  96. package/dist/Popover-CVX-dfYb.mjs.map +1 -0
  97. package/dist/{Radio-BlEtetrr.mjs → Radio-B1H_S-Qj.mjs} +2 -2
  98. package/dist/Radio-B1H_S-Qj.mjs.map +1 -0
  99. package/dist/{RadioGroup-CMrXmmn4.mjs → RadioGroup-7hdcVhsp.mjs} +2 -2
  100. package/dist/{RadioGroup-CMrXmmn4.mjs.map → RadioGroup-7hdcVhsp.mjs.map} +1 -1
  101. package/dist/RuleEditorFields.d.mts +2 -2
  102. package/dist/RulesPill.d.mts +1 -1
  103. package/dist/{SegmentedControl-D_DA-MU1.mjs → SegmentedControl-BNOJ1FYQ.mjs} +5 -2
  104. package/dist/SegmentedControl-BNOJ1FYQ.mjs.map +1 -0
  105. package/dist/{Select-DOlw_LPR.mjs → Select-DbWEgH5c.mjs} +5 -3
  106. package/dist/Select-DbWEgH5c.mjs.map +1 -0
  107. package/dist/{Select-CR9TjFfo.d.mts → Select-DsVeAyZy.d.mts} +2 -2
  108. package/dist/Select.d.mts +1 -1
  109. package/dist/SmartTextInputField.d.mts +2 -2
  110. package/dist/{Spinner-CXb-KUs1.mjs → Spinner-k9ZiOdTr.mjs} +1 -1
  111. package/dist/{Spinner-CXb-KUs1.mjs.map → Spinner-k9ZiOdTr.mjs.map} +1 -1
  112. package/dist/{Sticker-C1_6I08u.mjs → Sticker-4VdGEFAu.mjs} +2 -2
  113. package/dist/{Sticker-C1_6I08u.mjs.map → Sticker-4VdGEFAu.mjs.map} +1 -1
  114. package/dist/StringValueControl.d.mts +2 -1
  115. package/dist/{TabBar-BCFO38E0.mjs → TabBar-d4sdknti.mjs} +5 -5
  116. package/dist/TabBar-d4sdknti.mjs.map +1 -0
  117. package/dist/{Table-DPi4Dt5H.mjs → Table-9mNn8Q-d.mjs} +14 -6
  118. package/dist/Table-9mNn8Q-d.mjs.map +1 -0
  119. package/dist/{TableBox-DNQsgQ8x.mjs → TableBox-D9NA-s9l.mjs} +16 -12
  120. package/dist/TableBox-D9NA-s9l.mjs.map +1 -0
  121. package/dist/TableBox.d.mts +1 -1
  122. package/dist/{TableBoxCell-CsRt_5gP.d.mts → TableBoxCell-CQOL30et.d.mts} +4 -4
  123. package/dist/TableBoxCell.d.mts +1 -1
  124. package/dist/{TableBoxField-Db0Vjo6Z.d.mts → TableBoxField-z0GIFeQw.d.mts} +5 -5
  125. package/dist/TableBoxField.d.mts +1 -1
  126. package/dist/{TableBoxRow-exMlZyc4.d.mts → TableBoxRow-tb9-KMr9.d.mts} +2 -2
  127. package/dist/TableBoxRow.d.mts +1 -1
  128. package/dist/{TableBoxRowActions-UO9YN34k.d.mts → TableBoxRowActions-BZwulsFP.d.mts} +2 -2
  129. package/dist/TableBoxRowActions.d.mts +1 -1
  130. package/dist/{TableControls-BrP_BqnF.mjs → TableControls-BXykbUBf.mjs} +126 -40
  131. package/dist/TableControls-BXykbUBf.mjs.map +1 -0
  132. package/dist/{TableControls-Clo_0Mty.d.mts → TableControls-DE6eHq8h.d.mts} +4 -4
  133. package/dist/TableControls.d.mts +1 -1
  134. package/dist/{TableControlsContext-BNd6z9mD.d.mts → TableControlsContext-C2_2EuMh.d.mts} +2 -2
  135. package/dist/TableControlsContext.d.mts +1 -1
  136. package/dist/{TableViewConfigurationDropdown-Cp7ausV_.d.mts → TableViewConfigurationDropdown-DE9HFXYY.d.mts} +2 -2
  137. package/dist/TableViewConfigurationDropdown.d.mts +1 -1
  138. package/dist/{TechnicalSticker-Cq5jzYKQ.mjs → TechnicalSticker-DtV7Gawf.mjs} +5 -3
  139. package/dist/TechnicalSticker-DtV7Gawf.mjs.map +1 -0
  140. package/dist/{TextArea-Dro-HH8O.mjs → TextArea-CQ1YNi2b.mjs} +4 -5
  141. package/dist/TextArea-CQ1YNi2b.mjs.map +1 -0
  142. package/dist/{Toggle-D9MzTIZs.mjs → Toggle-CzHoIR-n.mjs} +8 -4
  143. package/dist/Toggle-CzHoIR-n.mjs.map +1 -0
  144. package/dist/{Tooltip-YViXzMdm.mjs → Tooltip-CVBxc1yf.mjs} +17 -4
  145. package/dist/Tooltip-CVBxc1yf.mjs.map +1 -0
  146. package/dist/chartColors.d.mts +92 -0
  147. package/dist/chartFrameLayout.d.mts +46 -0
  148. package/dist/{clientFilterUtils-CGHYF5NE.d.mts → clientFilterUtils-2TBUC31K.d.mts} +2 -2
  149. package/dist/clientFilterUtils.d.mts +1 -1
  150. package/dist/components/Accordion/index.mjs +22 -13
  151. package/dist/components/Accordion/index.mjs.map +1 -1
  152. package/dist/components/Attribute/index.mjs +6 -4
  153. package/dist/components/Attribute/index.mjs.map +1 -1
  154. package/dist/components/Badge/index.mjs +1 -1
  155. package/dist/components/Banner/index.mjs +1 -1
  156. package/dist/components/BottomPanel/index.mjs +7 -5
  157. package/dist/components/BottomPanel/index.mjs.map +1 -1
  158. package/dist/components/Breadcrumbs/index.mjs +1 -1
  159. package/dist/components/Button/index.mjs +1 -1
  160. package/dist/components/ButtonGroup/index.mjs +1 -1
  161. package/dist/components/CardV2/index.mjs +1 -1
  162. package/dist/components/Chart/index.d.mts +9 -0
  163. package/dist/components/Chart/index.mjs +680 -0
  164. package/dist/components/Chart/index.mjs.map +1 -0
  165. package/dist/components/Checkbox/index.mjs +1 -1
  166. package/dist/components/CodeHighlight/index.mjs +1 -1
  167. package/dist/components/Combobox/index.d.mts +5 -3
  168. package/dist/components/Combobox/index.mjs +1 -1
  169. package/dist/components/DataTable/TableControls/index.d.mts +19 -19
  170. package/dist/components/DataTable/TableControls/index.mjs +2 -2
  171. package/dist/components/DataTable/index.d.mts +5 -5
  172. package/dist/components/DataTable/index.mjs +1 -1
  173. package/dist/components/DataTable/types.d.mts +1 -1
  174. package/dist/components/DatePicker/index.mjs +1 -1
  175. package/dist/components/DropdownButton/index.mjs +1 -1
  176. package/dist/components/DropdownMenu/index.d.mts +1 -1
  177. package/dist/components/DropdownMenu/index.mjs +1 -1
  178. package/dist/components/FloatingPanel/index.mjs +16 -14
  179. package/dist/components/FloatingPanel/index.mjs.map +1 -1
  180. package/dist/components/FloatingToolbar/index.mjs +1 -1
  181. package/dist/components/FormControl/index.mjs +1 -1
  182. package/dist/components/FormField/index.d.mts +4 -4
  183. package/dist/components/FormField/index.mjs +1 -1
  184. package/dist/components/HoverCopyableField/index.mjs +1 -1
  185. package/dist/components/ImageTile/index.mjs +7 -7
  186. package/dist/components/ImageTile/index.mjs.map +1 -1
  187. package/dist/components/Input/index.mjs +1 -1
  188. package/dist/components/Link/index.mjs +1 -1
  189. package/dist/components/ListBox/index.d.mts +3 -3
  190. package/dist/components/ListBox/index.mjs +1 -1
  191. package/dist/components/LoadingShimmer/index.mjs +1 -1
  192. package/dist/components/MaskedInput/index.mjs +1 -1
  193. package/dist/components/Menu/index.d.mts +1 -1
  194. package/dist/components/Modal/index.mjs +1 -1
  195. package/dist/components/PageHeader/index.mjs +1 -1
  196. package/dist/components/Pagination/index.mjs +1 -1
  197. package/dist/components/Pii/index.mjs +1 -1
  198. package/dist/components/Popover/index.mjs +1 -1
  199. package/dist/components/ProgressBar/index.mjs +20 -3
  200. package/dist/components/ProgressBar/index.mjs.map +1 -1
  201. package/dist/components/Radio/index.mjs +1 -1
  202. package/dist/components/RadioGroup/index.mjs +1 -1
  203. package/dist/components/RichTextEditor/index.mjs +5 -5
  204. package/dist/components/RightPanel/index.mjs +28 -13
  205. package/dist/components/RightPanel/index.mjs.map +1 -1
  206. package/dist/components/SegmentedControl/index.mjs +1 -1
  207. package/dist/components/Select/index.d.mts +1 -1
  208. package/dist/components/Select/index.mjs +1 -1
  209. package/dist/components/SelectionCard/index.mjs +2 -2
  210. package/dist/components/Slider/index.mjs +3 -2
  211. package/dist/components/Slider/index.mjs.map +1 -1
  212. package/dist/components/SmartTextInput/index.mjs +9 -78
  213. package/dist/components/SmartTextInput/index.mjs.map +1 -1
  214. package/dist/{safe-parse.d.mts → components/SmartTextInput/parser/safe-parse.d.mts} +1 -1
  215. package/dist/components/SmartTextInput/parser/safe-parse.mjs +30 -0
  216. package/dist/components/SmartTextInput/parser/safe-parse.mjs.map +1 -0
  217. package/dist/{tree.d.mts → components/SmartTextInput/parser/tree.d.mts} +1 -1
  218. package/dist/components/SmartTextInput/parser/tree.mjs +42 -0
  219. package/dist/components/SmartTextInput/parser/tree.mjs.map +1 -0
  220. package/dist/components/Spinner/index.mjs +1 -1
  221. package/dist/components/Sticker/index.mjs +1 -1
  222. package/dist/components/SwatchPicker/index.mjs +2 -1
  223. package/dist/components/SwatchPicker/index.mjs.map +1 -1
  224. package/dist/components/TabBar/index.mjs +1 -1
  225. package/dist/components/Table/index.mjs +1 -1
  226. package/dist/components/TableBox/index.d.mts +1 -1
  227. package/dist/components/TableBox/index.mjs +1 -1
  228. package/dist/components/TechnicalSticker/index.mjs +1 -1
  229. package/dist/components/TextArea/index.mjs +1 -1
  230. package/dist/components/Tile/index.mjs +2 -2
  231. package/dist/components/Toast/index.mjs +16 -10
  232. package/dist/components/Toast/index.mjs.map +1 -1
  233. package/dist/components/Toggle/index.mjs +1 -1
  234. package/dist/components/Tooltip/index.mjs +1 -1
  235. package/dist/components/VersionHistory/index.mjs +5 -5
  236. package/dist/compound-expression.d.mts +1 -1
  237. package/dist/{date-range-rule-value-ASr06ClE.d.mts → date-range-rule-value-DyLlMtjr.d.mts} +2 -2
  238. package/dist/date-range-rule-value.d.mts +1 -1
  239. package/dist/display.d.mts +1 -1
  240. package/dist/duration-token.d.mts +11 -0
  241. package/dist/exit-motion.d.mts +7 -0
  242. package/dist/fieldPickerOptions.d.mts +2 -2
  243. package/dist/{filter-size-context-CmFyIPCm.d.mts → filter-size-context-DVnjmuhk.d.mts} +2 -2
  244. package/dist/filter-size-context.d.mts +1 -1
  245. package/dist/{filters-DTBc0mE7.d.mts → filters-DW7pqWv3.d.mts} +2 -2
  246. package/dist/filters.d.mts +1 -1
  247. package/dist/{helpers-CBJ2AqGZ.d.mts → helpers-BTD2kXLs.d.mts} +2 -2
  248. package/dist/helpers.d.mts +1 -1
  249. package/dist/{index-OkdnW-u5.d.mts → index-B4tE0RxY.d.mts} +3 -3
  250. package/dist/{index-kIon1vPp.d.mts → index-DTM_t7OG.d.mts} +2 -2
  251. package/dist/index4.d.mts +3 -3
  252. package/dist/index5.d.mts +1 -1
  253. package/dist/index6.d.mts +14 -14
  254. package/dist/{inputFields-DpHeZiFX.d.mts → inputFields-DnBb3NhK.d.mts} +4 -4
  255. package/dist/inputFields.d.mts +1 -1
  256. package/dist/lib/TruncatedTextWithTooltip.mjs +1 -1
  257. package/dist/lib/useCloseFocus.d.mts +45 -0
  258. package/dist/lib/useCloseFocus.mjs +123 -0
  259. package/dist/lib/useCloseFocus.mjs.map +1 -0
  260. package/dist/lib/useModalInsetRight.d.mts +4 -3
  261. package/dist/lib/useModalInsetRight.mjs +7 -5
  262. package/dist/lib/useModalInsetRight.mjs.map +1 -1
  263. package/dist/lint/THIRD_PARTY_NOTICES.md +30 -0
  264. package/dist/lint/index.mjs +696 -11
  265. package/dist/lint/index.mjs.map +1 -1
  266. package/dist/lint/recommended.json +7 -1
  267. package/dist/mixins/hoverable.mjs +1 -1
  268. package/dist/mixins/hoverable.mjs.map +1 -1
  269. package/dist/mixins/input.mjs +1 -0
  270. package/dist/mixins/input.mjs.map +1 -1
  271. package/dist/mixins/menuItem.mjs +2 -0
  272. package/dist/mixins/menuItem.mjs.map +1 -1
  273. package/dist/mixins/motion.d.mts +28 -0
  274. package/dist/mixins/motion.mjs +66 -0
  275. package/dist/mixins/motion.mjs.map +1 -0
  276. package/dist/motion-origin.d.mts +7 -0
  277. package/dist/motion.d.mts +63 -0
  278. package/dist/no-layout-motion.d.mts +7 -0
  279. package/dist/no-transition-all.d.mts +7 -0
  280. package/dist/{operators-BHxKZcpD.d.mts → operators-B8_k3r69.d.mts} +10 -3
  281. package/dist/operators.d.mts +2 -2
  282. package/dist/overlay-motion.d.mts +7 -0
  283. package/dist/patterns/CardGrouping/index.mjs +6 -6
  284. package/dist/patterns/CardGrouping/index.mjs.map +1 -1
  285. package/dist/patterns/IndexTableLayout/index.mjs +23 -16
  286. package/dist/patterns/IndexTableLayout/index.mjs.map +1 -1
  287. package/dist/patterns/LayoutLoadingShimmer/index.mjs +4 -4
  288. package/dist/patterns/LayoutLoadingSpinner/index.mjs +3 -1
  289. package/dist/patterns/LayoutLoadingSpinner/index.mjs.map +1 -1
  290. package/dist/patterns/PageLayout/index.mjs +1 -1
  291. package/dist/patterns/WizardModal/index.mjs +2 -2
  292. package/dist/relative-date-label.d.mts +1 -1
  293. package/dist/{types-DLnCkvTt.d.mts → types-BJqmRXFV.d.mts} +15 -1
  294. package/dist/{types-CqcbWyUY.d.mts → types-BOsCi-kZ.d.mts} +8 -2
  295. package/dist/{types-BiqzeNsa.d.mts → types-Dws2XDz2.d.mts} +2 -2
  296. package/dist/{types-BEdERA4v.d.mts → types-NO2GRlM-.d.mts} +2 -2
  297. package/dist/types4.d.mts +1 -1
  298. package/dist/types5.d.mts +1 -1
  299. package/dist/types6.d.mts +1 -1
  300. package/dist/{url-state-CXUuK3_r.d.mts → url-state-CXPmXzIZ.d.mts} +2 -2
  301. package/dist/url-state.d.mts +1 -1
  302. package/dist/useChartColors.d.mts +30 -0
  303. package/dist/useChartSeriesVisibility.d.mts +22 -0
  304. package/dist/useChartStyles.d.mts +108 -0
  305. package/dist/useColumnConfiguration.d.mts +2 -2
  306. package/dist/useComboboxFooterAction.d.mts +1 -1
  307. package/dist/{useFilterStateV2-DBpbxAEC.d.mts → useFilterStateV2-DiTS9DTg.d.mts} +3 -3
  308. package/dist/useFilterStateV2.d.mts +1 -1
  309. package/dist/{useTableColumns-Xd14vx_h.d.mts → useTableColumns-tITjHasE.d.mts} +2 -2
  310. package/dist/useTableColumns.d.mts +1 -1
  311. package/dist/useTruncation.d.mts +1 -1
  312. package/dist/useValueControlError.d.mts +26 -0
  313. package/dist/utils.d.mts +1 -1
  314. package/dist/{validation-Tgg3AhuP.d.mts → validation-BDQdQ1cY.d.mts} +3 -3
  315. package/dist/validation.d.mts +1 -1
  316. package/dist/{value-control-resolver-XQbGCdsP.d.mts → value-control-resolver-BFJZEWDn.d.mts} +9 -3
  317. package/dist/value-control-resolver.d.mts +1 -1
  318. package/dist/value-labels.d.mts +12 -0
  319. package/dist/variables/keyframes.d.mts +2 -1
  320. package/dist/variables/keyframes.mjs +9 -1
  321. package/dist/variables/keyframes.mjs.map +1 -1
  322. package/dist/variables/transitions.d.mts +31 -1
  323. package/dist/variables/transitions.mjs +50 -1
  324. package/dist/variables/transitions.mjs.map +1 -1
  325. package/llms.txt +2 -1
  326. package/package.json +20 -4
  327. package/skills/new-screen/SKILL.md +33 -0
  328. package/skills/ui-authoring/COMPONENTS.md +19 -1
  329. package/skills/ui-authoring/PATTERNS.md +57 -36
  330. package/skills/ui-authoring/STANDARD.md +78 -4
  331. package/skills/ui-authoring/TOKENS.md +27 -24
  332. package/dist/Breadcrumbs-CMf3Uvow.mjs.map +0 -1
  333. package/dist/CardV2-CrV6eEQb.mjs.map +0 -1
  334. package/dist/Checkbox-Dr4LMKHV.mjs.map +0 -1
  335. package/dist/Combobox-CIKqTYZt.d.mts +0 -11
  336. package/dist/Combobox-Gb_j1dg6.mjs.map +0 -1
  337. package/dist/DataTable-CIZJ1vO8.mjs.map +0 -1
  338. package/dist/DropdownMenu-c8XK2Lr4.mjs.map +0 -1
  339. package/dist/FloatingToolbar-DLRaE0o7.mjs.map +0 -1
  340. package/dist/HoverCopyableField-XHC_n9tp.mjs.map +0 -1
  341. package/dist/IconButton-DxHB2g80.mjs.map +0 -1
  342. package/dist/Link-D_kCyLYX.mjs.map +0 -1
  343. package/dist/LoadingShimmer-oPIv2ESr.mjs.map +0 -1
  344. package/dist/PageLayout-DjtGrvJa.mjs.map +0 -1
  345. package/dist/Popover-DordjYNM.mjs.map +0 -1
  346. package/dist/Radio-BlEtetrr.mjs.map +0 -1
  347. package/dist/SegmentedControl-D_DA-MU1.mjs.map +0 -1
  348. package/dist/Select-DOlw_LPR.mjs.map +0 -1
  349. package/dist/TabBar-BCFO38E0.mjs.map +0 -1
  350. package/dist/Table-DPi4Dt5H.mjs.map +0 -1
  351. package/dist/TableBox-DNQsgQ8x.mjs.map +0 -1
  352. package/dist/TableControls-BrP_BqnF.mjs.map +0 -1
  353. package/dist/TechnicalSticker-Cq5jzYKQ.mjs.map +0 -1
  354. package/dist/TextArea-Dro-HH8O.mjs.map +0 -1
  355. package/dist/Toggle-D9MzTIZs.mjs.map +0 -1
  356. package/dist/Tooltip-YViXzMdm.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataTable-CIZJ1vO8.mjs","names":["DropdownMenu","Pii","PlusIcon","DropdownMenu","tanstackMemo","DetailComponent","Pagination"],"sources":["../src/components/DataTable/clientFilterUtils.ts","../src/components/DataTable/constants.ts","../src/components/DataTable/FloatingActionBar.tsx","../src/components/DataTable/helpers.tsx","../src/components/DataTable/Inserter.tsx","../src/components/DataTable/useTableColumns.tsx","../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import type { Column, ColumnFiltersState, Header, RowData, Table } from '@tanstack/react-table';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport type { FilterConfig } from './TableControls/types';\nimport type { ClientFilterConfig } from './types';\n\nexport const getFilterFnName = (filterType: string): string => {\n switch (filterType) {\n case 'select':\n return 'equals';\n case 'multiselect':\n case 'multiselect-alt':\n case 'multiselect-legacy':\n return 'arrIncludesSome';\n case 'input':\n return 'includesString';\n default:\n return 'equals';\n }\n};\n\nconst isEmptyFilterValue = (value: unknown): boolean => {\n return value == null || value === '' || (Array.isArray(value) && value.length === 0);\n};\n\nconst isClientFilterConfig = (filter: unknown): filter is ClientFilterConfig => {\n if (typeof filter !== 'object' || filter === null || !('type' in filter)) {\n return false;\n }\n return filter.type === 'select' || filter.type === 'multiselect' || filter.type === 'input';\n};\n\n/** Converts column-level client filters into controls backed by TanStack's column-filter state. */\nexport const generateClientFilters = <TData extends RowData>(\n columns: Array<{\n id?: string;\n accessor: string;\n header:\n | string\n | ((props: {\n table: Table<TData>;\n header: Header<TData, unknown>;\n column: Column<TData, unknown>;\n }) => React.ReactNode);\n filter?: unknown;\n }>,\n columnFilters: ColumnFiltersState,\n setColumnFilters: Dispatch<SetStateAction<ColumnFiltersState>>,\n): FilterConfig[] => {\n return columns.flatMap((column): FilterConfig[] => {\n const filterConfig = column.filter;\n if (!isClientFilterConfig(filterConfig) || filterConfig.enabled === false) {\n return [];\n }\n\n const columnId = column.id || column.accessor;\n const name = typeof column.header === 'string' ? column.header : columnId;\n const currentValue = columnFilters.find((filter) => filter.id === columnId)?.value;\n const onChange = (value: unknown) => {\n setColumnFilters((previousFilters) => {\n if (isEmptyFilterValue(value)) {\n return previousFilters.filter((filter) => filter.id !== columnId);\n }\n\n const existingFilter = previousFilters.some((filter) => filter.id === columnId);\n if (existingFilter) {\n return previousFilters.map((filter) =>\n filter.id === columnId ? { ...filter, value } : filter,\n );\n }\n\n return [...previousFilters, { id: columnId, value }];\n });\n };\n\n const baseConfig = {\n id: columnId,\n name,\n placeholder: filterConfig.placeholder,\n enabled: true,\n };\n\n switch (filterConfig.type) {\n case 'select':\n return [\n {\n ...baseConfig,\n type: 'select',\n value: (currentValue as string | undefined) ?? '',\n options: filterConfig.options ?? [],\n onChange,\n },\n ];\n case 'multiselect':\n return [\n {\n ...baseConfig,\n type: 'multiselect',\n value: (currentValue as string[] | undefined) ?? [],\n options: filterConfig.options ?? [],\n onChange,\n },\n ];\n case 'input':\n return [\n {\n ...baseConfig,\n type: 'input',\n value: (currentValue as string | undefined) ?? '',\n onChange,\n onDelete: () => onChange(''),\n },\n ];\n default:\n return [];\n }\n });\n};\n","export function getColumnWidths(compact?: boolean) {\n return {\n EXPAND_COLUMN_WIDTH: compact ? 32 : 36,\n SELECT_COLUMN_WIDTH: compact ? 32 : 40,\n ACTION_COLUMN_WIDTH: compact ? 32 : 40,\n NEST_SPACING: compact ? 24 : 32,\n };\n}\n","import styled from 'styled-components';\n\nimport { BorderRadius, Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\n\nimport Button, { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport { HStack } from '#src/components/Stack';\nimport { Paragraph } from '#src/components/Text';\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { Elevation } from '#src/variables/effect';\n\nconst Bar = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n background-color: ${({ theme }) => semanticColor(theme, 'SurfaceElevated', theme.color.background.primary)};\n width: 100%;\n padding: ${Spacing[2]};\n border-radius: ${BorderRadius.Md};\n box-shadow: ${Elevation.Mid};\n gap: ${Spacing[8]};\n min-width: 380px;\n`;\n\ninterface FloatingActionBarProps {\n selectedCount: number;\n onClearSelection: React.MouseEventHandler<HTMLButtonElement>;\n extraContent?: React.ReactNode;\n actions: (\n | {\n label: string;\n variant?: 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n popover?: {\n options: { label: string; value: string }[];\n onOptionSelect: (option: string) => void | Promise<void>;\n };\n onClick: () => void | Promise<void>;\n }\n | {\n 'aria-label': string;\n icon: React.ReactNode;\n variant?: 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n popover?: {\n options: { label: string; value: string }[];\n onOptionSelect: (option: string) => void | Promise<void>;\n };\n onClick: () => void | Promise<void>;\n }\n )[];\n}\n\nconst FloatingActionBar = ({\n selectedCount,\n onClearSelection,\n extraContent,\n actions,\n}: FloatingActionBarProps) => {\n const strings = usePDSStrings();\n return (\n <Bar>\n <HStack align='center'>\n <IconButton size='sm' onClick={onClearSelection} aria-label={strings.clearSelection}>\n <XIcon />\n </IconButton>\n <Paragraph color='primary'>{strings.selectedItems(selectedCount)}</Paragraph>\n </HStack>\n <HStack align='center' spacing={Spacing[2]}>\n {extraContent}\n {actions.map((action, index) => {\n const key = 'label' in action ? action.label : `action-${index}`;\n\n if ('popover' in action) {\n let trigger = null;\n if ('icon' in action && 'aria-label' in action) {\n // Icon-only action\n trigger = (\n <IconButton key={key} size='sm' aria-label={action['aria-label']}>\n {action.icon}\n </IconButton>\n );\n } else {\n trigger = (\n <Button key={key} variant={action.variant || 'basic'} size='sm'>\n {'label' in action ? action.label : ''}\n </Button>\n );\n }\n\n return (\n // Portaled: the bar is absolutely positioned inside the table's\n // scroll container, which clips an inline menu when the table\n // has a sticky header (`overflow: auto`).\n <DropdownMenu key={key} trigger={trigger} align='center' portal>\n {(action.popover?.options ?? []).map((option) => (\n <DropdownMenu.Item\n id={option.value}\n key={option.value}\n onClick={() => action.popover!.onOptionSelect(option.value)}\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n );\n } else {\n if ('icon' in action && 'aria-label' in action) {\n // Icon-only action\n return (\n <IconButton\n key={key}\n size='sm'\n aria-label={action['aria-label']}\n onClick={action.onClick}\n >\n {action.icon}\n </IconButton>\n );\n } else {\n return (\n <Button\n key={key}\n onClick={action.onClick}\n variant={action.variant || 'basic'}\n size='sm'\n >\n {'label' in action ? action.label : ''}\n </Button>\n );\n }\n }\n })}\n </HStack>\n </Bar>\n );\n};\n\nexport default FloatingActionBar;\n","import { DateTime } from 'luxon';\nimport type { ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Spacing } from '@persona/design-tokens';\nimport { ImageIcon } from '@persona/icons';\n\nimport Checkbox, { type CheckboxProps } from '#src/components/Checkbox';\nimport HoverCopyableField from '#src/components/HoverCopyableField';\nimport Link from '#src/components/Link';\nimport Pii from '#src/components/Pii';\nimport { HStack } from '#src/components/Stack';\nimport Sticker from '#src/components/Sticker';\nimport { Paragraph, TabularNumber } from '#src/components/Text';\nimport {\n DEFAULT_COMMON_STRINGS,\n formatDate,\n formatDateTime,\n type CommonStrings,\n} from '#src/lib/i18n';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\n\nimport type {\n DataTableColumnFormat,\n DataTableColumnIDFormat,\n DataTableColumnImageFormat,\n DataTableColumnPiiFormat,\n DataTableColumnStringFormat,\n DateConfig,\n DatetimeConfig,\n RenderValueStickerFormatConfig,\n} from './types';\n\nconst EmptyCellText = styled(Paragraph)`\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondaryStatic};`)}\n`;\n\nexport const renderAsCheckbox = ({\n rowId,\n isChecked,\n onChange,\n onValueChange,\n columnHeader,\n disabled,\n indeterminate,\n strings = DEFAULT_COMMON_STRINGS,\n}: {\n rowId: string;\n isChecked: boolean;\n /**\n * Called when the checkbox is clicked\n * @param e - The event object\n */\n onChange?: CheckboxProps['onChange'];\n /**\n * Called when the checkbox value changes\n * @param rowId - The id of the row\n * @param checked - The new value of the checkbox\n */\n onValueChange?: (rowId: string, checked: boolean) => void;\n columnHeader?: string;\n disabled?: boolean;\n indeterminate?: boolean;\n /** Built-in copy, from `usePDSStrings()`; English when omitted. */\n strings?: Pick<CommonStrings, 'selectRow' | 'selectRowForColumn'>;\n}): ReactNode => {\n const ariaLabel = columnHeader\n ? strings.selectRowForColumn(columnHeader, rowId)\n : strings.selectRow(rowId);\n\n return (\n <Checkbox\n checked={isChecked}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(rowId, e.target.checked);\n }}\n containerProps={{\n onClick: (e) => {\n // Prevent checkbox clicks from triggering row selection\n e.stopPropagation();\n },\n }}\n aria-label={ariaLabel}\n indeterminate={indeterminate}\n disabled={disabled}\n />\n );\n};\n\nexport const renderAsCheckboxHeader = ({\n header,\n isChecked,\n isIndeterminate,\n onChange,\n onValueChange,\n strings = DEFAULT_COMMON_STRINGS,\n}: {\n /**\n * The header text to display to the right of the checkbox\n */\n header?: string;\n isChecked: boolean;\n isIndeterminate: boolean;\n /**\n * Called when the checkbox is clicked\n * @param e - The event object\n */\n onChange?: CheckboxProps['onChange'];\n /**\n * Called when the checkbox value changes\n * @param rowId - The id of the row\n * @param checked - The new value of the checkbox\n */\n onValueChange?: (checked: boolean) => void;\n /** Built-in copy, from `usePDSStrings()`; English when omitted. */\n strings?: Pick<CommonStrings, 'selectAll' | 'selectAllOf'>;\n}): ReactNode => {\n const checkbox = (\n <Checkbox\n checked={isChecked}\n indeterminate={isIndeterminate}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.checked);\n }}\n containerProps={{\n onClick: (e) => {\n // Prevent checkbox clicks from triggering column sorting\n e.stopPropagation();\n },\n }}\n aria-label={header ? strings.selectAllOf(header) : strings.selectAll}\n />\n );\n\n if (header) {\n return (\n <HStack spacing={Spacing[3]} align='center'>\n {checkbox}\n <span>{header}</span>\n </HStack>\n );\n }\n\n return checkbox;\n};\n\n// ---------------------------------------------------------------------------\n// Generic PDS cell renderers\n// ---------------------------------------------------------------------------\n\n/**\n * Options the built-in PDS cell renderers read from the provider. `DataTable` fills these in from\n * `usePDSLocale()` / `usePDSStrings()`; direct callers may omit them to get the English output.\n */\nexport interface PDSFormatOptions {\n /** BCP 47 locale. Dates and times keep the historical English format when omitted or en-US. */\n locale?: string;\n strings?: Pick<CommonStrings, 'noImage'>;\n}\n\nexport const renderAsString = (value: unknown): string => {\n if (value == null) {\n return '';\n }\n return typeof value === 'string'\n ? value\n : typeof value === 'object'\n ? JSON.stringify(value, null, 2)\n : String(value);\n};\n\nexport const renderAsDate = (value: unknown, config?: DateConfig, locale?: string): string => {\n if (value == null || typeof value !== 'string') {\n return '';\n }\n const date = DateTime.fromISO(value);\n return date.isValid\n ? formatDate(date, { locale, format: config?.format, showTimeZone: config?.showTimeZone })\n : '';\n};\n\nexport const renderAsDatetime = (\n value: unknown,\n config?: DatetimeConfig,\n locale?: string,\n): string => {\n if (value == null || typeof value !== 'string') {\n return '';\n }\n const date = DateTime.fromISO(value);\n return date.isValid\n ? formatDateTime(date, { locale, format: config?.format, showTimeZone: config?.showTimeZone })\n : '';\n};\n\nexport const renderAsURL = (value: unknown): ReactNode => {\n if (value == null || typeof value !== 'string' || value.length === 0) {\n return '';\n }\n return (\n <Link url={value} target='_blank'>\n {value}\n </Link>\n );\n};\n\nexport const renderAsNumber = (value: unknown): ReactNode => {\n if (value == null) {\n return '';\n }\n return <TabularNumber>{value}</TabularNumber>;\n};\n\nconst createSticker = (\n item: string,\n config?: RenderValueStickerFormatConfig,\n key?: string,\n): ReactNode => {\n const displayLabel = config?.labels?.[item] ?? item;\n const variant = config?.colors?.[item] ?? config?.defaultColor;\n return (\n <Sticker key={key} variant={variant}>\n {displayLabel}\n </Sticker>\n );\n};\n\nexport const renderAsSticker = (\n value: unknown,\n config?: RenderValueStickerFormatConfig,\n): ReactNode => {\n if (value == null) {\n return '';\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '';\n }\n return (\n <span style={{ display: 'flex', flexWrap: 'wrap', gap: '4px', alignItems: 'center' }}>\n {value.map((item, index) =>\n typeof item === 'string' ? createSticker(item, config, `${item}-${index}`) : null,\n )}\n </span>\n );\n }\n if (typeof value !== 'string') {\n return '';\n }\n return createSticker(value, config);\n};\n\n// ---------------------------------------------------------------------------\n// Private primitives used by PDS renderers\n// ---------------------------------------------------------------------------\n\n/** Inline monospace text — private DataTable primitive, avoids the dashboard Typography dep. */\nconst MonoText = styled.span`\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;\n font-size: 0.875em;\n`;\n\nconst WrappingText = styled.span`\n display: inline-block;\n max-width: 100%;\n word-break: break-word;\n overflow-wrap: break-word;\n`;\n\ntype EmptyImageProps = { $width?: string; $height?: string };\n\nconst EmptyImageContainer = styled.div<EmptyImageProps>`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: ${BorderRadius.Md};\n background-color: ${({ theme }) => semanticColor(theme, 'SurfaceSecondary', theme.color.background.secondary)};\n width: ${({ $width }) => $width ?? '200px'};\n height: ${({ $height }) => $height ?? '144px'};\n svg {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.border.disabled)};\n }\n`;\n\nconst LightweightImg = styled.img<{ $fit?: string }>`\n object-fit: ${({ $fit }) => $fit ?? 'cover'};\n display: block;\n`;\n\n// ---------------------------------------------------------------------------\n// Copyable string renderer (used by 'string' and 'id' formats)\n// ---------------------------------------------------------------------------\n\nexport const renderAsCopyableString = (\n value: unknown,\n config?: DataTableColumnStringFormat['config'] & { emptyText?: string },\n): ReactNode => {\n const valueAsString = renderAsString(value);\n const content = config?.mono ? <MonoText>{valueAsString}</MonoText> : valueAsString;\n\n if (!valueAsString) {\n return <EmptyCellText>{config?.emptyText ?? ''}</EmptyCellText>;\n }\n\n return (\n <WrappingText>\n {config?.copyable ? (\n <HoverCopyableField copyValue={valueAsString}>{content}</HoverCopyableField>\n ) : (\n content\n )}\n </WrappingText>\n );\n};\n\n// ---------------------------------------------------------------------------\n// PII renderer\n// ---------------------------------------------------------------------------\n\nexport const renderAsPii = <TData = unknown>(\n row?: TData,\n config?: DataTableColumnPiiFormat<TData>['config'],\n): ReactNode => {\n if (!config || !row) {\n return '';\n }\n const { isRedacted, piiValue, emptyText } = config;\n const piiValueString = piiValue(row);\n\n if (piiValueString == null || piiValueString.length === 0) {\n return (\n <>\n <EmptyCellText>{emptyText}</EmptyCellText>\n {config.subComponent?.(row)}\n </>\n );\n }\n\n return (\n <>\n <Pii isRedacted={isRedacted(row)}>{piiValueString}</Pii>\n {config.subComponent?.(row)}\n </>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Lightweight image renderer (no Redux / modal / forensics deps)\n// ---------------------------------------------------------------------------\n\nexport const renderAsLightweightImage = (\n value: unknown,\n config?: DataTableColumnImageFormat['config'],\n strings: Pick<CommonStrings, 'noImage'> = DEFAULT_COMMON_STRINGS,\n): ReactNode => {\n const isEmpty = value == null || value === '' || (Array.isArray(value) && value.length === 0);\n\n if (isEmpty) {\n return config?.fallback ? (\n <>{config.fallback}</>\n ) : (\n <EmptyImageContainer\n $width={config?.width}\n $height={config?.height}\n aria-label={config?.alt ?? 'image'}\n >\n <ImageIcon size={24} aria-label={strings.noImage} />\n </EmptyImageContainer>\n );\n }\n\n const src = typeof value === 'string' ? value : '';\n return (\n <LightweightImg\n src={src}\n alt={config?.alt ?? 'image'}\n width={config?.width ?? '200px'}\n height={config?.height ?? '144px'}\n $fit={config?.fit}\n />\n );\n};\n\n/**\n * Default PDS cell renderer. Handles all generic format types built into the design system.\n * Hosts should supply their own `renderFormat` prop to DataTable for format types that require\n * application-specific components (e.g. tags, files, PII masking, status indicators).\n */\nexport const renderAsPDSFormat = <TData = unknown>(\n value: unknown,\n format?: DataTableColumnFormat<TData>,\n row?: TData,\n options: PDSFormatOptions = {},\n): string | ReactNode => {\n switch (format?.type) {\n case 'date':\n return renderAsDate(value, format.config, options.locale);\n case 'datetime':\n return renderAsDatetime(value, format.config, options.locale);\n case 'sticker':\n return renderAsSticker(value, format.config);\n case 'url':\n return renderAsURL(value);\n case 'number':\n return renderAsNumber(value);\n case 'image':\n return renderAsLightweightImage(value, format.config, options.strings);\n case 'checkbox':\n // Checkbox columns are handled specially by the DataTable; this path is unreachable.\n return '';\n case 'id':\n return renderAsCopyableString(value, {\n copyable: true,\n mono: true,\n ...(format as DataTableColumnIDFormat).config,\n });\n case 'pii':\n return renderAsPii<TData>(row, (format as DataTableColumnPiiFormat<TData>).config);\n default:\n return renderAsCopyableString(\n value,\n (format as DataTableColumnStringFormat | undefined)?.config,\n );\n }\n};\n","import { kebabCase } from 'lodash-es';\nimport styled from 'styled-components';\n\nimport { Color } from '@persona/design-tokens';\nimport { PlusIcon } from '@persona/icons/12px';\n\nimport { TableCell, TableRow } from '#src/components/Table';\nimport { isFocused } from '#src/lib/pseudoClass';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nconst InserterTableCell = styled(TableCell)<{ $nestSpacing: number }>`\n padding: 0 !important;\n ${({ $nestSpacing }) => ($nestSpacing ? `padding-left: ${$nestSpacing}px !important` : '')};\n height: 0;\n position: relative;\n border: 0;\n z-index: ${Z_INDICES.withShadow};\n`;\n\nconst AddRowLine = styled.div<{ $nestSpacing: number }>`\n position: absolute;\n top: -1px;\n background-color: ${({ theme }) => semanticColor(theme, 'BorderAccent', theme.color.primary.brand)};\n width: ${({ $nestSpacing }) => ($nestSpacing ? `calc(100% - ${$nestSpacing}px)` : '100%')};\n transition-duration: ${TransitionDuration.Fast};\n transition-property: opacity;\n transition-timing-function: ease-in;\n`;\n\nconst StyledPlusButton = styled.button`\n position: absolute;\n top: -7px;\n left: calc(50% - 8px);\n border-radius: 50%;\n height: 14px;\n width: 14px;\n background-color: ${({ theme }) => semanticColor(theme, 'ActionPrimary', theme.color.primary.brand)};\n color: ${({ theme }) => semanticColor(theme, 'FgInverse', Color.BackgroundButtonInverse)};\n cursor: pointer;\n z-index: ${Z_INDICES.withShadow};\n // TODO: Add a focus style\n\n opacity: 0;\n\n &:hover {\n opacity: 1;\n }\n\n &:hover ~ ${AddRowLine} {\n opacity: 1;\n height: 2px;\n }\n`;\n\nconst StyledTableRow = styled(TableRow)`\n &${isFocused} {\n box-shadow: none;\n }\n cursor: pointer;\n &:hover > ${AddRowLine}, &:focus > ${AddRowLine} {\n opacity: 1;\n height: 2px;\n }\n\n &:hover > ${StyledPlusButton}, &:focus > ${StyledPlusButton} {\n opacity: 1;\n }\n`;\n\nconst HoverArea = styled.div<{ $nestSpacing: number }>`\n position: absolute;\n height: 12px;\n top: -6px;\n width: ${({ $nestSpacing }) => ($nestSpacing ? `calc(100% - ${$nestSpacing}px)` : '100%')};\n z-index: ${Z_INDICES.withShadow};\n &:hover ~ ${AddRowLine} {\n opacity: 1;\n height: 2px;\n }\n\n &:hover ~ ${StyledPlusButton} {\n opacity: 1;\n }\n`;\n\nconst StyledPlusIcon = styled(PlusIcon)`\n position: absolute;\n top: 1px;\n left: 1px;\n`;\n\ninterface InserterProps {\n priorRowLabel: string;\n colSpan: number;\n nestSpacing?: number;\n label?: string;\n onAddRow: () => void;\n}\n\nexport const Inserter: React.FC<InserterProps> = ({\n priorRowLabel,\n colSpan,\n nestSpacing = 0,\n label,\n onAddRow,\n}) => {\n return (\n <StyledTableRow\n onKeyDown={(evt) => {\n if (evt.key === ' ' || evt.key === 'Enter') {\n evt.preventDefault();\n evt.stopPropagation();\n onAddRow();\n }\n }}\n tabIndex={0}\n >\n <InserterTableCell colSpan={colSpan} $nestSpacing={nestSpacing}>\n <HoverArea\n $nestSpacing={nestSpacing}\n role='presentation'\n aria-label={label || `Insert a row after ${priorRowLabel}`}\n onClick={onAddRow}\n />\n <StyledPlusButton\n id={`${kebabCase(priorRowLabel)}-inserter`}\n aria-label={label || `Insert a row after ${priorRowLabel}`}\n onClick={onAddRow}\n type='button'\n >\n <StyledPlusIcon color='currentColor' />\n </StyledPlusButton>\n <AddRowLine $nestSpacing={nestSpacing} onClick={onAddRow} />\n </InserterTableCell>\n </StyledTableRow>\n );\n};\n","import {\n type CellContext,\n type ColumnDef,\n createColumnHelper,\n type Row,\n type RowData,\n type Table,\n} from '@tanstack/react-table';\nimport { startCase } from 'lodash-es';\nimport { useCallback, useMemo, useRef } from 'react';\nimport styled from 'styled-components';\n\nimport { ChevronDownIcon, ChevronRightIcon, MoreIcon } from '@persona/icons';\n\nimport Button from '#src/components/Button';\nimport { getColumnWidths } from '#src/components/DataTable';\nimport type { HeadlessFilterConfig, RowAction, SortProps } from '#src/components/DataTable/types';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nimport { renderAsCheckbox, renderAsCheckboxHeader } from './helpers';\nimport type { DataTableColumnFormat, DataTableColumns } from './types';\n\nconst ExpandButton = styled.button`\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n margin: 0;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n`;\n\nconst ExpandColumnPlaceholder = styled.span`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n`;\n\n/**\n * Host-injected cell format renderer. Dashboard passes its own implementation\n * that handles all format types including tags, files, and status indicators.\n */\nexport type RenderFormatFn<TData = unknown, TFormat extends { type: string } = { type: string }> = (\n value: unknown,\n format?: TFormat,\n row?: TData,\n) => React.ReactNode;\n\nexport interface UseTableColumnsParams<\n TData extends RowData,\n TFormat extends { type: string } = DataTableColumnFormat<TData>,\n TFilter = unknown,\n> {\n columns: DataTableColumns<TData, TFormat, TFilter>;\n data: TData[];\n compact?: boolean;\n sort?: boolean | SortProps;\n clientSearch?: boolean | { placeholder?: string; initialValue?: string };\n clientFiltering?: boolean;\n expandColumnVisibility?: 'auto' | 'always';\n showControls?: boolean;\n enableRowSelection?: boolean;\n enableSubRowSelection?: boolean;\n rowActions?: RowAction[] | ((row: TData) => RowAction[]);\n getRowId?: (row: TData) => string;\n expandedRows: Set<string>;\n toggleRowExpansion: (rowId: string) => void;\n canRowExpand: (rowData: TData) => boolean;\n checkboxColumnStates: Record<string, Set<string>>;\n handleCheckboxCellChange: (columnId: string, rowId: string, checked: boolean) => void;\n handleSelectAllCheckboxCell: (columnId: string, checked: boolean) => void;\n getSelfAndNestedRowIds: (row: TData, indexPath: number[]) => string[];\n handleRowSelectionWithShift: (\n clickedRow: Row<TData>,\n table: Table<TData>,\n checked: boolean,\n isShiftKey: boolean,\n ) => void;\n renderFormat: RenderFormatFn<TData, TFormat>;\n}\n\nexport function useTableColumns<\n TData extends RowData,\n TFormat extends { type: string } = DataTableColumnFormat<TData>,\n TFilter = unknown,\n>({\n columns,\n data,\n compact,\n sort,\n clientSearch,\n clientFiltering,\n expandColumnVisibility = 'auto',\n showControls,\n enableRowSelection = false,\n enableSubRowSelection = true,\n rowActions,\n getRowId,\n expandedRows,\n toggleRowExpansion,\n canRowExpand,\n checkboxColumnStates,\n handleCheckboxCellChange,\n handleSelectAllCheckboxCell,\n getSelfAndNestedRowIds,\n handleRowSelectionWithShift,\n renderFormat,\n}: UseTableColumnsParams<TData, TFormat, TFilter>): [\n ColumnDef<TData, any>[],\n { key: string; label: string }[],\n] {\n const { EXPAND_COLUMN_WIDTH, SELECT_COLUMN_WIDTH, ACTION_COLUMN_WIDTH } =\n getColumnWidths(compact);\n const strings = usePDSStrings();\n const stringsRef = useRef(strings);\n stringsRef.current = strings;\n\n // Stable renderer identity: an inline `cell` gets a new identity on each column\n // rebuild, which flexRender treats as a new component type and remounts —\n // closing any open row-actions menu. Read live `rowActions` from a ref instead.\n const rowActionsRef = useRef(rowActions);\n rowActionsRef.current = rowActions;\n const renderActionCell = useCallback((props: CellContext<TData, unknown>) => {\n const currentRowActions = rowActionsRef.current;\n const actions =\n typeof currentRowActions === 'function'\n ? currentRowActions(props.row.original)\n : currentRowActions;\n\n if (!actions || actions.length === 0) {\n return null;\n }\n\n return (\n <DropdownMenu\n trigger={\n <Button\n id={`data-table__row-actions-button--${props.row.id}`}\n variant='text'\n width='icon'\n size='sm'\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n aria-label={stringsRef.current.viewRowActions(props.row.index + 1)}\n >\n <MoreIcon />\n </Button>\n }\n portal\n >\n {actions.map(({ label, onClick, ...menuItemProps }, i) => (\n <DropdownMenu.Item\n key={label.toLowerCase().replace(/ /g, '-')}\n id={`data-table__row-actions--${props.row.id}-${i}`}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick(props.row.id);\n }}\n {...menuItemProps}\n >\n {label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n );\n }, []);\n const hasRowActions = rowActions != null;\n\n return useMemo(() => {\n const columnHelper = createColumnHelper<TData>();\n\n const tableColumns: ColumnDef<TData, any>[] = columns.map((column) => {\n if (typeof column === 'object') {\n const columnHelperOptions: Parameters<typeof columnHelper.accessor>[1] = {\n header: column.header,\n id: column.id || column.accessor,\n // Treats undefined and null as the lowest values for sorting\n sortUndefined: -1,\n meta: {\n align: column.align,\n format: column.format,\n minWidth: column.minWidth,\n width: column.width,\n headerTooltip: column.headerTooltip,\n },\n minSize: column.minWidth,\n };\n\n if (column.renderCell != null) {\n const renderCell = column.renderCell;\n columnHelperOptions.cell = (props) =>\n renderCell({ cellValue: props.getValue(), row: props.row.original });\n // A custom cell renderer controls display only — it does not affect sorting.\n // Honor the column's explicit `enableSorting` opt-in (defaults to off) so\n // server-sortable columns that need custom rendering still expose a sort control.\n columnHelperOptions.enableSorting = sort != null && (column.enableSorting ?? false);\n } else if (column.format?.type === 'checkbox') {\n // Handle checkbox column format\n const columnId = column.id || column.accessor;\n\n // Custom header with select all checkbox\n columnHelperOptions.header = (headerProps) => {\n const columnState = checkboxColumnStates[columnId] || new Set();\n // Select all rows for this column\n const allRowIds = data.flatMap((row, index) => getSelfAndNestedRowIds(row, [index]));\n const isChecked = allRowIds.length > 0 && allRowIds.every((id) => columnState.has(id));\n const isIndeterminate = !isChecked && allRowIds.some((id) => columnState.has(id));\n\n // If column.header is a function, call it with TanStack context props\n if (typeof column.header === 'function') {\n return column.header(headerProps);\n }\n\n return renderAsCheckboxHeader({\n header: column.header,\n isChecked,\n isIndeterminate,\n onValueChange: (checked) => handleSelectAllCheckboxCell(columnId, checked),\n strings,\n });\n };\n\n // Custom cell with individual checkbox\n columnHelperOptions.cell = (props) => {\n const rowId = getRowId ? getRowId(props.row.original) : props.row.id;\n const columnState = checkboxColumnStates[columnId] || new Set();\n const isChecked = columnState.has(rowId);\n\n return renderAsCheckbox({\n rowId,\n isChecked,\n onValueChange: (rowId, checked) => handleCheckboxCellChange(columnId, rowId, checked),\n columnHeader: typeof column.header === 'string' ? column.header : undefined,\n strings,\n });\n };\n\n // Disable sorting for checkbox columns\n columnHelperOptions.enableSorting = false;\n } else {\n // Ensure value is rendered as a string regardless of column value\n columnHelperOptions.cell = (props) =>\n renderFormat(props?.getValue(), column.format, props.row.original);\n // Only enable column sorting if table-level sorting is enabled and column allows it\n columnHelperOptions.enableSorting = sort != null && column.enableSorting;\n }\n\n // Enable global filtering based on clientSearch and column searchable property\n columnHelperOptions.enableGlobalFilter = clientSearch && (column.searchable ?? true);\n // Enable column pinning based on column configuration\n columnHelperOptions.enablePinning = column.pinned ?? false;\n\n // Configure column filtering\n if (clientFiltering && column.filter) {\n const filterConfig = column.filter as Partial<HeadlessFilterConfig>;\n if (filterConfig.enabled !== false) {\n columnHelperOptions.enableColumnFilter = true;\n if (filterConfig.filterFn) {\n columnHelperOptions.filterFn = filterConfig.filterFn;\n }\n }\n }\n\n return columnHelper.accessor(column.accessor, columnHelperOptions);\n }\n\n return columnHelper.accessor(column, {\n header: startCase(column),\n enableGlobalFilter: Boolean(clientSearch),\n enableSorting: sort != null,\n });\n });\n\n if (showControls && enableRowSelection) {\n tableColumns.unshift(\n columnHelper.display({\n id: 'select-col',\n enablePinning: true,\n enableResizing: false,\n size: SELECT_COLUMN_WIDTH,\n meta: {\n width: SELECT_COLUMN_WIDTH,\n },\n header: ({ table }) =>\n renderAsCheckboxHeader({\n isChecked: table.getIsAllRowsSelected(),\n // Show the dash whenever any row is selected (including all rows), since\n // clicking the header in that state deselects everything.\n isIndeterminate: table.getIsSomeRowsSelected() || table.getIsAllRowsSelected(),\n onChange: table.getToggleAllRowsSelectedHandler(),\n strings,\n }),\n cell: ({ row, table }) =>\n renderAsCheckbox({\n rowId: row.id,\n isChecked: row.getIsSelected(),\n onChange: (e) =>\n handleRowSelectionWithShift(\n row,\n table,\n e.target.checked,\n e.nativeEvent instanceof MouseEvent && e.nativeEvent.shiftKey,\n ),\n indeterminate: enableSubRowSelection && row.getIsSomeSelected(),\n disabled: !row.getCanSelect(),\n strings,\n }),\n }),\n );\n }\n\n // Add expansion column when any row can expand, or when forced visible for layout parity\n const showExpandColumn = expandColumnVisibility === 'always' || data.some(canRowExpand);\n if (showExpandColumn) {\n tableColumns.unshift(\n columnHelper.display({\n id: 'expand-col',\n enablePinning: true,\n enableResizing: false,\n size: EXPAND_COLUMN_WIDTH,\n meta: {\n width: EXPAND_COLUMN_WIDTH,\n },\n header: '',\n cell: ({ row }) => {\n const rowData = row.original;\n if (!canRowExpand(rowData)) {\n return <ExpandColumnPlaceholder aria-hidden />;\n }\n\n const rowId = getRowId ? getRowId(rowData) : row.id;\n const isExpanded = expandedRows.has(rowId);\n\n return (\n <ExpandColumnPlaceholder>\n <ExpandButton\n type='button'\n id={`datatable-expand-${rowId}`}\n onClick={(e) => {\n e.stopPropagation();\n toggleRowExpansion(rowId);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n toggleRowExpansion(rowId);\n }\n }}\n aria-label={\n isExpanded ? `Hide details for row ${rowId}` : `View details for row ${rowId}`\n }\n aria-expanded={isExpanded}\n >\n {isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\n </ExpandButton>\n </ExpandColumnPlaceholder>\n );\n },\n }),\n );\n }\n\n if (hasRowActions) {\n const emptyHeader = () => <></>;\n tableColumns.push(\n columnHelper.display({\n id: 'action-col',\n enableResizing: false,\n size: ACTION_COLUMN_WIDTH,\n meta: {\n width: ACTION_COLUMN_WIDTH,\n },\n header: emptyHeader,\n cell: renderActionCell,\n }),\n );\n }\n\n const columnOptions = columns.map((column) => {\n const key = typeof column === 'object' ? column.id || column.accessor : column;\n const label =\n typeof column === 'object'\n ? typeof column.header === 'string'\n ? column.header\n : key\n : startCase(column);\n\n return {\n key,\n label,\n };\n });\n\n return [tableColumns, columnOptions];\n }, [\n columns,\n enableRowSelection,\n hasRowActions,\n renderActionCell,\n showControls,\n sort,\n clientSearch,\n clientFiltering,\n data,\n canRowExpand,\n expandColumnVisibility,\n expandedRows,\n toggleRowExpansion,\n getRowId,\n checkboxColumnStates,\n handleCheckboxCellChange,\n handleSelectAllCheckboxCell,\n handleRowSelectionWithShift,\n renderFormat,\n strings,\n ]);\n}\n","import {\n type Column,\n type ColumnFiltersState,\n type ColumnPinningState,\n type ExpandedState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getMemoOptions,\n getPaginationRowModel,\n getSortedRowModel,\n memo as tanstackMemo,\n type Row,\n type RowData,\n type RowModel,\n type RowSelectionState,\n type Table,\n type TableOptions,\n useReactTable,\n} from '@tanstack/react-table';\nimport {\n type ComponentProps,\n type Dispatch,\n type MouseEvent,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Pagination, { MIN_PAGE_SIZE } from '#src/components/Pagination';\nimport {\n StickyTD,\n StickyTH,\n TableActionTD,\n TableLayout,\n TableTD,\n TableTH,\n TableTR,\n} from '#src/components/Table';\nimport { Paragraph } from '#src/components/Text';\nimport { TextUnderlineTooltip } from '#src/components/Tooltip';\nimport { usePDSLocale, usePDSStrings } from '#src/lib/i18n';\nimport { RouterLink } from '#src/lib/router';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { focusOutline } from '#src/mixins/focus';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\n\nimport { generateClientFilters, getFilterFnName } from './clientFilterUtils';\nimport { getColumnWidths } from './constants';\nimport FloatingActionBar from './FloatingActionBar';\nimport { renderAsPDSFormat } from './helpers';\nimport { Inserter } from './Inserter';\nimport TableControls, {\n isEmptyState,\n isFilterActive,\n TableViewConfigurationDropdown,\n type TableControlsProps,\n} from './TableControls';\nimport type { AttributeColumn, BaseFilterConfig, FilterConfig } from './TableControls/types';\nimport type {\n BulkAction,\n ColumnConfig,\n DataTableColumnFormat,\n DataTableColumns,\n RowAction,\n RowDataWithDetails,\n RowDataWithSubrows,\n RowDataWithSubrowsToAlwaysShowIds,\n RowDataWithTourTarget,\n SortProps,\n} from './types';\nimport { useTableColumns, type RenderFormatFn } from './useTableColumns';\n\n// https://tanstack.com/table/v8/docs/api/core/column-def#meta\ndeclare module '@tanstack/react-table' {\n // oxlint-disable-next-line no-unused-vars -- required for declaration merging\n interface ColumnMeta<TData extends RowData, TValue> {\n align?: 'left' | 'right';\n format?: { type: string };\n minWidth?: number;\n width?: number;\n headerTooltip?: React.ReactNode;\n }\n}\n\nconst forwardedRowLinkClicks = new WeakSet<Event>();\n\nconst TableEmptyState = styled.td`\n vertical-align: middle;\n text-align: center;\n width: 100%;\n height: 176px;\n`;\n\nconst StyledTableLayout = styled(TableLayout)<{ $onAddRow: boolean }>`\n ${({ $onAddRow }) =>\n $onAddRow &&\n css`\n padding-bottom: ${Spacing[3]};\n `}\n`;\n\nconst TableContainer = styled.div<{ $stickyHeader: boolean }>`\n position: relative;\n ${semanticScrollbar}\n\n ${({ $stickyHeader }) =>\n $stickyHeader &&\n css`\n flex-grow: 1;\n overflow: auto;\n display: flex;\n flex-direction: column;\n `}\n`;\n\nconst RowLink = styled(RouterLink)`\n /* Match surrounding cell text. The row is still a link; only URL cells use accent. */\n color: inherit;\n text-decoration: none;\n ${focusOutline}\n\n &:link,\n &:visited,\n &:hover,\n &:active {\n color: inherit;\n }\n`;\n\nconst StyledDataTableControls = styled(TableControls)``;\nexport const DataTableControls = StyledDataTableControls as typeof StyledDataTableControls &\n typeof TableControls;\n\nexport const DataTableContainer = styled.div<{ $stickyHeader: boolean }>`\n ${({ $stickyHeader }) =>\n $stickyHeader &&\n css`\n display: flex;\n flex-direction: column;\n height: 100%;\n `}\n`;\n\nconst StyledTableActionTD = styled(TableActionTD)<{ $nestSpacing?: number }>`\n ${({ $nestSpacing }) => css`\n ${\n $nestSpacing &&\n css`\n position: relative;\n left: ${$nestSpacing}px;\n `\n }\n `}\n`;\n\nconst StyledTableTD = styled(TableTD)<{ $nestSpacing?: number; $isFeatureCol?: boolean }>`\n // Move the cell to the right by the amount of the nest spacing, and\n // add same amount of padding to the right to not overlap with the next cell\n ${({ $nestSpacing, $isFeatureCol }) => css`\n ${\n $nestSpacing &&\n css`\n position: relative;\n left: ${$nestSpacing}px;\n `\n }\n ${\n !$isFeatureCol &&\n css`\n padding-right: ${$nestSpacing}px;\n `\n }\n `}\n`;\n\nconst DetailsTD = styled(TableTD)`\n padding: 0;\n border-top: none;\n border-left: none;\n border-right: none;\n`;\n\nconst StickyDetailsTD = styled(StickyTD)`\n padding: 0;\n border-top: none;\n border-left: none;\n border-right: none;\n`;\n\nconst StickyTDWithGapCoverage = styled(StickyTD)<{ $gapCoverage?: number }>`\n ${({ $gapCoverage }) =>\n $gapCoverage &&\n css`\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: ${-$gapCoverage}px;\n width: ${$gapCoverage}px;\n height: calc(100% + 1px); // +1px to cover the bottom border\n background: inherit;\n }\n `}\n`;\n\nexport const FloatingActionBarContainer = styled.div`\n position: absolute;\n top: 0;\n left: 50%;\n transform: translateX(-50%);\n`;\n\nconst isServerPagination = (\n pagination: DataTableProps<unknown>['pagination'],\n): pagination is ComponentProps<typeof Pagination> => {\n return typeof pagination === 'object' && !('clientPagination' in pagination);\n};\n\nconst isClientPagination = (\n pagination: DataTableProps<unknown>['pagination'],\n): pagination is ClientPaginationProps => {\n return typeof pagination === 'object' && 'clientPagination' in pagination;\n};\n\nconst isServerSorting = (sort: boolean | SortProps | undefined): sort is SortProps => {\n return typeof sort === 'object';\n};\n\nconst isRowWithDetails = <TData extends RowData>(row: TData): row is RowDataWithDetails<TData> => {\n return row != null && typeof row === 'object' && '_details' in row && row._details != null;\n};\n\nconst isRowWithSubrows = <TData extends RowData>(row: TData): row is RowDataWithSubrows<TData> => {\n return row != null && typeof row === 'object' && 'subrows' in row && row.subrows != null;\n};\n\nconst isRowWithSubrowsToAlwaysShowIds = <TData extends RowData>(\n row: TData,\n): row is RowDataWithSubrowsToAlwaysShowIds<TData> => {\n return (\n row != null &&\n typeof row === 'object' &&\n 'subrowsToAlwaysShowIds' in row &&\n row.subrowsToAlwaysShowIds != null\n );\n};\n\nconst isRowWithTourTarget = <TData extends RowData>(\n row: TData,\n): row is RowDataWithTourTarget<TData> => {\n return (\n row != null &&\n typeof row === 'object' &&\n 'dataTourTarget' in row &&\n typeof row.dataTourTarget === 'string'\n );\n};\n\ntype ClientPaginationProps = {\n clientPagination: true;\n pageSize?: number;\n pageSizeOptions?: number[];\n};\nexport interface DataTableProps<\n TData extends RowData,\n TFilter extends BaseFilterConfig = FilterConfig,\n> {\n /**\n * Data to render.\n * If a row has a _details property that is a function, it will be called\n * with the row data as props.\n * If a row has a _details property that is a React node, it will be rendered as is.\n */\n data: TData[];\n\n /**\n * Columns to display in the table. May be a string or column config object.\n *\n * Strings get converted from camelCase to Start Case.\n */\n columns: DataTableColumns<TData, DataTableColumnFormat<TData>>;\n\n /**\n * Component to render details for expandable rows.\n * Useful if we want to render the same details component for every row.\n * Receives rowData as props.\n */\n detailComponent?: React.ComponentType<{ rowData: TData }>;\n\n /**\n * When `'always'`, the leading expand column is shown even if no rows are expandable.\n * When `'auto'`, the column is omitted unless at least one row can expand. Rows that\n * cannot expand keep an empty spacer in this column so labels stay aligned.\n */\n expandColumnVisibility?: 'auto' | 'always';\n\n /**\n * Whether to display table controls such as search, filters, views, and selection\n */\n showControls?: boolean;\n\n /**\n * Props to pass to the TableControls component\n */\n controls?: TableControlsProps<TFilter>;\n\n /**\n * Custom text to display when the table is empty. Will default to \"No results found\"\n */\n emptyState?: {\n title?: string;\n description?: string;\n };\n\n /**\n * Whether to display pagination controls. If true, will use client-side pagination. If an object,\n * can be either advanced configuration of cleitn paginaton or server-side pagination state..\n */\n pagination?: boolean | ClientPaginationProps | ComponentProps<typeof Pagination>;\n\n /**\n * Whether to display sort controls. If true, will use client-side sorting. If an object, will use server-side sorting.\n */\n sort?: boolean | SortProps;\n\n /**\n * Whether to display the column properties button and popover. Allows control of column visiblity and ordering.\n */\n showColumnProperties?: boolean;\n\n /**\n * Whether to enable sorting removal. If true, will allow sorting to be removed by clicking the sort control.\n */\n enableSortingRemoval?: boolean;\n\n /**\n * Set to true to sort descending first, which is the case for most of our tables.\n */\n sortDescFirst?: boolean;\n\n /**\n * Called when column visibility or ordering is updated. Useful for saving column properties.\n */\n onUpdateColumnProperties?: (newConfiguration: AttributeColumn[]) => void;\n\n /**\n * Whether the table is loading data\n */\n isLoading?: boolean;\n\n /**\n * Whether to enable row selection\n */\n enableRowSelection?: boolean;\n\n /**\n * Whether to enable automatic sub row selection when a parent row is selected\n */\n enableSubRowSelection?: boolean;\n\n /**\n * Define the row id for the given row. Used by row selection and bulk actions.\n */\n getRowId?: (row: TData) => string;\n\n /**\n * Define the aria label for the given row.\n */\n getRowLabel?: (row: TData) => string;\n\n /**\n * Determine if a row can be selected. Used to disable row selection for specific rows.\n */\n getRowSelectable?: (row: TData) => boolean;\n\n /**\n * Makes the row link cell an anchor if provided. Get link for the given row.\n */\n getLinkToRow?: (row: TData) => string;\n\n /**\n * If set, each row will be a link to the given prefix + the row's `id` value.\n * `getLinkToRow` will override this.\n */\n rowLinkPrefix?: string;\n\n /**\n * Column id whose cell contains the row link when `getLinkToRow`/`rowLinkPrefix` is set.\n * Defaults to the first visible non-feature column (not select/expand/action). URL-formatted\n * columns are skipped.\n */\n rowLinkColumnId?: string;\n\n /**\n * Component to use for row links. Defaults to the PDS router-aware link.\n * Pass a custom component (e.g. Next.js Link) to use a different router.\n * The component renders as an inline anchor inside the link cell and receives `to`,\n * `className`, and `children`.\n */\n rowLinkComponent?: React.ElementType;\n\n /**\n * Whether to show the compact variant of the table.\n * Compact tables do not support views.\n */\n compact?: boolean;\n\n /**\n * Disables the row hover highlight. Use for read-only, non-interactive tables where the\n * hover background would misleadingly imply rows are selectable or clickable.\n */\n disableRowHover?: boolean;\n\n /**\n * Title to display in the table.\n */\n title?: string;\n\n /**\n * Whether to make the table header sticky when scrolling vertically.\n * When enabled, the controls and table header will remain visible at the top of the viewport while scrolling through table data.\n * Note that the sticky header styling assumes this component is contained within a parent with `display: flex` and `flex-direction: column`.\n */\n stickyHeader?: boolean;\n\n /**\n * Enable client-side search functionality.\n * Pass an object to configure the search input.\n */\n clientSearch?:\n | boolean\n | {\n placeholder?: string;\n initialValue?: string;\n };\n\n /**\n * Controlled search term for client-side search.\n * When provided, the search input becomes controlled.\n * Use with onSearchTermChange to manage search state externally.\n */\n searchTerm?: string;\n\n /**\n * Called when the search term changes (for controlled search).\n * Only used when searchTerm prop is provided.\n */\n onSearchTermChange?: (searchTerm: string) => void;\n\n /**\n * Whether to use manual filtering. If true, will not use the global filter function 'includesString'.\n */\n manualFiltering?: boolean;\n\n /**\n * Controlled expanded row IDs.\n * When provided, row expansion becomes controlled.\n * Use with onExpandedRowsChange to manage expansion state externally.\n */\n expandedRowIds?: Set<string>;\n\n /**\n * Called when expanded rows change (for controlled expansion).\n * Only used when expandedRowIds prop is provided.\n */\n onExpandedRowsChange?: (expandedRowIds: Set<string>) => void;\n\n /**\n * Enable client-side filtering functionality.\n * Users must explicitly define filter types for columns in TableControls.\n * Generated controls are legacy-only; `controls.filtersV2` does not drive client filtering.\n */\n clientFiltering?: boolean;\n\n /**\n * @internal Not part of the public API surface.\n * Used exclusively by the DashboardDataTable wrapper to share TanStack column-filter\n * state with the dashboard's generateClientFilters adapter.\n * Pass only via the wrapper's any-cast spread — do not use directly.\n * @deprecated Prefer `column.filter` for defining client-side filters.\n */\n columnFilters?: ColumnFiltersState;\n\n /**\n * When true, the empty-state message will read \"No results found. Try changing your filters.\"\n * even when the DataTable's own filter state is empty.\n * Use this when the host manages active server-side filters outside the DataTable\n * (e.g. via an injected filterPanel) so the conditional empty state still reflects those filters.\n */\n hasExternalActiveFilters?: boolean;\n\n /**\n * Called when the column-level filter state changes.\n * Use this to drive an injected filter-panel UI from outside the DataTable,\n * e.g. to feed `generateClientFilters` with the current TanStack filter state.\n */\n onColumnFiltersChange?: (filters: ColumnFiltersState) => void;\n\n /**\n * Host-provided cell format renderer.\n * The PDS built-in handles string, number, date, datetime, url, sticker, image, id, and pii.\n * Pass a custom renderer to handle additional application-specific formats (e.g. tags, files,\n * status indicators) or to override PDS defaults.\n */\n renderFormat?: RenderFormatFn<TData, DataTableColumnFormat<TData>>;\n\n /**\n * Actions to display in each table row.\n * Can be a static array (same actions for all rows) or a function that\n * receives the row data and returns actions specific to that row.\n */\n rowActions?: RowAction[] | ((row: TData) => RowAction[]);\n\n /**\n * Bulk actions to display when there are selected rows.\n * For standard variant, actions will be shown in the table controls.\n * For compact variant, actions will be shown in a floating action bar.\n * If bulkActions are provided in `controls.bulkActions`, they will override the bulkActions prop.\n */\n bulkActions?: BulkAction[];\n\n /**\n * Function that returns available bulk actions based on selected rows.\n * This allows dynamic bulk actions that change based on the selection.\n * Takes precedence over static bulkActions prop.\n */\n getAvailableBulkActions?: (selectedRows: TData[]) => BulkAction[];\n\n /**\n * Callback fired when the set of selected rows changes.\n * Receives the currently selected row data objects.\n */\n onRowSelectionChange?: (selectedRows: TData[]) => void;\n\n /**\n * If present, will display a thin row between rows as UI affordance to add a new row.\n * The row will be added after the row identified by the provided rowId, and the addAsChild flag will\n * indicate if the added row will be a sibling or a child of the referenced row\n * Adding said row will be handled by this `onAddRow` callback.\n */\n onAddRow?: (rowId: string, addAsChild: boolean) => void;\n\n /**\n * Called to determine if a row can be added after the provided row.\n * If not provided, assume true.\n * If this resolves to false, we will hide the inserter row.\n */\n canAddAfterRow?: (row: TData, addAsChild: boolean) => boolean;\n\n /**\n * Called when a row is clicked. If provided, rows will have cursor pointer\n * and clicking a row will call this function with the row id.\n * When omitted, rows that can expand (via `_details` or `detailComponent`) toggle expand/collapse on row click.\n */\n onRowClick?: (rowId: string) => void;\n\n /**\n * The active row id. If provided, the row will be in an active state.\n */\n activeRowId?: string;\n\n /**\n * Called with the ordered ids of the rows currently displayed, reflecting\n * client-side search, filtering, and sorting. Lets a parent step through the\n * on-screen order (e.g. prev/next navigation in a detail panel).\n */\n onDisplayedRowIdsChange?: (rowIds: string[]) => void;\n\n /**\n * Custom left offset in pixels to add to all pinned columns.\n * Useful when the table is nested inside containers that need additional spacing.\n */\n pinnedColumnLeftOffset?: number;\n\n /**\n * When false, the table does not scroll horizontally on its own and an ancestor is expected\n * to. Set this when a host scrolls the table and positions its header or pinned columns\n * against that ancestor, so those offsets are not trapped in the table's own scrollport.\n * Combining this with `stickyHeader` is contradictory: `stickyHeader` gives the table an\n * inner scrollport of its own, which is the thing this prop gives up.\n */\n scrollsHorizontally?: boolean;\n\n /**\n * Custom content to render inside the floating action bar, between the\n * selection count and the action buttons. Only rendered when the floating\n * action bar is visible (compact mode with selected rows).\n */\n floatingBarContent?: React.ReactNode;\n}\n\n// Unit-separator control char; joins row ids into a change-detection key that\n// can't collide with characters found in real row ids.\nconst DISPLAYED_ROW_IDS_SEPARATOR = '\\u001f';\n\n/**\n * The DataTable component is the core of Persona's table experiences.\n *\n * This component implements `@tanstack/react-table` and exposes a simplified, easy to use API.\n *\n * Planned functionality\n * - Column visibility, reordering\n * - Row selection\n * - Cell types (e.g. links, buttons, Stickers)\n *\n * Client-side support\n * - ✅ Sorting\n * - ✅ Search (enable with clientSearch prop)\n * - ✅ Pagination\n * - ✅ Filtering (requires explicit filter configuration in TableControls)\n *\n * Server-side support\n * - ✅ Sorting\n * - ✅ Filtering\n * - ✅ Pagination\n *\n * @example\n * // Basic usage with client-side search\n * <DataTable\n * data={data}\n * columns={columns}\n * showControls={true}\n * clientSearch={{ placeholder: \"Search accounts...\" }}\n * />\n *\n * @example\n * // Column-level search control\n * const columns = [\n * { accessor: 'id', header: 'ID', searchable: false },\n * { accessor: 'name', header: 'Name' }, // searchable by default\n * { accessor: 'email', header: 'Email' },\n * ];\n */\n\nexport const DataTable = <TData extends RowData, TFilter extends BaseFilterConfig = FilterConfig>({\n data,\n columns,\n detailComponent,\n expandColumnVisibility = 'auto',\n showControls,\n controls,\n emptyState,\n isLoading,\n pagination,\n sort,\n sortDescFirst,\n enableSortingRemoval,\n showColumnProperties = false,\n onUpdateColumnProperties,\n enableRowSelection = false,\n enableSubRowSelection = true,\n getRowId,\n getRowLabel,\n getRowSelectable,\n getLinkToRow,\n rowLinkPrefix,\n rowLinkColumnId,\n rowLinkComponent,\n compact,\n disableRowHover,\n title,\n clientSearch = false,\n searchTerm: controlledSearchTerm,\n onSearchTermChange,\n manualFiltering,\n expandedRowIds: controlledExpandedRowIds,\n onExpandedRowsChange,\n clientFiltering = false,\n columnFilters: controlledColumnFilters,\n hasExternalActiveFilters = false,\n onColumnFiltersChange,\n renderFormat,\n rowActions,\n bulkActions,\n getAvailableBulkActions,\n onRowSelectionChange,\n onAddRow,\n stickyHeader = false,\n canAddAfterRow,\n onRowClick,\n activeRowId,\n onDisplayedRowIdsChange,\n pinnedColumnLeftOffset = 0,\n scrollsHorizontally = true,\n floatingBarContent,\n}: DataTableProps<TData, TFilter>) => {\n const DEFAULT_SEARCH_PLACEHOLDER = 'Search...';\n const { NEST_SPACING, EXPAND_COLUMN_WIDTH } = getColumnWidths(compact);\n const [columnVisibility, setColumnVisibility] = useState(() => {\n const visibility: { [key: string]: boolean } = {};\n columns.forEach((column) => {\n const columnId = typeof column === 'object' ? (column.id ?? column.accessor) : column;\n visibility[columnId] = typeof column === 'object' ? (column.visibility ?? true) : true; // Set default visibility to true if no option is passed in\n });\n return visibility;\n });\n const [columnOrder, setColumnOrder] = useState<string[]>([]);\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n // Tracks the most recently clicked selection checkbox to support shift+click range selection.\n const lastSelectedRowIdRef = useRef<string | null>(null);\n\n // Search term: use controlled state if provided, otherwise use internal state\n const isSearchControlled = controlledSearchTerm != null;\n const [internalSearchTerm, setInternalSearchTerm] = useState<string>(\n typeof clientSearch === 'object' ? clientSearch.initialValue || '' : '',\n );\n const globalFilter = isSearchControlled ? controlledSearchTerm : internalSearchTerm;\n const setGlobalFilter = useCallback(\n (value: string) => {\n if (isSearchControlled) {\n onSearchTermChange?.(value);\n } else {\n setInternalSearchTerm(value);\n }\n },\n [isSearchControlled, onSearchTermChange],\n );\n\n const isColumnFiltersControlled = controlledColumnFilters != null;\n const [internalColumnFilters, setInternalColumnFilters] = useState<ColumnFiltersState>([]);\n const columnFilters = isColumnFiltersControlled ? controlledColumnFilters : internalColumnFilters;\n\n const setColumnFilters = useCallback<Dispatch<SetStateAction<ColumnFiltersState>>>(\n (updater) => {\n const next = typeof updater === 'function' ? updater(columnFilters) : updater;\n if (!isColumnFiltersControlled) {\n setInternalColumnFilters(next);\n }\n onColumnFiltersChange?.(next);\n },\n [columnFilters, isColumnFiltersControlled, onColumnFiltersChange],\n );\n\n // Expanded rows: use controlled state if provided, otherwise use internal state\n const isExpansionControlled = controlledExpandedRowIds != null;\n const [internalExpandedRows, setInternalExpandedRows] = useState<Set<string>>(new Set());\n const expandedRows = isExpansionControlled ? controlledExpandedRowIds : internalExpandedRows;\n const setExpandedRows = useCallback(\n (updater: (prev: Set<string>) => Set<string>) => {\n if (isExpansionControlled) {\n const newValue = updater(expandedRows);\n onExpandedRowsChange?.(newValue);\n } else {\n setInternalExpandedRows(updater);\n }\n },\n [expandedRows, isExpansionControlled, onExpandedRowsChange],\n );\n\n const [checkboxColumnStates, setCheckboxColumnStates] = useState<Record<string, Set<string>>>({});\n\n const orderMap = columnOrder.reduce<{ [key: string]: number }>((acc, columnId, index) => {\n acc[columnId] = index;\n return acc;\n }, {});\n\n /**\n * If basic client pagination is enabled, create a configuration object for client pagination.\n */\n if (pagination === true) {\n pagination = {\n clientPagination: true,\n pageSize: MIN_PAGE_SIZE,\n };\n }\n\n // Helper function to check if a row can be expanded\n const canRowExpand = useCallback(\n (rowData: TData): boolean => {\n if (isRowWithSubrows(rowData)) {\n return rowData.subrows.length > 0;\n }\n if (isRowWithDetails(rowData)) {\n return Boolean(rowData._details);\n }\n return detailComponent != null;\n },\n [detailComponent],\n );\n\n // Calculate initial column pinning state from column configuration\n const initialColumnPinning = useMemo((): ColumnPinningState => {\n const pinnedColumns: string[] = [];\n\n // Check if we have any pinned columns\n const hasPinnedColumns = columns.some((column) => typeof column === 'object' && column.pinned);\n\n if (hasPinnedColumns) {\n // Add special columns first (they should be leftmost)\n const showExpandColumn = expandColumnVisibility === 'always' || data.some(canRowExpand);\n if (showExpandColumn) {\n pinnedColumns.push('expand-col');\n }\n if (showControls && enableRowSelection) {\n pinnedColumns.push('select-col');\n }\n\n // Then add user-defined pinned columns\n columns.forEach((column) => {\n if (typeof column === 'object' && column.pinned) {\n pinnedColumns.push(column.accessor);\n }\n });\n }\n\n return {\n left: pinnedColumns,\n };\n }, [columns, data, canRowExpand, expandColumnVisibility, showControls, enableRowSelection]);\n\n // Helper function to toggle row expansion\n const toggleRowExpansion = useCallback(\n (rowId: string) => {\n setExpandedRows((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(rowId)) {\n newSet.delete(rowId);\n } else {\n newSet.add(rowId);\n }\n return newSet;\n });\n },\n [setExpandedRows],\n );\n\n // Helper function to call onUpdate for checkbox columns\n const dispatchCheckboxCellOnUpdate = useCallback(\n (columnId: string, columnState: Set<string>) => {\n const column = columns.find(\n (col) =>\n typeof col === 'object' && col.accessor === columnId && col.format?.type === 'checkbox',\n );\n if (column && typeof column === 'object' && column.format?.type === 'checkbox') {\n column.format.onUpdate(Array.from(columnState));\n }\n },\n [columns],\n );\n\n // Helper function to handle checkbox column state changes\n const handleCheckboxCellChange = useCallback(\n (columnId: string, rowId: string, checked: boolean) => {\n setCheckboxColumnStates((prev) => {\n const newStates = { ...prev };\n if (!newStates[columnId]) {\n newStates[columnId] = new Set();\n }\n\n const columnState = new Set(newStates[columnId]);\n if (checked) {\n columnState.add(rowId);\n } else {\n columnState.delete(rowId);\n }\n\n newStates[columnId] = columnState;\n dispatchCheckboxCellOnUpdate(columnId, columnState);\n return newStates;\n });\n },\n [dispatchCheckboxCellOnUpdate],\n );\n\n const getSelfAndNestedRowIds = useCallback(\n (row: TData, indexPath: number[]): string[] => {\n const rowId = getRowId ? getRowId(row) : indexPath.join('.');\n if (isRowWithSubrows(row)) {\n return [\n rowId,\n ...(row.subrows ?? [])\n .map((subrow, subrowIndex) =>\n getSelfAndNestedRowIds(subrow, [...indexPath, subrowIndex]),\n )\n .flat(),\n ];\n }\n return [rowId];\n },\n [getRowId],\n );\n\n // Helper function to handle \"select all\" checkbox for a column\n const handleSelectAllCheckboxCell = useCallback(\n (columnId: string, checked: boolean) => {\n setCheckboxColumnStates((prev) => {\n const newStates = { ...prev };\n let columnState: Set<string>;\n\n if (checked) {\n // Select all rows for this column\n const allRowIds = data.flatMap((row, index) => getSelfAndNestedRowIds(row, [index]));\n columnState = new Set(allRowIds);\n } else {\n // Deselect all rows for this column\n columnState = new Set();\n }\n\n newStates[columnId] = columnState;\n dispatchCheckboxCellOnUpdate(columnId, columnState);\n return newStates;\n });\n },\n [data, getRowId, dispatchCheckboxCellOnUpdate],\n );\n\n const tableOptions: Partial<TableOptions<TData>> = useMemo(() => {\n const options: Partial<TableOptions<TData>> = {};\n\n // Client-side pagination\n if (isClientPagination(pagination)) {\n options.getPaginationRowModel = getPaginationRowModel();\n options.initialState = {\n pagination: {\n pageSize: pagination.pageSize,\n },\n };\n } else if (isServerPagination(pagination)) {\n const currentPage = pagination.paginationParams?.['current-page'] || 1;\n const pageSize = pagination.pageSize || MIN_PAGE_SIZE;\n\n options.manualPagination = true;\n options.onPaginationChange = (updaterOrValue) => {\n const oldPageSize = pageSize;\n const oldPageIndex = currentPage - 1;\n\n if (typeof updaterOrValue === 'function') {\n const newPaginationState = updaterOrValue({\n pageSize,\n pageIndex: currentPage - 1,\n });\n\n if (newPaginationState.pageSize !== oldPageSize) {\n pagination.handlePageSizeClick(newPaginationState.pageSize);\n }\n\n if (newPaginationState.pageIndex !== oldPageIndex) {\n pagination.handlePageLinkClick(newPaginationState.pageIndex + 1);\n }\n }\n };\n options.state = {\n pagination: {\n pageSize,\n pageIndex: currentPage - 1,\n },\n };\n options.rowCount = pagination?.paginationParams?.['total-count'];\n // TanStack clamps page changes to pageCount, so a page count that is only a lower bound would\n // stop Next at the last page it knows of; -1 leaves paging unbounded.\n options.pageCount = pagination.totalIsLowerBound\n ? -1\n : pagination?.paginationParams?.['total-pages'];\n }\n\n if (sort === true) {\n options.getSortedRowModel = getSortedRowModel();\n options.enableSorting = true;\n } else if (isServerSorting(sort)) {\n options.manualSorting = true;\n options.enableSorting = true;\n options.onSortingChange = (updaterOrValue) => {\n if (typeof updaterOrValue === 'function') {\n const newSortingState = updaterOrValue(sort.state);\n sort.handleSortClick(newSortingState);\n }\n };\n\n options.state = {\n ...(options.state ? options.state : {}),\n sorting: sort.state,\n };\n } else {\n options.enableSorting = false;\n }\n\n if (showControls && enableRowSelection) {\n options.enableRowSelection = getRowSelectable\n ? (row) => getRowSelectable(row.original)\n : true;\n options.onRowSelectionChange = setRowSelection;\n }\n\n if (!enableSubRowSelection) {\n options.enableSubRowSelection = false;\n }\n\n // Client-side global filtering\n if (clientSearch) {\n if (manualFiltering) {\n options.manualFiltering = true;\n } else {\n options.getFilteredRowModel = getFilteredRowModel();\n options.globalFilterFn = 'includesString';\n }\n options.onGlobalFilterChange = setGlobalFilter;\n }\n\n // Client-side column filtering\n if (clientFiltering) {\n options.getFilteredRowModel = getFilteredRowModel();\n options.onColumnFiltersChange = setColumnFilters;\n }\n\n // Build column visibility: use explicit values when provided, fall back to state or default\n const columnOptionsVisibility: Record<string, boolean> = {};\n columns.forEach((column) => {\n const columnId = typeof column === 'object' ? column.id || column.accessor : column;\n // Use explicit visibility if provided, otherwise fall back to state value or default true\n if (typeof column === 'object' && 'visibility' in column && column.visibility != null) {\n columnOptionsVisibility[columnId] = column.visibility;\n } else {\n columnOptionsVisibility[columnId] = columnVisibility[columnId] ?? true;\n }\n });\n options.state = { ...options.state, columnVisibility: columnOptionsVisibility };\n\n const expandedState: Record<string, boolean> = {};\n for (const rowId of expandedRows) {\n expandedState[rowId] = true;\n }\n options.state = {\n ...options.state,\n columnOrder,\n rowSelection,\n columnPinning: initialColumnPinning,\n expanded: expandedState,\n ...(clientSearch && { globalFilter }),\n ...(clientFiltering && { columnFilters }),\n };\n options.onColumnVisibilityChange = setColumnVisibility;\n options.onColumnOrderChange = setColumnOrder;\n options.enableSortingRemoval = enableSortingRemoval;\n options.sortDescFirst = sortDescFirst;\n options.enableColumnPinning = initialColumnPinning.left && initialColumnPinning.left.length > 0;\n\n return options;\n }, [\n pagination,\n columnVisibility,\n columnOrder,\n enableRowSelection,\n enableSubRowSelection,\n rowSelection,\n showControls,\n sort,\n enableSortingRemoval,\n sortDescFirst,\n clientSearch,\n globalFilter,\n clientFiltering,\n columnFilters,\n columns,\n initialColumnPinning,\n expandedRows,\n ]);\n\n // Handle row selection from the built-in select column, supporting shift+click range selection.\n // On shift+click, every selectable row between the last clicked row and the current row (in the\n // displayed order) is set to the clicked checkbox's new value.\n const handleRowSelectionWithShift = useCallback(\n (clickedRow: Row<TData>, table: Table<TData>, checked: boolean, isShiftKey: boolean) => {\n const displayedRows = table.getRowModel().rows;\n const currentIndex = displayedRows.findIndex((r) => r.id === clickedRow.id);\n const lastSelectedRowId = lastSelectedRowIdRef.current;\n const lastIndex =\n lastSelectedRowId != null ? displayedRows.findIndex((r) => r.id === lastSelectedRowId) : -1;\n\n if (isShiftKey && lastIndex !== -1 && currentIndex !== -1) {\n const startIndex = Math.min(lastIndex, currentIndex);\n const endIndex = Math.max(lastIndex, currentIndex);\n displayedRows.slice(startIndex, endIndex + 1).forEach((rangeRow) => {\n if (rangeRow.getCanSelect()) {\n rangeRow.toggleSelected(checked);\n }\n });\n } else {\n clickedRow.toggleSelected(checked);\n }\n\n lastSelectedRowIdRef.current = clickedRow.id;\n },\n [],\n );\n\n // Enrich columns with filterFn derived from ClientFilterConfig.type so that\n // the PDS useTableColumns hook sets the correct TanStack filter function.\n const columnsWithFilterFn = useMemo(() => {\n if (!clientFiltering) {\n return columns;\n }\n return columns.map((column) => {\n if (\n typeof column === 'object' &&\n column.filter != null &&\n typeof column.filter === 'object' &&\n 'type' in column.filter &&\n typeof (column.filter as { type: unknown }).type === 'string'\n ) {\n const filterType = (column.filter as { type: string }).type;\n return {\n ...column,\n filter: { ...column.filter, filterFn: getFilterFnName(filterType) },\n };\n }\n return column;\n }) as DataTableColumns<TData>;\n }, [columns, clientFiltering]);\n\n const strings = usePDSStrings();\n const locale = usePDSLocale();\n const defaultRenderFormat = useCallback<RenderFormatFn<TData, DataTableColumnFormat<TData>>>(\n (value, format, row) => renderAsPDSFormat(value, format, row, { locale, strings }),\n [locale, strings],\n );\n\n const [tableColumns, columnOptions] = useTableColumns({\n columns: columnsWithFilterFn,\n data,\n compact,\n sort,\n clientSearch,\n clientFiltering,\n expandColumnVisibility,\n showControls,\n enableRowSelection,\n enableSubRowSelection,\n rowActions,\n getRowId,\n expandedRows,\n toggleRowExpansion,\n canRowExpand,\n checkboxColumnStates,\n handleCheckboxCellChange,\n handleSelectAllCheckboxCell,\n getSelfAndNestedRowIds,\n handleRowSelectionWithShift,\n renderFormat: renderFormat ?? defaultRenderFormat,\n });\n\n // Custom getExpandedRowModel and expandRows functions to support showing specific nested rows even if the parent row is not expanded\n // Particularly useful when searching for specific rows and we want to show the nested rows that match the search term,\n // but not the other sibling nested rows. The logic is copied from the tanstack table's implementation, we are just\n // adding the above logic. https://github.com/TanStack/table/blob/v8.20.6/packages/table-core/src/utils/getExpandedRowModel.ts#L4\n const expandRowsCustom = useCallback((rowModel: RowModel<TData>): RowModel<TData> => {\n const expandedRows: Row<TData>[] = [];\n\n const handleRow = (row: Row<TData>) => {\n expandedRows.push(row);\n\n if (row.subRows?.length && row.getIsExpanded()) {\n row.subRows.forEach(handleRow);\n } else if (isRowWithSubrowsToAlwaysShowIds(row.original)) {\n row.subRows\n .filter((subrow) =>\n (\n row.original as RowDataWithSubrowsToAlwaysShowIds<TData>\n ).subrowsToAlwaysShowIds.includes(subrow.id),\n )\n .forEach(handleRow);\n }\n };\n\n rowModel.rows.forEach(handleRow);\n\n return {\n rows: expandedRows,\n flatRows: rowModel.flatRows,\n rowsById: rowModel.rowsById,\n };\n }, []);\n\n function getExpandedRowModelCustom(): (table: Table<TData>) => () => RowModel<TData> {\n return (table) =>\n tanstackMemo(\n () => [\n table.getState().expanded,\n table.getPreExpandedRowModel(),\n table.options.paginateExpandedRows,\n ],\n (\n expanded: ExpandedState,\n rowModel: RowModel<TData>,\n paginateExpandedRows: boolean | undefined,\n ) => {\n if (!rowModel.rows.length || (expanded !== true && !Object.keys(expanded ?? {}).length)) {\n return expandRowsCustom(rowModel);\n }\n\n if (!paginateExpandedRows) {\n // Only expand rows at this point if they are being paginated\n return rowModel;\n }\n\n return expandRowsCustom(rowModel);\n },\n getMemoOptions(table.options, 'debugTable', 'getExpandedRowModel'),\n );\n }\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n getSubRows: (row) => (isRowWithSubrows(row) ? row.subrows : []),\n getCoreRowModel: getCoreRowModel(),\n getExpandedRowModel: getExpandedRowModelCustom(),\n getRowId,\n ...tableOptions,\n });\n\n // We don't yet support multi-header groups across our products so we can assume there's only one\n const tableHeaderGroup = table.getHeaderGroups()[0];\n\n const unprocessedRows = table.getCoreRowModel().rows;\n const rows = table.getRowModel().rows;\n\n // Keyed on the ordered id list so the callback only fires when the displayed\n // rows actually change, not on every render (rows is a fresh array each time).\n const displayedRowIdsKey = rows.map((row) => row.id).join(DISPLAYED_ROW_IDS_SEPARATOR);\n useEffect(() => {\n onDisplayedRowIdsChange?.(\n displayedRowIdsKey ? displayedRowIdsKey.split(DISPLAYED_ROW_IDS_SEPARATOR) : [],\n );\n }, [displayedRowIdsKey, onDisplayedRowIdsChange]);\n\n // Generate checkbox column states based on table data and column values\n useEffect(() => {\n const states: Record<string, Set<string>> = {};\n\n // Find all checkbox columns from the original columns configuration\n const checkboxColumns = columns.filter(\n (column): column is ColumnConfig<TData> =>\n typeof column === 'object' && column.format?.type === 'checkbox',\n );\n\n // For each checkbox column, initialize its state based on the actual column values in the data\n for (const column of checkboxColumns) {\n const columnId = column.id || column.accessor;\n const checkedRowIds = new Set<string>();\n\n // Use table rows to get the actual row data and check the column values\n const getSelfAndNestedRows = (row: Row<TData>): Row<TData>[] => [\n row,\n ...row.subRows.map(getSelfAndNestedRows).flat(),\n ];\n const rootAndNestedRows = unprocessedRows.flatMap(getSelfAndNestedRows);\n for (const row of rootAndNestedRows) {\n const rowId = row.id;\n const rowData = row.original;\n\n // Get the column value from the row data (use accessor, not custom id)\n const columnValue = rowData[column.accessor as keyof TData];\n\n // If the column value is truthy, consider it checked\n if (columnValue) {\n checkedRowIds.add(rowId);\n }\n }\n\n states[columnId] = checkedRowIds;\n }\n\n setCheckboxColumnStates(states);\n }, [unprocessedRows, columns]);\n\n // Generate search props for TableControls when client search is enabled\n const generatedSearchProps = clientSearch\n ? {\n value: globalFilter,\n handleInput: setGlobalFilter,\n placeholder:\n typeof clientSearch === 'object'\n ? clientSearch.placeholder || DEFAULT_SEARCH_PLACEHOLDER\n : DEFAULT_SEARCH_PLACEHOLDER,\n ...(typeof clientSearch === 'object' && clientSearch),\n }\n : undefined;\n\n const unifiedFilters = useMemo<TFilter[]>(() => {\n const configuredFilters = controls?.filters ?? [];\n if (!clientFiltering) {\n return [...configuredFilters];\n }\n\n const clientFilters = generateClientFilters(\n columns.filter((column): column is ColumnConfig<TData> => typeof column === 'object'),\n columnFilters,\n setColumnFilters,\n );\n return [...configuredFilters, ...(clientFilters as unknown as TFilter[])];\n }, [clientFiltering, columnFilters, columns, controls?.filters, setColumnFilters]);\n\n // Helper function to get common pinning styles\n const getCommonPinningStyles = useCallback(\n (column: Column<TData>) => {\n const isPinned = column.getIsPinned();\n const isLastPinned = isPinned === 'left' && column.getIsLastColumn('left');\n\n return {\n left:\n isPinned === 'left' ? `${column.getStart('left') + pinnedColumnLeftOffset}px` : undefined,\n position: isPinned ? 'sticky' : 'relative',\n hasRightBorder: isLastPinned,\n };\n },\n [pinnedColumnLeftOffset],\n );\n\n /**\n * Check if the column is a table feature column.\n * Feature columns are special columns set by the table to\n * allow a user to perform an action.\n */\n const isFeatureCol = (columnId: string) => {\n return ['select-col', 'expand-col', 'action-col'].includes(columnId);\n };\n\n const selectedRows = table.getFilteredSelectedRowModel().flatRows;\n\n useEffect(() => {\n onRowSelectionChange?.(selectedRows.map((row) => row.original));\n }, [selectedRows, onRowSelectionChange]);\n\n const actions = useMemo(() => {\n // Use dynamic bulk actions if provided, otherwise fall back to static ones\n const availableActions = getAvailableBulkActions\n ? getAvailableBulkActions(selectedRows.map((row) => row.original))\n : bulkActions || controls?.bulkActions;\n return availableActions?.map((action) => {\n // Create clearSelection callback that actions can call when they're ready\n const clearSelection = () => table.setRowSelection({});\n\n const baseAction = {\n ...action,\n onClick: async () => {\n await action.onClick(\n selectedRows.map((row) => row.id),\n clearSelection,\n );\n },\n };\n\n // Check if action has popover configuration (only on bulkActions, not controls?.bulkActions)\n if ('popover' in action && action.popover) {\n const popoverConfig = action.popover as {\n options: { label: string; value: string }[];\n onOptionSelect: (option: string, selectedRows: string[]) => void | Promise<void>;\n };\n return {\n ...baseAction,\n popover: {\n options: popoverConfig.options,\n onOptionSelect: async (option: string) => {\n await popoverConfig.onOptionSelect(\n option,\n selectedRows.map((row) => row.id),\n );\n table.setRowSelection({});\n },\n },\n };\n }\n\n return baseAction;\n });\n }, [bulkActions, getAvailableBulkActions, selectedRows, table, controls?.bulkActions]);\n\n const shouldShowFloatingActionBar =\n compact && actions && actions.length > 0 && selectedRows.length > 0;\n\n // Check if any filters are active\n const hasGlobalFilter = clientSearch && globalFilter && globalFilter.trim().length > 0;\n const hasFilters =\n columnFilters.length > 0 ||\n (controls?.filterPanel == null &&\n (controls?.filtersV2 != null\n ? controls.filtersV2.initialState != null && !isEmptyState(controls.filtersV2.initialState)\n : unifiedFilters.some(\n (filter) =>\n filter.enabled !== false && isFilterActive(filter, controls?.filterResolver),\n )));\n const hasActiveFilters = hasGlobalFilter || hasFilters || hasExternalActiveFilters;\n\n return (\n <DataTableContainer $stickyHeader={stickyHeader}>\n {showControls && (\n <DataTableControls<TFilter>\n compact={compact}\n title={title}\n propertiesButton={\n showColumnProperties && (\n <TableViewConfigurationDropdown\n disabled={false}\n columnConfiguration={table\n .getVisibleFlatColumns()\n .filter((column) => !isFeatureCol(column.columnDef.id ?? ''))\n .map((column) => ({\n key: column.id,\n label: column.columnDef.header?.toString() || column.id,\n }))\n .sort((a, b) => {\n return (orderMap[a.key] || 0) - (orderMap[b.key] || 0);\n })}\n attributeOptions={columnOptions}\n updateColumnConfiguration={(newConfiguration) => {\n table.getAllColumns().map((column) => {\n column.toggleVisibility(!!newConfiguration.find((c) => c.key === column.id));\n });\n\n setColumnOrder(newConfiguration.map((c) => c.key));\n\n if (onUpdateColumnProperties) {\n onUpdateColumnProperties(newConfiguration);\n }\n }}\n size={compact ? 'sm' : undefined}\n variant={compact ? 'text' : 'basic'}\n />\n )\n }\n selectedRows={table.getFilteredSelectedRowModel().flatRows.map((row) => row.id)}\n onClearSelection={() => table.setRowSelection({})}\n searchProps={generatedSearchProps}\n {...controls}\n bulkActions={actions}\n filters={unifiedFilters}\n />\n )}\n <TableContainer $stickyHeader={stickyHeader}>\n <StyledTableLayout\n $onAddRow={!!onAddRow}\n stickyHeader={stickyHeader}\n containerScrollsHorizontally={scrollsHorizontally}\n headerTR={\n <>\n {tableHeaderGroup.headers.map((header) => {\n const pinningStyles = getCommonPinningStyles(header.column);\n const isPinned = pinningStyles.position === 'sticky';\n const width = header.column.columnDef.meta?.width\n ? `${header.column.columnDef.meta?.width}px`\n : undefined;\n const minWidth = header.column.columnDef.meta?.minWidth\n ? `${header.column.columnDef.meta?.minWidth}px`\n : (width ?? `${header.column.getSize()}px`);\n const thProps = {\n id: header.id,\n sortable: isFeatureCol(header.id) ? false : header.column.getCanSort(),\n onClick: isFeatureCol(header.id)\n ? undefined\n : header.column.getToggleSortingHandler(),\n sortDirection: isFeatureCol(header.id) ? undefined : header.column.getIsSorted(),\n colSpan: header.colSpan,\n align: header.column.columnDef.meta?.align,\n width: header.column.columnDef.meta?.width\n ? `${header.column.columnDef.meta?.width}px`\n : undefined,\n size: (compact ? 'sm' : 'md') as 'sm' | 'md',\n style: {\n // We use `style` because this value is potentially highly dynamic.\n minWidth,\n },\n };\n\n if (isPinned) {\n return (\n <StickyTH\n {...thProps}\n key={header.id}\n left={pinningStyles.left ? parseInt(pinningStyles.left) : 0}\n hasRightBorder={pinningStyles.hasRightBorder}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n </StickyTH>\n );\n }\n\n return (\n <TableTH {...thProps} key={header.id}>\n {header.column.columnDef.meta?.headerTooltip ? (\n <TextUnderlineTooltip\n side='top'\n tooltip={header.column.columnDef.meta.headerTooltip}\n zIndex={Z_INDICES.topNavTooltip}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n </TextUnderlineTooltip>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n </TableTH>\n );\n })}\n </>\n }\n nullState={<p>{strings.noResults}</p>}\n isLoading={isLoading}\n size={compact ? 'sm' : undefined}\n >\n {columns.length === 0 ? (\n <TableTR disableHoverBackground>\n <TableEmptyState colSpan={1}>\n <Paragraph size='lg' weight='bold' color='primary'>\n {strings.noColumnsConfigured}\n </Paragraph>\n </TableEmptyState>\n </TableTR>\n ) : rows.length === 0 ? (\n <TableTR disableHoverBackground>\n <TableEmptyState colSpan={tableHeaderGroup.headers.length}>\n <Paragraph size='lg' weight='bold' color='primary'>\n {emptyState?.title ||\n (hasActiveFilters ? strings.noResultsTryFilters : strings.noResults)}\n </Paragraph>\n\n {emptyState?.description && (\n <Paragraph size='md' color='secondary'>\n {emptyState.description}\n </Paragraph>\n )}\n </TableEmptyState>\n </TableTR>\n ) : (\n rows.map((row) => {\n const rowData = row.original;\n const rowId = getRowId ? getRowId(rowData) : row.id;\n const rowLabel = getRowLabel?.(rowData);\n const isExpanded = expandedRows.has(rowId);\n const canExpand = canRowExpand(rowData);\n const rowLinkHref = getLinkToRow\n ? getLinkToRow(row.original)\n : rowLinkPrefix\n ? `${rowLinkPrefix}/${rowId}`\n : undefined;\n // Make the nested row's chevron / checkbox line up with the parent row's first column entry\n const dynamicNestSpacing =\n showControls && enableRowSelection ? NEST_SPACING + 8 : NEST_SPACING;\n\n const visibleCells = row.getVisibleCells();\n const isLinkableCell = (cell: (typeof visibleCells)[number]) =>\n !isFeatureCol(cell.column.id) && cell.column.columnDef.meta?.format?.type !== 'url';\n const rowLinkCellId = rowLinkHref\n ? (visibleCells.find(\n (cell) => cell.column.id === rowLinkColumnId && isLinkableCell(cell),\n )?.column.id ?? visibleCells.find(isLinkableCell)?.column.id)\n : undefined;\n const RowLinkComponent = rowLinkComponent ?? RouterLink;\n const renderCellContent = (cell: (typeof visibleCells)[number]) => {\n const content = flexRender(cell.column.columnDef.cell, cell.getContext());\n\n if (!rowLinkHref || cell.column.id !== rowLinkCellId) {\n return content;\n }\n\n const value = cell.getValue();\n const isEmpty = value == null || value === '';\n\n return (\n <RowLink\n as={RowLinkComponent}\n to={rowLinkHref}\n data-row-link\n aria-label={isEmpty ? rowLabel : undefined}\n >\n {content}\n </RowLink>\n );\n };\n\n let leftMostNonSpecialColumnFound = false;\n const rowElements = visibleCells.map((cell) => {\n const pinningStyles = getCommonPinningStyles(cell.column);\n const isPinned = pinningStyles.position === 'sticky';\n\n if (cell.column.id === 'action-col') {\n return (\n <StyledTableActionTD\n key={cell.id}\n style={{ textAlign: cell.column.columnDef.meta?.align }}\n $nestSpacing={row.depth * dynamicNestSpacing}\n >\n {renderCellContent(cell)}\n </StyledTableActionTD>\n );\n }\n\n if (isPinned) {\n const leftBumpFromNesting = !leftMostNonSpecialColumnFound\n ? row.depth * dynamicNestSpacing\n : 0;\n const width = cell.column.columnDef.meta?.width\n ? `${cell.column.columnDef.meta?.width}px`\n : undefined;\n const minWidth = cell.column.columnDef.meta?.minWidth\n ? `${cell.column.columnDef.meta?.minWidth}px`\n : (width ?? `${cell.column.getSize()}px`);\n\n // Use gap coverage component for expand column, regular StickyTD for others\n const isExpandColumn = cell.column.id === 'expand-col';\n const stickyTableCell = isExpandColumn ? (\n <StickyTDWithGapCoverage\n key={cell.id}\n left={\n (pinningStyles.left ? parseInt(pinningStyles.left) : 0) +\n leftBumpFromNesting\n }\n style={{\n // We use `style` because this value is potentially highly dynamic.\n minWidth,\n textAlign: cell.column.columnDef.meta?.align,\n }}\n hasRightBorder={pinningStyles.hasRightBorder}\n $gapCoverage={leftBumpFromNesting}\n >\n {renderCellContent(cell)}\n </StickyTDWithGapCoverage>\n ) : (\n <StickyTD\n key={cell.id}\n left={\n (pinningStyles.left ? parseInt(pinningStyles.left) : 0) +\n leftBumpFromNesting\n }\n style={{\n // We use `style` because this value is potentially highly dynamic.\n minWidth,\n textAlign: cell.column.columnDef.meta?.align,\n }}\n hasRightBorder={pinningStyles.hasRightBorder}\n >\n {renderCellContent(cell)}\n </StickyTD>\n );\n\n if (!leftMostNonSpecialColumnFound && !isFeatureCol(cell.column.id)) {\n leftMostNonSpecialColumnFound = true;\n }\n return stickyTableCell;\n }\n\n const tableCell = (\n <StyledTableTD\n key={cell.id}\n style={{ textAlign: cell.column.columnDef.meta?.align }}\n width={isFeatureCol(cell.column.id) ? '1%' : undefined}\n $nestSpacing={\n leftMostNonSpecialColumnFound ? undefined : row.depth * dynamicNestSpacing\n }\n $isFeatureCol={isFeatureCol(cell.column.id)}\n >\n {renderCellContent(cell)}\n </StyledTableTD>\n );\n if (!leftMostNonSpecialColumnFound && !isFeatureCol(cell.column.id)) {\n leftMostNonSpecialColumnFound = true;\n }\n\n return tableCell;\n });\n\n // Determine if row should be active and get active styling\n const isRowActive = rowId === activeRowId;\n const handleRowClick =\n onRowClick != null\n ? () => {\n onRowClick(rowId);\n }\n : canExpand\n ? () => {\n toggleRowExpansion(rowId);\n }\n : undefined;\n\n const handleRowClickWithLink = (event: MouseEvent<HTMLTableRowElement>) => {\n if (forwardedRowLinkClicks.has(event.nativeEvent)) {\n return;\n }\n\n handleRowClick?.();\n\n if (\n !rowLinkHref ||\n event.defaultPrevented ||\n (event.target as Element).closest(\n 'a, button, input, select, textarea, label, [role=\"checkbox\"], [role=\"button\"], [role=\"menuitem\"]',\n )\n ) {\n return;\n }\n\n const link = event.currentTarget.querySelector('a[data-row-link]');\n const ownerWindow = link?.ownerDocument.defaultView;\n\n if (!link || !ownerWindow) {\n return;\n }\n\n const forwardedClick = new ownerWindow.MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n button: event.button,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n forwardedRowLinkClicks.add(forwardedClick);\n link.dispatchEvent(forwardedClick);\n };\n\n const rowProps = {\n 'aria-label': rowLabel,\n onClick: handleRowClickWithLink,\n $isActive: isRowActive,\n disableHoverBackground: disableRowHover,\n css: {\n cursor: rowLinkHref || handleRowClick ? 'pointer' : undefined,\n },\n // Add data-tour-target if present on row data\n ...(isRowWithTourTarget(row.original) && {\n 'data-tour-target': row.original.dataTourTarget,\n }),\n };\n\n const mainRow = (\n <TableTR key={rowId} {...rowProps}>\n {rowElements}\n </TableTR>\n );\n\n const elements = [mainRow];\n\n // Add detail row if expandable and expanded\n if (canExpand && isExpanded) {\n let detailContent: React.ReactNode = null;\n\n if (isRowWithDetails(rowData) && rowData._details) {\n if (typeof rowData._details === 'function') {\n // If it's a function, call it with the row data as props\n detailContent = rowData._details(rowData);\n } else {\n // If it's a React node\n detailContent = rowData._details;\n }\n } else if (detailComponent) {\n const DetailComponent = detailComponent;\n detailContent = <DetailComponent rowData={rowData} />;\n }\n\n if (detailContent) {\n const detailCells = initialColumnPinning?.left?.length ? (\n <>\n <StickyTD colSpan={1} left={pinnedColumnLeftOffset} />\n <StickyDetailsTD\n colSpan={tableHeaderGroup.headers.length - 1}\n left={EXPAND_COLUMN_WIDTH + pinnedColumnLeftOffset}\n >\n {detailContent}\n </StickyDetailsTD>\n </>\n ) : (\n <>\n <TableTD colSpan={1} />\n <DetailsTD colSpan={tableHeaderGroup.headers.length - 1}>\n {detailContent}\n </DetailsTD>\n </>\n );\n\n elements.push(\n <TableTR key={`${row.id}-details`} disableHoverBackground>\n {detailCells}\n </TableTR>,\n );\n }\n }\n\n // Add inserter row if onAddRow prop is provided\n if (\n onAddRow &&\n (!canAddAfterRow ||\n canAddAfterRow?.(rowData, row.getIsExpanded() && isRowWithSubrows(rowData)))\n ) {\n elements.push(\n <Inserter\n key={`${rowId}-inserter`}\n priorRowLabel={`Row ${rowId}`}\n colSpan={tableHeaderGroup.headers.length}\n onAddRow={() =>\n onAddRow(rowId, row.getIsExpanded() && isRowWithSubrows(rowData))\n }\n nestSpacing={row.depth * dynamicNestSpacing}\n />,\n );\n }\n\n return elements;\n })\n )}\n </StyledTableLayout>\n {shouldShowFloatingActionBar && actions && (\n <FloatingActionBarContainer>\n <FloatingActionBar\n selectedCount={selectedRows.length}\n onClearSelection={() => table.setRowSelection({})}\n actions={actions}\n extraContent={floatingBarContent}\n />\n </FloatingActionBarContainer>\n )}\n </TableContainer>\n {pagination && data.length > 0 && (\n <Pagination\n pageSize={table.getState().pagination.pageSize}\n pageSizeOptions={typeof pagination === 'object' ? pagination.pageSizeOptions : undefined}\n showPageSizeSelector={\n isServerPagination(pagination) ? pagination.showPageSizeSelector : undefined\n }\n paginationParams={{\n 'current-page': table.getState().pagination.pageIndex + 1,\n 'total-count': table.getRowCount(),\n 'total-pages':\n isServerPagination(pagination) && pagination.totalIsLowerBound\n ? (pagination.paginationParams?.['total-pages'] ??\n table.getState().pagination.pageIndex + 1)\n : table.getPageCount(),\n }}\n handlePageLinkClick={(pageNumber) => table.setPageIndex(pageNumber - 1)}\n handlePageSizeClick={table.setPageSize}\n onPageChange={isServerPagination(pagination) ? pagination.onPageChange : undefined}\n totalIsLowerBound={\n isServerPagination(pagination) ? pagination.totalIsLowerBound : undefined\n }\n />\n )}\n </DataTableContainer>\n );\n};\n\nexport default DataTable;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DropdownMenu-c8XK2Lr4.mjs","names":[],"sources":["../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import * as Primitive from '@radix-ui/react-dropdown-menu';\nimport type { Property } from 'csstype';\nimport {\n Children,\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ElementType,\n type FC,\n forwardRef,\n type FunctionComponentElement,\n type Ref,\n} from 'react';\nimport styled from 'styled-components';\n\nimport Menu, {\n MenuDivider,\n MenuHeading,\n MenuItem,\n type MenuItemProps,\n} from '#src/components/Menu/Menu';\nimport { letPointerDownReachDocument } from '#src/lib/letPointerDownReachDocument';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { BASE } from '#src/variables/spacing';\n\nconst DropdownMenuContent = styled(Primitive.Content)<{ $zIndex?: Property.ZIndex }>`\n z-index: ${({ $zIndex }) => $zIndex || Z_INDICES.tooltip};\n`;\n\nexport interface DropdownMenuProps\n extends Primitive.DropdownMenuProps, Pick<Primitive.DropdownMenuContentProps, 'side' | 'align'> {\n id?: string;\n className?: string;\n\n trigger: FunctionComponentElement<any>;\n\n /**\n * Props passed to internal DropdownMenu.Content component.\n */\n contentProps?: Primitive.DropdownMenuContentProps;\n\n /**\n * Props passed to internal DropdownMenu.Trigger component.\n */\n triggerProps?: Primitive.DropdownMenuTriggerProps;\n\n /**\n * Props passed to internal DropdownMenu.Portal component.\n */\n portalProps?: Primitive.DropdownMenuPortalProps;\n\n /**\n * Whether or not to wrap menu with DropdownMenu.Portal component.\n */\n portal?: boolean;\n\n /**\n * Whether or not clicks render menu items.\n */\n disabled?: boolean;\n\n zIndex?: Property.ZIndex;\n}\n\nexport const DropdownMenu = ({\n trigger,\n children,\n side,\n align = 'end',\n contentProps,\n triggerProps,\n portalProps,\n className,\n portal = false, // Default to false for old behavior\n modal = false,\n disabled = false,\n zIndex,\n ...props\n}: DropdownMenuProps) => {\n if (Children.count(children) === 0) {\n return null;\n }\n\n const content = disabled ? null : (\n <DropdownMenuContent\n sideOffset={BASE}\n collisionPadding={BASE}\n align={align}\n side={side}\n $zIndex={zIndex}\n {...contentProps}\n onPointerDownCapture={(event) => {\n contentProps?.onPointerDownCapture?.(event);\n letPointerDownReachDocument(event);\n }}\n >\n <Menu className={className} doNotSetRole>\n {children}\n </Menu>\n </DropdownMenuContent>\n );\n\n return (\n <Primitive.Root modal={modal} {...props}>\n <Primitive.Trigger asChild {...triggerProps}>\n {trigger}\n </Primitive.Trigger>\n\n {portal ? <Primitive.Portal {...portalProps}>{content}</Primitive.Portal> : content}\n </Primitive.Root>\n );\n};\n\ninterface DropdownMenuItemProps<T extends ElementType = 'div'>\n extends MenuItemProps<T>, Omit<Primitive.DropdownMenuItemProps, 'asChild' | 'children'> {}\n\ninterface DropdownMenuItemType<T extends ElementType = 'div'> extends FC<\n DropdownMenuItemProps<T> & ComponentPropsWithRef<T>\n> {\n <T extends ElementType = 'div'>(\n props: DropdownMenuItemProps<T> & ComponentPropsWithoutRef<T>,\n ): ReturnType<FC<DropdownMenuItemProps<T> & ComponentPropsWithoutRef<T>>>;\n}\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst DropdownMenuItem: DropdownMenuItemType = forwardRef(function DropdownMenuItem(\n { children, disabled, ...props },\n ref: Ref<HTMLDivElement>,\n) {\n return (\n <Primitive.Item asChild disabled={disabled} {...props}>\n <MenuItem disabled={disabled} ref={ref}>\n {children}\n </MenuItem>\n </Primitive.Item>\n );\n});\n\nexport default Object.assign(DropdownMenu, {\n Item: DropdownMenuItem,\n Heading: MenuHeading,\n Divider: MenuDivider,\n});\n"],"mappings":";;;;;;;;;AAwBA,MAAM,sBAAsB,OAAO,UAAU,QAAQ;cACvC,EAAE,cAAc,WAAW,UAAU,QAAQ;;AAsC3D,MAAa,gBAAgB,EAC3B,SACA,UACA,MACA,QAAQ,OACR,cACA,cACA,aACA,WACA,SAAS,OACT,QAAQ,OACR,WAAW,OACX,QACA,GAAG,YACoB;AACvB,KAAI,SAAS,MAAM,SAAS,KAAK,EAC/B,QAAO;CAGT,MAAM,UAAU,WAAW,OACzB,oBAAC,qBAAD;EACE,YAAA;EACA,kBAAA;EACO;EACD;EACN,SAAS;EACT,GAAI;EACJ,uBAAuB,UAAU;AAC/B,iBAAc,uBAAuB,MAAM;AAC3C,+BAA4B,MAAM;;YAGpC,oBAAC,MAAD;GAAiB;GAAW,cAAA;GACzB;GACI,CAAA;EACa,CAAA;AAGxB,QACE,qBAAC,UAAU,MAAX;EAAuB;EAAO,GAAI;YAAlC,CACE,oBAAC,UAAU,SAAX;GAAmB,SAAA;GAAQ,GAAI;aAC5B;GACiB,CAAA,EAEnB,SAAS,oBAAC,UAAU,QAAX;GAAkB,GAAI;aAAc;GAA2B,CAAA,GAAG,QAC7D;;;AAgBrB,MAAM,mBAAyC,WAAW,SAAS,iBACjE,EAAE,UAAU,UAAU,GAAG,SACzB,KACA;AACA,QACE,oBAAC,UAAU,MAAX;EAAgB,SAAA;EAAkB;EAAU,GAAI;YAC9C,oBAAC,UAAD;GAAoB;GAAe;GAChC;GACQ,CAAA;EACI,CAAA;EAEnB;AAEF,IAAA,uBAAe,OAAO,OAAO,cAAc;CACzC,MAAM;CACN,SAAS;CACT,SAAS;CACV,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"FloatingToolbar-DLRaE0o7.mjs","names":["Input","DropdownMenu"],"sources":["../src/components/FloatingToolbar/FloatingToolbar.tsx"],"sourcesContent":["import { PluginKey } from '@tiptap/pm/state';\nimport type { EditorView } from '@tiptap/pm/view';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { BubbleMenu } from '@tiptap/react/menus';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\nimport {\n BoldIcon,\n CheckIcon,\n GridIcon,\n ItalicIcon,\n LinkIcon,\n ListIcon,\n UnlinkIcon,\n XIcon,\n} from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport Input from '#src/components/Input';\nimport Stack from '#src/components/Stack';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { TransitionDuration } from '#src/variables/transitions';\n\n// Core* colors throughout this file are intentional: the bubble toolbar is an\n// always-dark inverse surface floating over the editor, so it must not track\n// the semantic surface theme.\nconst BubbleMenuBar = styled(Stack)`\n padding: ${Spacing[1]} ${Spacing[2]};\n background-color: ${Color.CoreSlate1100};\n border-radius: ${BorderRadius.Lg};\n`;\n\nconst IconContainer = styled(motion.div)`\n display: flex;\n gap: ${Spacing[1]};\n`;\n\nconst InverseIconButton = styled(IconButton)<{ $selected?: boolean }>`\n background-color: ${({ $selected }) => ($selected ? Color.CoreSlate900 : 'transparent')};\n color: ${Color.PrimaryWhite};\n transition: background-color ${TransitionDuration.ExtraFast} ease-out;\n\n &:hover:not(:disabled) {\n background-color: ${Color.CoreSlate800};\n }\n\n &:disabled {\n background-color: transparent;\n opacity: 0.35;\n }\n`;\n\nconst InverseInput = styled(Input)`\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n\n :focus-within {\n border-color: ${Color.CoreBlue700};\n }\n ::placeholder {\n color: ${Color.TextDisabled};\n }\n\n input {\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n }\n`;\n\nconst StyledDropdownItem = styled(DropdownMenu.Item)`\n width: 100%;\n height: 30px;\n font-size: small;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n`;\n\n// Floating UI takes its offset as numbers while the spacing tokens are CSS lengths.\nconst TOOLBAR_GAP = parseInt(Spacing[1]);\n\n// Anchored to the field, the toolbar lines up with the input's left edge; over a\n// selection it sits back a notch so it does not crowd the first selected glyph.\nconst FIELD_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: 0 };\nconst SELECTION_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: -parseInt(Spacing[2]) };\n\n// The element EditorContent mounts the editor into — the visible field. Tiptap\n// types `options.element` loosely, so fall back to the editable root.\nconst getFieldElement = (editor: Editor): Element =>\n editor.options.element instanceof Element ? editor.options.element : editor.view.dom;\n\n// Schemes we trust as link targets. Anything else (no scheme, or an unsafe one\n// like javascript:/data:/vbscript:) is treated as a bare host and forced onto\n// https, which both preserves host:port input and neutralizes script schemes.\nconst SAFE_LINK_SCHEME = /^(https?|mailto|tel):/i;\nconst URI_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nexport const ensureProtocol = (url: string): string => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) {\n return '';\n }\n // Handlebars placeholders (e.g. {{inquiry.id}}) are legitimate link targets in\n // templated messages — the template render produces the final URL, so pass\n // the expression through unvalidated. Only when nothing before the first\n // placeholder looks like an unsafe scheme: javascript:alert(1)//{{x}} would\n // otherwise smuggle a script href past the allowlist. URL parsers strip C0\n // controls, tabs and spaces before reading the scheme, so normalize the\n // prefix the same way first — java\\tscript:...{{x}} must not slip through.\n if (trimmedUrl.includes('{{')) {\n const beforePlaceholder = trimmedUrl\n .slice(0, trimmedUrl.indexOf('{{'))\n // eslint-disable-next-line no-control-regex -- mirrors how URL parsers strip C0/space before reading the scheme\n .replace(/[\\u0000-\\u0020]/g, '');\n if (!URI_SCHEME.test(beforePlaceholder) || SAFE_LINK_SCHEME.test(beforePlaceholder)) {\n return trimmedUrl;\n }\n return '';\n }\n const candidate = SAFE_LINK_SCHEME.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;\n // Re-parse so malformed input — including an unsafe scheme that can't survive\n // the https prefix — is dropped instead of applied as a broken href.\n return URL.canParse(candidate) ? candidate : '';\n};\n\ninterface FloatingToolbarProps {\n /** TipTap editor instance to operate on. */\n editor: Editor | null;\n /**\n * Keep the toolbar up the whole time the editor is focused instead of only\n * while text is selected, so the formatting actions are discoverable without\n * knowing to select first.\n */\n showOnFocus?: boolean;\n}\n\n/**\n * Floating bubble toolbar that appears on text selection or inside a table, or —\n * with `showOnFocus` — for as long as the editor is focused.\n * Keyboard shortcut: Cmd/Ctrl+Shift+U opens the link-edit row.\n */\nfunction FloatingToolbar({ editor, showOnFocus = false }: FloatingToolbarProps) {\n const [linkURL, setLinkURL] = useState('');\n const [editingLink, setEditingLink] = useState(false);\n const linkInputRef = useRef<HTMLInputElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const savedSelection = useRef<{ from: number; to: number } | null>(null);\n const editingLinkRef = useRef(editingLink);\n const blurTimeout = useRef<ReturnType<typeof setTimeout>>();\n // Lets the toolbar close its own bubble menu plugin via a `hide` meta.\n const [pluginKey] = useState(() => new PluginKey('floatingToolbar'));\n\n useEffect(() => () => clearTimeout(blurTimeout.current), []);\n\n useEffect(() => {\n editingLinkRef.current = editingLink;\n }, [editingLink]);\n\n const restoreSelection = useCallback(() => {\n if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }, [editor]);\n\n const openLinkEditingMode = useCallback(() => {\n if (!editor) {\n return;\n }\n if (!editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run()) {\n return;\n }\n\n const { from, to } = editor.state.selection;\n savedSelection.current = { from, to };\n\n const linkAttr = editor.getAttributes('link');\n if (linkAttr.href) {\n setLinkURL(linkAttr.href);\n }\n\n editor.chain().focus().setTextSelection({ from, to }).run();\n setEditingLink(true);\n\n setTimeout(() => {\n linkInputRef.current?.focus();\n }, 250);\n }, [editor]);\n\n // Cmd/Ctrl+Shift+U → open link mode; Escape inside link mode → cancel.\n useEffect(() => {\n if (!editor) {\n return undefined;\n }\n const dom = editor.view.dom;\n const handler = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === 'u') {\n event.preventDefault();\n openLinkEditingMode();\n return;\n }\n if (event.key === 'Escape' && editingLinkRef.current) {\n event.preventDefault();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n }\n };\n dom.addEventListener('keydown', handler);\n return () => {\n dom.removeEventListener('keydown', handler);\n };\n }, [editor, openLinkEditingMode]);\n\n // Keep selection highlighted while focus is in the link input.\n useEffect(() => {\n if (!editingLink || !editor || !savedSelection.current) {\n return undefined;\n }\n restoreSelection();\n const timeoutId = setTimeout(() => {\n restoreSelection();\n editor.view.dom?.focus();\n }, 0);\n return () => clearTimeout(timeoutId);\n }, [editingLink, restoreSelection, editor]);\n\n // Pressing a toolbar button focuses that button, and the command's own\n // transaction re-runs this check before the chained `.focus()` hands focus\n // back to the editor. Ignoring focus held inside the toolbar therefore tears\n // the bar down for a frame mid-click, taking the pressed button with it.\n const isFocusWithinToolbar = useCallback(\n () => !!toolbarRef.current?.contains(document.activeElement),\n [],\n );\n\n // BubbleMenu dispatches an options-update transaction whenever these props\n // change identity, and editors that re-render per transaction would then\n // loop — so keep them stable across renders.\n const bubbleMenuOptions = useMemo(\n () => ({\n placement: 'top-start' as const,\n offset: showOnFocus ? FIELD_OFFSET : SELECTION_OFFSET,\n }),\n [showOnFocus],\n );\n\n // Sitting above the field rather than the selection: a toolbar that is up\n // for the whole time the field is focused looks jumpy if it chases the\n // caret and hops between selections.\n const getReferencedVirtualElement = useMemo(\n () =>\n showOnFocus && editor\n ? () => ({ getBoundingClientRect: () => getFieldElement(editor).getBoundingClientRect() })\n : undefined,\n [editor, showOnFocus],\n );\n\n const shouldShow = useCallback(\n ({\n editor: e,\n view,\n from,\n to,\n }: {\n editor: Editor;\n view: EditorView;\n from: number;\n to: number;\n }) => {\n if (!e.isEditable) {\n return false;\n }\n if (e.isActive('mention')) {\n return false;\n }\n // The toolbar carries the table-actions dropdown — a collapsed caret\n // inside a table must still show it or row/column controls are\n // unreachable.\n if (e.isActive('table')) {\n return true;\n }\n if (from !== to) {\n return true;\n }\n return showOnFocus && (view.hasFocus() || isFocusWithinToolbar());\n },\n [isFocusWithinToolbar, showOnFocus],\n );\n\n // Self-subscribe: standalone use can't rely on the host's useEditor options (shouldRerenderOnTransaction is off by default in Tiptap 3).\n const editorState = useEditorState({\n editor,\n selector: (snapshot) =>\n snapshot.editor && {\n isBold: snapshot.editor.isActive('bold'),\n canBold: snapshot.editor.can().chain().toggleBold().run(),\n isItalic: snapshot.editor.isActive('italic'),\n canItalic: snapshot.editor.can().chain().toggleItalic().run(),\n isLink: snapshot.editor.isActive('link'),\n isBulletList: snapshot.editor.isActive('bulletList'),\n canLink: snapshot.editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run(),\n isTable: snapshot.editor.isActive('table'),\n canInsertTable: snapshot.editor\n .can()\n .chain()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run(),\n },\n });\n\n if (!editor || !editorState) {\n return null;\n }\n\n // The plugin closes the toolbar off the editor's blur, which cannot fire again\n // once focus has moved in here, so leaving from the toolbar has to close it.\n // Focus only lands on its next target after this event, hence the tick.\n const handleToolbarBlur = () => {\n blurTimeout.current = setTimeout(() => {\n if (editor.isDestroyed || isFocusWithinToolbar() || editor.view.hasFocus()) {\n return;\n }\n editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'hide'));\n });\n };\n\n return (\n <BubbleMenu\n editor={editor}\n pluginKey={pluginKey}\n options={bubbleMenuOptions}\n getReferencedVirtualElement={getReferencedVirtualElement}\n shouldShow={shouldShow}\n // Floating UI sets no z-index on the portaled menu (Tippy used 9999).\n style={{ zIndex: Z_INDICES.modalElevated }}\n >\n <AnimatePresence>\n <BubbleMenuBar\n ref={toolbarRef}\n role='toolbar'\n aria-label='Text formatting'\n direction='horizontal'\n spacing={Spacing[1]}\n onBlur={handleToolbarBlur}\n >\n {!editingLink ? (\n <IconContainer\n key='main-toolbar'\n layout\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n >\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n $selected={editorState.isBulletList}\n size='sm'\n type='button'\n aria-label='Toggle bullet list'\n data-rte-menu-bar-item\n >\n <ListIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n disabled={!editorState.canBold}\n $selected={editorState.isBold}\n size='sm'\n type='button'\n aria-label='Toggle bold'\n data-rte-menu-bar-item\n >\n <BoldIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n $selected={editorState.isItalic}\n disabled={!editorState.canItalic}\n type='button'\n size='sm'\n aria-label='Toggle italic'\n data-rte-menu-bar-item\n >\n <ItalicIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n openLinkEditingMode();\n }}\n $selected={editorState.isLink}\n disabled={!editorState.canLink}\n size='sm'\n type='button'\n aria-label='Toggle link'\n data-rte-menu-bar-item\n >\n <LinkIcon />\n </InverseIconButton>\n {editorState.isTable ? (\n <DropdownMenu\n contentProps={{\n // @ts-expect-error data attribute on dropdown menu\n 'data-rte-menu-bar-item': 'table-actions-dropdown-menu',\n onCloseAutoFocus: (event) => {\n event.preventDefault();\n editor.commands.focus();\n },\n }}\n trigger={\n <InverseIconButton\n size='sm'\n type='button'\n aria-label='Table actions'\n data-rte-menu-bar-item\n $selected\n >\n <GridIcon />\n </InverseIconButton>\n }\n >\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-after'\n onClick={() => editor.chain().focus().addRowAfter().run()}\n >\n Add row below\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-before'\n onClick={() => editor.chain().focus().addRowBefore().run()}\n >\n Add row above\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-after'\n onClick={() => editor.chain().focus().addColumnAfter().run()}\n >\n Add column right\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-before'\n onClick={() => editor.chain().focus().addColumnBefore().run()}\n >\n Add column left\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteRow'\n variant='basic'\n data-rte-menu-bar-item='table-delete-row'\n onClick={() => editor.chain().focus().deleteRow().run()}\n >\n Delete row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteColumn'\n variant='basic'\n data-rte-menu-bar-item='table-delete-column'\n onClick={() => editor.chain().focus().deleteColumn().run()}\n >\n Delete column\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableToggleHeaderRow'\n variant='basic'\n data-rte-menu-bar-item='table-toggle-header-row'\n onClick={() => editor.chain().focus().toggleHeaderRow().run()}\n >\n Toggle header row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDelete'\n variant='basic'\n data-rte-menu-bar-item='table-delete'\n onClick={() => editor.chain().focus().deleteTable().run()}\n >\n Delete table\n </StyledDropdownItem>\n </DropdownMenu>\n ) : (\n <InverseIconButton\n onClick={() =>\n editor\n .chain()\n .focus()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run()\n }\n disabled={!editorState.canInsertTable}\n size='sm'\n type='button'\n aria-label='Insert table'\n data-rte-menu-bar-item\n >\n <GridIcon />\n </InverseIconButton>\n )}\n </IconContainer>\n ) : (\n <IconContainer\n key='link-toolbar'\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n aria-label='Link toolbar'\n onAnimationComplete={() => {\n if (editor && savedSelection.current) {\n setTimeout(() => {\n restoreSelection();\n linkInputRef.current?.focus();\n }, 10);\n }\n }}\n >\n <InverseInput\n ref={linkInputRef}\n size='sm'\n value={linkURL}\n onChange={(e) => setLinkURL(e.target.value)}\n placeholder='Click to enter URL...'\n aria-label='Link input'\n data-rte-menu-bar-item\n onClick={() => {\n linkInputRef.current?.focus();\n }}\n onFocus={() => {\n if (savedSelection.current && editor) {\n const { from, to } = savedSelection.current;\n editor.chain().setTextSelection({ from, to }).run();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && linkURL.trim() && editor && savedSelection.current) {\n e.preventDefault();\n e.stopPropagation();\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n const { from, to } = editor.state.selection;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }}\n />\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL) {\n editor.chain().focus().unsetLink().run();\n }\n restoreSelection();\n setLinkURL('');\n savedSelection.current = null;\n setEditingLink(false);\n }}\n size='sm'\n type='button'\n aria-label='Cancel link'\n data-rte-menu-bar-item\n >\n {linkURL && editorState.isLink ? <UnlinkIcon /> : <XIcon />}\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL.trim() && editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n } else if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).unsetLink().run();\n }\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n }}\n size='sm'\n type='button'\n aria-label='Apply link'\n data-rte-menu-bar-item\n >\n <CheckIcon />\n </InverseIconButton>\n </IconContainer>\n )}\n </BubbleMenuBar>\n </AnimatePresence>\n </BubbleMenu>\n );\n}\n\nexport default FloatingToolbar;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"HoverCopyableField-XHC_n9tp.mjs","names":["Card","Popover"],"sources":["../src/components/HoverCopyableField/HoverCopyableField.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\nimport { CopyIcon } from '@persona/icons';\n\nimport Button from '#src/components/Button';\nimport Card from '#src/components/Card';\nimport Popover from '#src/components/Popover';\nimport { Paragraph } from '#src/components/Text';\nimport useToggle from '#src/lib/useToggle';\nimport { fadeIn } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nexport type CopySuccessDetail = {\n text: string;\n clientX: number;\n clientY: number;\n};\n\nexport type HoverCopyableFieldProps = {\n copyValue: string | undefined;\n confirmationText?: string;\n /**\n * Called after a successful clipboard write. When provided, the Copied\n * popover is skipped so the host can own post-copy UX.\n */\n onCopySuccess?: (detail: CopySuccessDetail) => void;\n children: ReactNode;\n};\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if ('clipboard' in navigator) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n return document.execCommand('copy', true, text);\n }\n } catch {\n return false;\n }\n};\n\nconst clickOrigin = (e: MouseEvent<HTMLButtonElement>): { clientX: number; clientY: number } => {\n const rect = e.currentTarget.getBoundingClientRect();\n const hasPointer = e.clientX !== 0 || e.clientY !== 0;\n return {\n clientX: hasPointer ? e.clientX : rect.left + rect.width / 2,\n clientY: rect.top,\n };\n};\n\nconst CopyableFieldContainer = styled.div`\n display: flex;\n gap: ${Spacing[1]};\n align-items: center;\n`;\n\nconst CopyButton = styled(Button).attrs(() => ({\n type: 'button',\n variant: 'inverse',\n width: 'icon',\n}))<{ isActive: boolean }>`\n height: ${Spacing[5]};\n width: ${Spacing[5]};\n visibility: ${({ isActive }) => (isActive ? 'visible' : 'hidden')};\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nconst StyledCard = styled(Card)`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n padding: 6px;\n margin: 0;\n`;\n\nconst HoverCopyableField = ({\n copyValue,\n confirmationText = 'Copied',\n onCopySuccess,\n children,\n}: HoverCopyableFieldProps) => {\n const [copyButtonActive, { enable: showCopyButton, disable: hideCopyButton }] = useToggle(false);\n const [confirmationActive, { enable: showConfirmation, disable: hideConfirmation }] =\n useToggle(false);\n\n const copyTextToClipboard = async (origin: { clientX: number; clientY: number }) => {\n if (copyValue == null) {\n return;\n }\n const copyWasSuccessful = await copyToClipboard(copyValue);\n if (!copyWasSuccessful) {\n return;\n }\n if (onCopySuccess) {\n onCopySuccess({ text: copyValue, ...origin });\n hideCopyButton();\n return;\n }\n showConfirmation();\n setTimeout(() => {\n hideCopyButton();\n hideConfirmation();\n }, 1200);\n };\n\n const copyField = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n void copyTextToClipboard(clickOrigin(e));\n };\n\n return copyValue != null && copyValue.trim().length > 0 ? (\n <CopyableFieldContainer onMouseEnter={showCopyButton} onMouseLeave={hideCopyButton}>\n {children}\n <Popover open={confirmationActive}>\n <Popover.Anchor asChild>\n <CopyButton\n id='hover-copyable-field__copy-button'\n isActive={copyButtonActive || confirmationActive}\n onClick={copyField}\n >\n <CopyIcon width={16} height={16} />\n </CopyButton>\n </Popover.Anchor>\n <Popover.Content side='top' align='center' style={{ zIndex: 2 }}>\n <StyledCard elevated>\n <Paragraph>{confirmationText}</Paragraph>\n </StyledCard>\n </Popover.Content>\n </Popover>\n </CopyableFieldContainer>\n ) : null;\n};\n\nexport default HoverCopyableField;\n"],"mappings":";;;;;;;;;;;;AA+BA,MAAM,kBAAkB,OAAO,SAAmC;AAChE,KAAI;AACF,MAAI,eAAe,WAAW;AAC5B,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAO;QAEP,QAAO,SAAS,YAAY,QAAQ,MAAM,KAAK;SAE3C;AACN,SAAO;;;AAIX,MAAM,eAAe,MAA2E;CAC9F,MAAM,OAAO,EAAE,cAAc,uBAAuB;AAEpD,QAAO;EACL,SAFiB,EAAE,YAAY,KAAK,EAAE,YAAY,IAE5B,EAAE,UAAU,KAAK,OAAO,KAAK,QAAQ;EAC3D,SAAS,KAAK;EACf;;AAGH,MAAM,yBAAyB,OAAO,GAAG;;SAEhC,QAAQ,GAAG;;;AAIpB,MAAM,aAAa,OAAO,OAAO,CAAC,aAAa;CAC7C,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAAE;YACS,QAAQ,GAAG;WACZ,QAAQ,GAAG;iBACL,EAAE,eAAgB,WAAW,YAAY,SAAU;eACrD,OAAO,GAAA,QAA6B;;;;;;AAOnD,MAAM,aAAa,OAAOA,aAAK;;;;;eAKhB,OAAO,GAAA,QAA6B;;;;AAKnD,MAAM,sBAAsB,EAC1B,WACA,mBAAmB,UACnB,eACA,eAC6B;CAC7B,MAAM,CAAC,kBAAkB,EAAE,QAAQ,gBAAgB,SAAS,oBAAoB,UAAU,MAAM;CAChG,MAAM,CAAC,oBAAoB,EAAE,QAAQ,kBAAkB,SAAS,sBAC9D,UAAU,MAAM;CAElB,MAAM,sBAAsB,OAAO,WAAiD;AAClF,MAAI,aAAa,KACf;AAGF,MAAI,CAAC,MAD2B,gBAAgB,UAAU,CAExD;AAEF,MAAI,eAAe;AACjB,iBAAc;IAAE,MAAM;IAAW,GAAG;IAAQ,CAAC;AAC7C,mBAAgB;AAChB;;AAEF,oBAAkB;AAClB,mBAAiB;AACf,mBAAgB;AAChB,qBAAkB;KACjB,KAAK;;CAGV,MAAM,aAAa,MAAqC;AACtD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACd,sBAAoB,YAAY,EAAE,CAAC;;AAG1C,QAAO,aAAa,QAAQ,UAAU,MAAM,CAAC,SAAS,IACpD,qBAAC,wBAAD;EAAwB,cAAc;EAAgB,cAAc;YAApE,CACG,UACD,qBAACC,iBAAD;GAAS,MAAM;aAAf,CACE,oBAACA,gBAAQ,QAAT;IAAgB,SAAA;cACd,oBAAC,YAAD;KACE,IAAG;KACH,UAAU,oBAAoB;KAC9B,SAAS;eAET,oBAAC,UAAD;MAAU,OAAO;MAAI,QAAQ;MAAM,CAAA;KACxB,CAAA;IACE,CAAA,EACjB,oBAACA,gBAAQ,SAAT;IAAiB,MAAK;IAAM,OAAM;IAAS,OAAO,EAAE,QAAQ,GAAG;cAC7D,oBAAC,YAAD;KAAY,UAAA;eACV,oBAAC,WAAD,EAAA,UAAY,kBAA6B,CAAA;KAC9B,CAAA;IACG,CAAA,CACV;KACa;MACvB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"IconButton-DxHB2g80.mjs","names":["noop"],"sources":["../src/components/Button/palette.ts","../src/components/Button/Button.tsx","../src/components/Button/IconButton.tsx"],"sourcesContent":["import type { Color } from '@persona/design-tokens';\n\nimport { type PdsColor, transparent, withAlpha } from '#src/lib/color';\nimport { semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme } from '#src/theme';\nimport type { SemanticTokens } from '#src/variables/semantic';\n\nexport type ButtonVariant = 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n\nexport interface ButtonPalette {\n default: PdsColor;\n hover: Color;\n active: Color;\n disabled: PdsColor;\n text: Color;\n textDisabled: PdsColor;\n /** Set only under semantic theming; legacy leaves disabled icon colour to the stroke rules. */\n iconDisabled?: PdsColor;\n highlightDark: Color;\n}\n\nconst buildSemanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n const neutral = {\n hover: tokens.ActionNeutralHover,\n active: tokens.ActionNeutralActive,\n text: tokens.FgPrimary,\n textDisabled: tokens.FgDisabled,\n iconDisabled: tokens.FgDisabled,\n highlightDark: tokens.FgDisabled,\n };\n return {\n basic: {\n ...neutral,\n default: tokens.ActionNeutral,\n disabled: withAlpha(tokens.ActionNeutral, tokens.Opacity65),\n },\n text: { ...neutral, default: transparent, disabled: transparent },\n outline: {\n ...neutral,\n default: transparent,\n hover: tokens.ActionOutlineHover,\n active: tokens.ActionOutlineActive,\n disabled: transparent,\n },\n primary: {\n default: tokens.ActionPrimary,\n hover: tokens.ActionPrimaryHover,\n active: tokens.ActionPrimaryActive,\n disabled: tokens.ActionPrimary,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n danger: {\n default: tokens.ActionDanger,\n hover: tokens.ActionDangerHover,\n active: tokens.ActionDangerActive,\n disabled: tokens.ActionDanger,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n inverse: {\n default: tokens.ActionInverse,\n hover: tokens.ActionInverseHover,\n active: tokens.ActionInverseActive,\n disabled: withAlpha(tokens.ActionInverse, tokens.Opacity65),\n text: tokens.FgPrimaryStatic,\n textDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n iconDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n highlightDark: tokens.ActionNeutralActive,\n },\n };\n};\n\nconst semanticPaletteCache = new WeakMap<SemanticTokens, Record<ButtonVariant, ButtonPalette>>();\n\nconst semanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n let palettes = semanticPaletteCache.get(tokens);\n if (!palettes) {\n palettes = buildSemanticPalettes(tokens);\n semanticPaletteCache.set(tokens, palettes);\n }\n return palettes;\n};\n\nexport const buttonPalette = (theme: PersonaTheme, variant: ButtonVariant): ButtonPalette => {\n const tokens = semanticTokens(theme);\n return tokens ? semanticPalettes(tokens)[variant] : theme.color.variants[variant];\n};\n","import { isEmpty, isFunction } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type HTMLAttributeAnchorTarget,\n type MouseEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from 'react';\nimport styled, {\n css,\n type DefaultTheme,\n type FlattenInterpolation,\n type ThemeProps,\n} from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LoaderIcon } from '@persona/icons';\n\nimport { opacityOf, withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { RouterLink, type To } from '#src/lib/router';\nimport { semanticColor, semanticOnly, semanticTokens } from '#src/lib/semanticColor';\nimport useToggle from '#src/lib/useToggle';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport { paragraphMixins } from '#src/mixins/text';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { rotate } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport { type ButtonVariant, buttonPalette } from './palette';\n\nconst noop = (): void => undefined;\n\n// TODO(joseph): Bring this fix back to pseudoClass\nconst isActive = ({ active }: PseudoClassProps) => (active ? '' : ':active:enabled');\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst sizeStyles: Record<ButtonProps['size'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n md: css`\n ${paragraphMixins.md}\n height: ${({ theme }) => theme.button.height.md};\n padding: ${Spacing[2]};\n svg {\n height: 16px;\n width: 16px;\n }\n `,\n sm: css`\n ${paragraphMixins.sm}\n height: ${({ theme }) => theme.button.height.sm};\n padding: ${Spacing[1]} 6px;\n svg {\n height: 12px;\n width: 12px;\n }\n `,\n};\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst widthStyles: Record<ButtonProps['width'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n full: css`\n width: 100%;\n `,\n auto: css`\n width: auto;\n `,\n // TODO: rename this prop to 'element' as a standard unresponsive element width\n button: css`\n width: ${({ theme }) => theme.element.width.md};\n `,\n icon: css<ButtonProps>`\n width: ${({ theme, size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return theme.button.height[size];\n }};\n padding: 0;\n flex: none;\n `,\n};\n\ninterface ButtonPropsWithTransientProps extends Omit<ButtonProps, 'isPending'> {\n $isPending: boolean;\n $onSecondaryBackground?: boolean;\n}\n\nexport const StyledButton = styled.button.attrs<ButtonPropsWithTransientProps>(({ to, target }) => {\n if (isEmpty(to)) {\n return 'button';\n } else if (typeof to === 'string' && to.startsWith('https://')) {\n return {\n as: 'a',\n href: to,\n target: target ?? '_blank',\n rel: 'noreferrer',\n };\n } else {\n return {\n as: RouterLink,\n };\n }\n})<ButtonPropsWithTransientProps>`\n cursor: pointer;\n border: none;\n box-sizing: border-box;\n white-space: nowrap;\n ${({ theme, variant = 'primary' }) => {\n const palette = buttonPalette(theme, variant);\n const tokens = semanticTokens(theme);\n return css`\n &:disabled {\n background-color: ${palette.disabled};\n color: ${palette.textDisabled};\n ${\n tokens &&\n (variant === 'primary' || variant === 'danger') &&\n css`\n opacity: ${opacityOf(tokens.Opacity65)};\n `\n }\n ${\n palette.iconDisabled &&\n css`\n svg {\n color: ${palette.iconDisabled};\n }\n `\n }\n svg path {\n stroke: ${palette.iconDisabled ?? palette.textDisabled};\n }\n\n /* For backwards compatibility with current coloring scheme (targeting stroke property) */\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n /* Support icons with stroke */\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n user-select: none;\n }\n `;\n }}\n\n ${({ theme, variant }) =>\n variant === 'outline' &&\n css`\n border: 1px solid ${semanticColor(theme, 'BorderDefault', theme.color.border.input)};\n `}\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n /* To properly position loading spinner */\n position: relative;\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n\n transition-duration: ${TransitionDuration.Fast};\n transition-property: background-color, color, border-color, width, height;\n\n ${({ size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return sizeStyles[size];\n }}\n ${({ width }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return widthStyles[width];\n }}\n\n /* Variant styling */\n ${({ theme, variant = 'primary', $isPending, $onSecondaryBackground }) => {\n let palette = buttonPalette(theme, variant);\n\n if (variant === 'basic' && $onSecondaryBackground) {\n const tokens = semanticTokens(theme);\n palette = tokens\n ? {\n ...palette,\n default: tokens.ActionNeutralHover,\n hover: tokens.ActionNeutralActive,\n active: tokens.ActionNeutralActive,\n disabled: withAlpha(tokens.ActionNeutralHover, tokens.Opacity65),\n }\n : {\n ...palette,\n default: Color.CoreSlate300,\n hover: Color.CoreSlate400,\n active: Color.CoreSlate400,\n disabled: Color.CoreSlate100,\n };\n }\n\n return css`\n background-color: ${palette.default};\n color: ${palette.text};\n svg path {\n stroke: ${palette.text};\n }\n\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${palette.hover};\n }\n\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n &${isActive} {\n background-color: ${palette.active};\n }\n\n ${focusOutlineControlled}\n\n ${\n $isPending &&\n css`\n cursor: default;\n background-color: ${palette.active};\n &:disabled {\n background-color: ${buttonPalette(theme, variant).active};\n user-select: none;\n ${semanticOnly(() => 'opacity: 1;')}\n }\n\n svg path {\n stroke: ${palette.highlightDark};\n }\n\n // For backwards compatibility with current coloring scheme (targeting stroke property)\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n `\n }\n `;\n }}\n\n\n ${printMixins.hide}\n`;\n\ntype WithPendingProps = Pick<ButtonProps, 'isPending'>;\n\nconst LoaderContainer = styled.div<WithPendingProps>`\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 2s;\n opacity: ${({ isPending }) => (isPending ? '1' : '0')};\n`;\n\nconst Loader = styled(LoaderIcon)`\n animation: ${rotate} linear 1s infinite;\n`;\n\nexport const ButtonChildren = styled('div').attrs(({ isPending }: WithPendingProps) => ({\n ['aria-hidden']: isPending,\n}))<WithPendingProps>`\n width: 100%;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: center;\n transition: opacity ${TransitionDuration.Fast};\n opacity: ${({ isPending }) => (isPending ? '0' : '1')};\n gap: ${Spacing[1]};\n`;\n\nconst PrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst InheritPrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n\n & svg {\n width: inherit;\n height: inherit;\n }\n`;\n\nexport const SuffixIconContainer = styled(PrefixIconContainer)`\n margin-right: 0;\n flex-grow: 1;\n justify-content: flex-end;\n`;\n\nconst ButtonText = styled.span<{ size: 'md' | 'sm'; width: 'full' | 'auto' | 'button' | 'icon' }>`\n position: relative;\n\n /* Needed to align for browsers that don't support text-box yet\n (which at this time, is firefox, and opera, and a few niche browsers)\n This checks firefox. Otherwise, it will default back to the original\n which is a slightly misaligned button\n */\n\n /* Was trying to use this with @supports not, but genuinely could not figure out why this wouldn't\n work */\n\n line-height: ${({ width }) => (width === 'icon' ? '0' : 'inherit')};\n @-moz-document url-prefix() {\n top: ${({ size }) => (size === 'md' ? '1px' : '0.5px')};\n }\n\n @supports (text-box: cap alphabetic) {\n text-box: ${({ width }) => (width === 'icon' ? 'normal' : 'cap alphabetic')};\n }\n`;\n\ntype MaybePromise =\n | ((e: MouseEvent<HTMLButtonElement>) => void)\n | ((e: MouseEvent<HTMLButtonElement>) => Promise<void>);\n\nexport interface ButtonProps\n extends ComponentPropsWithoutRef<'button'>, Omit<PseudoClassProps, 'checked'> {\n /**\n * Visual style of the button.\n *\n * - `primary` – filled brand colour, for the primary action on a surface.\n * - `basic` – subtle grey fill, for secondary actions.\n * - `outline` – transparent with a border, alternative secondary style.\n * - `text` – no background or border, for tertiary / inline actions.\n * - `inverse` – inverted fill for use on dark/coloured backgrounds.\n * - `danger` – red fill, for destructive actions.\n *\n * @defaultValue 'primary'\n */\n variant?: ButtonVariant;\n /**\n * Shows a loading spinner and disables the button. Also triggers automatically\n * when `onClick` returns a Promise, clearing once the promise settles.\n */\n isPending?: boolean;\n /**\n * Icon rendered to the left of the button label.\n * Import from `@persona/icons`.\n */\n prefixIcon?: ReactNode;\n /**\n * Controls how the prefix icon inherits sizing.\n *\n * - `basic` – icon is rendered inside a fixed-size container.\n * - `inherit` – icon stretches to fill the surrounding element's dimensions.\n *\n * @defaultValue 'basic'\n */\n prefixIconType?: 'basic' | 'inherit';\n\n /**\n * Icon rendered to the right of the button label.\n * Import from `@persona/icons`.\n */\n suffixIcon?: ReactNode;\n\n /**\n * Height and typography scale of the button.\n *\n * @defaultValue 'md'\n */\n size?: 'md' | 'sm';\n\n /**\n * Changes the button into a link.\n * A relative path renders a router-aware link (PDS `RouterProvider` adapter,\n * react-router when present, otherwise a plain `<a>`); an absolute `https://`\n * URL renders an `<a>` that opens in a new tab.\n */\n to?: To;\n\n /**\n * Overrides the target of the link if `to` is provided and is an external link.\n */\n target?: HTMLAttributeAnchorTarget;\n\n /**\n * History state attached to the navigation when `to` is an internal link.\n */\n state?: unknown;\n\n /**\n * Replaces the current history entry instead of pushing, when `to` is an internal link.\n */\n replace?: boolean;\n\n /**\n * Note: we may want to default this to 'button' in the future, but many instances of this Button component\n * in dashboard currently rely on the default 'submit' behavior that occurs when using this in redux-form\n * so we'll have to comb through and manually add the type='submit' prop.\n */\n type?: 'button' | 'reset' | 'submit';\n /**\n * Controls the width of the button.\n *\n * - `full` – stretches to fill its container (`width: 100%`).\n * - `auto` – shrinks to fit its content.\n * - `button` – a fixed medium element width (from design tokens).\n * - `icon` – square, sized to match the button height; use for icon-only buttons.\n *\n * @defaultValue 'full'\n */\n width?: 'full' | 'auto' | 'button' | 'icon';\n onClick?: MaybePromise;\n ref?: Ref<HTMLButtonElement>;\n\n /**\n * In some cases we render a button on a secondary background, which needs an adjustment\n * for certain variants.\n */\n onSecondaryBackground?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n id,\n children,\n prefixIcon,\n suffixIcon,\n disabled,\n isPending,\n type = 'button',\n prefixIconType = 'basic',\n variant = 'primary',\n size = 'md',\n width = 'full',\n onClick,\n onSecondaryBackground,\n to,\n target,\n state,\n replace,\n ...props\n }: ButtonProps,\n ref,\n) {\n const [isResolving, { enable, disable }] = useToggle(false);\n const innerOnClick: MaybePromise = isFunction(onClick) ? onClick : noop;\n const loading = isPending || isResolving;\n const isInternalLink = !isEmpty(to) && !(typeof to === 'string' && to.startsWith('https://'));\n\n const handleClick = useCallback(\n async (e: MouseEvent<HTMLButtonElement>) => {\n if (loading) {\n return;\n }\n\n const maybePromise = innerOnClick(e);\n\n if (maybePromise instanceof Promise) {\n enable();\n try {\n await maybePromise;\n } catch {\n // A failed action should not leave the button pending.\n } finally {\n disable();\n }\n }\n },\n [loading, innerOnClick],\n );\n\n return (\n <StyledButton\n id={id}\n type={type}\n data-test={'button__' + variant}\n variant={variant}\n size={size}\n width={width}\n disabled={disabled || loading}\n $isPending={loading}\n $onSecondaryBackground={onSecondaryBackground}\n to={to}\n target={target}\n {...(isInternalLink ? { state, replace } : {})}\n {...props}\n onClick={handleClick}\n ref={ref}\n >\n {loading && (\n <LoaderContainer isPending={loading}>\n <Loader aria-label={`Loading ${props['aria-label'] || ''}`} />\n </LoaderContainer>\n )}\n <ButtonChildren isPending={loading}>\n {prefixIcon != null && (\n <>\n {prefixIconType === 'basic' && <PrefixIconContainer>{prefixIcon}</PrefixIconContainer>}\n {prefixIconType === 'inherit' && (\n <InheritPrefixIconContainer>{prefixIcon}</InheritPrefixIconContainer>\n )}\n </>\n )}\n {children && (\n <ButtonText width={width} size={size}>\n {children}\n </ButtonText>\n )}\n {suffixIcon != null && <SuffixIconContainer>{suffixIcon}</SuffixIconContainer>}\n </ButtonChildren>\n </StyledButton>\n );\n});\n\nexport default Button;\n","import { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\n\nimport { semanticOnly } from '#src/lib/semanticColor';\n\nimport Button, { type ButtonProps } from './Button';\n\nconst BUTTON_SIZE_MAP = {\n xs: '16px',\n sm: '24px',\n md: '32px',\n};\n\nconst ICON_SIZE_MAP = {\n xs: '12px',\n sm: '16px',\n md: '16px',\n};\n\ntype IconBtnSize = keyof typeof BUTTON_SIZE_MAP;\n\nconst IconBtn = styled(Button).attrs({\n width: 'icon',\n variant: 'basic',\n})`\n background-color: transparent;\n padding: 0;\n border-radius: ${BorderRadius.Md};\n\n ${semanticOnly(\n () => css`\n &:disabled {\n background-color: transparent;\n }\n `,\n )}\n\n ${({ size }) => css`\n height: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n width: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n\n svg {\n width: ${ICON_SIZE_MAP[size as IconBtnSize]};\n height: ${ICON_SIZE_MAP[size as IconBtnSize]};\n }\n `}\n`;\n\nexport interface IconButtonProps extends Omit<\n ButtonProps,\n 'width' | 'prefixIcon' | 'prefixIconType' | 'suffixIcon' | 'variant' | 'size'\n> {\n /**\n * `xs` - 16px. `sm` - 24px. `md` - 32px.\n * Pair with a PDS icon in the prescribed size.\n */\n size?: IconBtnSize;\n}\n\n/**\n * Use to render icon-only buttons. Ensure buttons have proper aria properties.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { size = 'xs', ...props },\n ref,\n) {\n return <IconBtn size={size as ButtonProps['size']} ref={ref} {...props} />;\n});\n\nexport default IconButton;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Link-D_kCyLYX.mjs","names":[],"sources":["../src/components/Link/Link.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LinkExternalIcon } from '@persona/icons';\n\nimport { RouterLink, type RouterLinkComponentProps } from '#src/lib/router';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { focusOutline } from '#src/mixins/focus';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { TransitionDuration } from '#src/variables/transitions';\n\ntype Target = '_blank' | '_self' | '_parent' | '_top';\n\ninterface BaseLinkProps {\n /**\n * The content to display inside the link.\n *\n */\n children?: ReactNode;\n /**\n * Provides an accessible name for the link when the visible text alone\n * isn't descriptive enough for screen reader users\n */\n 'aria-label'?: string;\n}\n\ninterface ExternalLinkProps extends BaseLinkProps, AnchorHTMLAttributes<HTMLAnchorElement> {\n /**\n * The URL to navigate to. Can be internal (e.g., \"/settings\") or external (e.g., \"https://example.com\").\n */\n url: string;\n\n /**\n * Where to open the link. Use \"_blank\" for external links to open in a new tab.\n */\n target?: Target;\n}\n\ninterface InternalLinkProps\n extends BaseLinkProps, Omit<RouterLinkComponentProps, 'to' | 'children'> {\n /**\n * The URL to navigate to. Should be an internal route (e.g., \"/settings\").\n */\n url: string;\n}\n\nexport type LinkProps = ExternalLinkProps | InternalLinkProps;\n\nconst IconContainer = styled.span`\n display: inline-block;\n vertical-align: middle;\n /* Uses padding here since we can't define flex on the element for multiline support */\n padding-left: 2px;\n /* Needed to reset the height of the container for SVG */\n line-height: 0;\n position: relative;\n /* Optical alignment adjustments */\n bottom: 1px;\n`;\n\nconst baseLinkStyles = css`\n ${paragraphMixins.md};\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', Color.CorePurple600)};\n width: fit-content;\n position: relative;\n overflow: hidden;\n text-decoration: underline;\n\n transition:\n color ${TransitionDuration.ExtraFast} ease-out,\n text-underline-offset ${TransitionDuration.ExtraFast} ease-out;\n text-underline-offset: 2px;\n\n &:hover {\n color: ${({ theme }) => semanticColor(theme, 'FgAccentHover', Color.CorePurple800)};\n text-underline-offset: ${Spacing[1]};\n }\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n ${focusOutline}\n\n &:active {\n color: ${({ theme }) => semanticColor(theme, 'FgAccentActive', Color.CorePurple900)};\n }\n`;\n\nconst StyledAnchor = styled.a`\n ${baseLinkStyles}\n`;\n\nconst StyledRouterLink = styled(RouterLink)`\n ${baseLinkStyles}\n`;\n\nexport const Link = ({ children, url, ...props }: LinkProps) => {\n // Check if the URL is external by looking at the protocol or if target is _blank\n const isAbsoluteUrl = /^https?:\\/\\//.test(url);\n const hasBlankTarget = props.target === '_blank';\n const isExternal = isAbsoluteUrl || hasBlankTarget;\n\n if (isExternal) {\n const { 'aria-label': ariaLabel, ...anchorProps } = props;\n const externalProps = {\n href: url,\n target: '_blank',\n rel: 'noopener noreferrer',\n 'aria-label': ariaLabel,\n // Automatically inform screen readers that link opens in new window\n title: ariaLabel ? undefined : 'Opens in new window',\n ...anchorProps,\n };\n\n return (\n <StyledAnchor {...externalProps}>\n {children}\n <IconContainer>\n <LinkExternalIcon size={12} />\n </IconContainer>\n </StyledAnchor>\n );\n }\n\n const { 'aria-label': ariaLabel, ...routerProps } = props;\n const internalProps = {\n to: url,\n 'aria-label': ariaLabel,\n\n ...routerProps,\n };\n\n return <StyledRouterLink {...internalProps}>{children}</StyledRouterLink>;\n};\n\nexport default Link;\n"],"mappings":";;;;;;;;;;AAiDA,MAAM,gBAAgB,OAAO,IAAI;;;;;;;;;;;AAYjC,MAAM,iBAAiB,GAAG;IACtB,gBAAgB,GAAG;YACX,EAAE,YAAY,cAAc,OAAO,YAAY,MAAM,cAAc,CAAC;;;;;;;oBAOvC;oCACgB;;;;cAI3C,EAAE,YAAY,cAAc,OAAO,iBAAiB,MAAM,cAAc,CAAC;6BAC1D,QAAQ,GAAG;;;oBAGpB,EAAE,YAAY,MAAM,OAAO,aAAa;IACxD,aAAa;;;cAGH,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,cAAc,CAAC;;;AAIxF,MAAM,eAAe,OAAO,CAAC;IACzB,eAAe;;AAGnB,MAAM,mBAAmB,OAAO,WAAW;IACvC,eAAe;;AAGnB,MAAa,QAAQ,EAAE,UAAU,KAAK,GAAG,YAAuB;CAE9D,MAAM,gBAAgB,eAAe,KAAK,IAAI;CAC9C,MAAM,iBAAiB,MAAM,WAAW;AAGxC,KAFmB,iBAAiB,gBAEpB;EACd,MAAM,EAAE,cAAc,WAAW,GAAG,gBAAgB;AAWpD,SACE,qBAAC,cAAD;GAVA,MAAM;GACN,QAAQ;GACR,KAAK;GACL,cAAc;GAEd,OAAO,YAAY,KAAA,IAAY;GAC/B,GAAG;aAIH,CACG,UACD,oBAAC,eAAD,EAAA,UACE,oBAAC,kBAAD,EAAkB,MAAM,IAAM,CAAA,EAChB,CAAA,CACH;;;CAInB,MAAM,EAAE,cAAc,WAAW,GAAG,gBAAgB;AAQpD,QAAO,oBAAC,kBAAD;EANL,IAAI;EACJ,cAAc;EAEd,GAAG;EAGwC;EAA4B,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"LoadingShimmer-oPIv2ESr.mjs","names":[],"sources":["../src/components/LoadingShimmer/LoadingShimmer.tsx"],"sourcesContent":["import { motion } from 'framer-motion';\nimport type { ComponentPropsWithoutRef, FC } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color } from '@persona/design-tokens';\n\nimport { type CssColor, withAlpha } from '#src/lib/color';\nimport { type MaybeSemanticTheme, semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport type { HeadingSize, ParagraphSize } from '#src/mixins/text';\n\n// A one-off colour predating the token set; no primitive matches it exactly.\n// oxlint-disable-next-line persona-web/no-raw-hex-colors\nconst LEGACY_SECONDARY_BAR = '#eaeaea' as CssColor;\n\n// Relay renders this under its own theme, which has neither a semantic namespace nor `theme.color`,\n// so each fallback is a constant rather than a theme expression — the latter would throw there.\nconst shimmerColors = (theme: MaybeSemanticTheme, variant: 'primary' | 'secondary') => {\n if (variant === 'secondary') {\n return {\n bar: semanticColor(theme, 'FeedbackNeutral2', LEGACY_SECONDARY_BAR),\n highlight: semanticColor(theme, 'FeedbackNeutral1', Color.CoreSlate50),\n };\n }\n\n const tokens = semanticTokens(theme);\n\n return {\n bar: semanticColor(theme, 'FeedbackNeutral1', Color.CoreSlate50),\n highlight: tokens ? withAlpha(tokens.SurfaceSecondary, tokens.Opacity25) : Color.CoreSlate25,\n };\n};\n\ninterface LoadingShimmerProps extends ComponentPropsWithoutRef<'span'> {\n height?: string;\n width?: string;\n variant?: 'primary' | 'secondary';\n}\n\ntype ShimmerContainerProps = {\n width?: string;\n height?: string;\n $variant: 'primary' | 'secondary';\n};\nconst ShimmerContainer = styled.span<ShimmerContainerProps>`\n position: relative;\n display: inline-block;\n background-color: ${({ theme, $variant }) => shimmerColors(theme, $variant).bar};\n width: ${({ width }) => width ?? '100px'};\n height: ${({ height }) => height ?? 'auto'};\n border-radius: ${BorderRadius.Md};\n overflow: hidden;\n`;\n\ntype ShimmerProps = {\n $variant: 'primary' | 'secondary';\n};\nconst Shimmer = styled(motion.span)<ShimmerProps>`\n position: absolute;\n width: 100%;\n height: 100%;\n background: ${({ theme, $variant }) =>\n `linear-gradient(90deg, transparent 0%, ${shimmerColors(theme, $variant).highlight} 50%, transparent 100%)`};\n filter: blur(4px);\n`;\n\n/**\n * Base class of all Loading Shimmer components.\n */\nexport function LoadingShimmer({\n width,\n height,\n variant = 'primary',\n ...props\n}: LoadingShimmerProps) {\n return (\n <ShimmerContainer\n width={width}\n height={height}\n $variant={variant}\n aria-live='polite'\n aria-busy='true'\n data-test='loading-shimmer'\n data-loading-indicator='true'\n {...props}\n >\n <Shimmer\n initial={{ x: '-100%', skew: -30 }}\n animate={{ x: '100%', skew: -30 }}\n $variant={variant}\n transition={{ repeat: Infinity, duration: 1, ease: 'easeOut' }}\n />\n </ShimmerContainer>\n );\n}\n\nexport interface LoadingShimmerHeadingProps extends LoadingShimmerProps {\n size?: HeadingSize;\n}\n\nexport const LoadingShimmerHeading = styled(LoadingShimmer)<LoadingShimmerHeadingProps>`\n height: ${({ theme, size = 'lg' }) => theme.text.heading[size].fontSize};\n`;\n\ninterface LoadingShimmerParagraphProps extends LoadingShimmerProps {\n size?: ParagraphSize;\n // eg. 200px\n width?: string;\n}\n\nexport const LoadingShimmerParagraph = styled(LoadingShimmer)<LoadingShimmerParagraphProps>`\n height: ${({ theme, size = 'md' }) => theme.text.paragraph[size].fontSize};\n`;\n\n// A \"maybe\" shimmer block that is shimmering if the `isLoading`\n// value is set to true and otherwise just displays its children\ninterface MaybeLoadingShimmerProps {\n isLoading: boolean;\n height?: string;\n width?: string;\n}\n\nexport const MaybeLoadingShimmer: FC<MaybeLoadingShimmerProps> = ({\n isLoading,\n children,\n height,\n width,\n}) => (isLoading ? <LoadingShimmer height={height} width={width} /> : <>{children}</>);\n"],"mappings":";;;;;;;AAYA,MAAM,uBAAuB;AAI7B,MAAM,iBAAiB,OAA2B,YAAqC;AACrF,KAAI,YAAY,YACd,QAAO;EACL,KAAK,cAAc,OAAO,oBAAoB,qBAAqB;EACnE,WAAW,cAAc,OAAO,oBAAoB,MAAM,YAAY;EACvE;CAGH,MAAM,SAAS,eAAe,MAAM;AAEpC,QAAO;EACL,KAAK,cAAc,OAAO,oBAAoB,MAAM,YAAY;EAChE,WAAW,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAClF;;AAcH,MAAM,mBAAmB,OAAO,IAA2B;;;uBAGpC,EAAE,OAAO,eAAe,cAAc,OAAO,SAAS,CAAC,IAAI;YACtE,EAAE,YAAY,SAAS,QAAQ;aAC9B,EAAE,aAAa,UAAU,OAAO;mBAC1B,aAAa,GAAG;;;AAOnC,MAAM,UAAU,OAAO,OAAO,KAAK;;;;iBAIlB,EAAE,OAAO,eACtB,0CAA0C,cAAc,OAAO,SAAS,CAAC,UAAU,yBAAyB;;;;;;AAOhH,SAAgB,eAAe,EAC7B,OACA,QACA,UAAU,WACV,GAAG,SACmB;AACtB,QACE,oBAAC,kBAAD;EACS;EACC;EACR,UAAU;EACV,aAAU;EACV,aAAU;EACV,aAAU;EACV,0BAAuB;EACvB,GAAI;YAEJ,oBAAC,SAAD;GACE,SAAS;IAAE,GAAG;IAAS,MAAM;IAAK;GAClC,SAAS;IAAE,GAAG;IAAQ,MAAM;IAAK;GACjC,UAAU;GACV,YAAY;IAAE,QAAQ;IAAU,UAAU;IAAG,MAAM;IAAW;GAC9D,CAAA;EACe,CAAA;;AAQvB,MAAa,wBAAwB,OAAO,eAAe;aAC9C,EAAE,OAAO,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,SAAS;;AAS1E,MAAa,0BAA0B,OAAO,eAAe;aAChD,EAAE,OAAO,OAAO,WAAW,MAAM,KAAK,UAAU,MAAM,SAAS;;AAW5E,MAAa,uBAAqD,EAChE,WACA,UACA,QACA,YACK,YAAY,oBAAC,gBAAD;CAAwB;CAAe;CAAS,CAAA,GAAG,oBAAA,UAAA,EAAG,UAAY,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PageLayout-DjtGrvJa.mjs","names":[],"sources":["../src/patterns/PageLayout/PageLayout.tsx","../src/patterns/PageLayout/PageLayoutFrame.tsx","../src/patterns/PageLayout/SingleColumnLayout.tsx","../src/patterns/PageLayout/SplitColumnLayout.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nexport const Backdrop = styled.div`\n position: relative;\n width: 100%;\n padding: ${Spacing[7]} ${Spacing[5]};\n\n display: flex;\n flex-direction: column;\n`;\n\nconst StyledContainer = styled('div')`\n position: relative;\n width: 100%;\n padding: 0;\n\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nexport const Container = ({\n children,\n ...rest\n}: { children: ReactNode } & ComponentPropsWithoutRef<'div'>) => {\n return <StyledContainer {...rest}>{children}</StyledContainer>;\n};\n\nexport const Section = styled('div')`\n width: 100%;\n padding: ${Spacing[7]};\n`;\n","import { type ReactNode, useLayoutEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Grid, { GRID_BREAKPOINTS, GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nexport type PageLayoutWidth = 'standard' | 'wide';\n\nexport interface PageLayoutChromeProps {\n /**\n * `standard` uses the fixed grid (centered, max 1408px). `wide` uses the fluid grid.\n *\n * @defaultValue 'standard'\n */\n width?: PageLayoutWidth;\n /** Tab group. Sits above the page notice and scrolls with the page. Omit to skip the region and its gap. */\n tabs?: ReactNode;\n /** Page notice under the tabs. Omit to skip the region and its gap. */\n pageNotice?: ReactNode;\n}\n\nconst topPadding = (condensed: boolean) => (condensed ? Spacing[5] : Spacing[6]);\n\nconst Root = styled.div<{ $condensed: boolean; $tabs: boolean }>`\n width: 100%;\n min-width: ${GRID_BREAKPOINTS.sm - 1}px;\n padding-top: ${({ $condensed, $tabs }) => ($tabs ? Spacing[5] : topPadding($condensed))};\n padding-bottom: ${({ $condensed }) => topPadding($condensed)};\n`;\n\nconst gridMode = (width: PageLayoutWidth): 'fixed' | 'fluid' =>\n width === 'wide' ? 'fluid' : 'fixed';\n\nconst FullWidthBand = ({ mode, children }: { mode: 'fixed' | 'fluid'; children: ReactNode }) => (\n <Grid mode={mode}>\n <GridItem span={12}>{children}</GridItem>\n </Grid>\n);\n\nexport const PageLayoutFrame = ({\n width = 'standard',\n tabs,\n pageNotice,\n children,\n}: PageLayoutChromeProps & { children: ReactNode }) => {\n const mode = gridMode(width);\n const ref = useRef<HTMLDivElement>(null);\n const [condensed, setCondensed] = useState(false);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) {\n return;\n }\n const update = () => setCondensed(node.offsetWidth < GRID_BREAKPOINTS.md);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n return (\n <Root ref={ref} $condensed={condensed} $tabs={Boolean(tabs)}>\n <Stack spacing={Spacing[5]}>\n {tabs && <FullWidthBand mode={mode}>{tabs}</FullWidthBand>}\n {pageNotice && <FullWidthBand mode={mode}>{pageNotice}</FullWidthBand>}\n <Grid mode={mode}>{children}</Grid>\n </Stack>\n </Root>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nexport interface SingleColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary page content. Direct children stack vertically. */\n main: ReactNode;\n}\n\nexport const SingleColumnLayout = ({ main, ...chrome }: SingleColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <GridItem span={12}>\n <Stack spacing={Spacing[4]}>{main}</Stack>\n </GridItem>\n </PageLayoutFrame>\n);\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem, type GridSpan, useGridBreakpoint } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nconst SPLIT_COLUMN_SPANS = { main: 8, aside: 4 } as const satisfies Record<string, GridSpan>;\n\nexport interface SplitColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary column. Direct children stack vertically and stay in this column. */\n main: ReactNode;\n /** Supporting column. Direct children stack vertically and stay in this column. */\n aside: ReactNode;\n}\n\nconst Region = ({ children }: { children: ReactNode }) => (\n <Stack spacing={Spacing[4]}>{children}</Stack>\n);\n\nconst SplitBody = ({ main, aside }: { main: ReactNode; aside: ReactNode }) => {\n const stacked = useGridBreakpoint() === 'xs';\n const mainSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.main;\n const asideSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.aside;\n\n return (\n <>\n <GridItem span={mainSpan}>\n <Region>{main}</Region>\n </GridItem>\n <GridItem span={asideSpan}>\n <aside>\n <Region>{aside}</Region>\n </aside>\n </GridItem>\n </>\n );\n};\n\nexport const SplitColumnLayout = ({ main, aside, ...chrome }: SplitColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <SplitBody main={main} aside={aside} />\n </PageLayoutFrame>\n);\n"],"mappings":";;;;;;;AAKA,MAAa,WAAW,OAAO,GAAG;;;aAGrB,QAAQ,GAAG,GAAG,QAAQ,GAAG;;;;;AAMtC,MAAM,kBAAkB,OAAO,MAAM;;;;;;;;;AAUrC,MAAa,aAAa,EACxB,UACA,GAAG,WAC4D;AAC/D,QAAO,oBAAC,iBAAD;EAAiB,GAAI;EAAO;EAA2B,CAAA;;AAGhE,MAAa,UAAU,OAAO,MAAM;;aAEvB,QAAQ,GAAG;;;;ACVxB,MAAM,cAAc,cAAwB,YAAY,QAAQ,KAAK,QAAQ;AAE7E,MAAM,OAAO,OAAO,GAA4C;;eAEjD,iBAAiB,KAAK,EAAE;kBACrB,EAAE,YAAY,YAAa,QAAQ,QAAQ,KAAK,WAAW,WAAW,CAAE;qBACrE,EAAE,iBAAiB,WAAW,WAAW,CAAC;;AAG/D,MAAM,YAAY,UAChB,UAAU,SAAS,UAAU;AAE/B,MAAM,iBAAiB,EAAE,MAAM,eAC7B,oBAAC,MAAD;CAAY;WACV,oBAAC,UAAD;EAAU,MAAM;EAAK;EAAoB,CAAA;CACpC,CAAA;AAGT,MAAa,mBAAmB,EAC9B,QAAQ,YACR,MACA,YACA,eACqD;CACrD,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAM,MAAM,OAAuB,KAAK;CACxC,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;AAEjD,uBAAsB;EACpB,MAAM,OAAO,IAAI;AACjB,MAAI,CAAC,KACH;EAEF,MAAM,eAAe,aAAa,KAAK,cAAc,iBAAiB,GAAG;AACzE,UAAQ;EACR,MAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,WAAS,QAAQ,KAAK;AACtB,eAAa,SAAS,YAAY;IACjC,EAAE,CAAC;AAEN,QACE,oBAAC,MAAD;EAAW;EAAK,YAAY;EAAW,OAAO,QAAQ,KAAK;YACzD,qBAAC,OAAD;GAAO,SAAS,QAAQ;aAAxB;IACG,QAAQ,oBAAC,eAAD;KAAqB;eAAO;KAAqB,CAAA;IACzD,cAAc,oBAAC,eAAD;KAAqB;eAAO;KAA2B,CAAA;IACtE,oBAAC,MAAD;KAAY;KAAO;KAAgB,CAAA;IAC7B;;EACH,CAAA;;;;ACxDX,MAAa,sBAAsB,EAAE,MAAM,GAAG,aAC5C,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,OAAD;GAAO,SAAS,QAAQ;aAAK;GAAa,CAAA;EACjC,CAAA;CACK,CAAA;;;ACVpB,MAAM,qBAAqB;CAAE,MAAM;CAAG,OAAO;CAAG;AAShD,MAAM,UAAU,EAAE,eAChB,oBAAC,OAAD;CAAO,SAAS,QAAQ;CAAK;CAAiB,CAAA;AAGhD,MAAM,aAAa,EAAE,MAAM,YAAmD;CAC5E,MAAM,UAAU,mBAAmB,KAAK;CACxC,MAAM,WAAW,UAAU,KAAK,mBAAmB;CACnD,MAAM,YAAY,UAAU,KAAK,mBAAmB;AAEpD,QACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,QAAD,EAAA,UAAS,MAAc,CAAA;EACd,CAAA,EACX,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,SAAD,EAAA,UACE,oBAAC,QAAD,EAAA,UAAS,OAAe,CAAA,EAClB,CAAA;EACC,CAAA,CACV,EAAA,CAAA;;AAIP,MAAa,qBAAqB,EAAE,MAAM,OAAO,GAAG,aAClD,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,WAAD;EAAiB;EAAa;EAAS,CAAA;CACvB,CAAA"}