@persona/design-system 0.10.5 → 0.10.7

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 (559) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/Accordion.d.mts +1 -1
  3. package/dist/AccordionItem.d.mts +1 -1
  4. package/dist/{Action-Bmo8B-Q3.d.mts → Action-BLMJwLBV.d.mts} +3 -3
  5. package/dist/Action.d.mts +1 -1
  6. package/dist/AdvancedFilterRuleRow.d.mts +2 -2
  7. package/dist/AdvancedFilterRulesPopover.d.mts +2 -2
  8. package/dist/ArrayValueControl.d.mts +1 -1
  9. package/dist/Attribute.d.mts +3 -3
  10. package/dist/Badge-8YzapjWf.mjs.map +1 -1
  11. package/dist/BooleanValueControl.d.mts +1 -1
  12. package/dist/BottomPanel.d.mts +7 -0
  13. package/dist/{Breadcrumb-DnY8n3EL.d.mts → Breadcrumb-chGXhl3V.d.mts} +1 -1
  14. package/dist/Breadcrumb.d.mts +1 -1
  15. package/dist/{Breadcrumbs-DRu_JfdI.d.mts → Breadcrumbs-ChKWIuRq.d.mts} +2 -2
  16. package/dist/Breadcrumbs-Dft2TR4v.mjs.map +1 -1
  17. package/dist/Breadcrumbs.d.mts +1 -1
  18. package/dist/{Button-Cg8KyT5M.d.mts → Button-B79_aXfC.d.mts} +4 -4
  19. package/dist/Button.d.mts +1 -1
  20. package/dist/{Calendar-D-6WOLJ1.d.mts → Calendar-50D7poM_.d.mts} +1 -1
  21. package/dist/Calendar.d.mts +1 -1
  22. package/dist/CalendarBase.d.mts +1 -1
  23. package/dist/CalendarCell.d.mts +1 -1
  24. package/dist/CalendarGrid.d.mts +1 -1
  25. package/dist/{Card-CfECLwQ6.d.mts → Card-DOIqF954.d.mts} +3 -3
  26. package/dist/Card-DuQHyroh.mjs.map +1 -1
  27. package/dist/Card.d.mts +1 -1
  28. package/dist/CardGrouping.d.mts +2 -2
  29. package/dist/CardV2-BRJbRSts.mjs.map +1 -1
  30. package/dist/Checkbox-Dr4LMKHV.mjs.map +1 -1
  31. package/dist/{Checkbox-ZywrdT_h.d.mts → Checkbox-EgYclGfH.d.mts} +1 -1
  32. package/dist/Checkbox.d.mts +1 -1
  33. package/dist/{CheckboxGroupField-UHpA38U5.d.mts → CheckboxGroupField-Cw-1UxIW.d.mts} +3 -3
  34. package/dist/CheckboxGroupField.d.mts +1 -1
  35. package/dist/ChoicesValueControl.d.mts +1 -1
  36. package/dist/{Combobox-BXkcQ2aY.d.mts → Combobox-BkDYZlUh.d.mts} +3 -3
  37. package/dist/Combobox-DQxaOCLA.mjs.map +1 -1
  38. package/dist/Combobox.d.mts +2 -2
  39. package/dist/{ComboboxBase-D2rDQHYZ.d.mts → ComboboxBase-1Xy4pnRV.d.mts} +6 -6
  40. package/dist/ComboboxBase.d.mts +1 -1
  41. package/dist/{ComboboxMultiSelect-CrvB6ap5.d.mts → ComboboxMultiSelect-DHf7NK7Z.d.mts} +2 -2
  42. package/dist/ComboboxMultiSelect.d.mts +1 -1
  43. package/dist/{ComboboxSingleSelect-Dp0iTdDO.d.mts → ComboboxSingleSelect-Ble5PcXQ.d.mts} +4 -4
  44. package/dist/ComboboxSingleSelect.d.mts +1 -1
  45. package/dist/{CompactBar-zYfXjFmn.d.mts → CompactBar-DmoFq5i6.d.mts} +3 -3
  46. package/dist/CompactBar.d.mts +1 -1
  47. package/dist/{ControlBar-kJ_eWf8f.d.mts → ControlBar-dqzVo6e6.d.mts} +2 -2
  48. package/dist/ControlBar.d.mts +1 -1
  49. package/dist/{DataTable-DEJHWrsy.mjs → DataTable-B7QqP6YU.mjs} +8 -7
  50. package/dist/DataTable-B7QqP6YU.mjs.map +1 -0
  51. package/dist/{DataTable-C000E74h.d.mts → DataTable-Cblw6bLk.d.mts} +7 -6
  52. package/dist/DataTable.d.mts +1 -1
  53. package/dist/{DateField-g7malFm-.d.mts → DateField-CbTxDzYF.d.mts} +2 -2
  54. package/dist/DateField.d.mts +1 -1
  55. package/dist/{DatePicker-8kUpFFh8.d.mts → DatePicker-1BADH9Pi.d.mts} +2 -2
  56. package/dist/{DatePicker-D-_ibUd1.mjs → DatePicker-CHaNe2Es.mjs} +2 -2
  57. package/dist/DatePicker-CHaNe2Es.mjs.map +1 -0
  58. package/dist/DatePicker.d.mts +1 -1
  59. package/dist/{DateRangePicker-Nv4uNuIW.d.mts → DateRangePicker-fq-_pFpg.d.mts} +3 -3
  60. package/dist/DateRangePicker.d.mts +1 -1
  61. package/dist/DateRangeValueControl.d.mts +2 -2
  62. package/dist/DateValueControl.d.mts +1 -1
  63. package/dist/DropdownButton-BiFRlSVD.mjs.map +1 -1
  64. package/dist/DropdownButton.d.mts +2 -2
  65. package/dist/{DropdownMenu-CQbS7ML5.d.mts → DropdownMenu-DjdNBJqP.d.mts} +2 -2
  66. package/dist/DropdownMenu-Q8S-9rXm.mjs.map +1 -1
  67. package/dist/DropdownMenu.d.mts +1 -1
  68. package/dist/{ErrorProps-Cy-APmdC.d.mts → ErrorProps-D4G9EWX2.d.mts} +1 -1
  69. package/dist/ErrorProps.d.mts +1 -1
  70. package/dist/{FieldRegistry-a44G08fS.d.mts → FieldRegistry-CPr7YoG5.d.mts} +2 -2
  71. package/dist/FieldRegistry.d.mts +1 -1
  72. package/dist/{FilterBar-BpMguIXl.d.mts → FilterBar-DPCPfr4_.d.mts} +4 -4
  73. package/dist/FilterBar.d.mts +1 -1
  74. package/dist/FilterPickerMenu.d.mts +2 -2
  75. package/dist/FilterPill.d.mts +1 -1
  76. package/dist/FilterPopover.d.mts +1 -1
  77. package/dist/FloatValueControl.d.mts +1 -1
  78. package/dist/{FloatingActionBar-DPA9v_yH.d.mts → FloatingActionBar-u3TJcigs.d.mts} +1 -1
  79. package/dist/FloatingActionBar.d.mts +1 -1
  80. package/dist/FloatingToolbar-Df90f7Dm.mjs +493 -0
  81. package/dist/FloatingToolbar-Df90f7Dm.mjs.map +1 -0
  82. package/dist/FloatingToolbar.d.mts +1 -1
  83. package/dist/FormControl-BztNXLn6.mjs.map +1 -1
  84. package/dist/{FormControl-TkYMZeBd.d.mts → FormControl-D8vpeAPI.d.mts} +2 -2
  85. package/dist/FormControl.d.mts +1 -1
  86. package/dist/FormControlLabel.d.mts +1 -1
  87. package/dist/{FormField-g1zQFM9T.mjs → FormField-BStxmlZT.mjs} +2 -2
  88. package/dist/FormField-BStxmlZT.mjs.map +1 -0
  89. package/dist/{FormField-PBo1ctY8.d.mts → FormField-C6vp1Vfe.d.mts} +3 -3
  90. package/dist/FormField.d.mts +1 -1
  91. package/dist/{Grid-BtTuj5mR.mjs → Grid-CYpOqTUu.mjs} +1 -1
  92. package/dist/{Grid-BtTuj5mR.mjs.map → Grid-CYpOqTUu.mjs.map} +1 -1
  93. package/dist/{Header-fwlbzxYx.d.mts → Header-C9oYPBLv.d.mts} +1 -1
  94. package/dist/Header.d.mts +1 -1
  95. package/dist/{HelperTooltip-BLfPfJRN.d.mts → HelperTooltip-jHTdkLQq.d.mts} +2 -2
  96. package/dist/HelperTooltip.d.mts +1 -1
  97. package/dist/HighlightedText.d.mts +2 -2
  98. package/dist/HoverCopyableField-CW7Jxmni.mjs.map +1 -1
  99. package/dist/{I18nContext-EPmbUprm.d.mts → I18nContext-DzV-RDIh.d.mts} +2 -2
  100. package/dist/I18nContext.d.mts +1 -1
  101. package/dist/{IconButton-KhCwTwPx.d.mts → IconButton-CaEvsrOn.d.mts} +2 -2
  102. package/dist/IconButton-DftINsp7.mjs.map +1 -1
  103. package/dist/IconButton.d.mts +1 -1
  104. package/dist/ImageTile.d.mts +1 -1
  105. package/dist/IndexTableLayout.d.mts +5 -5
  106. package/dist/InlineCombobox.d.mts +1 -1
  107. package/dist/InlineInput.d.mts +1 -1
  108. package/dist/{Input-QNjbGo38.d.mts → Input-DQ2J9wlC.d.mts} +3 -3
  109. package/dist/Input-DtO3qMnE.mjs.map +1 -1
  110. package/dist/Input.d.mts +1 -1
  111. package/dist/{InputProps-BT7-RfnD.d.mts → InputProps-DrG94eFF.d.mts} +2 -2
  112. package/dist/InputProps.d.mts +1 -1
  113. package/dist/{Inserter-BnQVEqHV.d.mts → Inserter-CZeKlPqj.d.mts} +1 -1
  114. package/dist/Inserter.d.mts +1 -1
  115. package/dist/IntegerValueControl.d.mts +1 -1
  116. package/dist/Link-DKYmdL9t.mjs.map +1 -1
  117. package/dist/Link.d.mts +1 -1
  118. package/dist/ListBox-CDG0EAPg.mjs.map +1 -1
  119. package/dist/{ListBox-D9SYTzOd.d.mts → ListBox-DxbXE_EE.d.mts} +3 -3
  120. package/dist/ListBox.d.mts +1 -1
  121. package/dist/{ListBoxField-CtPDd_Aw.d.mts → ListBoxField-DVLggscv.d.mts} +4 -4
  122. package/dist/ListBoxField.d.mts +1 -1
  123. package/dist/LoadingShimmer-oPIv2ESr.mjs.map +1 -1
  124. package/dist/LoadingShimmer.d.mts +1 -1
  125. package/dist/{LogicRow-BWIZ7262.d.mts → LogicRow-DG06PsUe.d.mts} +3 -3
  126. package/dist/LogicRow.d.mts +1 -1
  127. package/dist/MaskedInput.d.mts +1 -1
  128. package/dist/{Menu-DizjcMbO.d.mts → Menu-Bq6Lij2L.d.mts} +3 -3
  129. package/dist/Menu-EIT_MwK6.mjs.map +1 -1
  130. package/dist/Menu.d.mts +1 -1
  131. package/dist/{Modal-92O_uW8H.mjs → Modal-BBlilB-B.mjs} +2 -2
  132. package/dist/Modal-BBlilB-B.mjs.map +1 -0
  133. package/dist/{Modal-Bhwq1bQJ.d.mts → Modal-kEgKwLg4.d.mts} +2 -2
  134. package/dist/Modal.d.mts +1 -1
  135. package/dist/{PageHeader-D2QLrS7-.d.mts → PageHeader-BGGhOS81.d.mts} +2 -2
  136. package/dist/{PageHeader-BzvA_NNt.mjs → PageHeader-DEKTopzU.mjs} +1 -1
  137. package/dist/PageHeader-DEKTopzU.mjs.map +1 -0
  138. package/dist/PageHeader.d.mts +1 -1
  139. package/dist/{PageLayout-DfAbeFIh.d.mts → PageLayout-B_LKPZD8.d.mts} +1 -1
  140. package/dist/{PageLayout-DCe3F76N.mjs → PageLayout-DjtGrvJa.mjs} +2 -2
  141. package/dist/PageLayout-DjtGrvJa.mjs.map +1 -0
  142. package/dist/PageLayout.d.mts +1 -1
  143. package/dist/{PageLayoutFrame-CQLREOBH.d.mts → PageLayoutFrame-uf17F41p.d.mts} +1 -1
  144. package/dist/PageLayoutFrame.d.mts +1 -1
  145. package/dist/{PageSelector-QaKYtk6y.d.mts → PageSelector-CLeG2gFh.d.mts} +10 -4
  146. package/dist/PageSelector.d.mts +1 -1
  147. package/dist/{Pagination-dTsHLVAk.mjs → Pagination-C8hPOu0l.mjs} +15 -11
  148. package/dist/Pagination-C8hPOu0l.mjs.map +1 -0
  149. package/dist/{Pagination-DeXorbSK.d.mts → Pagination-y3kn2X_A.d.mts} +11 -3
  150. package/dist/Pagination.d.mts +1 -1
  151. package/dist/{PillShell-B35z66jZ.d.mts → PillShell-Clv4b-2w.d.mts} +2 -2
  152. package/dist/PillShell.d.mts +1 -1
  153. package/dist/Popover-DordjYNM.mjs.map +1 -1
  154. package/dist/{ProgressIndicator-COCwRZfK.d.mts → ProgressIndicator-tVvf0cY5.d.mts} +1 -1
  155. package/dist/{ProgressIndicator-ISARECzW.mjs → ProgressIndicator-zt3ndT9U.mjs} +1 -1
  156. package/dist/ProgressIndicator-zt3ndT9U.mjs.map +1 -0
  157. package/dist/ProgressIndicator.d.mts +1 -1
  158. package/dist/{PseudoClassProps-D_f-JUT1.d.mts → PseudoClassProps-D-sdJdnG.d.mts} +1 -1
  159. package/dist/PseudoClassProps.d.mts +1 -1
  160. package/dist/Radio-BlEtetrr.mjs.map +1 -1
  161. package/dist/{RadioGroup-pyGpWhhj.d.mts → RadioGroup-9AnTQbh9.d.mts} +1 -1
  162. package/dist/RadioGroup-CMrXmmn4.mjs.map +1 -1
  163. package/dist/RadioGroup.d.mts +1 -1
  164. package/dist/{RangeCalendar-BiugsdSP.d.mts → RangeCalendar-D86xh2yV.d.mts} +2 -2
  165. package/dist/RangeCalendar.d.mts +1 -1
  166. package/dist/RangeCalendarPresets.d.mts +2 -2
  167. package/dist/{RouterContext-BUdfr1it.d.mts → RouterContext-Bgg29ZJo.d.mts} +2 -2
  168. package/dist/RouterContext.d.mts +1 -1
  169. package/dist/{RouterLink-BKbfvJcM.d.mts → RouterLink-CMCsV5H-.d.mts} +2 -2
  170. package/dist/RouterLink.d.mts +1 -1
  171. package/dist/RuleEditorFields.d.mts +2 -2
  172. package/dist/RulesPill.d.mts +1 -1
  173. package/dist/{SearchInput-BejaiGsS.d.mts → SearchInput-NlIspWun.d.mts} +2 -2
  174. package/dist/SearchInput.d.mts +1 -1
  175. package/dist/SectionHeading.d.mts +1 -1
  176. package/dist/{SegmentedControl-UV03Ujqn.d.mts → SegmentedControl-C4C5ge4p.d.mts} +1 -1
  177. package/dist/SegmentedControl-D_DA-MU1.mjs.map +1 -1
  178. package/dist/SegmentedControl.d.mts +1 -1
  179. package/dist/{Select-Chk5WB1F.d.mts → Select-By_LoM1n.d.mts} +3 -3
  180. package/dist/Select-DkUMz4LG.mjs.map +1 -1
  181. package/dist/Select.d.mts +1 -1
  182. package/dist/{SingleColumnLayout-DBo35psH.d.mts → SingleColumnLayout-C4qrVyMf.d.mts} +2 -2
  183. package/dist/SingleColumnLayout.d.mts +1 -1
  184. package/dist/SmartTextInput.d.mts +6 -6
  185. package/dist/SmartTextInputField.d.mts +2 -2
  186. package/dist/SmartTextInputFunctionDialog.d.mts +4 -4
  187. package/dist/SmartTextInputListbox.d.mts +2 -2
  188. package/dist/SmartTextInputPopover.d.mts +1 -1
  189. package/dist/Spacer-C4d9Aho6.mjs.map +1 -1
  190. package/dist/Spinner-CXb-KUs1.mjs.map +1 -1
  191. package/dist/{SplitColumnLayout-C6m_mwdf.d.mts → SplitColumnLayout-BXT7AeNx.d.mts} +2 -2
  192. package/dist/SplitColumnLayout.d.mts +1 -1
  193. package/dist/{Stack-DrYxBkiF.d.mts → Stack-BqRcxDQM.d.mts} +1 -1
  194. package/dist/Stack.d.mts +1 -1
  195. package/dist/{StatusIndicator-pWl1-FLb.mjs → StatusIndicator-Zf75KK3O.mjs} +1 -1
  196. package/dist/StatusIndicator-Zf75KK3O.mjs.map +1 -0
  197. package/dist/Sticker-Bi_fezCO.mjs.map +1 -1
  198. package/dist/{Sticker-sIBnBbHD.d.mts → Sticker-C2zp47FB.d.mts} +4 -4
  199. package/dist/Sticker.d.mts +1 -1
  200. package/dist/StringValueControl.d.mts +1 -1
  201. package/dist/Tab.d.mts +1 -1
  202. package/dist/TabBar-DpXYsWgS.mjs.map +1 -1
  203. package/dist/{Table-BJfcRpMX.d.mts → Table-DGl3mDwc.d.mts} +1 -1
  204. package/dist/Table-DPi4Dt5H.mjs.map +1 -1
  205. package/dist/Table.d.mts +1 -1
  206. package/dist/{TableBody-CBz2PjA-.d.mts → TableBody-BbC-H2qj.d.mts} +1 -1
  207. package/dist/TableBody.d.mts +1 -1
  208. package/dist/TableBox-BfSF36Gy.mjs.map +1 -1
  209. package/dist/TableBox.d.mts +2 -2
  210. package/dist/{TableBoxCell-CwroLAWy.d.mts → TableBoxCell-DuvWTwOm.d.mts} +6 -6
  211. package/dist/TableBoxCell.d.mts +1 -1
  212. package/dist/{TableBoxField-B7bHv7uV.d.mts → TableBoxField-DRx24VAz.d.mts} +5 -5
  213. package/dist/TableBoxField.d.mts +1 -1
  214. package/dist/{TableBoxRow-Dke8B99J.d.mts → TableBoxRow-DFPTf-bZ.d.mts} +3 -3
  215. package/dist/TableBoxRow.d.mts +1 -1
  216. package/dist/{TableBoxRowActions-CkUDVERC.d.mts → TableBoxRowActions-CFCnGc7D.d.mts} +2 -2
  217. package/dist/TableBoxRowActions.d.mts +1 -1
  218. package/dist/{TableCell-KHx5JlqZ.d.mts → TableCell-Do9W49SJ.d.mts} +2 -2
  219. package/dist/TableCell.d.mts +1 -1
  220. package/dist/{TableControls-BDXOQMr7.mjs → TableControls-Dgle87OP.mjs} +8 -6
  221. package/dist/TableControls-Dgle87OP.mjs.map +1 -0
  222. package/dist/{TableControls-DAjx1TYG.d.mts → TableControls-r58fZb_C.d.mts} +6 -5
  223. package/dist/TableControls.d.mts +1 -1
  224. package/dist/{TableControlsContext-BEIvE9qN.d.mts → TableControlsContext-nz8GXmXc.d.mts} +2 -2
  225. package/dist/TableControlsContext.d.mts +1 -1
  226. package/dist/{TableHead-D5A3bOwt.d.mts → TableHead-CIXIrZGE.d.mts} +1 -1
  227. package/dist/TableHead.d.mts +1 -1
  228. package/dist/{TableHeaderCell-BXgnxPpX.d.mts → TableHeaderCell-wKcp8rZj.d.mts} +1 -1
  229. package/dist/TableHeaderCell.d.mts +1 -1
  230. package/dist/{TableLayout-Dy5ht8KO.d.mts → TableLayout-0-9FnNvt.d.mts} +1 -1
  231. package/dist/TableLayout.d.mts +1 -1
  232. package/dist/{TableRow-C1iGbNjZ.d.mts → TableRow-C011thJ3.d.mts} +2 -2
  233. package/dist/TableRow.d.mts +1 -1
  234. package/dist/TableTH.d.mts +1 -1
  235. package/dist/{TableViewConfigurationDropdown-vYnU0d4k.d.mts → TableViewConfigurationDropdown-D0VcRmd4.d.mts} +2 -2
  236. package/dist/TableViewConfigurationDropdown.d.mts +1 -1
  237. package/dist/TechnicalSticker-B_JlBkXZ.mjs.map +1 -1
  238. package/dist/{Text-SaoRBdB6.d.mts → Text-BgSW0yDb.d.mts} +3 -3
  239. package/dist/Text-D0vEReED.mjs.map +1 -1
  240. package/dist/Text.d.mts +1 -1
  241. package/dist/{TextArea-gtSlghjy.d.mts → TextArea-CyWv8jaV.d.mts} +2 -2
  242. package/dist/TextArea-Dro-HH8O.mjs.map +1 -1
  243. package/dist/TextArea.d.mts +1 -1
  244. package/dist/{TextUnderlineTooltip-DV61avLv.d.mts → TextUnderlineTooltip-CcyG4VkJ.d.mts} +2 -2
  245. package/dist/TextUnderlineTooltip.d.mts +1 -1
  246. package/dist/Tile.d.mts +1 -1
  247. package/dist/Toast.d.mts +1 -1
  248. package/dist/{Toggle-BlvrM-Cw.d.mts → Toggle-BIJoB1AA.d.mts} +1 -1
  249. package/dist/Toggle-D9MzTIZs.mjs.map +1 -1
  250. package/dist/Toggle.d.mts +1 -1
  251. package/dist/{Tooltip-CysnLwST.d.mts → Tooltip-CrpfAAfA.d.mts} +2 -2
  252. package/dist/Tooltip-YViXzMdm.mjs.map +1 -1
  253. package/dist/Tooltip.d.mts +1 -1
  254. package/dist/{TruncatedText-YcjNG-zP.d.mts → TruncatedText-DaGx3CX6.d.mts} +1 -1
  255. package/dist/VersionHistory.d.mts +1 -1
  256. package/dist/{VersionHistoryItem-Px3ylMMq.d.mts → VersionHistoryItem-Bo78T7y7.d.mts} +1 -1
  257. package/dist/VersionHistoryItem.d.mts +1 -1
  258. package/dist/WizardModal.d.mts +2 -2
  259. package/dist/{accordionTitleTypography-Dlo2YyWd.d.mts → accordionTitleTypography-D7tOgRzj.d.mts} +2 -2
  260. package/dist/accordionTitleTypography.d.mts +1 -1
  261. package/dist/{chainTypes-aF5rWav-.d.mts → chainTypes-CLKwXymd.d.mts} +4 -4
  262. package/dist/{clientFilterUtils-DYKgw2Yq.d.mts → clientFilterUtils-BnASP9Tt.d.mts} +2 -2
  263. package/dist/clientFilterUtils.d.mts +1 -1
  264. package/dist/{codec-D8ZKFLgs.d.mts → codec-C4WJftW6.d.mts} +2 -2
  265. package/dist/codec.d.mts +1 -1
  266. package/dist/{color-Cy_0z4IY.d.mts → color-Db57Wms_.d.mts} +2 -2
  267. package/dist/complete-typography.d.mts +1 -1
  268. package/dist/components/Accordion/index.d.mts +1 -1
  269. package/dist/components/Accordion/index.mjs.map +1 -1
  270. package/dist/components/Attribute/index.mjs.map +1 -1
  271. package/dist/components/Banner/index.mjs.map +1 -1
  272. package/dist/components/BottomPanel/index.mjs +67 -6
  273. package/dist/components/BottomPanel/index.mjs.map +1 -1
  274. package/dist/components/Breadcrumbs/index.d.mts +1 -1
  275. package/dist/components/Button/index.d.mts +2 -2
  276. package/dist/components/ButtonGroup/index.mjs.map +1 -1
  277. package/dist/components/Card/index.d.mts +2 -2
  278. package/dist/components/CardV2/index.d.mts +1 -1
  279. package/dist/components/Checkbox/index.d.mts +1 -1
  280. package/dist/components/CodeHighlight/index.mjs.map +1 -1
  281. package/dist/components/Combobox/index.d.mts +2 -2
  282. package/dist/components/DataTable/TableControls/index.d.mts +21 -21
  283. package/dist/components/DataTable/TableControls/index.mjs +1 -1
  284. package/dist/components/DataTable/index.d.mts +8 -8
  285. package/dist/components/DataTable/index.mjs +1 -1
  286. package/dist/components/DataTable/types.d.mts +1 -1
  287. package/dist/components/DatePicker/index.d.mts +5 -5
  288. package/dist/components/DatePicker/index.mjs +1 -1
  289. package/dist/components/DropdownMenu/index.d.mts +1 -1
  290. package/dist/components/FloatingPanel/index.mjs.map +1 -1
  291. package/dist/components/FloatingToolbar/index.d.mts +2 -0
  292. package/dist/components/FloatingToolbar/index.mjs +2 -0
  293. package/dist/components/FormControl/index.d.mts +2 -2
  294. package/dist/components/FormField/index.d.mts +5 -5
  295. package/dist/components/FormField/index.mjs +1 -1
  296. package/dist/components/Grid/index.mjs +1 -1
  297. package/dist/components/ImageTile/index.mjs.map +1 -1
  298. package/dist/components/Input/index.d.mts +1 -1
  299. package/dist/components/ListBox/index.d.mts +3 -3
  300. package/dist/components/MaskedInput/index.mjs.map +1 -1
  301. package/dist/components/MatchHighlight/index.mjs.map +1 -1
  302. package/dist/components/Menu/index.d.mts +1 -1
  303. package/dist/components/Modal/index.d.mts +1 -1
  304. package/dist/components/Modal/index.mjs +1 -1
  305. package/dist/components/PageHeader/index.d.mts +1 -1
  306. package/dist/components/PageHeader/index.mjs +1 -1
  307. package/dist/components/Pagination/index.d.mts +3 -3
  308. package/dist/components/Pagination/index.mjs +1 -1
  309. package/dist/components/ProgressBar/index.mjs.map +1 -1
  310. package/dist/components/ProgressIndicator/index.d.mts +1 -1
  311. package/dist/components/ProgressIndicator/index.mjs +1 -1
  312. package/dist/components/RadioGroup/index.d.mts +1 -1
  313. package/dist/components/RichTextEditor/index.d.mts +1 -2
  314. package/dist/components/RichTextEditor/index.mjs +22 -477
  315. package/dist/components/RichTextEditor/index.mjs.map +1 -1
  316. package/dist/components/RightPanel/index.mjs.map +1 -1
  317. package/dist/components/SegmentedControl/index.d.mts +1 -1
  318. package/dist/components/Select/index.d.mts +1 -1
  319. package/dist/components/SelectionCard/index.mjs.map +1 -1
  320. package/dist/components/Slider/index.mjs.map +1 -1
  321. package/dist/components/SmartTextInput/index.d.mts +2 -2
  322. package/dist/components/SmartTextInput/index.mjs +2 -2
  323. package/dist/components/SmartTextInput/index.mjs.map +1 -1
  324. package/dist/components/SmartTextInput/parser/method-chain/types.d.mts +1 -1
  325. package/dist/components/SmartTextInput/parser/smart-text/types.d.mts +2 -2
  326. package/dist/components/Stack/index.d.mts +1 -1
  327. package/dist/components/StatusIndicator/index.mjs +1 -1
  328. package/dist/components/Sticker/index.d.mts +1 -1
  329. package/dist/components/SwatchPicker/index.mjs.map +1 -1
  330. package/dist/components/Table/index.d.mts +8 -8
  331. package/dist/components/TableBox/index.d.mts +2 -2
  332. package/dist/components/Text/index.d.mts +1 -1
  333. package/dist/components/TextArea/index.d.mts +1 -1
  334. package/dist/components/Tile/index.mjs.map +1 -1
  335. package/dist/components/Toast/index.mjs.map +1 -1
  336. package/dist/components/Toggle/index.d.mts +1 -1
  337. package/dist/components/Tooltip/index.d.mts +3 -3
  338. package/dist/components/VersionHistory/index.d.mts +1 -1
  339. package/dist/components/VersionHistory/index.mjs +2 -2
  340. package/dist/components/VersionHistory/index.mjs.map +1 -1
  341. package/dist/compound-expression.d.mts +1 -1
  342. package/dist/{constants-CW1DRgwi.d.mts → constants-B2NIZBD6.d.mts} +1 -1
  343. package/dist/{constants-D1hoZ5LO.d.mts → constants-ChVceduh.d.mts} +1 -1
  344. package/dist/constants.d.mts +1 -1
  345. package/dist/constants2.d.mts +1 -1
  346. package/dist/{createPath-C4ZFkt93.d.mts → createPath-D_opTH9A.d.mts} +2 -2
  347. package/dist/createPath.d.mts +1 -1
  348. package/dist/{date-range-rule-value-CrVBpQcf.d.mts → date-range-rule-value-3izEoXmi.d.mts} +2 -2
  349. package/dist/date-range-rule-value.d.mts +1 -1
  350. package/dist/{date-rule-intent-C1aptAoX.d.mts → date-rule-intent-DjYIGcGO.d.mts} +3 -3
  351. package/dist/date-rule-intent.d.mts +1 -1
  352. package/dist/display.d.mts +2 -2
  353. package/dist/fieldPickerOptions.d.mts +2 -2
  354. package/dist/{filter-size-context-CbT4pi3S.d.mts → filter-size-context-BcpjykVw.d.mts} +2 -2
  355. package/dist/filter-size-context.d.mts +1 -1
  356. package/dist/{filters-DjXkx8GJ.d.mts → filters-DUI7TLSn.d.mts} +2 -2
  357. package/dist/filters.d.mts +1 -1
  358. package/dist/{formatDateTime-BikGGrvq.d.mts → formatDateTime-CgQvW3A5.d.mts} +1 -1
  359. package/dist/formatDateTime.d.mts +1 -1
  360. package/dist/{helpers-CdxEL7ri.d.mts → helpers-CDZ7Zk9G.d.mts} +4 -4
  361. package/dist/helpers.d.mts +1 -1
  362. package/dist/{i18n-BLyCaSdJ.mjs → i18n-DaOKaFc2.mjs} +4 -2
  363. package/dist/i18n-DaOKaFc2.mjs.map +1 -0
  364. package/dist/{index-BWAycP6L.d.mts → index-B9kfFACl.d.mts} +1 -1
  365. package/dist/{index-DX5Zu9JU.d.mts → index-CDFw-zKW.d.mts} +3 -3
  366. package/dist/{index-D2YFHdsf.d.mts → index-DntqThoS.d.mts} +2 -2
  367. package/dist/{index-FgIOTuJ4.d.mts → index-_D_TMpPU.d.mts} +2 -2
  368. package/dist/index2.d.mts +1 -1
  369. package/dist/index3.d.mts +1 -1
  370. package/dist/index4.d.mts +3 -3
  371. package/dist/index5.d.mts +1 -1
  372. package/dist/index6.d.mts +14 -14
  373. package/dist/{input-gtTnb9M8.d.mts → input-RTMLTvG1.d.mts} +3 -3
  374. package/dist/{inputFields-CYttsz5M.d.mts → inputFields-iRg_emVK.d.mts} +11 -11
  375. package/dist/inputFields.d.mts +1 -1
  376. package/dist/{jsonSchema-DUkfAip_.d.mts → jsonSchema-BJpNaFc4.d.mts} +1 -1
  377. package/dist/lib/PDSProvider.d.mts +3 -3
  378. package/dist/lib/PDSProvider.mjs +1 -1
  379. package/dist/lib/PDSProvider.mjs.map +1 -1
  380. package/dist/lib/TruncatedText.d.mts +1 -1
  381. package/dist/lib/TruncatedText.mjs.map +1 -1
  382. package/dist/lib/TruncatedTextWithTooltip.d.mts +1 -1
  383. package/dist/lib/TruncatedTextWithTooltip.mjs.map +1 -1
  384. package/dist/lib/chainTypes.d.mts +1 -1
  385. package/dist/lib/color.d.mts +1 -1
  386. package/dist/lib/color.mjs.map +1 -1
  387. package/dist/lib/colorMode.d.mts +2 -2
  388. package/dist/lib/colorMode.mjs.map +1 -1
  389. package/dist/lib/customFunctionSchema.d.mts +1 -1
  390. package/dist/lib/date-filter/index.d.mts +2 -2
  391. package/dist/lib/i18n/index.d.mts +3 -3
  392. package/dist/lib/i18n/index.mjs +1 -1
  393. package/dist/lib/jsonSchema.d.mts +1 -1
  394. package/dist/lib/jsonSchemaType.d.mts +1 -1
  395. package/dist/lib/message.d.mts +1 -1
  396. package/dist/lib/methodChain.d.mts +2 -2
  397. package/dist/lib/methodChainNormalize.d.mts +2 -2
  398. package/dist/lib/methodChainTypes.d.mts +1 -1
  399. package/dist/lib/objectSchemaTypes.d.mts +1 -1
  400. package/dist/lib/platformObject.d.mts +1 -1
  401. package/dist/lib/pseudoClass.d.mts +1 -1
  402. package/dist/lib/pseudoClass.mjs.map +1 -1
  403. package/dist/lib/router/adapters/reactRouter.d.mts +1 -1
  404. package/dist/lib/router/adapters/tanstack.d.mts +1 -1
  405. package/dist/lib/router/index.d.mts +5 -5
  406. package/dist/lib/schemaOptions.d.mts +1 -1
  407. package/dist/lib/semanticColor.d.mts +1 -1
  408. package/dist/lib/semanticColor.mjs.map +1 -1
  409. package/dist/lib/useChain.d.mts +1 -1
  410. package/dist/lib/useEmbeddedSurface.mjs.map +1 -1
  411. package/dist/lint/index.d.mts +1 -1
  412. package/dist/{listbox-options-CkwENvff.d.mts → listbox-options-D0JmYWjB.d.mts} +3 -3
  413. package/dist/listbox-options.d.mts +1 -1
  414. package/dist/{message-klSuXfNN.d.mts → message-Bk5UTw75.d.mts} +1 -1
  415. package/dist/{methodChain-CRYRDa1k.d.mts → methodChain-C3u60_V8.d.mts} +4 -4
  416. package/dist/{methodChainTypes-BtbYWrdP.d.mts → methodChainTypes-Di4GCMX7.d.mts} +2 -2
  417. package/dist/min-copy-size.d.mts +1 -1
  418. package/dist/mixins/focus.d.mts +1 -1
  419. package/dist/mixins/focus.mjs.map +1 -1
  420. package/dist/mixins/hoverable.d.mts +2 -2
  421. package/dist/mixins/hoverable.mjs.map +1 -1
  422. package/dist/mixins/input.d.mts +1 -1
  423. package/dist/mixins/input.mjs.map +1 -1
  424. package/dist/mixins/menuItem.d.mts +2 -2
  425. package/dist/mixins/menuItem.mjs.map +1 -1
  426. package/dist/mixins/print/index.mjs.map +1 -1
  427. package/dist/mixins/scrollbar.d.mts +1 -1
  428. package/dist/mixins/scrollbar.mjs.map +1 -1
  429. package/dist/mixins/text.d.mts +1 -1
  430. package/dist/no-raw-table.d.mts +1 -1
  431. package/dist/{operators-gCG7uZ6y.d.mts → operators-BTCnQpeu.d.mts} +3 -3
  432. package/dist/operators.d.mts +1 -1
  433. package/dist/{palette-C1gBbxLO.d.mts → palette-D61sDyDI.d.mts} +3 -3
  434. package/dist/palette.d.mts +1 -1
  435. package/dist/patterns/CardGrouping/index.mjs +1 -1
  436. package/dist/patterns/CardGrouping/index.mjs.map +1 -1
  437. package/dist/patterns/IndexTableLayout/index.mjs +3 -3
  438. package/dist/patterns/IndexTableLayout/index.mjs.map +1 -1
  439. package/dist/patterns/LayoutLoadingShimmer/index.mjs +1 -1
  440. package/dist/patterns/LayoutLoadingShimmer/index.mjs.map +1 -1
  441. package/dist/patterns/LayoutLoadingSpinner/index.mjs.map +1 -1
  442. package/dist/patterns/PageLayout/index.d.mts +4 -4
  443. package/dist/patterns/PageLayout/index.mjs +1 -1
  444. package/dist/patterns/WizardModal/index.mjs +2 -2
  445. package/dist/patterns/WizardModal/index.mjs.map +1 -1
  446. package/dist/reactRouterFallback.d.mts +1 -1
  447. package/dist/reduced-motion.d.mts +1 -1
  448. package/dist/relative-date-label.d.mts +1 -1
  449. package/dist/safe-parse.d.mts +1 -1
  450. package/dist/{schemaOptions-C_JM2-sg.d.mts → schemaOptions-BKtrXvjR.d.mts} +3 -3
  451. package/dist/{semantic-BLaQSW1r.d.mts → semantic-BZbvb3LV.d.mts} +1 -1
  452. package/dist/semantic-color.d.mts +1 -1
  453. package/dist/{semanticColor-Bxufk3ZO.d.mts → semanticColor-y9byerSl.d.mts} +3 -3
  454. package/dist/shared.d.mts +1 -1
  455. package/dist/{strings-CK9n6b65.d.mts → strings-T-gsdqiJ.d.mts} +8 -1
  456. package/dist/strings.d.mts +1 -1
  457. package/dist/{text-Csytfclh.d.mts → text-CKLxMlG4.d.mts} +1 -1
  458. package/dist/{theme-mQ4WkH90.d.mts → theme-BFP-_PEh.d.mts} +3 -3
  459. package/dist/theme.d.mts +1 -1
  460. package/dist/theme.mjs.map +1 -1
  461. package/dist/tone.d.mts +3 -3
  462. package/dist/tree.d.mts +1 -1
  463. package/dist/{types-B4KbdEDc.d.mts → types-1p-ij0cd.d.mts} +2 -2
  464. package/dist/{types-Dhz6VMKx.d.mts → types-B5RbKp2V.d.mts} +1 -1
  465. package/dist/{types-dmItSshr.d.mts → types-Bg_sfqXE.d.mts} +2 -2
  466. package/dist/{types-CayYd8EX.d.mts → types-BiRayNak.d.mts} +3 -3
  467. package/dist/{types-XjJqUj-p.d.mts → types-BnXYfNrd.d.mts} +4 -4
  468. package/dist/{types-C2RhHxbE.d.mts → types-Bu5rhBdH.d.mts} +1 -1
  469. package/dist/{types-DJobO07d.d.mts → types-C31ecr0j.d.mts} +3 -3
  470. package/dist/{types-rDQg74j-.d.mts → types-FG-jOit9.d.mts} +1 -1
  471. package/dist/{types-DbOD5vE_.d.mts → types-K57NVM0M.d.mts} +2 -2
  472. package/dist/{types-6L0ptM6-.d.mts → types-QYT1VZgy.d.mts} +1 -1
  473. package/dist/types.d.mts +1 -1
  474. package/dist/types2.d.mts +1 -1
  475. package/dist/types3.d.mts +1 -1
  476. package/dist/types4.d.mts +1 -1
  477. package/dist/types5.d.mts +1 -1
  478. package/dist/types6.d.mts +1 -1
  479. package/dist/types8.d.mts +1 -1
  480. package/dist/{url-state-CmgyDnG7.d.mts → url-state-DmhG0Qg-.d.mts} +2 -2
  481. package/dist/url-state.d.mts +1 -1
  482. package/dist/{useChain-7ztbfujM.d.mts → useChain-CIwI4Xop.d.mts} +6 -6
  483. package/dist/useChain-D1aNsdvn.mjs.map +1 -1
  484. package/dist/useChainAtCursor.d.mts +6 -6
  485. package/dist/useCodeChainFunctionPanel.d.mts +1 -1
  486. package/dist/useColumnConfiguration.d.mts +2 -2
  487. package/dist/useComboboxFooterAction.d.mts +1 -1
  488. package/dist/{useFilterStateV2-CPBt0qwc.d.mts → useFilterStateV2-DPzkJpGT.d.mts} +3 -3
  489. package/dist/useFilterStateV2.d.mts +1 -1
  490. package/dist/{useFormField-CmEJCqse.d.mts → useFormField-ATKyX8CU.d.mts} +2 -2
  491. package/dist/useFormField-pOVkb5BK.mjs.map +1 -1
  492. package/dist/useFormField.d.mts +1 -1
  493. package/dist/{useLocationPathname-Cnqj8pf4.d.mts → useLocationPathname-DPMpqO1_.d.mts} +1 -1
  494. package/dist/useLocationPathname.d.mts +1 -1
  495. package/dist/{useTableBoxDragAndDrop-8NS4JBuI.d.mts → useTableBoxDragAndDrop-CCMADt-F.d.mts} +1 -1
  496. package/dist/useTableBoxDragAndDrop.d.mts +1 -1
  497. package/dist/{useTableColumns-BK-KYY0L.d.mts → useTableColumns-Bw0HvnP4.d.mts} +2 -2
  498. package/dist/useTableColumns.d.mts +1 -1
  499. package/dist/useTruncation.d.mts +1 -1
  500. package/dist/{utilities-CXoc5Cyr.d.mts → utilities-BfXjJZQt.d.mts} +1 -1
  501. package/dist/utilities.d.mts +1 -1
  502. package/dist/utils/storybook.mjs.map +1 -1
  503. package/dist/utils/testing.d.mts +1 -1
  504. package/dist/utils.d.mts +1 -1
  505. package/dist/utils4.d.mts +5 -5
  506. package/dist/{validation-BaqPVG1C.d.mts → validation-yhA0siru.d.mts} +3 -3
  507. package/dist/validation.d.mts +1 -1
  508. package/dist/validation2.d.mts +4 -4
  509. package/dist/{value-control-resolver-CMyFwEY7.d.mts → value-control-resolver-Df0AmGFe.d.mts} +2 -2
  510. package/dist/value-control-resolver.d.mts +1 -1
  511. package/dist/variables/effect.d.mts +1 -1
  512. package/dist/variables/effect.mjs.map +1 -1
  513. package/dist/variables/semantic.d.mts +1 -1
  514. package/llms.txt +1 -1
  515. package/package.json +25 -13
  516. package/skills/ui-authoring/COMPONENTS.md +1 -0
  517. package/dist/DataTable-DEJHWrsy.mjs.map +0 -1
  518. package/dist/DatePicker-D-_ibUd1.mjs.map +0 -1
  519. package/dist/FormField-g1zQFM9T.mjs.map +0 -1
  520. package/dist/Modal-92O_uW8H.mjs.map +0 -1
  521. package/dist/PageHeader-BzvA_NNt.mjs.map +0 -1
  522. package/dist/PageLayout-DCe3F76N.mjs.map +0 -1
  523. package/dist/Pagination-dTsHLVAk.mjs.map +0 -1
  524. package/dist/ProgressIndicator-ISARECzW.mjs.map +0 -1
  525. package/dist/StatusIndicator-pWl1-FLb.mjs.map +0 -1
  526. package/dist/TableControls-BDXOQMr7.mjs.map +0 -1
  527. package/dist/i18n-BLyCaSdJ.mjs.map +0 -1
  528. /package/dist/{index-AnhM47-e2.d.mts → index-BAJc0Rej.d.mts} +0 -0
  529. /package/dist/{index-B33elXxm.d.mts → index-BFHp82YL.d.mts} +0 -0
  530. /package/dist/{index-B4woaFSm.d.mts → index-BYd3Btr1.d.mts} +0 -0
  531. /package/dist/{index-B6T7ov8p.d.mts → index-C6HcjJiY.d.mts} +0 -0
  532. /package/dist/{index-BNRXMhlr.d.mts → index-CEUVsenl.d.mts} +0 -0
  533. /package/dist/{index-BPiqSRRl.d.mts → index-CEqOS-7M.d.mts} +0 -0
  534. /package/dist/{index-BTviwbFV.d.mts → index-CNxS4Tlu.d.mts} +0 -0
  535. /package/dist/{index-Bo9LXG4r.d.mts → index-CP2eJYlK.d.mts} +0 -0
  536. /package/dist/{index-Bq9Ub6MB.d.mts → index-CQQezDJQ2.d.mts} +0 -0
  537. /package/dist/{index-BrGZHEgX.d.mts → index-CWB6exYm.d.mts} +0 -0
  538. /package/dist/{index-Bt4QNofW.d.mts → index-CcSfkYLp2.d.mts} +0 -0
  539. /package/dist/{index-CFuHCx9T.d.mts → index-Cm-1i165.d.mts} +0 -0
  540. /package/dist/{index-CLTQPxoD.d.mts → index-D-giXKyu.d.mts} +0 -0
  541. /package/dist/{index-CaqYCRmZ.d.mts → index-D4DUvwPf.d.mts} +0 -0
  542. /package/dist/{index-CjmAoxrR2.d.mts → index-DCTy4zg0.d.mts} +0 -0
  543. /package/dist/{index-Cx0vQ6ld.d.mts → index-DWIh4oP5.d.mts} +0 -0
  544. /package/dist/{index-CzItj62a.d.mts → index-Dflz2i1X.d.mts} +0 -0
  545. /package/dist/{index-CzUpNo0e.d.mts → index-DhiymMxa.d.mts} +0 -0
  546. /package/dist/{index-DBGd4WeR.d.mts → index-DkrC-i1D.d.mts} +0 -0
  547. /package/dist/{index-DMRtRo7y.d.mts → index-Dp7lwkTl2.d.mts} +0 -0
  548. /package/dist/{index-DNjQe1D8.d.mts → index-DqCA6utX.d.mts} +0 -0
  549. /package/dist/{index-DW3xeuzq.d.mts → index-Iujpc9_6.d.mts} +0 -0
  550. /package/dist/{index-DZlqSwCF.d.mts → index-Jh0C5PIG.d.mts} +0 -0
  551. /package/dist/{index-De7MV8-j.d.mts → index-N-OgGgfF.d.mts} +0 -0
  552. /package/dist/{index-DjG1RCY5.d.mts → index-Oio5ygqN.d.mts} +0 -0
  553. /package/dist/{index-Dlcv6Ku22.d.mts → index-Rvd9MEUQ.d.mts} +0 -0
  554. /package/dist/{index-DrK1_jKY.d.mts → index-YB8V3VRW.d.mts} +0 -0
  555. /package/dist/{index-DztUdPP_.d.mts → index-aKlsLnwy.d.mts} +0 -0
  556. /package/dist/{index-K614ZhWK.d.mts → index-fxXoW-qc.d.mts} +0 -0
  557. /package/dist/{index-NKYLt_R9.d.mts → index-ikHBE458.d.mts} +0 -0
  558. /package/dist/{index-VWno75SQ.d.mts → index-luywJTzJ.d.mts} +0 -0
  559. /package/dist/{index-uMNhmxEh.d.mts → index-xmouCHX9.d.mts} +0 -0
package/dist/codec.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as selectedPresetFor, i as resolveDateFilterValue, n as isRelative, r as parseDateFilterValue, t as formatDateFilterValue } from "./codec-D8ZKFLgs.mjs";
1
+ import { a as selectedPresetFor, i as resolveDateFilterValue, n as isRelative, r as parseDateFilterValue, t as formatDateFilterValue } from "./codec-C4WJftW6.mjs";
2
2
  export { formatDateFilterValue, isRelative, parseDateFilterValue, resolveDateFilterValue, selectedPresetFor };
@@ -1,4 +1,4 @@
1
- import { t as CssPercentage } from "./semantic-BLaQSW1r.mjs";
1
+ import { t as CssPercentage } from "./semantic-BZbvb3LV.mjs";
2
2
  import { Color } from "@persona/design-tokens";
3
3
 
4
4
  //#region src/lib/color.d.ts
@@ -22,4 +22,4 @@ declare const withAlpha: (color: Color, amount: CssPercentage) => CssColor;
22
22
  declare const opaqueOver: (overlay: Color, amount: CssPercentage, base: Color) => CssColor;
23
23
  //#endregion
24
24
  export { transparent as a, opaqueOver as i, PdsColor as n, withAlpha as o, opacityOf as r, CssColor as t };
25
- //# sourceMappingURL=color-Cy_0z4IY.d.mts.map
25
+ //# sourceMappingURL=color-Db57Wms_.d.mts.map
@@ -1,4 +1,4 @@
1
- import { r as Rule } from "./index-BWAycP6L.mjs";
1
+ import { r as Rule } from "./index-B9kfFACl.mjs";
2
2
 
3
3
  //#region src/lint/rules/complete-typography.d.ts
4
4
  declare const completeTypography: Rule;
@@ -1,4 +1,4 @@
1
- import { n as AccordionTitleTypography, t as AccordionSize } from "../../accordionTitleTypography-Dlo2YyWd.mjs";
1
+ import { n as AccordionTitleTypography, t as AccordionSize } from "../../accordionTitleTypography-D7tOgRzj.mjs";
2
2
  import { AccordionTitleHeadingAs } from "../../AccordionItem.mjs";
3
3
  import { Accordion, AccordionItemProps, AccordionProps } from "../../Accordion.mjs";
4
4
  export { Accordion, Accordion as default, type AccordionItemProps, type AccordionProps, type AccordionSize, type AccordionTitleHeadingAs, type AccordionTitleTypography };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Heading"],"sources":["../../../src/components/Accordion/scrollExpandedItemIntoView.ts","../../../src/components/Accordion/AccordionItem.tsx","../../../src/components/Accordion/accordionTitleTypography.ts","../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import { TransitionDurationInSeconds } from 'design-system/variables/transitions';\n\nexport type ScrollExpandedItemTarget = {\n itemElement: HTMLElement;\n triggerElement: HTMLElement;\n};\n\nconst SCROLL_ALIGN_THRESHOLD_PX = 4;\n\nconst prefersReducedMotion = () =>\n typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\nconst getScrollBehavior = (): ScrollBehavior => (prefersReducedMotion() ? 'auto' : 'smooth');\n\nconst isScrollableOverflow = (overflowY: string) =>\n overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay';\n\nexport const findScrollContainer = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n\n while (parent) {\n const { overflowY } = getComputedStyle(parent);\n if (isScrollableOverflow(overflowY) && parent.scrollHeight > parent.clientHeight) {\n return parent;\n }\n parent = parent.parentElement;\n }\n\n return null;\n};\n\nconst getContainerRect = (container: HTMLElement | null) => {\n if (container) {\n return container.getBoundingClientRect();\n }\n\n return {\n top: 0,\n bottom: window.innerHeight,\n } as Pick<DOMRect, 'top' | 'bottom'>;\n};\n\nconst scrollBy = (container: HTMLElement | null, deltaY: number) => {\n if (Math.abs(deltaY) <= SCROLL_ALIGN_THRESHOLD_PX) {\n return;\n }\n\n const behavior = getScrollBehavior();\n\n if (container) {\n container.scrollTo({ top: container.scrollTop + deltaY, behavior });\n return;\n }\n\n window.scrollBy({ top: deltaY, behavior });\n};\n\nexport const scrollExpandedItemIntoView = (target: ScrollExpandedItemTarget | null) => {\n if (!target) {\n return;\n }\n\n const { itemElement, triggerElement } = target;\n const container = findScrollContainer(itemElement);\n const containerRect = getContainerRect(container);\n const itemRect = itemElement.getBoundingClientRect();\n const triggerRect = triggerElement.getBoundingClientRect();\n const overflowBottom = itemRect.bottom - containerRect.bottom;\n\n if (overflowBottom > SCROLL_ALIGN_THRESHOLD_PX) {\n const maxScrollWithoutHidingTrigger = Math.max(0, triggerRect.top - containerRect.top);\n const deltaY = Math.min(overflowBottom, maxScrollWithoutHidingTrigger);\n scrollBy(container, deltaY);\n }\n};\n\nexport const scrollExpandedItemIntoViewAfterExpand = (target: ScrollExpandedItemTarget | null) => {\n scrollExpandedItemIntoView(target);\n\n if (!target) {\n return undefined;\n }\n\n const cleanups: Array<() => void> = [];\n const resyncScroll = () => scrollExpandedItemIntoView(target);\n\n const timeoutId = window.setTimeout(resyncScroll, TransitionDurationInSeconds.Fast * 1000);\n cleanups.push(() => window.clearTimeout(timeoutId));\n\n const panel = target.itemElement.querySelector<HTMLElement>('[data-accordion-panel]');\n if (panel) {\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== panel || event.propertyName !== 'height') {\n return;\n }\n\n resyncScroll();\n };\n\n panel.addEventListener('transitionend', onTransitionEnd);\n cleanups.push(() => panel.removeEventListener('transitionend', onTransitionEnd));\n }\n\n const rafId = window.requestAnimationFrame(() => {\n const innerRafId = window.requestAnimationFrame(resyncScroll);\n cleanups.push(() => window.cancelAnimationFrame(innerRafId));\n });\n cleanups.push(() => window.cancelAnimationFrame(rafId));\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n};\n\nexport const resolveAccordionTriggerElement = (itemElement: HTMLElement | null) => {\n if (!itemElement) {\n return null;\n }\n\n return (\n itemElement.querySelector<HTMLElement>('[slot=\"trigger\"]') ??\n itemElement.querySelector<HTMLElement>('button')\n );\n};\n","import type { ReactNode, RefObject } from 'react';\nimport { useLayoutEffect, useRef } from 'react';\nimport { Disclosure, DisclosurePanel } from 'react-aria-components';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { ChevronDownIcon, ChevronRightIcon } from '@persona/icons/12px';\nimport { HStack } from 'design-system/components/Stack';\nimport { Heading, Paragraph } from 'design-system/components/Text';\nimport { HeadlessAriaButton } from 'design-system/lib/HeadlessAriaButton';\nimport { isFocusedVisible, isNotDisabled } from 'design-system/lib/pseudoClass';\nimport { semanticColor } from 'design-system/lib/semanticColor';\nimport { TruncatedText } from 'design-system/lib/TruncatedText';\nimport { focusOutlineControlled } from 'design-system/mixins/focus';\nimport { TransitionDuration } from 'design-system/variables/transitions';\n\nimport type { AccordionSize, AccordionTitleTypography } from './accordionTitleTypography';\nimport {\n scrollExpandedItemIntoViewAfterExpand,\n resolveAccordionTriggerElement,\n} from './scrollExpandedItemIntoView';\n\nexport type AccordionTitleHeadingAs = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\nexport type { AccordionSize, AccordionTitleTypography };\n\nconst SIZE_HEIGHT: Record<AccordionSize, string> = {\n sm: Spacing[5],\n md: Spacing[6],\n lg: Spacing[7],\n};\n\nconst ItemContainer = styled(Disclosure)<{ $showDivider: boolean }>`\n display: flex;\n flex-direction: column;\n position: relative;\n\n &:focus-within {\n z-index: 1;\n }\n\n ${({ $showDivider }) =>\n $showDivider &&\n css`\n border-top: 1px solid\n ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n `}\n`;\n\nconst ChevronContainer = styled.span`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n width: ${Spacing[3]};\n height: ${Spacing[3]};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.BorderIconSecondary)};\n transition: color ${TransitionDuration.Fast} ease;\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\nconst TriggerButton = styled(HeadlessAriaButton)<{\n $size: AccordionSize;\n $usesTitleTypographyOverride: boolean;\n}>`\n width: 100%;\n min-height: ${({ $size }) => SIZE_HEIGHT[$size]};\n height: ${({ $size, $usesTitleTypographyOverride }) =>\n $usesTitleTypographyOverride ? 'auto' : SIZE_HEIGHT[$size]};\n display: flex;\n align-items: center;\n text-align: left;\n border-radius: 0;\n background-color: transparent;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n transition: background-color ${TransitionDuration.Fast} ease-in-out;\n ${focusOutlineControlled}\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n\n &${isFocusedVisible}${isNotDisabled} {\n position: relative;\n z-index: 1;\n }\n\n &:disabled {\n cursor: default;\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n background-color: transparent;\n\n ${ChevronContainer} {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', Color.BorderIconDisabled)};\n }\n }\n\n &:hover:not(:disabled) {\n background-color: ${({ theme }) =>\n semanticColor(theme, 'SurfaceHover', Color.BackgroundInteractiveHover)};\n }\n\n &:not(:disabled):hover ${ChevronContainer},\n &${isFocusedVisible}${isNotDisabled} ${ChevronContainer} {\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.BorderIconPrimary)};\n }\n`;\n\nconst CollapseTitle = styled(HStack)`\n width: 100%;\n min-width: 0;\n`;\n\nconst TitleWrapper = styled.span`\n display: flex;\n align-items: center;\n min-width: 0;\n`;\n\nconst Panel = styled(DisclosurePanel)`\n height: var(--disclosure-panel-height);\n overflow: clip;\n transition: height ${TransitionDuration.Fast} ease-out;\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\nconst TitleHeading = styled(Heading)`\n margin: 0;\n width: 100%;\n min-width: 0;\n font: inherit;\n font-size: inherit;\n line-height: inherit;\n font-weight: inherit;\n letter-spacing: inherit;\n`;\n\nconst PanelContent = styled.div`\n padding: ${Spacing[3]} ${Spacing[4]};\n`;\n\nconst TitleText = styled.span`\n min-width: 0;\n flex: 1;\n`;\n\nexport type AccordionItemComponentProps = {\n title: string;\n children: ReactNode;\n defaultExpanded?: boolean;\n disabled?: boolean;\n showDivider?: boolean;\n size: AccordionSize;\n titleTypography: AccordionTitleTypography;\n usesTitleTypographyOverride: boolean;\n titleHeadingAs: AccordionTitleHeadingAs;\n};\n\nconst renderTitleLabel = (\n title: string,\n titleTypography: AccordionTitleTypography,\n disabled: boolean,\n) => {\n const content = <TruncatedText>{title}</TruncatedText>;\n const textColor = disabled ? 'disabled' : 'primary';\n\n if (titleTypography.variant === 'heading') {\n return (\n <TitleText>\n <TitleWrapper>\n <Heading as='span' color={textColor} size={titleTypography.size}>\n {content}\n </Heading>\n </TitleWrapper>\n </TitleText>\n );\n }\n\n return (\n <TitleText>\n <TitleWrapper>\n <Paragraph\n as='span'\n color={textColor}\n size={titleTypography.size}\n weight={titleTypography.weight ?? 'normal'}\n >\n {content}\n </Paragraph>\n </TitleWrapper>\n </TitleText>\n );\n};\n\nconst renderChevron = (isExpanded: boolean) =>\n isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />;\n\nconst ExpandScrollSync = ({\n disabled,\n isExpanded,\n itemRef,\n}: {\n disabled: boolean;\n isExpanded: boolean;\n itemRef: RefObject<HTMLElement | null>;\n}) => {\n const wasExpandedRef = useRef(isExpanded);\n\n useLayoutEffect(() => {\n if (disabled) {\n wasExpandedRef.current = isExpanded;\n return undefined;\n }\n\n const didExpand = isExpanded && !wasExpandedRef.current;\n wasExpandedRef.current = isExpanded;\n\n const itemElement = itemRef.current;\n const triggerElement = resolveAccordionTriggerElement(itemElement);\n\n if (!didExpand || !itemElement || !triggerElement) {\n return undefined;\n }\n\n return scrollExpandedItemIntoViewAfterExpand({\n itemElement,\n triggerElement,\n });\n }, [disabled, isExpanded, itemRef]);\n\n return null;\n};\n\nconst AccordionItem = ({\n title,\n children,\n defaultExpanded = false,\n disabled = false,\n showDivider = false,\n size,\n titleTypography,\n usesTitleTypographyOverride,\n titleHeadingAs,\n}: AccordionItemComponentProps) => {\n const itemRef = useRef<HTMLDivElement>(null);\n\n return (\n <ItemContainer\n ref={itemRef}\n defaultExpanded={disabled ? false : defaultExpanded}\n isDisabled={disabled}\n $showDivider={showDivider}\n >\n {({ isExpanded }) => (\n <>\n <ExpandScrollSync disabled={disabled} isExpanded={isExpanded} itemRef={itemRef} />\n <TitleHeading forwardedAs={titleHeadingAs} size='xsm'>\n <TriggerButton\n slot='trigger'\n $size={size}\n $usesTitleTypographyOverride={usesTitleTypographyOverride}\n isDisabled={disabled}\n >\n <CollapseTitle align='center' spacing={Spacing[1]}>\n <ChevronContainer aria-hidden='true'>{renderChevron(isExpanded)}</ChevronContainer>\n {renderTitleLabel(title, titleTypography, disabled)}\n </CollapseTitle>\n </TriggerButton>\n </TitleHeading>\n <Panel data-accordion-panel>\n <PanelContent>{children}</PanelContent>\n </Panel>\n </>\n )}\n </ItemContainer>\n );\n};\n\nexport default AccordionItem;\n","import type { HeadingSize, ParagraphSize } from 'design-system/mixins/text';\n\nexport type AccordionSize = 'sm' | 'md' | 'lg';\n\nexport type AccordionTitleTypography =\n | { variant: 'heading'; size: HeadingSize }\n | {\n variant: 'paragraph';\n size: Extract<ParagraphSize, 'sm' | 'md' | 'lg'>;\n weight?: 'normal' | 'bold';\n };\n\nexport const getDefaultTitleTypography = (size: AccordionSize): AccordionTitleTypography => {\n if (size === 'lg') {\n return { variant: 'heading', size: 'xsm' };\n }\n\n if (size === 'sm') {\n return { variant: 'paragraph', size: 'sm', weight: 'normal' };\n }\n\n return { variant: 'paragraph', size: 'md', weight: 'bold' };\n};\n\nexport const resolveTitleTypography = (\n size: AccordionSize,\n titleTypography?: AccordionTitleTypography,\n): AccordionTitleTypography => titleTypography ?? getDefaultTitleTypography(size);\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\nimport { Stack } from 'design-system/components/Stack';\n\nimport AccordionItem, {\n type AccordionSize,\n type AccordionTitleHeadingAs,\n type AccordionTitleTypography,\n} from './AccordionItem';\nimport { resolveTitleTypography } from './accordionTitleTypography';\n\nexport type AccordionItemProps = {\n id?: string;\n title: string;\n children: ReactNode;\n defaultExpanded?: boolean;\n disabled?: boolean;\n};\n\nexport type AccordionProps = {\n items: AccordionItemProps[];\n size?: AccordionSize;\n dividers?: boolean;\n titleTypography?: AccordionTitleTypography;\n /**\n * Heading element for each item title (inside the trigger), matching Card section headings.\n * Defaults to `h3`; use a lower level when the page already uses higher headings.\n */\n titleHeadingAs?: AccordionTitleHeadingAs;\n 'aria-label'?: string;\n className?: string;\n};\n\nexport const Accordion = ({\n items,\n size = 'md',\n dividers = false,\n titleTypography,\n titleHeadingAs = 'h3',\n 'aria-label': ariaLabel = 'Accordion',\n className,\n}: AccordionProps) => {\n if (items.length === 0) {\n return null;\n }\n\n const resolvedTitleTypography = resolveTitleTypography(size, titleTypography);\n const usesTitleTypographyOverride = titleTypography != null;\n\n return (\n <Stack aria-label={ariaLabel} className={className} fullWidth role='group' spacing={Spacing[0]}>\n {items.map((item, index) => (\n <AccordionItem\n key={item.id ?? `${item.title}-${index}`}\n defaultExpanded={item.defaultExpanded}\n disabled={item.disabled}\n showDivider={dividers}\n size={size}\n title={item.title}\n titleHeadingAs={titleHeadingAs}\n titleTypography={resolvedTitleTypography}\n usesTitleTypographyOverride={usesTitleTypographyOverride}\n >\n {item.children}\n </AccordionItem>\n ))}\n </Stack>\n );\n};\n\nexport default Accordion;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["Heading"],"sources":["../../../src/components/Accordion/scrollExpandedItemIntoView.ts","../../../src/components/Accordion/AccordionItem.tsx","../../../src/components/Accordion/accordionTitleTypography.ts","../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import { TransitionDurationInSeconds } from '#src/variables/transitions';\n\nexport type ScrollExpandedItemTarget = {\n itemElement: HTMLElement;\n triggerElement: HTMLElement;\n};\n\nconst SCROLL_ALIGN_THRESHOLD_PX = 4;\n\nconst prefersReducedMotion = () =>\n typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\nconst getScrollBehavior = (): ScrollBehavior => (prefersReducedMotion() ? 'auto' : 'smooth');\n\nconst isScrollableOverflow = (overflowY: string) =>\n overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay';\n\nexport const findScrollContainer = (element: HTMLElement): HTMLElement | null => {\n let parent = element.parentElement;\n\n while (parent) {\n const { overflowY } = getComputedStyle(parent);\n if (isScrollableOverflow(overflowY) && parent.scrollHeight > parent.clientHeight) {\n return parent;\n }\n parent = parent.parentElement;\n }\n\n return null;\n};\n\nconst getContainerRect = (container: HTMLElement | null) => {\n if (container) {\n return container.getBoundingClientRect();\n }\n\n return {\n top: 0,\n bottom: window.innerHeight,\n } as Pick<DOMRect, 'top' | 'bottom'>;\n};\n\nconst scrollBy = (container: HTMLElement | null, deltaY: number) => {\n if (Math.abs(deltaY) <= SCROLL_ALIGN_THRESHOLD_PX) {\n return;\n }\n\n const behavior = getScrollBehavior();\n\n if (container) {\n container.scrollTo({ top: container.scrollTop + deltaY, behavior });\n return;\n }\n\n window.scrollBy({ top: deltaY, behavior });\n};\n\nexport const scrollExpandedItemIntoView = (target: ScrollExpandedItemTarget | null) => {\n if (!target) {\n return;\n }\n\n const { itemElement, triggerElement } = target;\n const container = findScrollContainer(itemElement);\n const containerRect = getContainerRect(container);\n const itemRect = itemElement.getBoundingClientRect();\n const triggerRect = triggerElement.getBoundingClientRect();\n const overflowBottom = itemRect.bottom - containerRect.bottom;\n\n if (overflowBottom > SCROLL_ALIGN_THRESHOLD_PX) {\n const maxScrollWithoutHidingTrigger = Math.max(0, triggerRect.top - containerRect.top);\n const deltaY = Math.min(overflowBottom, maxScrollWithoutHidingTrigger);\n scrollBy(container, deltaY);\n }\n};\n\nexport const scrollExpandedItemIntoViewAfterExpand = (target: ScrollExpandedItemTarget | null) => {\n scrollExpandedItemIntoView(target);\n\n if (!target) {\n return undefined;\n }\n\n const cleanups: Array<() => void> = [];\n const resyncScroll = () => scrollExpandedItemIntoView(target);\n\n const timeoutId = window.setTimeout(resyncScroll, TransitionDurationInSeconds.Fast * 1000);\n cleanups.push(() => window.clearTimeout(timeoutId));\n\n const panel = target.itemElement.querySelector<HTMLElement>('[data-accordion-panel]');\n if (panel) {\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== panel || event.propertyName !== 'height') {\n return;\n }\n\n resyncScroll();\n };\n\n panel.addEventListener('transitionend', onTransitionEnd);\n cleanups.push(() => panel.removeEventListener('transitionend', onTransitionEnd));\n }\n\n const rafId = window.requestAnimationFrame(() => {\n const innerRafId = window.requestAnimationFrame(resyncScroll);\n cleanups.push(() => window.cancelAnimationFrame(innerRafId));\n });\n cleanups.push(() => window.cancelAnimationFrame(rafId));\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n};\n\nexport const resolveAccordionTriggerElement = (itemElement: HTMLElement | null) => {\n if (!itemElement) {\n return null;\n }\n\n return (\n itemElement.querySelector<HTMLElement>('[slot=\"trigger\"]') ??\n itemElement.querySelector<HTMLElement>('button')\n );\n};\n","import type { ReactNode, RefObject } from 'react';\nimport { useLayoutEffect, useRef } from 'react';\nimport { Disclosure, DisclosurePanel } from 'react-aria-components';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { ChevronDownIcon, ChevronRightIcon } from '@persona/icons/12px';\n\nimport { HStack } from '#src/components/Stack';\nimport { Heading, Paragraph } from '#src/components/Text';\nimport { HeadlessAriaButton } from '#src/lib/HeadlessAriaButton';\nimport { isFocusedVisible, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { TruncatedText } from '#src/lib/TruncatedText';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport type { AccordionSize, AccordionTitleTypography } from './accordionTitleTypography';\nimport {\n scrollExpandedItemIntoViewAfterExpand,\n resolveAccordionTriggerElement,\n} from './scrollExpandedItemIntoView';\n\nexport type AccordionTitleHeadingAs = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\nexport type { AccordionSize, AccordionTitleTypography };\n\nconst SIZE_HEIGHT: Record<AccordionSize, string> = {\n sm: Spacing[5],\n md: Spacing[6],\n lg: Spacing[7],\n};\n\nconst ItemContainer = styled(Disclosure)<{ $showDivider: boolean }>`\n display: flex;\n flex-direction: column;\n position: relative;\n\n &:focus-within {\n z-index: 1;\n }\n\n ${({ $showDivider }) =>\n $showDivider &&\n css`\n border-top: 1px solid\n ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n `}\n`;\n\nconst ChevronContainer = styled.span`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n width: ${Spacing[3]};\n height: ${Spacing[3]};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.BorderIconSecondary)};\n transition: color ${TransitionDuration.Fast} ease;\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\nconst TriggerButton = styled(HeadlessAriaButton)<{\n $size: AccordionSize;\n $usesTitleTypographyOverride: boolean;\n}>`\n width: 100%;\n min-height: ${({ $size }) => SIZE_HEIGHT[$size]};\n height: ${({ $size, $usesTitleTypographyOverride }) =>\n $usesTitleTypographyOverride ? 'auto' : SIZE_HEIGHT[$size]};\n display: flex;\n align-items: center;\n text-align: left;\n border-radius: 0;\n background-color: transparent;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n transition: background-color ${TransitionDuration.Fast} ease-in-out;\n ${focusOutlineControlled}\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n\n &${isFocusedVisible}${isNotDisabled} {\n position: relative;\n z-index: 1;\n }\n\n &:disabled {\n cursor: default;\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n background-color: transparent;\n\n ${ChevronContainer} {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', Color.BorderIconDisabled)};\n }\n }\n\n &:hover:not(:disabled) {\n background-color: ${({ theme }) =>\n semanticColor(theme, 'SurfaceHover', Color.BackgroundInteractiveHover)};\n }\n\n &:not(:disabled):hover ${ChevronContainer},\n &${isFocusedVisible}${isNotDisabled} ${ChevronContainer} {\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.BorderIconPrimary)};\n }\n`;\n\nconst CollapseTitle = styled(HStack)`\n width: 100%;\n min-width: 0;\n`;\n\nconst TitleWrapper = styled.span`\n display: flex;\n align-items: center;\n min-width: 0;\n`;\n\nconst Panel = styled(DisclosurePanel)`\n height: var(--disclosure-panel-height);\n overflow: clip;\n transition: height ${TransitionDuration.Fast} ease-out;\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n`;\n\nconst TitleHeading = styled(Heading)`\n margin: 0;\n width: 100%;\n min-width: 0;\n font: inherit;\n font-size: inherit;\n line-height: inherit;\n font-weight: inherit;\n letter-spacing: inherit;\n`;\n\nconst PanelContent = styled.div`\n padding: ${Spacing[3]} ${Spacing[4]};\n`;\n\nconst TitleText = styled.span`\n min-width: 0;\n flex: 1;\n`;\n\nexport type AccordionItemComponentProps = {\n title: string;\n children: ReactNode;\n defaultExpanded?: boolean;\n disabled?: boolean;\n showDivider?: boolean;\n size: AccordionSize;\n titleTypography: AccordionTitleTypography;\n usesTitleTypographyOverride: boolean;\n titleHeadingAs: AccordionTitleHeadingAs;\n};\n\nconst renderTitleLabel = (\n title: string,\n titleTypography: AccordionTitleTypography,\n disabled: boolean,\n) => {\n const content = <TruncatedText>{title}</TruncatedText>;\n const textColor = disabled ? 'disabled' : 'primary';\n\n if (titleTypography.variant === 'heading') {\n return (\n <TitleText>\n <TitleWrapper>\n <Heading as='span' color={textColor} size={titleTypography.size}>\n {content}\n </Heading>\n </TitleWrapper>\n </TitleText>\n );\n }\n\n return (\n <TitleText>\n <TitleWrapper>\n <Paragraph\n as='span'\n color={textColor}\n size={titleTypography.size}\n weight={titleTypography.weight ?? 'normal'}\n >\n {content}\n </Paragraph>\n </TitleWrapper>\n </TitleText>\n );\n};\n\nconst renderChevron = (isExpanded: boolean) =>\n isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />;\n\nconst ExpandScrollSync = ({\n disabled,\n isExpanded,\n itemRef,\n}: {\n disabled: boolean;\n isExpanded: boolean;\n itemRef: RefObject<HTMLElement | null>;\n}) => {\n const wasExpandedRef = useRef(isExpanded);\n\n useLayoutEffect(() => {\n if (disabled) {\n wasExpandedRef.current = isExpanded;\n return undefined;\n }\n\n const didExpand = isExpanded && !wasExpandedRef.current;\n wasExpandedRef.current = isExpanded;\n\n const itemElement = itemRef.current;\n const triggerElement = resolveAccordionTriggerElement(itemElement);\n\n if (!didExpand || !itemElement || !triggerElement) {\n return undefined;\n }\n\n return scrollExpandedItemIntoViewAfterExpand({\n itemElement,\n triggerElement,\n });\n }, [disabled, isExpanded, itemRef]);\n\n return null;\n};\n\nconst AccordionItem = ({\n title,\n children,\n defaultExpanded = false,\n disabled = false,\n showDivider = false,\n size,\n titleTypography,\n usesTitleTypographyOverride,\n titleHeadingAs,\n}: AccordionItemComponentProps) => {\n const itemRef = useRef<HTMLDivElement>(null);\n\n return (\n <ItemContainer\n ref={itemRef}\n defaultExpanded={disabled ? false : defaultExpanded}\n isDisabled={disabled}\n $showDivider={showDivider}\n >\n {({ isExpanded }) => (\n <>\n <ExpandScrollSync disabled={disabled} isExpanded={isExpanded} itemRef={itemRef} />\n <TitleHeading forwardedAs={titleHeadingAs} size='xsm'>\n <TriggerButton\n slot='trigger'\n $size={size}\n $usesTitleTypographyOverride={usesTitleTypographyOverride}\n isDisabled={disabled}\n >\n <CollapseTitle align='center' spacing={Spacing[1]}>\n <ChevronContainer aria-hidden='true'>{renderChevron(isExpanded)}</ChevronContainer>\n {renderTitleLabel(title, titleTypography, disabled)}\n </CollapseTitle>\n </TriggerButton>\n </TitleHeading>\n <Panel data-accordion-panel>\n <PanelContent>{children}</PanelContent>\n </Panel>\n </>\n )}\n </ItemContainer>\n );\n};\n\nexport default AccordionItem;\n","import type { HeadingSize, ParagraphSize } from '#src/mixins/text';\n\nexport type AccordionSize = 'sm' | 'md' | 'lg';\n\nexport type AccordionTitleTypography =\n | { variant: 'heading'; size: HeadingSize }\n | {\n variant: 'paragraph';\n size: Extract<ParagraphSize, 'sm' | 'md' | 'lg'>;\n weight?: 'normal' | 'bold';\n };\n\nexport const getDefaultTitleTypography = (size: AccordionSize): AccordionTitleTypography => {\n if (size === 'lg') {\n return { variant: 'heading', size: 'xsm' };\n }\n\n if (size === 'sm') {\n return { variant: 'paragraph', size: 'sm', weight: 'normal' };\n }\n\n return { variant: 'paragraph', size: 'md', weight: 'bold' };\n};\n\nexport const resolveTitleTypography = (\n size: AccordionSize,\n titleTypography?: AccordionTitleTypography,\n): AccordionTitleTypography => titleTypography ?? getDefaultTitleTypography(size);\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { Stack } from '#src/components/Stack';\n\nimport AccordionItem, {\n type AccordionSize,\n type AccordionTitleHeadingAs,\n type AccordionTitleTypography,\n} from './AccordionItem';\nimport { resolveTitleTypography } from './accordionTitleTypography';\n\nexport type AccordionItemProps = {\n id?: string;\n title: string;\n children: ReactNode;\n defaultExpanded?: boolean;\n disabled?: boolean;\n};\n\nexport type AccordionProps = {\n items: AccordionItemProps[];\n size?: AccordionSize;\n dividers?: boolean;\n titleTypography?: AccordionTitleTypography;\n /**\n * Heading element for each item title (inside the trigger), matching Card section headings.\n * Defaults to `h3`; use a lower level when the page already uses higher headings.\n */\n titleHeadingAs?: AccordionTitleHeadingAs;\n 'aria-label'?: string;\n className?: string;\n};\n\nexport const Accordion = ({\n items,\n size = 'md',\n dividers = false,\n titleTypography,\n titleHeadingAs = 'h3',\n 'aria-label': ariaLabel = 'Accordion',\n className,\n}: AccordionProps) => {\n if (items.length === 0) {\n return null;\n }\n\n const resolvedTitleTypography = resolveTitleTypography(size, titleTypography);\n const usesTitleTypographyOverride = titleTypography != null;\n\n return (\n <Stack aria-label={ariaLabel} className={className} fullWidth role='group' spacing={Spacing[0]}>\n {items.map((item, index) => (\n <AccordionItem\n key={item.id ?? `${item.title}-${index}`}\n defaultExpanded={item.defaultExpanded}\n disabled={item.disabled}\n showDivider={dividers}\n size={size}\n title={item.title}\n titleHeadingAs={titleHeadingAs}\n titleTypography={resolvedTitleTypography}\n usesTitleTypographyOverride={usesTitleTypographyOverride}\n >\n {item.children}\n </AccordionItem>\n ))}\n </Stack>\n );\n};\n\nexport default Accordion;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/Attribute/Attribute.tsx","../../../src/components/Attribute/AttributeGrid.tsx"],"sourcesContent":["import { repeat, uniqueId } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n type ComponentType,\n createContext,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport { useToggleButton } from 'react-aria';\nimport { useToggleState } from 'react-stately';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\nimport { EyeIcon, EyeOffIcon } from '@persona/icons';\nimport IconButton from 'design-system/components/Button/IconButton';\nimport Sticker from 'design-system/components/Sticker';\nimport { Paragraph } from 'design-system/components/Text';\nimport { HelperTooltip } from 'design-system/components/Tooltip';\nimport { isHovered, isNotDisabled } from 'design-system/lib/pseudoClass';\nimport { semanticColor, semanticOnly } from 'design-system/lib/semanticColor';\nimport type { ParagraphSize } from 'design-system/mixins/text';\n\nexport type WordBreak = 'break-all' | 'break-word' | 'normal';\nexport type TextTransform = 'capitalize' | 'sentence';\nexport type TableLayoutValue = boolean | 'full-width';\n\nexport type AttributeSize = 'sm' | 'md';\n\nexport const AttributeContext = createContext<{\n table?: TableLayoutValue;\n horizontal?: boolean;\n size?: AttributeSize;\n}>({});\n\n// TODO: Create Toggle Button component\nexport const IconButtonContainer = styled(IconButton)`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n svg {\n transition-duration: 150ms;\n }\n\n :hover {\n svg {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', Color.CorePurple800)};\n }\n }\n\n ${semanticOnly(\n (tokens) => css`\n background-color: ${tokens.ActionNeutral};\n color: ${tokens.FgPrimary};\n\n svg {\n color: ${tokens.FgPrimary};\n }\n\n svg.pds-icon path[stroke] {\n stroke: currentColor;\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${tokens.ActionNeutralHover};\n color: ${tokens.FgAccent};\n\n svg path {\n stroke: currentColor;\n }\n }\n `,\n )}\n`;\n\ninterface AttributeValueProps {\n placeholder: ReactNode;\n show?: boolean;\n redacted?: boolean;\n value?: ReactNode;\n textTransform?: TextTransform;\n wordBreak?: WordBreak;\n size?: AttributeSize;\n 'aria-labelledby': string;\n id: string;\n}\n\ninterface ValueFormatterProps {\n isPlaceholder?: boolean;\n wordBreak?: WordBreak;\n size?: AttributeSize;\n}\n\nconst Value = styled.dd<ValueFormatterProps>`\n ${({ size }) => (size === 'sm' ? Typography.TextSmall : Typography.TextMedium)};\n color: ${({ isPlaceholder, theme }) =>\n isPlaceholder\n ? semanticColor(theme, 'FgSecondary', Color.TextSecondary)\n : semanticColor(theme, 'FgPrimary', Color.CoreSlate1000)};\n margin: 0;\n text-overflow: ellipsis;\n overflow-x: hidden;\n word-break: ${({ wordBreak }) => (wordBreak ? wordBreak : 'normal')};\n\n ul,\n ol {\n list-style-position: inside;\n }\n\n a {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n text-decoration: none;\n\n &:visited {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n }\n }\n`;\n\nexport const AttributeValue = ({\n placeholder,\n show,\n redacted,\n value,\n wordBreak,\n size,\n id,\n 'aria-labelledby': ariaLabelledBy,\n}: AttributeValueProps) => {\n const isEmpty = value == null || value === '';\n\n const renderedVal = isEmpty ? (\n placeholder\n ) : (\n <>{!show ? repeat('•', typeof value === 'string' ? value.length : 8) : value}</>\n );\n\n return (\n <Value\n isPlaceholder={isEmpty}\n wordBreak={wordBreak}\n size={size}\n title={typeof value === 'string' ? value : undefined}\n aria-labelledby={ariaLabelledBy}\n id={id}\n >\n {redacted ? <Sticker id={id}>Redacted</Sticker> : renderedVal}\n </Value>\n );\n};\n\nexport interface AttributeProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Title of the attribute. Rendered as a <dt>.\n */\n label: ReactNode;\n\n /**\n * Value to display. Rendered as a <dd>.\n */\n value?: ReactNode;\n\n /**\n * Will display a \"Redacted\" sticker if there is a value.\n */\n redacted?: boolean;\n\n /**\n * Renders toggleable eye button to the right of the label\n */\n toggleable?: boolean;\n\n /**\n * Text to display in presence of null value.\n */\n placeholder?: string;\n\n /**\n * Word break styling for value.\n */\n wordBreak?: WordBreak;\n\n /**\n * Render a custom label component\n */\n labelComponent?: FC<PropsWithChildren<{ id: string; size?: ParagraphSize }>>;\n\n /**\n * Render a custom value component\n */\n valueComponent?: ComponentType<AttributeValueProps>;\n\n /**\n * Renders a HelperTooltip to display help text to the right of the label.\n */\n helpText?: ReactNode;\n\n /**\n * Custom adornments to display to the right of the label.\n */\n right?: ReactNode;\n\n /**\n * Renders attributes in a tabular layout.\n */\n table?: TableLayoutValue;\n}\n\ntype AttributeContainerProps = {\n horizontal?: boolean;\n table?: TableLayoutValue;\n size?: AttributeSize;\n};\nconst AttributeContainer = styled('div')<AttributeContainerProps>`\n ${({ table, size }) =>\n table &&\n css`\n display: table-row;\n\n > * {\n display: table-cell;\n }\n\n & > ${AttributeLabel} {\n padding: ${Spacing[1]} 0;\n padding-right: ${size === 'sm' ? Spacing[2] : Spacing[3]};\n }\n & > ${Value} {\n padding: ${size === 'sm' ? Spacing[1] : Spacing[2]} 0;\n }\n `}\n\n ${({ horizontal }) =>\n horizontal &&\n css`\n display: grid;\n gap: ${Spacing[4]};\n grid-template-columns: subgrid;\n grid-column: span 2;\n `}\n`;\n\nexport const AttributeLabel = styled(Paragraph).attrs<{ size?: ParagraphSize }>((props) => ({\n size: props.size ?? 'md',\n color: 'tertiary',\n as: 'dt',\n}))`\n margin: 0;\n overflow-wrap: break-word;\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondary};`)}\n`;\n\nconst RightContainer = styled.span`\n display: inline-block;\n vertical-align: middle;\n margin-left: ${Spacing[2]};\n`;\n\nexport const Attribute = ({\n label,\n value,\n redacted,\n placeholder = '-',\n wordBreak,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n labelComponent: LabelComponent = AttributeLabel,\n valueComponent: ValueComponent = AttributeValue,\n right,\n helpText,\n toggleable,\n table,\n ...elemProps\n}: AttributeProps) => {\n const attrCtx = useContext(AttributeContext);\n const size = attrCtx?.size ?? 'md';\n const toggleRef = useRef();\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n const valueAsArray = [].concat(value).filter(Boolean);\n const showToggleButton = toggleable && !redacted && valueAsArray.length > 0;\n const state = useToggleState({ defaultSelected: !toggleable });\n const { buttonProps } = useToggleButton(\n {\n 'aria-label': state.isSelected ? `Hide ${label} value` : `Show ${label} value`,\n elementType: 'button',\n },\n state,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n toggleRef,\n );\n const labelId = useMemo(() => uniqueId('pds_attribute_label__'), []);\n const valueId = useMemo(() => uniqueId('pds_attribute_value__'), []);\n const show = state.isSelected;\n\n useEffect(() => {\n state.setSelected(!toggleable);\n }, [toggleable]);\n\n return (\n <AttributeContainer\n table={table || attrCtx?.table}\n horizontal={attrCtx?.horizontal}\n size={size}\n {...elemProps}\n >\n <LabelComponent id={labelId} aria-details={valueId} size={size}>\n {label}\n {helpText && (\n <RightContainer>\n <HelperTooltip size='sm'>{helpText}</HelperTooltip>\n </RightContainer>\n )}\n {showToggleButton && (\n <RightContainer>\n {/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */}\n <IconButtonContainer {...buttonProps} ref={toggleRef}>\n {show ? <EyeIcon /> : <EyeOffIcon />}\n </IconButtonContainer>\n </RightContainer>\n )}\n {right && <RightContainer>{right}</RightContainer>}\n </LabelComponent>\n <ValueComponent\n id={valueId}\n value={value}\n placeholder={placeholder}\n wordBreak={wordBreak}\n redacted={redacted}\n show={show}\n size={size}\n aria-labelledby={labelId}\n />\n </AttributeContainer>\n );\n};\n\nexport default Attribute;\n","import type { ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { AttributeContext, type AttributeSize, type TableLayoutValue } from './Attribute';\n\ntype AttributeGridProps = {\n children?: ReactNode;\n /**\n * Sets the font size and spacing density for all child Attributes.\n * Defaults to `'md'`.\n */\n size?: AttributeSize;\n} & (\n | {\n /**\n * Set a fixed number of columns for the grid.\n */\n colCount?: number;\n /**\n * Display attributes in a stacked list with label first then value.\n */\n horizontal?: boolean;\n\n table?: never;\n }\n | {\n /**\n * Display attributes in a fixed tabular layout.\n * Set to `full-width` to expand to full width of container.\n */\n table?: TableLayoutValue;\n\n colCount?: never;\n horizontal?: never;\n }\n);\n\ntype AttributeGridComponentProps = {\n colCount?: number;\n horizontal?: boolean;\n table?: TableLayoutValue;\n size?: AttributeSize;\n};\nconst AttributeGridComponent = styled.dl<AttributeGridComponentProps>`\n ${({ colCount, table, horizontal, size }) =>\n table\n ? css`\n display: table;\n ${\n table === 'full-width' &&\n css`\n width: 100%;\n table-layout: fixed;\n border-spacing: 0 ${size === 'sm' ? Spacing[1] : Spacing[2]};\n `\n };\n `\n : css`\n display: grid;\n gap: ${size === 'sm' ? Spacing[2] : Spacing[4]};\n /* If the layout is horizontal we guarentee an even number of columns */\n grid-template-columns: ${\n colCount\n ? `repeat(${colCount}, ${horizontal ? '1fr 2fr' : '1fr'})`\n : `repeat(auto-fit, ${horizontal ? 'minmax(120px, 1fr) minmax(225px, 2fr)' : 'minmax(225px, 1fr)'})`\n };\n `}\n margin: 0;\n\n & + & {\n padding-bottom: ${Spacing[5]};\n }\n`;\n\nconst AttributeGrid = ({ children, horizontal, table, size, ...props }: AttributeGridProps) => {\n return (\n <AttributeGridComponent table={table} horizontal={horizontal} size={size} {...props}>\n <AttributeContext.Provider value={{ horizontal, table, size }}>\n {children}\n </AttributeContext.Provider>\n </AttributeGridComponent>\n );\n};\n\nexport default AttributeGrid;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/Attribute/Attribute.tsx","../../../src/components/Attribute/AttributeGrid.tsx"],"sourcesContent":["import { repeat, uniqueId } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n type ComponentType,\n createContext,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport { useToggleButton } from 'react-aria';\nimport { useToggleState } from 'react-stately';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\nimport { EyeIcon, EyeOffIcon } from '@persona/icons';\n\nimport IconButton from '#src/components/Button/IconButton';\nimport Sticker from '#src/components/Sticker';\nimport { Paragraph } from '#src/components/Text';\nimport { HelperTooltip } from '#src/components/Tooltip';\nimport { isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\nimport type { ParagraphSize } from '#src/mixins/text';\n\nexport type WordBreak = 'break-all' | 'break-word' | 'normal';\nexport type TextTransform = 'capitalize' | 'sentence';\nexport type TableLayoutValue = boolean | 'full-width';\n\nexport type AttributeSize = 'sm' | 'md';\n\nexport const AttributeContext = createContext<{\n table?: TableLayoutValue;\n horizontal?: boolean;\n size?: AttributeSize;\n}>({});\n\n// TODO: Create Toggle Button component\nexport const IconButtonContainer = styled(IconButton)`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n svg {\n transition-duration: 150ms;\n }\n\n :hover {\n svg {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', Color.CorePurple800)};\n }\n }\n\n ${semanticOnly(\n (tokens) => css`\n background-color: ${tokens.ActionNeutral};\n color: ${tokens.FgPrimary};\n\n svg {\n color: ${tokens.FgPrimary};\n }\n\n svg.pds-icon path[stroke] {\n stroke: currentColor;\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${tokens.ActionNeutralHover};\n color: ${tokens.FgAccent};\n\n svg path {\n stroke: currentColor;\n }\n }\n `,\n )}\n`;\n\ninterface AttributeValueProps {\n placeholder: ReactNode;\n show?: boolean;\n redacted?: boolean;\n value?: ReactNode;\n textTransform?: TextTransform;\n wordBreak?: WordBreak;\n size?: AttributeSize;\n 'aria-labelledby': string;\n id: string;\n}\n\ninterface ValueFormatterProps {\n isPlaceholder?: boolean;\n wordBreak?: WordBreak;\n size?: AttributeSize;\n}\n\nconst Value = styled.dd<ValueFormatterProps>`\n ${({ size }) => (size === 'sm' ? Typography.TextSmall : Typography.TextMedium)};\n color: ${({ isPlaceholder, theme }) =>\n isPlaceholder\n ? semanticColor(theme, 'FgSecondary', Color.TextSecondary)\n : semanticColor(theme, 'FgPrimary', Color.CoreSlate1000)};\n margin: 0;\n text-overflow: ellipsis;\n overflow-x: hidden;\n word-break: ${({ wordBreak }) => (wordBreak ? wordBreak : 'normal')};\n\n ul,\n ol {\n list-style-position: inside;\n }\n\n a {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n text-decoration: none;\n\n &:visited {\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n }\n }\n`;\n\nexport const AttributeValue = ({\n placeholder,\n show,\n redacted,\n value,\n wordBreak,\n size,\n id,\n 'aria-labelledby': ariaLabelledBy,\n}: AttributeValueProps) => {\n const isEmpty = value == null || value === '';\n\n const renderedVal = isEmpty ? (\n placeholder\n ) : (\n <>{!show ? repeat('•', typeof value === 'string' ? value.length : 8) : value}</>\n );\n\n return (\n <Value\n isPlaceholder={isEmpty}\n wordBreak={wordBreak}\n size={size}\n title={typeof value === 'string' ? value : undefined}\n aria-labelledby={ariaLabelledBy}\n id={id}\n >\n {redacted ? <Sticker id={id}>Redacted</Sticker> : renderedVal}\n </Value>\n );\n};\n\nexport interface AttributeProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Title of the attribute. Rendered as a <dt>.\n */\n label: ReactNode;\n\n /**\n * Value to display. Rendered as a <dd>.\n */\n value?: ReactNode;\n\n /**\n * Will display a \"Redacted\" sticker if there is a value.\n */\n redacted?: boolean;\n\n /**\n * Renders toggleable eye button to the right of the label\n */\n toggleable?: boolean;\n\n /**\n * Text to display in presence of null value.\n */\n placeholder?: string;\n\n /**\n * Word break styling for value.\n */\n wordBreak?: WordBreak;\n\n /**\n * Render a custom label component\n */\n labelComponent?: FC<PropsWithChildren<{ id: string; size?: ParagraphSize }>>;\n\n /**\n * Render a custom value component\n */\n valueComponent?: ComponentType<AttributeValueProps>;\n\n /**\n * Renders a HelperTooltip to display help text to the right of the label.\n */\n helpText?: ReactNode;\n\n /**\n * Custom adornments to display to the right of the label.\n */\n right?: ReactNode;\n\n /**\n * Renders attributes in a tabular layout.\n */\n table?: TableLayoutValue;\n}\n\ntype AttributeContainerProps = {\n horizontal?: boolean;\n table?: TableLayoutValue;\n size?: AttributeSize;\n};\nconst AttributeContainer = styled('div')<AttributeContainerProps>`\n ${({ table, size }) =>\n table &&\n css`\n display: table-row;\n\n > * {\n display: table-cell;\n }\n\n & > ${AttributeLabel} {\n padding: ${Spacing[1]} 0;\n padding-right: ${size === 'sm' ? Spacing[2] : Spacing[3]};\n }\n & > ${Value} {\n padding: ${size === 'sm' ? Spacing[1] : Spacing[2]} 0;\n }\n `}\n\n ${({ horizontal }) =>\n horizontal &&\n css`\n display: grid;\n gap: ${Spacing[4]};\n grid-template-columns: subgrid;\n grid-column: span 2;\n `}\n`;\n\nexport const AttributeLabel = styled(Paragraph).attrs<{ size?: ParagraphSize }>((props) => ({\n size: props.size ?? 'md',\n color: 'tertiary',\n as: 'dt',\n}))`\n margin: 0;\n overflow-wrap: break-word;\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondary};`)}\n`;\n\nconst RightContainer = styled.span`\n display: inline-block;\n vertical-align: middle;\n margin-left: ${Spacing[2]};\n`;\n\nexport const Attribute = ({\n label,\n value,\n redacted,\n placeholder = '-',\n wordBreak,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n labelComponent: LabelComponent = AttributeLabel,\n valueComponent: ValueComponent = AttributeValue,\n right,\n helpText,\n toggleable,\n table,\n ...elemProps\n}: AttributeProps) => {\n const attrCtx = useContext(AttributeContext);\n const size = attrCtx?.size ?? 'md';\n const toggleRef = useRef();\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n const valueAsArray = [].concat(value).filter(Boolean);\n const showToggleButton = toggleable && !redacted && valueAsArray.length > 0;\n const state = useToggleState({ defaultSelected: !toggleable });\n const { buttonProps } = useToggleButton(\n {\n 'aria-label': state.isSelected ? `Hide ${label} value` : `Show ${label} value`,\n elementType: 'button',\n },\n state,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n toggleRef,\n );\n const labelId = useMemo(() => uniqueId('pds_attribute_label__'), []);\n const valueId = useMemo(() => uniqueId('pds_attribute_value__'), []);\n const show = state.isSelected;\n\n useEffect(() => {\n state.setSelected(!toggleable);\n }, [toggleable]);\n\n return (\n <AttributeContainer\n table={table || attrCtx?.table}\n horizontal={attrCtx?.horizontal}\n size={size}\n {...elemProps}\n >\n <LabelComponent id={labelId} aria-details={valueId} size={size}>\n {label}\n {helpText && (\n <RightContainer>\n <HelperTooltip size='sm'>{helpText}</HelperTooltip>\n </RightContainer>\n )}\n {showToggleButton && (\n <RightContainer>\n {/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */}\n <IconButtonContainer {...buttonProps} ref={toggleRef}>\n {show ? <EyeIcon /> : <EyeOffIcon />}\n </IconButtonContainer>\n </RightContainer>\n )}\n {right && <RightContainer>{right}</RightContainer>}\n </LabelComponent>\n <ValueComponent\n id={valueId}\n value={value}\n placeholder={placeholder}\n wordBreak={wordBreak}\n redacted={redacted}\n show={show}\n size={size}\n aria-labelledby={labelId}\n />\n </AttributeContainer>\n );\n};\n\nexport default Attribute;\n","import type { ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { AttributeContext, type AttributeSize, type TableLayoutValue } from './Attribute';\n\ntype AttributeGridProps = {\n children?: ReactNode;\n /**\n * Sets the font size and spacing density for all child Attributes.\n * Defaults to `'md'`.\n */\n size?: AttributeSize;\n} & (\n | {\n /**\n * Set a fixed number of columns for the grid.\n */\n colCount?: number;\n /**\n * Display attributes in a stacked list with label first then value.\n */\n horizontal?: boolean;\n\n table?: never;\n }\n | {\n /**\n * Display attributes in a fixed tabular layout.\n * Set to `full-width` to expand to full width of container.\n */\n table?: TableLayoutValue;\n\n colCount?: never;\n horizontal?: never;\n }\n);\n\ntype AttributeGridComponentProps = {\n colCount?: number;\n horizontal?: boolean;\n table?: TableLayoutValue;\n size?: AttributeSize;\n};\nconst AttributeGridComponent = styled.dl<AttributeGridComponentProps>`\n ${({ colCount, table, horizontal, size }) =>\n table\n ? css`\n display: table;\n ${\n table === 'full-width' &&\n css`\n width: 100%;\n table-layout: fixed;\n border-spacing: 0 ${size === 'sm' ? Spacing[1] : Spacing[2]};\n `\n };\n `\n : css`\n display: grid;\n gap: ${size === 'sm' ? Spacing[2] : Spacing[4]};\n /* If the layout is horizontal we guarentee an even number of columns */\n grid-template-columns: ${\n colCount\n ? `repeat(${colCount}, ${horizontal ? '1fr 2fr' : '1fr'})`\n : `repeat(auto-fit, ${horizontal ? 'minmax(120px, 1fr) minmax(225px, 2fr)' : 'minmax(225px, 1fr)'})`\n };\n `}\n margin: 0;\n\n & + & {\n padding-bottom: ${Spacing[5]};\n }\n`;\n\nconst AttributeGrid = ({ children, horizontal, table, size, ...props }: AttributeGridProps) => {\n return (\n <AttributeGridComponent table={table} horizontal={horizontal} size={size} {...props}>\n <AttributeContext.Provider value={{ horizontal, table, size }}>\n {children}\n </AttributeContext.Provider>\n </AttributeGridComponent>\n );\n};\n\nexport default AttributeGrid;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';\nimport { useFocusVisible } from 'react-aria';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\nimport Button from 'design-system/components/Button';\nimport { withAlpha } from 'design-system/lib/color';\nimport { isActive, isFocused, isHovered, isNotDisabled } from 'design-system/lib/pseudoClass';\nimport { semanticOnly, semanticTokens } from 'design-system/lib/semanticColor';\nimport { paragraphMixins } from 'design-system/mixins/text';\n\nexport interface BannerProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n\n /**\n * Semantic colour theme for the banner background.\n *\n * - `informational` – purple, for general tips or announcements (default).\n * - `success` – green, for confirmations or completed actions.\n * - `warning` – yellow, for non-blocking cautions.\n * - `alert` – red, for errors or destructive warnings.\n *\n * @defaultValue 'informational'\n */\n variant?: 'informational' | 'success' | 'warning' | 'alert';\n\n /**\n * Action affordance rendered to the right of the content.\n *\n * - Pass a `string` together with `onClose` to show a text button that calls `onClose`.\n * - Pass a `ReactElement` to render a fully custom action (e.g. a link or icon button).\n * In this case `onClose` is ignored for the action slot; wire dismissal inside the element.\n */\n action?: string | ReactElement;\n\n /**\n * Called when the user clicks the close (×) button.\n * When provided and `action` is absent, a close icon button is rendered automatically.\n * When `action` is a string, clicking that string-labelled button calls this handler.\n */\n onClose?: VoidFunction;\n\n /**\n * When true, the content area stretches to fill the full banner width.\n * Useful when `children` contains a layout that needs to span the entire space.\n */\n extendContentWidth?: boolean;\n}\n\nconst StyledBanner = styled('div')<BannerProps>`\n ${paragraphMixins.sm};\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n min-height: 40px;\n padding: ${Spacing[2]};\n border-radius: 4px;\n background: ${({ theme, variant }) => {\n const tokens = semanticTokens(theme);\n switch (variant) {\n case 'success':\n return tokens ? withAlpha(tokens.FeedbackSuccess1, tokens.Opacity15) : Color.CoreGreen100;\n case 'warning':\n return tokens ? withAlpha(tokens.FeedbackWarning1, tokens.Opacity15) : Color.CoreYellow100;\n case 'alert':\n return tokens ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity15) : Color.CoreRed100;\n case 'informational':\n default:\n return tokens ? withAlpha(tokens.FeedbackInfo1, tokens.Opacity25) : Color.CorePurple100;\n }\n }};\n\n ${semanticOnly(\n (tokens) => css`\n color: ${tokens.FgPrimary};\n\n svg {\n color: ${tokens.FgPrimary};\n }\n `,\n )}\n`;\n\nconst BannerContent = styled.div<{ extendContentWidth?: boolean }>`\n display: flex;\n align-items: center;\n\n > svg:first-child {\n margin-right: ${Spacing[2]};\n flex-shrink: 0;\n }\n\n ${({ extendContentWidth }) =>\n extendContentWidth &&\n css`\n width: 100%;\n `}\n`;\n\nconst ActionButton = styled(Button)<{ isFocusVisible?: boolean }>`\n background-color: transparent;\n justify-self: space-between;\n\n &${isActive}${isNotDisabled}, &${isHovered}${isNotDisabled} {\n background-color: unset;\n }\n\n ${({ isFocusVisible }) =>\n !isFocusVisible &&\n css`\n &${isHovered}${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n &${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n `}\n`;\n\nexport const Banner = ({\n children,\n variant,\n action,\n onClose,\n extendContentWidth,\n ...elemProps\n}: BannerProps) => {\n const { isFocusVisible } = useFocusVisible();\n\n return (\n <StyledBanner variant={variant} role='alert' {...elemProps}>\n <BannerContent extendContentWidth={extendContentWidth}>{children}</BannerContent>\n {typeof action === 'string'\n ? onClose && (\n <ActionButton variant='basic' width='auto' size='sm' onClick={onClose}>\n {action}\n </ActionButton>\n )\n : action}\n {!action && onClose && (\n <ActionButton\n variant='basic'\n width='icon'\n size='sm'\n aria-label='Close'\n title='Close'\n onClick={onClose}\n isFocusVisible={isFocusVisible}\n >\n <XIcon />\n </ActionButton>\n )}\n </StyledBanner>\n );\n};\n\nexport default Banner;\n"],"mappings":";;;;;;;;;;;AAkDA,MAAM,eAAe,OAAO,MAAM;IAC9B,gBAAgB,GAAG;;;;;;aAMV,QAAQ,GAAG;;iBAEP,EAAE,OAAO,cAAc;CACpC,MAAM,SAAS,eAAe,MAAM;AACpC,SAAQ,SAAR;EACE,KAAK,UACH,QAAO,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAC/E,KAAK,UACH,QAAO,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAC/E,KAAK,QACH,QAAO,SAAS,UAAU,OAAO,iBAAiB,OAAO,UAAU,GAAG,MAAM;EAE9E,QACE,QAAO,SAAS,UAAU,OAAO,eAAe,OAAO,UAAU,GAAG,MAAM;;EAE9E;;IAEA,cACC,WAAW,GAAG;eACJ,OAAO,UAAU;;;iBAGf,OAAO,UAAU;;MAG/B,CAAC;;AAGJ,MAAM,gBAAgB,OAAO,GAAqC;;;;;oBAK9C,QAAQ,GAAG;;;;KAI1B,EAAE,yBACH,sBACA,GAAG;;MAED;;AAGN,MAAM,eAAe,OAAO,OAAO;;;;KAI9B,WAAW,cAAc,KAAK,YAAY,cAAc;;;;KAIxD,EAAE,qBACH,CAAC,kBACD,GAAG;SACE,YAAY,YAAY,cAAc;;;SAGtC,YAAY,cAAc;;;MAG7B;;AAGN,MAAa,UAAU,EACrB,UACA,SACA,QACA,SACA,oBACA,GAAG,gBACc;CACjB,MAAM,EAAE,mBAAmB,iBAAiB;AAE5C,QACE,qBAAC,cAAD;EAAuB;EAAS,MAAK;EAAQ,GAAI;YAAjD;GACE,oBAAC,eAAD;IAAmC;IAAqB;IAAyB,CAAA;GAChF,OAAO,WAAW,WACf,WACE,oBAAC,cAAD;IAAc,SAAQ;IAAQ,OAAM;IAAO,MAAK;IAAK,SAAS;cAC3D;IACY,CAAA,GAEjB;GACH,CAAC,UAAU,WACV,oBAAC,cAAD;IACE,SAAQ;IACR,OAAM;IACN,MAAK;IACL,cAAW;IACX,OAAM;IACN,SAAS;IACO;cAEhB,oBAAC,OAAD,EAAS,CAAA;IACI,CAAA;GAEJ"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';\nimport { useFocusVisible } from 'react-aria';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\n\nimport Button from '#src/components/Button';\nimport { withAlpha } from '#src/lib/color';\nimport { isActive, isFocused, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticOnly, semanticTokens } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\n\nexport interface BannerProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n\n /**\n * Semantic colour theme for the banner background.\n *\n * - `informational` – purple, for general tips or announcements (default).\n * - `success` – green, for confirmations or completed actions.\n * - `warning` – yellow, for non-blocking cautions.\n * - `alert` – red, for errors or destructive warnings.\n *\n * @defaultValue 'informational'\n */\n variant?: 'informational' | 'success' | 'warning' | 'alert';\n\n /**\n * Action affordance rendered to the right of the content.\n *\n * - Pass a `string` together with `onClose` to show a text button that calls `onClose`.\n * - Pass a `ReactElement` to render a fully custom action (e.g. a link or icon button).\n * In this case `onClose` is ignored for the action slot; wire dismissal inside the element.\n */\n action?: string | ReactElement;\n\n /**\n * Called when the user clicks the close (×) button.\n * When provided and `action` is absent, a close icon button is rendered automatically.\n * When `action` is a string, clicking that string-labelled button calls this handler.\n */\n onClose?: VoidFunction;\n\n /**\n * When true, the content area stretches to fill the full banner width.\n * Useful when `children` contains a layout that needs to span the entire space.\n */\n extendContentWidth?: boolean;\n}\n\nconst StyledBanner = styled('div')<BannerProps>`\n ${paragraphMixins.sm};\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n min-height: 40px;\n padding: ${Spacing[2]};\n border-radius: 4px;\n background: ${({ theme, variant }) => {\n const tokens = semanticTokens(theme);\n switch (variant) {\n case 'success':\n return tokens ? withAlpha(tokens.FeedbackSuccess1, tokens.Opacity15) : Color.CoreGreen100;\n case 'warning':\n return tokens ? withAlpha(tokens.FeedbackWarning1, tokens.Opacity15) : Color.CoreYellow100;\n case 'alert':\n return tokens ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity15) : Color.CoreRed100;\n case 'informational':\n default:\n return tokens ? withAlpha(tokens.FeedbackInfo1, tokens.Opacity25) : Color.CorePurple100;\n }\n }};\n\n ${semanticOnly(\n (tokens) => css`\n color: ${tokens.FgPrimary};\n\n svg {\n color: ${tokens.FgPrimary};\n }\n `,\n )}\n`;\n\nconst BannerContent = styled.div<{ extendContentWidth?: boolean }>`\n display: flex;\n align-items: center;\n\n > svg:first-child {\n margin-right: ${Spacing[2]};\n flex-shrink: 0;\n }\n\n ${({ extendContentWidth }) =>\n extendContentWidth &&\n css`\n width: 100%;\n `}\n`;\n\nconst ActionButton = styled(Button)<{ isFocusVisible?: boolean }>`\n background-color: transparent;\n justify-self: space-between;\n\n &${isActive}${isNotDisabled}, &${isHovered}${isNotDisabled} {\n background-color: unset;\n }\n\n ${({ isFocusVisible }) =>\n !isFocusVisible &&\n css`\n &${isHovered}${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n &${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n `}\n`;\n\nexport const Banner = ({\n children,\n variant,\n action,\n onClose,\n extendContentWidth,\n ...elemProps\n}: BannerProps) => {\n const { isFocusVisible } = useFocusVisible();\n\n return (\n <StyledBanner variant={variant} role='alert' {...elemProps}>\n <BannerContent extendContentWidth={extendContentWidth}>{children}</BannerContent>\n {typeof action === 'string'\n ? onClose && (\n <ActionButton variant='basic' width='auto' size='sm' onClick={onClose}>\n {action}\n </ActionButton>\n )\n : action}\n {!action && onClose && (\n <ActionButton\n variant='basic'\n width='icon'\n size='sm'\n aria-label='Close'\n title='Close'\n onClick={onClose}\n isFocusVisible={isFocusVisible}\n >\n <XIcon />\n </ActionButton>\n )}\n </StyledBanner>\n );\n};\n\nexport default Banner;\n"],"mappings":";;;;;;;;;;;AAmDA,MAAM,eAAe,OAAO,MAAM;IAC9B,gBAAgB,GAAG;;;;;;aAMV,QAAQ,GAAG;;iBAEP,EAAE,OAAO,cAAc;CACpC,MAAM,SAAS,eAAe,MAAM;AACpC,SAAQ,SAAR;EACE,KAAK,UACH,QAAO,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAC/E,KAAK,UACH,QAAO,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAC/E,KAAK,QACH,QAAO,SAAS,UAAU,OAAO,iBAAiB,OAAO,UAAU,GAAG,MAAM;EAE9E,QACE,QAAO,SAAS,UAAU,OAAO,eAAe,OAAO,UAAU,GAAG,MAAM;;EAE9E;;IAEA,cACC,WAAW,GAAG;eACJ,OAAO,UAAU;;;iBAGf,OAAO,UAAU;;MAG/B,CAAC;;AAGJ,MAAM,gBAAgB,OAAO,GAAqC;;;;;oBAK9C,QAAQ,GAAG;;;;KAI1B,EAAE,yBACH,sBACA,GAAG;;MAED;;AAGN,MAAM,eAAe,OAAO,OAAO;;;;KAI9B,WAAW,cAAc,KAAK,YAAY,cAAc;;;;KAIxD,EAAE,qBACH,CAAC,kBACD,GAAG;SACE,YAAY,YAAY,cAAc;;;SAGtC,YAAY,cAAc;;;MAG7B;;AAGN,MAAa,UAAU,EACrB,UACA,SACA,QACA,SACA,oBACA,GAAG,gBACc;CACjB,MAAM,EAAE,mBAAmB,iBAAiB;AAE5C,QACE,qBAAC,cAAD;EAAuB;EAAS,MAAK;EAAQ,GAAI;YAAjD;GACE,oBAAC,eAAD;IAAmC;IAAqB;IAAyB,CAAA;GAChF,OAAO,WAAW,WACf,WACE,oBAAC,cAAD;IAAc,SAAQ;IAAQ,OAAM;IAAO,MAAK;IAAK,SAAS;cAC3D;IACY,CAAA,GAEjB;GACH,CAAC,UAAU,WACV,oBAAC,cAAD;IACE,SAAQ;IACR,OAAM;IACN,MAAK;IACL,cAAW;IACX,OAAM;IACN,SAAS;IACO;cAEhB,oBAAC,OAAD,EAAS,CAAA;IACI,CAAA;GAEJ"}
@@ -1,14 +1,19 @@
1
- import { a as styled, r as css } from "../../styledComponentsInterop-Cs5CCPRy.mjs";
1
+ import { a as styled, o as useTheme, r as css } from "../../styledComponentsInterop-Cs5CCPRy.mjs";
2
+ import { l as usePDSStrings } from "../../i18n-DaOKaFc2.mjs";
3
+ import { semanticColor } from "../../lib/semanticColor.mjs";
4
+ import { i as Paragraph } from "../../Text-D0vEReED.mjs";
2
5
  import { useResizablePanel } from "../../lib/useResizablePanel.mjs";
3
6
  import { Z_INDICES } from "../../lib/zindex.mjs";
7
+ import { focusOutline } from "../../mixins/focus.mjs";
4
8
  import { semanticScrollbar } from "../../mixins/scrollbar.mjs";
9
+ import { n as Stack, t as HStack } from "../../Stack-Bzom2BTR.mjs";
5
10
  import { t as IconButton } from "../../IconButton-DftINsp7.mjs";
6
11
  import { t as Badge } from "../../Badge-8YzapjWf.mjs";
7
12
  import { i as TabBar, r as Tab } from "../../TabBar-DpXYsWgS.mjs";
8
13
  import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
9
- import { Color, Spacing } from "@persona/design-tokens";
14
+ import { BorderRadius, Color, Spacing } from "@persona/design-tokens";
10
15
  import { jsx, jsxs } from "react/jsx-runtime";
11
- import { ArrowCollapseIcon, ArrowExpandIcon, XIcon } from "@persona/icons";
16
+ import { ArrowCollapseIcon, ArrowExpandIcon, CircleXInverseIcon, XIcon } from "@persona/icons";
12
17
  import { useId } from "react-aria";
13
18
  //#region src/components/BottomPanel/ResizeHandle.tsx
14
19
  const DRAGGING_CLASSNAME = "dragging";
@@ -215,12 +220,50 @@ const OPEN_HEIGHT = 200;
215
220
  const Header = styled.div`
216
221
  display: flex;
217
222
  align-items: center;
223
+ justify-content: space-between;
218
224
  box-sizing: border-box;
219
225
  width: 100%;
226
+ min-width: 0;
220
227
  padding-left: ${Spacing[4]};
221
228
  `;
229
+ const ErrorSummary = styled(HStack).attrs({ align: "center" })`
230
+ flex-shrink: 0;
231
+ padding-right: ${Spacing[2]};
232
+ `;
233
+ const ErrorSummaryDivider = styled.div`
234
+ width: 1px;
235
+ height: ${Spacing[6]};
236
+ background: ${({ theme }) => semanticColor(theme, "BorderSubtle", Color.BorderDivider)};
237
+ `;
238
+ const ErrorIndicator = styled(Stack).attrs({
239
+ align: "center",
240
+ direction: "horizontal",
241
+ spacing: Spacing[1]
242
+ })`
243
+ padding: ${Spacing[1]} ${Spacing[2]};
244
+ background: none;
245
+ border: none;
246
+ border-radius: ${BorderRadius.Sm};
247
+ font: inherit;
248
+ color: inherit;
249
+ ${({ $clickable }) => $clickable ? css`
250
+ cursor: pointer;
251
+
252
+ &:hover {
253
+ background: ${({ theme }) => semanticColor(theme, "ActionNeutralHover", theme.color.variants.basic.hover)};
254
+ }
255
+
256
+ &:active {
257
+ background: ${({ theme }) => semanticColor(theme, "ActionNeutralActive", theme.color.variants.basic.highlight)};
258
+ }
259
+
260
+ ${focusOutline}
261
+ ` : ""}
262
+ `;
222
263
  const HeaderTabBar = styled(TabBar)`
223
264
  border-bottom: none;
265
+ flex: 1;
266
+ min-width: 0;
224
267
  `;
225
268
  const PanelContent = styled.div`
226
269
  ${({ $hidden }) => $hidden ? css`
@@ -241,7 +284,9 @@ const PanelContent = styled.div`
241
284
  * panel. Owns the tab bar, expand/collapse/resize, and always-mounted content;
242
285
  * the caller owns what each panel shows.
243
286
  */
244
- const BottomPanel = forwardRef(function BottomPanel({ panels }, ref) {
287
+ const BottomPanel = forwardRef(function BottomPanel({ panels, errorCount, onErrorCountClick }, ref) {
288
+ const strings = usePDSStrings();
289
+ const theme = useTheme();
245
290
  const baseId = useId();
246
291
  const [selected, setSelected] = useState(panels[0]?.label);
247
292
  const hasSelected = panels.some((panel) => panel.label === selected);
@@ -266,14 +311,30 @@ const BottomPanel = forwardRef(function BottomPanel({ panels }, ref) {
266
311
  if (panels.some((panel) => panel.label === label)) openPanel(label);
267
312
  } }), [openPanel, panels]);
268
313
  return /* @__PURE__ */ jsx(ResizableVerticalPanel, {
269
- headerContent: /* @__PURE__ */ jsx(Header, { children: /* @__PURE__ */ jsx(HeaderTabBar, { children: panels.map((panel, index) => /* @__PURE__ */ jsx(Tab, {
314
+ headerContent: /* @__PURE__ */ jsxs(Header, { children: [/* @__PURE__ */ jsx(HeaderTabBar, { children: panels.map((panel, index) => /* @__PURE__ */ jsx(Tab, {
270
315
  "aria-controls": `${baseId}-panel-${index}`,
271
316
  badge: panel.badge ? /* @__PURE__ */ jsx(Badge, { children: panel.badge }) : void 0,
272
317
  id: `${baseId}-tab-${index}`,
273
318
  onClick: () => openPanel(panel.label),
274
319
  selected: selectedLabel === panel.label,
275
320
  children: panel.label
276
- }, panel.label)) }) }),
321
+ }, panel.label)) }), errorCount != null && /* @__PURE__ */ jsxs(ErrorSummary, { children: [/* @__PURE__ */ jsx(ErrorSummaryDivider, { "aria-hidden": true }), /* @__PURE__ */ jsxs(ErrorIndicator, {
322
+ $clickable: onErrorCountClick != null,
323
+ "aria-label": strings.errorCount(errorCount),
324
+ as: onErrorCountClick ? "button" : "div",
325
+ onClick: onErrorCountClick,
326
+ role: onErrorCountClick ? void 0 : "img",
327
+ type: onErrorCountClick ? "button" : void 0,
328
+ children: [/* @__PURE__ */ jsx(CircleXInverseIcon, {
329
+ "aria-hidden": true,
330
+ color: errorCount === 0 ? semanticColor(theme, "FgDisabled", Color.TextDisabled) : semanticColor(theme, "FgDanger1", Color.TextDanger)
331
+ }), /* @__PURE__ */ jsx(Paragraph, {
332
+ as: "span",
333
+ color: errorCount === 0 ? "disabled" : "primary",
334
+ size: "md",
335
+ children: errorCount
336
+ })]
337
+ })] })] }),
277
338
  hookState: resizablePanelState,
278
339
  minHeight: PANEL_MIN_HEIGHT,
279
340
  children: panels.map((panel, index) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/BottomPanel/ResizeHandle.tsx","../../../src/components/BottomPanel/ResizableVerticalPanel.tsx","../../../src/components/BottomPanel/BottomPanel.tsx"],"sourcesContent":["import { type FC, type RefObject, useEffect, useRef } from 'react';\nimport styled from 'styled-components';\n\nimport { Z_INDICES } from '@persona/design-system/lib/zindex';\nimport { Spacing } from '@persona/design-tokens';\n\nconst DRAGGING_CLASSNAME = 'dragging';\n\ninterface ResizeHandleProps {\n ariaLabel: string;\n /** Fires on double-click or Enter/Space so the host can toggle/reset the size. */\n onDoubleClick?: () => void;\n /** Called on each pointer move with the new top edge position (clientY) in px. */\n onMoveTo: (position: number) => void;\n /** Called once when the drag ends (pointerup, cancel, or lost capture). */\n onRelease?: () => void;\n /** The panel being resized; its edge seeds the grab offset so the handle doesn't jump. */\n panelRef: RefObject<HTMLDivElement>;\n}\n\n// The visible line is 2px tall on the panel's top border; the hitbox is Spacing[2] tall and\n// straddles that border so it is easy to grab without covering the header row's controls.\nconst ResizeHandleContainer = styled.div`\n cursor: row-resize;\n position: absolute;\n height: ${Spacing[2]};\n top: -${Spacing[1]};\n left: 0;\n right: 0;\n z-index: ${Z_INDICES.dropdown};\n touch-action: none;\n\n &::after {\n content: '';\n position: absolute;\n top: ${Spacing[1]};\n left: 0;\n right: 0;\n height: 2px;\n background-color: transparent;\n transition: background-color 0.15s ease-in;\n transition-delay: 0.025s;\n }\n\n &:hover::after,\n &.${DRAGGING_CLASSNAME}::after {\n background-color: ${({ theme }) => theme.color.border.active};\n }\n`;\n\n/** Vertical resize handle pinned to the top edge of a bottom-anchored panel. */\nexport const ResizeHandle: FC<ResizeHandleProps> = ({\n ariaLabel,\n onDoubleClick,\n onMoveTo,\n onRelease,\n panelRef,\n}) => {\n const resizeHandleRef = useRef<HTMLDivElement>(null);\n const panelOffsetRef = useRef(0);\n const activePointerIdRef = useRef<number | null>(null);\n const documentListenersRef = useRef<{\n handleEnd: (event: PointerEvent) => void;\n handleMove: (event: PointerEvent) => void;\n } | null>(null);\n // Document listeners are registered once per drag; reading the callbacks through\n // refs keeps them on the latest props without re-registering mid-drag.\n const onMoveToRef = useRef(onMoveTo);\n const onReleaseRef = useRef(onRelease);\n onMoveToRef.current = onMoveTo;\n onReleaseRef.current = onRelease;\n\n const removeDocumentListeners = () => {\n const listeners = documentListenersRef.current;\n if (!listeners) {\n return;\n }\n\n document.removeEventListener('pointermove', listeners.handleMove);\n document.removeEventListener('pointerup', listeners.handleEnd);\n document.removeEventListener('pointercancel', listeners.handleEnd);\n documentListenersRef.current = null;\n };\n\n // Pointer capture routes events through the handle (including over iframes), but\n // some surfaces still drop pointerup. Document-level listeners during an active\n // drag are the release safety net. Only the pointer that started the drag may\n // move or end it.\n const endDrag = (pointerId: number) => {\n if (activePointerIdRef.current !== pointerId) {\n return;\n }\n\n activePointerIdRef.current = null;\n removeDocumentListeners();\n try {\n resizeHandleRef.current?.releasePointerCapture(pointerId);\n } catch {\n // No active capture (or unsupported, e.g. jsdom) — nothing to release.\n }\n\n resizeHandleRef.current?.classList.remove(DRAGGING_CLASSNAME);\n panelOffsetRef.current = 0;\n onReleaseRef.current?.();\n };\n\n const handleDocumentPointerMove = (event: PointerEvent) => {\n if (activePointerIdRef.current !== event.pointerId) {\n return;\n }\n\n onMoveToRef.current(event.clientY + panelOffsetRef.current);\n };\n\n const addDocumentListeners = () => {\n removeDocumentListeners();\n\n const listeners = {\n handleEnd: (event: PointerEvent) => endDrag(event.pointerId),\n handleMove: handleDocumentPointerMove,\n };\n documentListenersRef.current = listeners;\n document.addEventListener('pointermove', listeners.handleMove);\n document.addEventListener('pointerup', listeners.handleEnd);\n document.addEventListener('pointercancel', listeners.handleEnd);\n };\n\n const endDragRef = useRef(endDrag);\n endDragRef.current = endDrag;\n useEffect(() => {\n return () => {\n const activePointerId = activePointerIdRef.current;\n if (activePointerId != null) {\n endDragRef.current(activePointerId);\n }\n };\n }, []);\n\n return (\n <ResizeHandleContainer\n aria-label={ariaLabel}\n onDoubleClick={onDoubleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n onDoubleClick?.();\n e.preventDefault();\n }\n }}\n onLostPointerCapture={(e) => endDrag(e.pointerId)}\n onPointerCancel={(e) => endDrag(e.pointerId)}\n onPointerDown={(e) => {\n // Primary button / touch / pen only; ignore secondary and middle clicks,\n // and a second pointer while a drag is already active.\n if (e.button !== 0 || activePointerIdRef.current != null) {\n return;\n }\n const panelRect = panelRef.current?.getBoundingClientRect();\n panelOffsetRef.current = panelRect ? panelRect.top - e.clientY : 0;\n activePointerIdRef.current = e.pointerId;\n resizeHandleRef.current?.classList.add(DRAGGING_CLASSNAME);\n addDocumentListeners();\n try {\n resizeHandleRef.current?.setPointerCapture(e.pointerId);\n } catch {\n // Pointer capture unsupported (e.g. jsdom) — document listeners still\n // route move/up events for the duration of the drag.\n }\n e.preventDefault();\n e.stopPropagation();\n }}\n onPointerUp={(e) => endDrag(e.pointerId)}\n ref={resizeHandleRef}\n role='button'\n tabIndex={0}\n />\n );\n};\n","import { type FC, type ReactNode, useRef } from 'react';\nimport styled from 'styled-components';\n\nimport { IconButton } from '@persona/design-system/components/Button';\nimport { PanelState, type ResizablePanelState } from '@persona/design-system/lib/useResizablePanel';\nimport { Z_INDICES } from '@persona/design-system/lib/zindex';\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { ArrowCollapseIcon, ArrowExpandIcon, XIcon } from '@persona/icons';\nimport { semanticScrollbar } from 'design-system/mixins/scrollbar';\n\nimport { ResizeHandle } from './ResizeHandle';\n\ninterface ResizableVerticalPanelProps {\n /** Panel body, rendered in the scrollable content area below the header. */\n children: ReactNode;\n /** Content for the header row, left of the maximize/minimize/close buttons. */\n headerContent?: ReactNode;\n /** State and drag/resize handlers from `useResizablePanel`. */\n hookState: ResizablePanelState;\n /** Minimum panel height in px. */\n minHeight: number;\n}\n\nconst TriStatePanel = styled.div.attrs<{\n customHeight: number | null;\n minHeight: number;\n panelState: PanelState;\n}>(({ customHeight, minHeight, panelState }) => ({\n style: {\n height: panelState === PanelState.Maximized ? '100%' : `${customHeight ?? minHeight}px`,\n },\n}))<{\n customHeight: number | null;\n minHeight: number;\n panelState: PanelState;\n}>`\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n background-color: ${({ theme }) => theme.color.background.primary};\n position: relative;\n min-height: ${({ minHeight }) => minHeight}px;\n width: 100%;\n border-top: 1px solid ${Color.BorderDivider};\n z-index: ${Z_INDICES.topNav};\n`;\n\nconst TopRowContainer = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n box-shadow: inset 0px -1px 0px 0px ${Color.BorderDivider};\n`;\n\nconst TopRightIconsContainer = styled.div`\n display: flex;\n align-items: center;\n padding: 0 ${Spacing[2]};\n gap: ${Spacing[2]};\n flex-direction: row;\n`;\n\nconst ContentContainer = styled.div`\n /* offset by the top row container height */\n height: calc(100% - ${Spacing[6]});\n overflow: auto;\n ${semanticScrollbar}\n display: flex;\n flex-direction: column;\n min-height: 0;\n`;\n\n/**\n * Bottom-anchored panel with a drag-to-resize top edge, a header row, and\n * maximize/minimize/close controls.\n */\nexport const ResizableVerticalPanel: FC<ResizableVerticalPanelProps> = ({\n children,\n headerContent,\n hookState,\n minHeight,\n}) => {\n const {\n collapse,\n handleDragMove: handlePanelDragMove,\n handleDragRelease,\n maximize,\n panelState,\n restore,\n size,\n toggleMaximized,\n } = hookState;\n const panelRef = useRef<HTMLDivElement>(null);\n // Controls only make sense once the drawer is taller than its collapsed header.\n const showControls = (size != null && size > minHeight) || panelState === PanelState.Maximized;\n // Converts the dragged top edge (clientY) into a panel height bounded by the\n // panel's container.\n const handleDragMove = (clientY: number) => {\n const panel = panelRef.current;\n const container = panel?.parentElement;\n if (!panel || !container) {\n return;\n }\n const panelBottom = panel.getBoundingClientRect().bottom;\n const containerTop = container.getBoundingClientRect().top;\n handlePanelDragMove(panelBottom - clientY, panelBottom - containerTop);\n };\n\n return (\n <TriStatePanel\n aria-label='Bottom panel'\n customHeight={size}\n minHeight={minHeight}\n panelState={panelState}\n ref={panelRef}\n role='region'\n >\n <ResizeHandle\n ariaLabel='Drag to resize bottom panel'\n onDoubleClick={toggleMaximized}\n onMoveTo={handleDragMove}\n onRelease={handleDragRelease}\n panelRef={panelRef}\n />\n\n <TopRowContainer>\n {headerContent}\n\n {showControls && (\n <TopRightIconsContainer>\n {panelState === PanelState.Maximized ? (\n <IconButton aria-label='Restore the bottom panel' onClick={restore} size='sm'>\n <ArrowCollapseIcon />\n </IconButton>\n ) : (\n <IconButton aria-label='Maximize the bottom panel' onClick={maximize} size='sm'>\n <ArrowExpandIcon />\n </IconButton>\n )}\n <IconButton aria-label='Close bottom panel' onClick={collapse} size='sm'>\n <XIcon />\n </IconButton>\n </TopRightIconsContainer>\n )}\n </TopRowContainer>\n\n <ContentContainer>{children}</ContentContainer>\n </TriStatePanel>\n );\n};\n","import {\n forwardRef,\n type ReactNode,\n useCallback,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react';\nimport { useId } from 'react-aria';\nimport styled, { css } from 'styled-components';\n\nimport Badge from '@persona/design-system/components/Badge';\nimport TabBar, { Tab } from '@persona/design-system/components/TabBar';\nimport { PanelState, useResizablePanel } from '@persona/design-system/lib/useResizablePanel';\nimport { Spacing } from '@persona/design-tokens';\n\nimport { ResizableVerticalPanel } from './ResizableVerticalPanel';\n\n// One-pixel panel top border plus the 32px header row sets the collapsed drawer height.\nconst PANEL_MIN_HEIGHT = 33;\n// Where the drawer opens to when a collapsed tab is selected; the user can drag from there.\nconst OPEN_HEIGHT = 200;\n\nexport interface BottomPanelItemProps {\n /** Tab text; also the key `openPanel(label)` looks up. Unique per BottomPanel. */\n label: string;\n /**\n * Tab body. Every panel stays mounted while another tab is selected, so local\n * state (scroll, expanded rows) survives a switch.\n */\n content: ReactNode;\n /** Count shown as a badge on the tab. `0`/`undefined` hides it. */\n badge?: number;\n}\n\nexport interface BottomPanelHandle {\n /** Select the tab and expand the drawer if collapsed. No-op for an unknown label. */\n openPanel: (label: string) => void;\n}\n\nexport interface BottomPanelProps {\n /** Tabs to show, in order. */\n panels: BottomPanelItemProps[];\n}\n\nconst Header = styled.div`\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding-left: ${Spacing[4]};\n`;\n\n// The header row draws the divider edge to edge; the tab bar must not add its own.\nconst HeaderTabBar = styled(TabBar)`\n border-bottom: none;\n`;\n\nconst PanelContent = styled.div<{ $hidden: boolean }>`\n ${({ $hidden }) =>\n $hidden\n ? css`\n position: absolute;\n inset: 0;\n overflow: hidden;\n visibility: hidden;\n pointer-events: none;\n `\n : css`\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n `}\n`;\n\n/**\n * Resizable drawer anchored to the bottom of its container with one tab per\n * panel. Owns the tab bar, expand/collapse/resize, and always-mounted content;\n * the caller owns what each panel shows.\n */\nconst BottomPanel = forwardRef<BottomPanelHandle, BottomPanelProps>(function BottomPanel(\n { panels },\n ref,\n) {\n const baseId = useId();\n const [selected, setSelected] = useState<string | undefined>(panels[0]?.label);\n // Falls back to the first panel when the selected label has left `panels`, and\n // commits the fallback so the old label does not regain selection if it returns.\n const hasSelected = panels.some((panel) => panel.label === selected);\n const selectedLabel = hasSelected ? selected : panels[0]?.label;\n useEffect(() => {\n if (!hasSelected) {\n setSelected(selectedLabel);\n }\n }, [hasSelected, selectedLabel]);\n\n const resizablePanelState = useResizablePanel({\n initialSize: PANEL_MIN_HEIGHT,\n minSize: PANEL_MIN_HEIGHT,\n });\n const { expandTo, panelState, size } = resizablePanelState;\n\n // Selecting a tab opens a collapsed drawer but leaves a maximized one as is.\n const openPanel = useCallback(\n (label: string) => {\n if (panelState === PanelState.Drawer && (size == null || size <= PANEL_MIN_HEIGHT)) {\n expandTo(OPEN_HEIGHT);\n }\n setSelected(label);\n },\n [expandTo, panelState, size],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n openPanel: (label: string) => {\n if (panels.some((panel) => panel.label === label)) {\n openPanel(label);\n }\n },\n }),\n [openPanel, panels],\n );\n\n return (\n <ResizableVerticalPanel\n headerContent={\n <Header>\n <HeaderTabBar>\n {panels.map((panel, index) => (\n <Tab\n aria-controls={`${baseId}-panel-${index}`}\n badge={panel.badge ? <Badge>{panel.badge}</Badge> : undefined}\n id={`${baseId}-tab-${index}`}\n key={panel.label}\n onClick={() => openPanel(panel.label)}\n selected={selectedLabel === panel.label}\n >\n {panel.label}\n </Tab>\n ))}\n </HeaderTabBar>\n </Header>\n }\n hookState={resizablePanelState}\n minHeight={PANEL_MIN_HEIGHT}\n >\n {panels.map((panel, index) => {\n const isSelected = selectedLabel === panel.label;\n return (\n <PanelContent\n $hidden={!isSelected}\n aria-hidden={!isSelected}\n aria-labelledby={`${baseId}-tab-${index}`}\n id={`${baseId}-panel-${index}`}\n key={panel.label}\n role='tabpanel'\n >\n {panel.content}\n </PanelContent>\n );\n })}\n </ResizableVerticalPanel>\n );\n});\n\nexport default BottomPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/BottomPanel/ResizeHandle.tsx","../../../src/components/BottomPanel/ResizableVerticalPanel.tsx","../../../src/components/BottomPanel/BottomPanel.tsx"],"sourcesContent":["import { type FC, type RefObject, useEffect, useRef } from 'react';\nimport styled from 'styled-components';\n\nimport { Z_INDICES } from '@persona/design-system/lib/zindex';\nimport { Spacing } from '@persona/design-tokens';\n\nconst DRAGGING_CLASSNAME = 'dragging';\n\ninterface ResizeHandleProps {\n ariaLabel: string;\n /** Fires on double-click or Enter/Space so the host can toggle/reset the size. */\n onDoubleClick?: () => void;\n /** Called on each pointer move with the new top edge position (clientY) in px. */\n onMoveTo: (position: number) => void;\n /** Called once when the drag ends (pointerup, cancel, or lost capture). */\n onRelease?: () => void;\n /** The panel being resized; its edge seeds the grab offset so the handle doesn't jump. */\n panelRef: RefObject<HTMLDivElement>;\n}\n\n// The visible line is 2px tall on the panel's top border; the hitbox is Spacing[2] tall and\n// straddles that border so it is easy to grab without covering the header row's controls.\nconst ResizeHandleContainer = styled.div`\n cursor: row-resize;\n position: absolute;\n height: ${Spacing[2]};\n top: -${Spacing[1]};\n left: 0;\n right: 0;\n z-index: ${Z_INDICES.dropdown};\n touch-action: none;\n\n &::after {\n content: '';\n position: absolute;\n top: ${Spacing[1]};\n left: 0;\n right: 0;\n height: 2px;\n background-color: transparent;\n transition: background-color 0.15s ease-in;\n transition-delay: 0.025s;\n }\n\n &:hover::after,\n &.${DRAGGING_CLASSNAME}::after {\n background-color: ${({ theme }) => theme.color.border.active};\n }\n`;\n\n/** Vertical resize handle pinned to the top edge of a bottom-anchored panel. */\nexport const ResizeHandle: FC<ResizeHandleProps> = ({\n ariaLabel,\n onDoubleClick,\n onMoveTo,\n onRelease,\n panelRef,\n}) => {\n const resizeHandleRef = useRef<HTMLDivElement>(null);\n const panelOffsetRef = useRef(0);\n const activePointerIdRef = useRef<number | null>(null);\n const documentListenersRef = useRef<{\n handleEnd: (event: PointerEvent) => void;\n handleMove: (event: PointerEvent) => void;\n } | null>(null);\n // Document listeners are registered once per drag; reading the callbacks through\n // refs keeps them on the latest props without re-registering mid-drag.\n const onMoveToRef = useRef(onMoveTo);\n const onReleaseRef = useRef(onRelease);\n onMoveToRef.current = onMoveTo;\n onReleaseRef.current = onRelease;\n\n const removeDocumentListeners = () => {\n const listeners = documentListenersRef.current;\n if (!listeners) {\n return;\n }\n\n document.removeEventListener('pointermove', listeners.handleMove);\n document.removeEventListener('pointerup', listeners.handleEnd);\n document.removeEventListener('pointercancel', listeners.handleEnd);\n documentListenersRef.current = null;\n };\n\n // Pointer capture routes events through the handle (including over iframes), but\n // some surfaces still drop pointerup. Document-level listeners during an active\n // drag are the release safety net. Only the pointer that started the drag may\n // move or end it.\n const endDrag = (pointerId: number) => {\n if (activePointerIdRef.current !== pointerId) {\n return;\n }\n\n activePointerIdRef.current = null;\n removeDocumentListeners();\n try {\n resizeHandleRef.current?.releasePointerCapture(pointerId);\n } catch {\n // No active capture (or unsupported, e.g. jsdom) — nothing to release.\n }\n\n resizeHandleRef.current?.classList.remove(DRAGGING_CLASSNAME);\n panelOffsetRef.current = 0;\n onReleaseRef.current?.();\n };\n\n const handleDocumentPointerMove = (event: PointerEvent) => {\n if (activePointerIdRef.current !== event.pointerId) {\n return;\n }\n\n onMoveToRef.current(event.clientY + panelOffsetRef.current);\n };\n\n const addDocumentListeners = () => {\n removeDocumentListeners();\n\n const listeners = {\n handleEnd: (event: PointerEvent) => endDrag(event.pointerId),\n handleMove: handleDocumentPointerMove,\n };\n documentListenersRef.current = listeners;\n document.addEventListener('pointermove', listeners.handleMove);\n document.addEventListener('pointerup', listeners.handleEnd);\n document.addEventListener('pointercancel', listeners.handleEnd);\n };\n\n const endDragRef = useRef(endDrag);\n endDragRef.current = endDrag;\n useEffect(() => {\n return () => {\n const activePointerId = activePointerIdRef.current;\n if (activePointerId != null) {\n endDragRef.current(activePointerId);\n }\n };\n }, []);\n\n return (\n <ResizeHandleContainer\n aria-label={ariaLabel}\n onDoubleClick={onDoubleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n onDoubleClick?.();\n e.preventDefault();\n }\n }}\n onLostPointerCapture={(e) => endDrag(e.pointerId)}\n onPointerCancel={(e) => endDrag(e.pointerId)}\n onPointerDown={(e) => {\n // Primary button / touch / pen only; ignore secondary and middle clicks,\n // and a second pointer while a drag is already active.\n if (e.button !== 0 || activePointerIdRef.current != null) {\n return;\n }\n const panelRect = panelRef.current?.getBoundingClientRect();\n panelOffsetRef.current = panelRect ? panelRect.top - e.clientY : 0;\n activePointerIdRef.current = e.pointerId;\n resizeHandleRef.current?.classList.add(DRAGGING_CLASSNAME);\n addDocumentListeners();\n try {\n resizeHandleRef.current?.setPointerCapture(e.pointerId);\n } catch {\n // Pointer capture unsupported (e.g. jsdom) — document listeners still\n // route move/up events for the duration of the drag.\n }\n e.preventDefault();\n e.stopPropagation();\n }}\n onPointerUp={(e) => endDrag(e.pointerId)}\n ref={resizeHandleRef}\n role='button'\n tabIndex={0}\n />\n );\n};\n","import { type FC, type ReactNode, useRef } from 'react';\nimport styled from 'styled-components';\n\nimport { IconButton } from '@persona/design-system/components/Button';\nimport { PanelState, type ResizablePanelState } from '@persona/design-system/lib/useResizablePanel';\nimport { Z_INDICES } from '@persona/design-system/lib/zindex';\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { ArrowCollapseIcon, ArrowExpandIcon, XIcon } from '@persona/icons';\n\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\n\nimport { ResizeHandle } from './ResizeHandle';\n\ninterface ResizableVerticalPanelProps {\n /** Panel body, rendered in the scrollable content area below the header. */\n children: ReactNode;\n /** Content for the header row, left of the maximize/minimize/close buttons. */\n headerContent?: ReactNode;\n /** State and drag/resize handlers from `useResizablePanel`. */\n hookState: ResizablePanelState;\n /** Minimum panel height in px. */\n minHeight: number;\n}\n\nconst TriStatePanel = styled.div.attrs<{\n customHeight: number | null;\n minHeight: number;\n panelState: PanelState;\n}>(({ customHeight, minHeight, panelState }) => ({\n style: {\n height: panelState === PanelState.Maximized ? '100%' : `${customHeight ?? minHeight}px`,\n },\n}))<{\n customHeight: number | null;\n minHeight: number;\n panelState: PanelState;\n}>`\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n background-color: ${({ theme }) => theme.color.background.primary};\n position: relative;\n min-height: ${({ minHeight }) => minHeight}px;\n width: 100%;\n border-top: 1px solid ${Color.BorderDivider};\n z-index: ${Z_INDICES.topNav};\n`;\n\nconst TopRowContainer = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n box-shadow: inset 0px -1px 0px 0px ${Color.BorderDivider};\n`;\n\nconst TopRightIconsContainer = styled.div`\n display: flex;\n align-items: center;\n padding: 0 ${Spacing[2]};\n gap: ${Spacing[2]};\n flex-direction: row;\n`;\n\nconst ContentContainer = styled.div`\n /* offset by the top row container height */\n height: calc(100% - ${Spacing[6]});\n overflow: auto;\n ${semanticScrollbar}\n display: flex;\n flex-direction: column;\n min-height: 0;\n`;\n\n/**\n * Bottom-anchored panel with a drag-to-resize top edge, a header row, and\n * maximize/minimize/close controls.\n */\nexport const ResizableVerticalPanel: FC<ResizableVerticalPanelProps> = ({\n children,\n headerContent,\n hookState,\n minHeight,\n}) => {\n const {\n collapse,\n handleDragMove: handlePanelDragMove,\n handleDragRelease,\n maximize,\n panelState,\n restore,\n size,\n toggleMaximized,\n } = hookState;\n const panelRef = useRef<HTMLDivElement>(null);\n // Controls only make sense once the drawer is taller than its collapsed header.\n const showControls = (size != null && size > minHeight) || panelState === PanelState.Maximized;\n // Converts the dragged top edge (clientY) into a panel height bounded by the\n // panel's container.\n const handleDragMove = (clientY: number) => {\n const panel = panelRef.current;\n const container = panel?.parentElement;\n if (!panel || !container) {\n return;\n }\n const panelBottom = panel.getBoundingClientRect().bottom;\n const containerTop = container.getBoundingClientRect().top;\n handlePanelDragMove(panelBottom - clientY, panelBottom - containerTop);\n };\n\n return (\n <TriStatePanel\n aria-label='Bottom panel'\n customHeight={size}\n minHeight={minHeight}\n panelState={panelState}\n ref={panelRef}\n role='region'\n >\n <ResizeHandle\n ariaLabel='Drag to resize bottom panel'\n onDoubleClick={toggleMaximized}\n onMoveTo={handleDragMove}\n onRelease={handleDragRelease}\n panelRef={panelRef}\n />\n\n <TopRowContainer>\n {headerContent}\n\n {showControls && (\n <TopRightIconsContainer>\n {panelState === PanelState.Maximized ? (\n <IconButton aria-label='Restore the bottom panel' onClick={restore} size='sm'>\n <ArrowCollapseIcon />\n </IconButton>\n ) : (\n <IconButton aria-label='Maximize the bottom panel' onClick={maximize} size='sm'>\n <ArrowExpandIcon />\n </IconButton>\n )}\n <IconButton aria-label='Close bottom panel' onClick={collapse} size='sm'>\n <XIcon />\n </IconButton>\n </TopRightIconsContainer>\n )}\n </TopRowContainer>\n\n <ContentContainer>{children}</ContentContainer>\n </TriStatePanel>\n );\n};\n","import {\n forwardRef,\n type ReactNode,\n useCallback,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react';\nimport { useId } from 'react-aria';\nimport styled, { css, useTheme } from 'styled-components';\n\nimport Badge from '@persona/design-system/components/Badge';\nimport { HStack, Stack } from '@persona/design-system/components/Stack';\nimport TabBar, { Tab } from '@persona/design-system/components/TabBar';\nimport { Paragraph } from '@persona/design-system/components/Text';\nimport { usePDSStrings } from '@persona/design-system/lib/i18n';\nimport { semanticColor } from '@persona/design-system/lib/semanticColor';\nimport { PanelState, useResizablePanel } from '@persona/design-system/lib/useResizablePanel';\nimport { focusOutline } from '@persona/design-system/mixins/focus';\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\nimport { CircleXInverseIcon } from '@persona/icons';\n\nimport { ResizableVerticalPanel } from './ResizableVerticalPanel';\n\n// One-pixel panel top border plus the 32px header row sets the collapsed drawer height.\nconst PANEL_MIN_HEIGHT = 33;\n// Where the drawer opens to when a collapsed tab is selected; the user can drag from there.\nconst OPEN_HEIGHT = 200;\n\nexport interface BottomPanelItemProps {\n /** Tab text; also the key `openPanel(label)` looks up. Unique per BottomPanel. */\n label: string;\n /**\n * Tab body. Every panel stays mounted while another tab is selected, so local\n * state (scroll, expanded rows) survives a switch.\n */\n content: ReactNode;\n /** Count shown as a badge on the tab. `0`/`undefined` hides it. */\n badge?: number;\n}\n\nexport interface BottomPanelHandle {\n /** Select the tab and expand the drawer if collapsed. No-op for an unknown label. */\n openPanel: (label: string) => void;\n}\n\nexport interface BottomPanelProps {\n /** Tabs to show, in order. */\n panels: BottomPanelItemProps[];\n /**\n * Error count rendered as an icon + count at the right edge of the header, next to\n * the expand/collapse controls. `0` renders dimmed; `undefined` hides it.\n */\n errorCount?: number;\n /** Turns the error count into a button (e.g. to open the panel listing the errors). */\n onErrorCountClick?: () => void;\n}\n\nconst Header = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n padding-left: ${Spacing[4]};\n`;\n\nconst ErrorSummary = styled(HStack).attrs({ align: 'center' })`\n flex-shrink: 0;\n padding-right: ${Spacing[2]};\n`;\n\nconst ErrorSummaryDivider = styled.div`\n width: 1px;\n height: ${Spacing[6]};\n background: ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n`;\n\n// styled(Stack), not styled(HStack): HStack is a plain function component, so `as` would\n// replace it entirely and drop the flex layout when this renders as a <button>.\nconst ErrorIndicator = styled(Stack).attrs<{ $clickable: boolean }>({\n align: 'center',\n direction: 'horizontal',\n spacing: Spacing[1],\n})`\n padding: ${Spacing[1]} ${Spacing[2]};\n background: none;\n border: none;\n border-radius: ${BorderRadius.Sm};\n font: inherit;\n color: inherit;\n ${({ $clickable }) =>\n $clickable\n ? css`\n cursor: pointer;\n\n &:hover {\n background: ${({ theme }) =>\n semanticColor(theme, 'ActionNeutralHover', theme.color.variants.basic.hover)};\n }\n\n &:active {\n background: ${({ theme }) =>\n semanticColor(theme, 'ActionNeutralActive', theme.color.variants.basic.highlight)};\n }\n\n ${focusOutline}\n `\n : ''}\n`;\n\n// The header row draws the divider edge to edge; the tab bar must not add its own.\n// It shrinks and clips overflowing tabs so the header controls stay pinned right.\nconst HeaderTabBar = styled(TabBar)`\n border-bottom: none;\n flex: 1;\n min-width: 0;\n`;\n\nconst PanelContent = styled.div<{ $hidden: boolean }>`\n ${({ $hidden }) =>\n $hidden\n ? css`\n position: absolute;\n inset: 0;\n overflow: hidden;\n visibility: hidden;\n pointer-events: none;\n `\n : css`\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n `}\n`;\n\n/**\n * Resizable drawer anchored to the bottom of its container with one tab per\n * panel. Owns the tab bar, expand/collapse/resize, and always-mounted content;\n * the caller owns what each panel shows.\n */\nconst BottomPanel = forwardRef<BottomPanelHandle, BottomPanelProps>(function BottomPanel(\n { panels, errorCount, onErrorCountClick },\n ref,\n) {\n const strings = usePDSStrings();\n const theme = useTheme();\n const baseId = useId();\n const [selected, setSelected] = useState<string | undefined>(panels[0]?.label);\n // Falls back to the first panel when the selected label has left `panels`, and\n // commits the fallback so the old label does not regain selection if it returns.\n const hasSelected = panels.some((panel) => panel.label === selected);\n const selectedLabel = hasSelected ? selected : panels[0]?.label;\n useEffect(() => {\n if (!hasSelected) {\n setSelected(selectedLabel);\n }\n }, [hasSelected, selectedLabel]);\n\n const resizablePanelState = useResizablePanel({\n initialSize: PANEL_MIN_HEIGHT,\n minSize: PANEL_MIN_HEIGHT,\n });\n const { expandTo, panelState, size } = resizablePanelState;\n\n // Selecting a tab opens a collapsed drawer but leaves a maximized one as is.\n const openPanel = useCallback(\n (label: string) => {\n if (panelState === PanelState.Drawer && (size == null || size <= PANEL_MIN_HEIGHT)) {\n expandTo(OPEN_HEIGHT);\n }\n setSelected(label);\n },\n [expandTo, panelState, size],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n openPanel: (label: string) => {\n if (panels.some((panel) => panel.label === label)) {\n openPanel(label);\n }\n },\n }),\n [openPanel, panels],\n );\n\n return (\n <ResizableVerticalPanel\n headerContent={\n <Header>\n <HeaderTabBar>\n {panels.map((panel, index) => (\n <Tab\n aria-controls={`${baseId}-panel-${index}`}\n badge={panel.badge ? <Badge>{panel.badge}</Badge> : undefined}\n id={`${baseId}-tab-${index}`}\n key={panel.label}\n onClick={() => openPanel(panel.label)}\n selected={selectedLabel === panel.label}\n >\n {panel.label}\n </Tab>\n ))}\n </HeaderTabBar>\n {errorCount != null && (\n <ErrorSummary>\n <ErrorSummaryDivider aria-hidden />\n <ErrorIndicator\n $clickable={onErrorCountClick != null}\n aria-label={strings.errorCount(errorCount)}\n as={onErrorCountClick ? 'button' : 'div'}\n onClick={onErrorCountClick}\n role={onErrorCountClick ? undefined : 'img'}\n type={onErrorCountClick ? 'button' : undefined}\n >\n <CircleXInverseIcon\n aria-hidden\n color={\n errorCount === 0\n ? semanticColor(theme, 'FgDisabled', Color.TextDisabled)\n : semanticColor(theme, 'FgDanger1', Color.TextDanger)\n }\n />\n <Paragraph as='span' color={errorCount === 0 ? 'disabled' : 'primary'} size='md'>\n {errorCount}\n </Paragraph>\n </ErrorIndicator>\n </ErrorSummary>\n )}\n </Header>\n }\n hookState={resizablePanelState}\n minHeight={PANEL_MIN_HEIGHT}\n >\n {panels.map((panel, index) => {\n const isSelected = selectedLabel === panel.label;\n return (\n <PanelContent\n $hidden={!isSelected}\n aria-hidden={!isSelected}\n aria-labelledby={`${baseId}-tab-${index}`}\n id={`${baseId}-panel-${index}`}\n key={panel.label}\n role='tabpanel'\n >\n {panel.content}\n </PanelContent>\n );\n })}\n </ResizableVerticalPanel>\n );\n});\n\nexport default BottomPanel;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAMA,MAAM,qBAAqB;AAgB3B,MAAM,wBAAwB,OAAO,GAAG;;;YAG5B,QAAQ,GAAG;UACb,QAAQ,GAAG;;;aAGR,UAAU,SAAS;;;;;;WAMrB,QAAQ,GAAG;;;;;;;;;;MAUhB,mBAAmB;yBACA,EAAE,YAAY,MAAM,MAAM,OAAO,OAAO;;;;AAKjE,MAAa,gBAAuC,EAClD,WACA,eACA,UACA,WACA,eACI;CACJ,MAAM,kBAAkB,OAAuB,KAAK;CACpD,MAAM,iBAAiB,OAAO,EAAE;CAChC,MAAM,qBAAqB,OAAsB,KAAK;CACtD,MAAM,uBAAuB,OAGnB,KAAK;CAGf,MAAM,cAAc,OAAO,SAAS;CACpC,MAAM,eAAe,OAAO,UAAU;AACtC,aAAY,UAAU;AACtB,cAAa,UAAU;CAEvB,MAAM,gCAAgC;EACpC,MAAM,YAAY,qBAAqB;AACvC,MAAI,CAAC,UACH;AAGF,WAAS,oBAAoB,eAAe,UAAU,WAAW;AACjE,WAAS,oBAAoB,aAAa,UAAU,UAAU;AAC9D,WAAS,oBAAoB,iBAAiB,UAAU,UAAU;AAClE,uBAAqB,UAAU;;CAOjC,MAAM,WAAW,cAAsB;AACrC,MAAI,mBAAmB,YAAY,UACjC;AAGF,qBAAmB,UAAU;AAC7B,2BAAyB;AACzB,MAAI;AACF,mBAAgB,SAAS,sBAAsB,UAAU;UACnD;AAIR,kBAAgB,SAAS,UAAU,OAAO,mBAAmB;AAC7D,iBAAe,UAAU;AACzB,eAAa,WAAW;;CAG1B,MAAM,6BAA6B,UAAwB;AACzD,MAAI,mBAAmB,YAAY,MAAM,UACvC;AAGF,cAAY,QAAQ,MAAM,UAAU,eAAe,QAAQ;;CAG7D,MAAM,6BAA6B;AACjC,2BAAyB;EAEzB,MAAM,YAAY;GAChB,YAAY,UAAwB,QAAQ,MAAM,UAAU;GAC5D,YAAY;GACb;AACD,uBAAqB,UAAU;AAC/B,WAAS,iBAAiB,eAAe,UAAU,WAAW;AAC9D,WAAS,iBAAiB,aAAa,UAAU,UAAU;AAC3D,WAAS,iBAAiB,iBAAiB,UAAU,UAAU;;CAGjE,MAAM,aAAa,OAAO,QAAQ;AAClC,YAAW,UAAU;AACrB,iBAAgB;AACd,eAAa;GACX,MAAM,kBAAkB,mBAAmB;AAC3C,OAAI,mBAAmB,KACrB,YAAW,QAAQ,gBAAgB;;IAGtC,EAAE,CAAC;AAEN,QACE,oBAAC,uBAAD;EACE,cAAY;EACG;EACf,YAAY,MAAM;AAChB,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,qBAAiB;AACjB,MAAE,gBAAgB;;;EAGtB,uBAAuB,MAAM,QAAQ,EAAE,UAAU;EACjD,kBAAkB,MAAM,QAAQ,EAAE,UAAU;EAC5C,gBAAgB,MAAM;AAGpB,OAAI,EAAE,WAAW,KAAK,mBAAmB,WAAW,KAClD;GAEF,MAAM,YAAY,SAAS,SAAS,uBAAuB;AAC3D,kBAAe,UAAU,YAAY,UAAU,MAAM,EAAE,UAAU;AACjE,sBAAmB,UAAU,EAAE;AAC/B,mBAAgB,SAAS,UAAU,IAAI,mBAAmB;AAC1D,yBAAsB;AACtB,OAAI;AACF,oBAAgB,SAAS,kBAAkB,EAAE,UAAU;WACjD;AAIR,KAAE,gBAAgB;AAClB,KAAE,iBAAiB;;EAErB,cAAc,MAAM,QAAQ,EAAE,UAAU;EACxC,KAAK;EACL,MAAK;EACL,UAAU;EACV,CAAA;;;;ACtJN,MAAM,gBAAgB,OAAO,IAAI,OAI7B,EAAE,cAAc,WAAW,kBAAkB,EAC/C,OAAO,EACL,QAAQ,eAAA,cAAsC,SAAS,GAAG,gBAAgB,UAAU,KACrF,EACF,EAAE;;;;;uBASoB,EAAE,YAAY,MAAM,MAAM,WAAW,QAAQ;;iBAEnD,EAAE,gBAAgB,UAAU;;0BAEnB,MAAM,cAAc;aACjC,UAAU,OAAO;;AAG9B,MAAM,kBAAkB,OAAO,GAAG;;;;uCAIK,MAAM,cAAc;;AAG3D,MAAM,yBAAyB,OAAO,GAAG;;;eAG1B,QAAQ,GAAG;SACjB,QAAQ,GAAG;;;AAIpB,MAAM,mBAAmB,OAAO,GAAG;;wBAEX,QAAQ,GAAG;;IAE/B,kBAAkB;;;;;;;;;AAUtB,MAAa,0BAA2D,EACtE,UACA,eACA,WACA,gBACI;CACJ,MAAM,EACJ,UACA,gBAAgB,qBAChB,mBACA,UACA,YACA,SACA,MACA,oBACE;CACJ,MAAM,WAAW,OAAuB,KAAK;CAE7C,MAAM,eAAgB,QAAQ,QAAQ,OAAO,aAAc,eAAA;CAG3D,MAAM,kBAAkB,YAAoB;EAC1C,MAAM,QAAQ,SAAS;EACvB,MAAM,YAAY,OAAO;AACzB,MAAI,CAAC,SAAS,CAAC,UACb;EAEF,MAAM,cAAc,MAAM,uBAAuB,CAAC;EAClD,MAAM,eAAe,UAAU,uBAAuB,CAAC;AACvD,sBAAoB,cAAc,SAAS,cAAc,aAAa;;AAGxE,QACE,qBAAC,eAAD;EACE,cAAW;EACX,cAAc;EACH;EACC;EACZ,KAAK;EACL,MAAK;YANP;GAQE,oBAAC,cAAD;IACE,WAAU;IACV,eAAe;IACf,UAAU;IACV,WAAW;IACD;IACV,CAAA;GAEF,qBAAC,iBAAD,EAAA,UAAA,CACG,eAEA,gBACC,qBAAC,wBAAD,EAAA,UAAA,CACG,eAAA,cACC,oBAAC,YAAD;IAAY,cAAW;IAA2B,SAAS;IAAS,MAAK;cACvE,oBAAC,mBAAD,EAAqB,CAAA;IACV,CAAA,GAEb,oBAAC,YAAD;IAAY,cAAW;IAA4B,SAAS;IAAU,MAAK;cACzE,oBAAC,iBAAD,EAAmB,CAAA;IACR,CAAA,EAEf,oBAAC,YAAD;IAAY,cAAW;IAAqB,SAAS;IAAU,MAAK;cAClE,oBAAC,OAAD,EAAS,CAAA;IACE,CAAA,CACU,EAAA,CAAA,CAEX,EAAA,CAAA;GAElB,oBAAC,kBAAD,EAAmB,UAA4B,CAAA;GACjC;;;;;AC5HpB,MAAM,mBAAmB;AAEzB,MAAM,cAAc;AA+BpB,MAAM,SAAS,OAAO,GAAG;;;;;;;kBAOP,QAAQ,GAAG;;AAG7B,MAAM,eAAe,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC;;mBAE3C,QAAQ,GAAG;;AAG9B,MAAM,sBAAsB,OAAO,GAAG;;YAE1B,QAAQ,GAAG;iBACN,EAAE,YAAY,cAAc,OAAO,gBAAgB,MAAM,cAAc,CAAC;;AAKzF,MAAM,iBAAiB,OAAO,MAAM,CAAC,MAA+B;CAClE,OAAO;CACP,WAAW;CACX,SAAS,QAAQ;CAClB,CAAC;aACW,QAAQ,GAAG,GAAG,QAAQ,GAAG;;;mBAGnB,aAAa,GAAG;;;KAG9B,EAAE,iBACH,aACI,GAAG;;;;2BAIgB,EAAE,YACf,cAAc,OAAO,sBAAsB,MAAM,MAAM,SAAS,MAAM,MAAM,CAAC;;;;2BAIhE,EAAE,YACf,cAAc,OAAO,uBAAuB,MAAM,MAAM,SAAS,MAAM,UAAU,CAAC;;;YAGpF,aAAa;YAEjB,GAAG;;AAKX,MAAM,eAAe,OAAO,OAAO;;;;;AAMnC,MAAM,eAAe,OAAO,GAAyB;KAChD,EAAE,cACH,UACI,GAAG;;;;;;YAOH,GAAG;;;;;UAKD;;;;;;;AAQV,MAAM,cAAc,WAAgD,SAAS,YAC3E,EAAE,QAAQ,YAAY,qBACtB,KACA;CACA,MAAM,UAAU,eAAe;CAC/B,MAAM,QAAQ,UAAU;CACxB,MAAM,SAAS,OAAO;CACtB,MAAM,CAAC,UAAU,eAAe,SAA6B,OAAO,IAAI,MAAM;CAG9E,MAAM,cAAc,OAAO,MAAM,UAAU,MAAM,UAAU,SAAS;CACpE,MAAM,gBAAgB,cAAc,WAAW,OAAO,IAAI;AAC1D,iBAAgB;AACd,MAAI,CAAC,YACH,aAAY,cAAc;IAE3B,CAAC,aAAa,cAAc,CAAC;CAEhC,MAAM,sBAAsB,kBAAkB;EAC5C,aAAa;EACb,SAAS;EACV,CAAC;CACF,MAAM,EAAE,UAAU,YAAY,SAAS;CAGvC,MAAM,YAAY,aACf,UAAkB;AACjB,MAAI,eAAA,aAAqC,QAAQ,QAAQ,QAAQ,kBAC/D,UAAS,YAAY;AAEvB,cAAY,MAAM;IAEpB;EAAC;EAAU;EAAY;EAAK,CAC7B;AAED,qBACE,YACO,EACL,YAAY,UAAkB;AAC5B,MAAI,OAAO,MAAM,UAAU,MAAM,UAAU,MAAM,CAC/C,WAAU,MAAM;IAGrB,GACD,CAAC,WAAW,OAAO,CACpB;AAED,QACE,oBAAC,wBAAD;EACE,eACE,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,cAAD,EAAA,UACG,OAAO,KAAK,OAAO,UAClB,oBAAC,KAAD;GACE,iBAAe,GAAG,OAAO,SAAS;GAClC,OAAO,MAAM,QAAQ,oBAAC,OAAD,EAAA,UAAQ,MAAM,OAAc,CAAA,GAAG,KAAA;GACpD,IAAI,GAAG,OAAO,OAAO;GAErB,eAAe,UAAU,MAAM,MAAM;GACrC,UAAU,kBAAkB,MAAM;aAEjC,MAAM;GACH,EALC,MAAM,MAKP,CACN,EACW,CAAA,EACd,cAAc,QACb,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD,EAAqB,eAAA,MAAc,CAAA,EACnC,qBAAC,gBAAD;GACE,YAAY,qBAAqB;GACjC,cAAY,QAAQ,WAAW,WAAW;GAC1C,IAAI,oBAAoB,WAAW;GACnC,SAAS;GACT,MAAM,oBAAoB,KAAA,IAAY;GACtC,MAAM,oBAAoB,WAAW,KAAA;aANvC,CAQE,oBAAC,oBAAD;IACE,eAAA;IACA,OACE,eAAe,IACX,cAAc,OAAO,cAAc,MAAM,aAAa,GACtD,cAAc,OAAO,aAAa,MAAM,WAAW;IAEzD,CAAA,EACF,oBAAC,WAAD;IAAW,IAAG;IAAO,OAAO,eAAe,IAAI,aAAa;IAAW,MAAK;cACzE;IACS,CAAA,CACG;KACJ,EAAA,CAAA,CAEV,EAAA,CAAA;EAEX,WAAW;EACX,WAAW;YAEV,OAAO,KAAK,OAAO,UAAU;GAC5B,MAAM,aAAa,kBAAkB,MAAM;AAC3C,UACE,oBAAC,cAAD;IACE,SAAS,CAAC;IACV,eAAa,CAAC;IACd,mBAAiB,GAAG,OAAO,OAAO;IAClC,IAAI,GAAG,OAAO,SAAS;IAEvB,MAAK;cAEJ,MAAM;IACM,EAJR,MAAM,MAIE;IAEjB;EACqB,CAAA;EAE3B"}
@@ -1,2 +1,2 @@
1
- import { n as BreadcrumbsItemProps, r as BreadcrumbsProps, t as Breadcrumbs } from "../../Breadcrumbs-DRu_JfdI.mjs";
1
+ import { n as BreadcrumbsItemProps, r as BreadcrumbsProps, t as Breadcrumbs } from "../../Breadcrumbs-ChKWIuRq.mjs";
2
2
  export { Breadcrumbs, Breadcrumbs as default, BreadcrumbsItemProps, BreadcrumbsProps };
@@ -1,3 +1,3 @@
1
- import { a as SuffixIconContainer, i as StyledButton, n as ButtonChildren, r as ButtonProps, t as Button } from "../../Button-Cg8KyT5M.mjs";
2
- import { t as IconButton } from "../../IconButton-KhCwTwPx.mjs";
1
+ import { a as SuffixIconContainer, i as StyledButton, n as ButtonChildren, r as ButtonProps, t as Button } from "../../Button-B79_aXfC.mjs";
2
+ import { t as IconButton } from "../../IconButton-CaEvsrOn.mjs";
3
3
  export { Button, Button as default, ButtonChildren, ButtonProps, IconButton, StyledButton, SuffixIconContainer };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';\nimport type {\n ToggleGroupMultipleProps,\n ToggleGroupSingleProps,\n} from '@radix-ui/react-toggle-group';\nimport { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\nimport IconButton from 'design-system/components/Button/IconButton';\nimport { buttonPalette } from 'design-system/components/Button/palette';\nimport useFormField from 'design-system/components/FormControl/useFormField';\nimport { withAlpha } from 'design-system/lib/color';\nimport { semanticOnly } from 'design-system/lib/semanticColor';\n\nexport interface ButtonGroupProps {\n id?: string;\n className?: string;\n fullWidth?: boolean;\n}\n\nconst OptionItem = styled(IconButton)`\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n flex: 1;\n border-radius: ${BorderRadius.Md};\n width: 32px;\n height: 32px;\n background-color: ${({ theme }) => buttonPalette(theme, 'basic').default};\n white-space: nowrap;\n\n // radix-toggle-group adds a wrapping div to the options, so this is to\n // make sure the content is always center-aligned\n & > div {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n &[data-state='on'] {\n background-color: ${({ theme }) => buttonPalette(theme, 'basic').active};\n }\n\n ${semanticOnly(\n (tokens) => css`\n &:disabled {\n background-color: ${withAlpha(tokens.ActionNeutral, tokens.Opacity65)};\n }\n `,\n )}\n\n &:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n\n &[tabindex='0'] {\n z-index: 1;\n }\n`;\n\nconst ButtonGroupContainer = styled.div<{ fullWidth?: boolean }>`\n display: inline-flex;\n justify-content: space-between;\n border-radius: 4px;\n width: ${({ fullWidth }) => (fullWidth ? `100%` : `max-content`)};\n gap: 1px;\n\n > * {\n ${({ fullWidth }) =>\n fullWidth &&\n css`\n flex: 1;\n `}\n }\n`;\n\nexport const ButtonGroup = ({\n children,\n fullWidth,\n ...props\n}: (ToggleGroupSingleProps | ToggleGroupMultipleProps) & ButtonGroupProps) => {\n const { disabled } = props;\n const field = useFormField({ inputId: props.id, disabled });\n\n return (\n <ToggleGroupPrimitive.Root\n {...props}\n disabled={field.disabled}\n aria-describedby={field.helperTextId}\n aria-errormessage={field.hasError ? field.helperTextId : undefined}\n aria-invalid={field.hasError}\n >\n <ButtonGroupContainer fullWidth={fullWidth} {...props}>\n {children}\n </ButtonGroupContainer>\n </ToggleGroupPrimitive.Root>\n );\n};\n\nexport default ButtonGroup;\n\nconst ButtonItem = forwardRef<HTMLButtonElement, ToggleGroupPrimitive.ToggleGroupItemProps>(\n function ButtonItem(props: ToggleGroupPrimitive.ToggleGroupItemProps, forwardedRef) {\n return <OptionItem ref={forwardedRef} {...props} />;\n },\n);\n\nexport const ButtonGroupItem = forwardRef<\n HTMLButtonElement,\n ToggleGroupPrimitive.ToggleGroupItemProps\n>(function ButtonGroupItem({ children, ...props }, forwardedRef) {\n return (\n <ToggleGroupPrimitive.Item {...props} ref={forwardedRef} asChild>\n <ButtonItem {...props}>{children}</ButtonItem>\n </ToggleGroupPrimitive.Item>\n );\n});\n"],"mappings":";;;;;;;;;;AAqBA,MAAM,aAAa,OAAO,WAAW;;;;;;mBAMlB,aAAa,GAAG;;;uBAGZ,EAAE,YAAY,cAAc,OAAO,QAAQ,CAAC,QAAQ;;;;;;;;;;;;yBAYlD,EAAE,YAAY,cAAc,OAAO,QAAQ,CAAC,OAAO;;;IAGxE,cACC,WAAW,GAAG;;4BAES,UAAU,OAAO,eAAe,OAAO,UAAU,CAAC;;MAG3E,CAAC;;;;;;;;;;;;;;;;;;;;AAqBJ,MAAM,uBAAuB,OAAO,GAA4B;;;;YAIpD,EAAE,gBAAiB,YAAY,SAAS,cAAe;;;;OAI5D,EAAE,gBACH,aACA,GAAG;;QAED;;;AAIR,MAAa,eAAe,EAC1B,UACA,WACA,GAAG,YACyE;CAC5E,MAAM,EAAE,aAAa;CACrB,MAAM,QAAQ,aAAa;EAAE,SAAS,MAAM;EAAI;EAAU,CAAC;AAE3D,QACE,oBAAC,qBAAqB,MAAtB;EACE,GAAI;EACJ,UAAU,MAAM;EAChB,oBAAkB,MAAM;EACxB,qBAAmB,MAAM,WAAW,MAAM,eAAe,KAAA;EACzD,gBAAc,MAAM;YAEpB,oBAAC,sBAAD;GAAiC;GAAW,GAAI;GAC7C;GACoB,CAAA;EACG,CAAA;;AAMhC,MAAM,aAAa,WACjB,SAAS,WAAW,OAAkD,cAAc;AAClF,QAAO,oBAAC,YAAD;EAAY,KAAK;EAAc,GAAI;EAAS,CAAA;EAEtD;AAED,MAAa,kBAAkB,WAG7B,SAAS,gBAAgB,EAAE,UAAU,GAAG,SAAS,cAAc;AAC/D,QACE,oBAAC,qBAAqB,MAAtB;EAA2B,GAAI;EAAO,KAAK;EAAc,SAAA;YACvD,oBAAC,YAAD;GAAY,GAAI;GAAQ;GAAsB,CAAA;EACpB,CAAA;EAE9B"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';\nimport type {\n ToggleGroupMultipleProps,\n ToggleGroupSingleProps,\n} from '@radix-ui/react-toggle-group';\nimport { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\n\nimport IconButton from '#src/components/Button/IconButton';\nimport { buttonPalette } from '#src/components/Button/palette';\nimport useFormField from '#src/components/FormControl/useFormField';\nimport { withAlpha } from '#src/lib/color';\nimport { semanticOnly } from '#src/lib/semanticColor';\n\nexport interface ButtonGroupProps {\n id?: string;\n className?: string;\n fullWidth?: boolean;\n}\n\nconst OptionItem = styled(IconButton)`\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n flex: 1;\n border-radius: ${BorderRadius.Md};\n width: 32px;\n height: 32px;\n background-color: ${({ theme }) => buttonPalette(theme, 'basic').default};\n white-space: nowrap;\n\n // radix-toggle-group adds a wrapping div to the options, so this is to\n // make sure the content is always center-aligned\n & > div {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n &[data-state='on'] {\n background-color: ${({ theme }) => buttonPalette(theme, 'basic').active};\n }\n\n ${semanticOnly(\n (tokens) => css`\n &:disabled {\n background-color: ${withAlpha(tokens.ActionNeutral, tokens.Opacity65)};\n }\n `,\n )}\n\n &:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n\n &[tabindex='0'] {\n z-index: 1;\n }\n`;\n\nconst ButtonGroupContainer = styled.div<{ fullWidth?: boolean }>`\n display: inline-flex;\n justify-content: space-between;\n border-radius: 4px;\n width: ${({ fullWidth }) => (fullWidth ? `100%` : `max-content`)};\n gap: 1px;\n\n > * {\n ${({ fullWidth }) =>\n fullWidth &&\n css`\n flex: 1;\n `}\n }\n`;\n\nexport const ButtonGroup = ({\n children,\n fullWidth,\n ...props\n}: (ToggleGroupSingleProps | ToggleGroupMultipleProps) & ButtonGroupProps) => {\n const { disabled } = props;\n const field = useFormField({ inputId: props.id, disabled });\n\n return (\n <ToggleGroupPrimitive.Root\n {...props}\n disabled={field.disabled}\n aria-describedby={field.helperTextId}\n aria-errormessage={field.hasError ? field.helperTextId : undefined}\n aria-invalid={field.hasError}\n >\n <ButtonGroupContainer fullWidth={fullWidth} {...props}>\n {children}\n </ButtonGroupContainer>\n </ToggleGroupPrimitive.Root>\n );\n};\n\nexport default ButtonGroup;\n\nconst ButtonItem = forwardRef<HTMLButtonElement, ToggleGroupPrimitive.ToggleGroupItemProps>(\n function ButtonItem(props: ToggleGroupPrimitive.ToggleGroupItemProps, forwardedRef) {\n return <OptionItem ref={forwardedRef} {...props} />;\n },\n);\n\nexport const ButtonGroupItem = forwardRef<\n HTMLButtonElement,\n ToggleGroupPrimitive.ToggleGroupItemProps\n>(function ButtonGroupItem({ children, ...props }, forwardedRef) {\n return (\n <ToggleGroupPrimitive.Item {...props} ref={forwardedRef} asChild>\n <ButtonItem {...props}>{children}</ButtonItem>\n </ToggleGroupPrimitive.Item>\n );\n});\n"],"mappings":";;;;;;;;;;AAsBA,MAAM,aAAa,OAAO,WAAW;;;;;;mBAMlB,aAAa,GAAG;;;uBAGZ,EAAE,YAAY,cAAc,OAAO,QAAQ,CAAC,QAAQ;;;;;;;;;;;;yBAYlD,EAAE,YAAY,cAAc,OAAO,QAAQ,CAAC,OAAO;;;IAGxE,cACC,WAAW,GAAG;;4BAES,UAAU,OAAO,eAAe,OAAO,UAAU,CAAC;;MAG3E,CAAC;;;;;;;;;;;;;;;;;;;;AAqBJ,MAAM,uBAAuB,OAAO,GAA4B;;;;YAIpD,EAAE,gBAAiB,YAAY,SAAS,cAAe;;;;OAI5D,EAAE,gBACH,aACA,GAAG;;QAED;;;AAIR,MAAa,eAAe,EAC1B,UACA,WACA,GAAG,YACyE;CAC5E,MAAM,EAAE,aAAa;CACrB,MAAM,QAAQ,aAAa;EAAE,SAAS,MAAM;EAAI;EAAU,CAAC;AAE3D,QACE,oBAAC,qBAAqB,MAAtB;EACE,GAAI;EACJ,UAAU,MAAM;EAChB,oBAAkB,MAAM;EACxB,qBAAmB,MAAM,WAAW,MAAM,eAAe,KAAA;EACzD,gBAAc,MAAM;YAEpB,oBAAC,sBAAD;GAAiC;GAAW,GAAI;GAC7C;GACoB,CAAA;EACG,CAAA;;AAMhC,MAAM,aAAa,WACjB,SAAS,WAAW,OAAkD,cAAc;AAClF,QAAO,oBAAC,YAAD;EAAY,KAAK;EAAc,GAAI;EAAS,CAAA;EAEtD;AAED,MAAa,kBAAkB,WAG7B,SAAS,gBAAgB,EAAE,UAAU,GAAG,SAAS,cAAc;AAC/D,QACE,oBAAC,qBAAqB,MAAtB;EAA2B,GAAI;EAAO,KAAK;EAAc,SAAA;YACvD,oBAAC,YAAD;GAAY,GAAI;GAAQ;GAAsB,CAAA;EACpB,CAAA;EAE9B"}
@@ -1,3 +1,3 @@
1
- import { a as Root, i as HeaderProps, n as Header, o as Title, r as HeaderContainer, s as TitleContainer, t as ActionsContainer } from "../../Header-fwlbzxYx.mjs";
2
- import { n as SectionProps, r as _default, t as CardProps } from "../../Card-CfECLwQ6.mjs";
1
+ import { a as Root, i as HeaderProps, n as Header, o as Title, r as HeaderContainer, s as TitleContainer, t as ActionsContainer } from "../../Header-C9oYPBLv.mjs";
2
+ import { n as SectionProps, r as _default, t as CardProps } from "../../Card-DOIqF954.mjs";
3
3
  export { ActionsContainer, CardProps, Header, HeaderContainer, HeaderProps, Root, SectionProps, Title, TitleContainer, _default as default };
@@ -1,4 +1,4 @@
1
- import { i as TextAction, n as IconAction, r as MenuAction } from "../../Action-Bmo8B-Q3.mjs";
1
+ import { i as TextAction, n as IconAction, r as MenuAction } from "../../Action-BLMJwLBV.mjs";
2
2
  import { CARD_HEADING_STICKY_OFFSET } from "../../SectionHeading.mjs";
3
3
  import _default from "../../Card2.mjs";
4
4
  export { CARD_HEADING_STICKY_OFFSET, _default as Card, _default as default, type IconAction, type MenuAction, type TextAction };
@@ -1,2 +1,2 @@
1
- import { n as CheckboxProps, t as Checkbox } from "../../Checkbox-ZywrdT_h.mjs";
1
+ import { n as CheckboxProps, t as Checkbox } from "../../Checkbox-EgYclGfH.mjs";
2
2
  export { Checkbox, Checkbox as default, CheckboxProps };