@persona/design-system 0.10.14 → 0.10.15

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 (381) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{Action-CHWYwpYR.d.mts → Action-sLO73eKq.d.mts} +2 -2
  3. package/dist/Action.d.mts +1 -1
  4. package/dist/AdvancedFilterRuleRow.d.mts +2 -2
  5. package/dist/AdvancedFilterRulesPopover.d.mts +2 -2
  6. package/dist/ArrayValueControl.d.mts +1 -1
  7. package/dist/Attribute.d.mts +2 -2
  8. package/dist/{Badge-B2AJMf3d.mjs → Badge-DZq6ByIU.mjs} +2 -2
  9. package/dist/{Badge-B2AJMf3d.mjs.map → Badge-DZq6ByIU.mjs.map} +1 -1
  10. package/dist/BooleanValueControl.d.mts +1 -1
  11. package/dist/{Breadcrumbs-DRs9eo1o.mjs → Breadcrumbs-I4VWR3NE.mjs} +9 -9
  12. package/dist/{Breadcrumbs-DRs9eo1o.mjs.map → Breadcrumbs-I4VWR3NE.mjs.map} +1 -1
  13. package/dist/{Button-DjD8QxcY.d.mts → Button-C4a4BTjL.d.mts} +2 -2
  14. package/dist/Button.d.mts +1 -1
  15. package/dist/CalendarBase.d.mts +1 -1
  16. package/dist/{Card-DiUHtYg_.d.mts → Card-CPV4_mHk.d.mts} +4 -4
  17. package/dist/Card.d.mts +1 -1
  18. package/dist/Card2.d.mts +3 -3
  19. package/dist/CardGrouping.d.mts +1 -1
  20. package/dist/{CardV2-DO-8COfu.mjs → CardV2-CGwm01p7.mjs} +13 -13
  21. package/dist/{CardV2-DO-8COfu.mjs.map → CardV2-CGwm01p7.mjs.map} +1 -1
  22. package/dist/{Checkbox-BAh-wF_F.mjs → Checkbox-C0uefDLS.mjs} +6 -6
  23. package/dist/{Checkbox-BAh-wF_F.mjs.map → Checkbox-C0uefDLS.mjs.map} +1 -1
  24. package/dist/{CheckboxGroupField-tBvP22Bo.d.mts → CheckboxGroupField-NZ2-Y5KV.d.mts} +2 -2
  25. package/dist/CheckboxGroupField.d.mts +1 -1
  26. package/dist/ChoicesValueControl.d.mts +1 -1
  27. package/dist/{Combobox-RX4DfO5L.d.mts → Combobox-CHpJVaXK.d.mts} +3 -3
  28. package/dist/{Combobox-DmFQ5cAy.mjs → Combobox-DPhX1GIR.mjs} +34 -23
  29. package/dist/Combobox-DPhX1GIR.mjs.map +1 -0
  30. package/dist/Combobox.d.mts +2 -2
  31. package/dist/{ComboboxBase-VIGR58Uc.d.mts → ComboboxBase-D2X8exFX.d.mts} +8 -6
  32. package/dist/ComboboxBase.d.mts +1 -1
  33. package/dist/{ComboboxMultiSelect-D5TWGGKZ.d.mts → ComboboxMultiSelect-O4awZnXr.d.mts} +2 -2
  34. package/dist/ComboboxMultiSelect.d.mts +1 -1
  35. package/dist/{ComboboxSingleSelect-D9It8t6W.d.mts → ComboboxSingleSelect-Ck-xBJqU.d.mts} +3 -3
  36. package/dist/ComboboxSingleSelect.d.mts +1 -1
  37. package/dist/{CompactBar-tNtY2EhN.d.mts → CompactBar-DdlHPalF.d.mts} +3 -3
  38. package/dist/CompactBar.d.mts +1 -1
  39. package/dist/{ConfigFormGroup-BCTWCws5.mjs → ConfigFormGroup-gOg83LzL.mjs} +3 -3
  40. package/dist/{ConfigFormGroup-BCTWCws5.mjs.map → ConfigFormGroup-gOg83LzL.mjs.map} +1 -1
  41. package/dist/{ControlBar-CDb6b1_6.d.mts → ControlBar-Z_GGxMpa.d.mts} +4 -2
  42. package/dist/ControlBar.d.mts +1 -1
  43. package/dist/{DataTable-6t5ryaEq.mjs → DataTable-D2iX3Ua6.mjs} +18 -18
  44. package/dist/{DataTable-6t5ryaEq.mjs.map → DataTable-D2iX3Ua6.mjs.map} +1 -1
  45. package/dist/{DataTable-0nhT5_Fe.d.mts → DataTable-Xt9cBYlh.d.mts} +6 -6
  46. package/dist/DataTable.d.mts +1 -1
  47. package/dist/{DatePicker-CHVYVKB-.mjs → DatePicker-CZsjaBO2.mjs} +11 -11
  48. package/dist/{DatePicker-CHVYVKB-.mjs.map → DatePicker-CZsjaBO2.mjs.map} +1 -1
  49. package/dist/DateRangeValueControl.d.mts +1 -1
  50. package/dist/DateValueControl.d.mts +1 -1
  51. package/dist/{DropdownButton-BxZ5hn0X.mjs → DropdownButton-ILgsmuFy.mjs} +3 -3
  52. package/dist/{DropdownButton-BxZ5hn0X.mjs.map → DropdownButton-ILgsmuFy.mjs.map} +1 -1
  53. package/dist/DropdownButton.d.mts +2 -2
  54. package/dist/{DropdownMenu-Db6N6ZNB.d.mts → DropdownMenu-BK-AmDAC.d.mts} +3 -3
  55. package/dist/{DropdownMenu-Ip75l4Th.mjs → DropdownMenu-CYZTQS02.mjs} +3 -3
  56. package/dist/{DropdownMenu-Ip75l4Th.mjs.map → DropdownMenu-CYZTQS02.mjs.map} +1 -1
  57. package/dist/DropdownMenu.d.mts +1 -1
  58. package/dist/{FieldRegistry-CJwGpUVK.d.mts → FieldRegistry-CD8fjf9Z.d.mts} +2 -2
  59. package/dist/FieldRegistry.d.mts +1 -1
  60. package/dist/{FilterBar-CA4mDAXK.d.mts → FilterBar-B1fwBKuZ.d.mts} +4 -4
  61. package/dist/FilterBar.d.mts +1 -1
  62. package/dist/FilterPanelSlot.d.mts +30 -0
  63. package/dist/FilterPanelVisibilityContext.d.mts +9 -0
  64. package/dist/FilterPickerMenu.d.mts +2 -2
  65. package/dist/FilterPill.d.mts +1 -1
  66. package/dist/FilterPopover.d.mts +1 -14
  67. package/dist/FloatValueControl.d.mts +1 -1
  68. package/dist/{FloatingToolbar-BA8Fqmrz.mjs → FloatingToolbar-Do5PMF_v.mjs} +4 -4
  69. package/dist/{FloatingToolbar-BA8Fqmrz.mjs.map → FloatingToolbar-Do5PMF_v.mjs.map} +1 -1
  70. package/dist/{FormControl-BoKGiWdQ.mjs → FormControl--iW9afGv.mjs} +5 -5
  71. package/dist/{FormControl-BoKGiWdQ.mjs.map → FormControl--iW9afGv.mjs.map} +1 -1
  72. package/dist/{FormControl-BQe3GRhi.d.mts → FormControl-DPYbLcBK.d.mts} +2 -2
  73. package/dist/FormControl.d.mts +1 -1
  74. package/dist/FormControlLabel.d.mts +2 -2
  75. package/dist/{FormField-BW5uMzId.d.mts → FormField-CYNGm2bJ.d.mts} +2 -2
  76. package/dist/{FormField-BfVrDOY0.mjs → FormField-C_rAxIPH.mjs} +16 -16
  77. package/dist/{FormField-BfVrDOY0.mjs.map → FormField-C_rAxIPH.mjs.map} +1 -1
  78. package/dist/FormField.d.mts +1 -1
  79. package/dist/{Grid-CYpOqTUu.mjs → Grid-DVC0SSEZ.mjs} +2 -2
  80. package/dist/{Grid-CYpOqTUu.mjs.map → Grid-DVC0SSEZ.mjs.map} +1 -1
  81. package/dist/{Header-CV0Lcf0C.d.mts → Header-DaaUprCL.d.mts} +2 -2
  82. package/dist/Header.d.mts +1 -1
  83. package/dist/{HelperTooltip-BNM3pTM-.d.mts → HelperTooltip-C5BDdJSI.d.mts} +2 -2
  84. package/dist/HelperTooltip.d.mts +1 -1
  85. package/dist/HighlightedText.d.mts +1 -1
  86. package/dist/{HoverCopyableField-CJ_p3llp.mjs → HoverCopyableField-Dy_lE6Wg.mjs} +5 -5
  87. package/dist/{HoverCopyableField-CJ_p3llp.mjs.map → HoverCopyableField-Dy_lE6Wg.mjs.map} +1 -1
  88. package/dist/{IconButton-C_ReZm8v.d.mts → IconButton-7k-wjvH3.d.mts} +2 -2
  89. package/dist/{IconButton-Bj1fry_K.mjs → IconButton-kSjnfhWt.mjs} +8 -8
  90. package/dist/{IconButton-Bj1fry_K.mjs.map → IconButton-kSjnfhWt.mjs.map} +1 -1
  91. package/dist/IconButton.d.mts +1 -1
  92. package/dist/ImageTile.d.mts +1 -1
  93. package/dist/IndexTableLayout.d.mts +4 -4
  94. package/dist/InlineCombobox.d.mts +1 -1
  95. package/dist/InlineInput.d.mts +1 -1
  96. package/dist/{Input-DcbzPaax.mjs → Input-BIHbRmmU.mjs} +6 -6
  97. package/dist/{Input-DcbzPaax.mjs.map → Input-BIHbRmmU.mjs.map} +1 -1
  98. package/dist/{Input-DH-5dKor.d.mts → Input-CwvrBsiS.d.mts} +3 -3
  99. package/dist/Input.d.mts +1 -1
  100. package/dist/IntegerValueControl.d.mts +1 -1
  101. package/dist/{Link-Df3zJrj2.mjs → Link-CnT85JqA.mjs} +4 -4
  102. package/dist/{Link-Df3zJrj2.mjs.map → Link-CnT85JqA.mjs.map} +1 -1
  103. package/dist/{ListBox-l47zUDj4.d.mts → ListBox-Cu-NLNRF.d.mts} +3 -3
  104. package/dist/{ListBox-BRgjgUSp.mjs → ListBox-CwC9YztW.mjs} +13 -13
  105. package/dist/{ListBox-BRgjgUSp.mjs.map → ListBox-CwC9YztW.mjs.map} +1 -1
  106. package/dist/ListBox.d.mts +1 -1
  107. package/dist/{ListBoxField-Di_6uD3S.d.mts → ListBoxField-Vetrl4r5.d.mts} +4 -4
  108. package/dist/ListBoxField.d.mts +1 -1
  109. package/dist/{LoadingShimmer-BVVdBeN-.mjs → LoadingShimmer-BypAGgyP.mjs} +1 -1
  110. package/dist/{LoadingShimmer-BVVdBeN-.mjs.map → LoadingShimmer-BypAGgyP.mjs.map} +1 -1
  111. package/dist/LoadingShimmer.d.mts +1 -1
  112. package/dist/{LogicRow-7f17CKrW.d.mts → LogicRow-D4YL4C6U.d.mts} +2 -2
  113. package/dist/LogicRow.d.mts +1 -1
  114. package/dist/MaskedInput.d.mts +2 -2
  115. package/dist/MatchHighlight.d.mts +1 -1
  116. package/dist/{Menu-DvzoR8e7.d.mts → Menu-DNJMfxfw.d.mts} +4 -4
  117. package/dist/{Menu-BVn1jh46.mjs → Menu-DQPxDJ11.mjs} +5 -5
  118. package/dist/{Menu-BVn1jh46.mjs.map → Menu-DQPxDJ11.mjs.map} +1 -1
  119. package/dist/Menu.d.mts +1 -1
  120. package/dist/{MiddleTruncatedText-DicQsLDG.mjs → MiddleTruncatedText--jzGTD00.mjs} +2 -2
  121. package/dist/{MiddleTruncatedText-DicQsLDG.mjs.map → MiddleTruncatedText--jzGTD00.mjs.map} +1 -1
  122. package/dist/{Modal-IVXc4p8Y.d.mts → Modal-7ZHanMzZ.d.mts} +3 -3
  123. package/dist/{Modal-C_vSgqgl.mjs → Modal-bsjGJxTM.mjs} +6 -6
  124. package/dist/{Modal-C_vSgqgl.mjs.map → Modal-bsjGJxTM.mjs.map} +1 -1
  125. package/dist/Modal.d.mts +1 -1
  126. package/dist/{PageHeader-UPiqJpIF.d.mts → PageHeader-BeBmYmUX.d.mts} +2 -2
  127. package/dist/{PageHeader-6KvtGED-.mjs → PageHeader-jvLx6GUu.mjs} +2 -2
  128. package/dist/{PageHeader-6KvtGED-.mjs.map → PageHeader-jvLx6GUu.mjs.map} +1 -1
  129. package/dist/PageHeader.d.mts +1 -1
  130. package/dist/{PageLayout-BdVM37bV.d.mts → PageLayout-BXM_pyrU.d.mts} +2 -2
  131. package/dist/{PageLayout-CPiVnS_r.mjs → PageLayout-D_NZNEit.mjs} +3 -3
  132. package/dist/{PageLayout-CPiVnS_r.mjs.map → PageLayout-D_NZNEit.mjs.map} +1 -1
  133. package/dist/PageLayout.d.mts +1 -1
  134. package/dist/{PageSelector-B5CcAzss.d.mts → PageSelector-C14ABZVL.d.mts} +2 -2
  135. package/dist/PageSelector.d.mts +1 -1
  136. package/dist/{Pagination-CqFvnlXc.mjs → Pagination-CgT2eQrk.mjs} +5 -5
  137. package/dist/{Pagination-CqFvnlXc.mjs.map → Pagination-CgT2eQrk.mjs.map} +1 -1
  138. package/dist/{Pii-BYPkrBuT.mjs → Pii-x1UInvWe.mjs} +2 -2
  139. package/dist/{Pii-BYPkrBuT.mjs.map → Pii-x1UInvWe.mjs.map} +1 -1
  140. package/dist/{PillShell-Bkyu5FXB.d.mts → PillShell-DuTRfsS1.d.mts} +2 -2
  141. package/dist/PillShell.d.mts +1 -1
  142. package/dist/{Popover-DP9DXReH.mjs → Popover-BMX-ff3L.mjs} +3 -3
  143. package/dist/{Popover-DP9DXReH.mjs.map → Popover-BMX-ff3L.mjs.map} +1 -1
  144. package/dist/Popover.d.mts +1 -1
  145. package/dist/ProgressBar.d.mts +1 -1
  146. package/dist/{ProgressIndicator-zt3ndT9U.mjs → ProgressIndicator-hy1P-RG1.mjs} +3 -3
  147. package/dist/{ProgressIndicator-zt3ndT9U.mjs.map → ProgressIndicator-hy1P-RG1.mjs.map} +1 -1
  148. package/dist/{Radio-B1H_S-Qj.mjs → Radio-D6Vydkx-.mjs} +5 -5
  149. package/dist/{Radio-B1H_S-Qj.mjs.map → Radio-D6Vydkx-.mjs.map} +1 -1
  150. package/dist/{RadioGroup-7hdcVhsp.mjs → RadioGroup-C04h3el1.mjs} +3 -3
  151. package/dist/{RadioGroup-7hdcVhsp.mjs.map → RadioGroup-C04h3el1.mjs.map} +1 -1
  152. package/dist/RichTextEditor.d.mts +1 -1
  153. package/dist/RuleEditorFields.d.mts +2 -2
  154. package/dist/RulesPill.d.mts +1 -1
  155. package/dist/SectionHeading.d.mts +1 -1
  156. package/dist/{SegmentedControl-BNOJ1FYQ.mjs → SegmentedControl-CaQ2DJsa.mjs} +4 -4
  157. package/dist/{SegmentedControl-BNOJ1FYQ.mjs.map → SegmentedControl-CaQ2DJsa.mjs.map} +1 -1
  158. package/dist/{Select-DbWEgH5c.mjs → Select-Bicuj8VD.mjs} +10 -10
  159. package/dist/{Select-DbWEgH5c.mjs.map → Select-Bicuj8VD.mjs.map} +1 -1
  160. package/dist/{Select-boZ6XP8k.d.mts → Select-O4aTrBuF.d.mts} +2 -2
  161. package/dist/Select.d.mts +1 -1
  162. package/dist/SmartTextInput.d.mts +1 -1
  163. package/dist/SmartTextInputField.d.mts +2 -2
  164. package/dist/SmartTextInputFunctionDialog.d.mts +1 -1
  165. package/dist/SmartTextInputPopover.d.mts +1 -1
  166. package/dist/{Spinner-k9ZiOdTr.mjs → Spinner-B8KWWUWy.mjs} +2 -2
  167. package/dist/{Spinner-k9ZiOdTr.mjs.map → Spinner-B8KWWUWy.mjs.map} +1 -1
  168. package/dist/{Stack-CODxfzhl.d.mts → Stack-B6MrjJeW.d.mts} +2 -2
  169. package/dist/Stack.d.mts +1 -1
  170. package/dist/{StatusIndicator-CzRaEFSz.mjs → StatusIndicator-lwt35J6B.mjs} +3 -3
  171. package/dist/{StatusIndicator-CzRaEFSz.mjs.map → StatusIndicator-lwt35J6B.mjs.map} +1 -1
  172. package/dist/{Sticker-CLvRB8V5.d.mts → Sticker-C7Wv3Obx.d.mts} +4 -4
  173. package/dist/{Sticker-4VdGEFAu.mjs → Sticker-jfOM4Yi6.mjs} +5 -5
  174. package/dist/{Sticker-4VdGEFAu.mjs.map → Sticker-jfOM4Yi6.mjs.map} +1 -1
  175. package/dist/Sticker.d.mts +1 -1
  176. package/dist/StringValueControl.d.mts +1 -1
  177. package/dist/Tab.d.mts +2 -2
  178. package/dist/{TabBar-d4sdknti.mjs → TabBar-B7U2uVD3.mjs} +6 -6
  179. package/dist/{TabBar-d4sdknti.mjs.map → TabBar-B7U2uVD3.mjs.map} +1 -1
  180. package/dist/{Table-9mNn8Q-d.mjs → Table-BsDubdR2.mjs} +10 -10
  181. package/dist/{Table-9mNn8Q-d.mjs.map → Table-BsDubdR2.mjs.map} +1 -1
  182. package/dist/{TableBox-RxpwflEb.mjs → TableBox-DmEfPlTG.mjs} +15 -15
  183. package/dist/{TableBox-RxpwflEb.mjs.map → TableBox-DmEfPlTG.mjs.map} +1 -1
  184. package/dist/TableBox.d.mts +1 -1
  185. package/dist/{TableBoxCell-B6Z23mby.d.mts → TableBoxCell-DiKY6wne.d.mts} +6 -6
  186. package/dist/TableBoxCell.d.mts +1 -1
  187. package/dist/{TableBoxField-6qAOW8t9.d.mts → TableBoxField-DPq_rueS.d.mts} +5 -5
  188. package/dist/TableBoxField.d.mts +1 -1
  189. package/dist/{TableBoxRow-CpgNWdLS.d.mts → TableBoxRow-B3DdXy6r.d.mts} +2 -2
  190. package/dist/TableBoxRow.d.mts +1 -1
  191. package/dist/{TableBoxRowActions-BDx5naRj.d.mts → TableBoxRowActions-BYXYa9s5.d.mts} +2 -2
  192. package/dist/TableBoxRowActions.d.mts +1 -1
  193. package/dist/{TableCell-CQsF7t4e.d.mts → TableCell-uv_jqT5e.d.mts} +2 -2
  194. package/dist/TableCell.d.mts +1 -1
  195. package/dist/{TableControls-BGKL7_zF.d.mts → TableControls-C4tMGBao.d.mts} +5 -5
  196. package/dist/{TableControls-BwZl4TjJ.mjs → TableControls-fuaMJFA6.mjs} +115 -41
  197. package/dist/TableControls-fuaMJFA6.mjs.map +1 -0
  198. package/dist/TableControls.d.mts +1 -1
  199. package/dist/{TableControlsContext-DhABbtVY.d.mts → TableControlsContext-D8UNXFkq.d.mts} +2 -2
  200. package/dist/TableControlsContext.d.mts +1 -1
  201. package/dist/{TableViewConfigurationDropdown-D76ApJ_-.d.mts → TableViewConfigurationDropdown-BlQj0RyT.d.mts} +2 -2
  202. package/dist/TableViewConfigurationDropdown.d.mts +1 -1
  203. package/dist/{TechnicalSticker-DtV7Gawf.mjs → TechnicalSticker--98wizQK.mjs} +7 -7
  204. package/dist/{TechnicalSticker-DtV7Gawf.mjs.map → TechnicalSticker--98wizQK.mjs.map} +1 -1
  205. package/dist/{Text-CvaqognH.d.mts → Text-CdHeSHCc.d.mts} +2 -2
  206. package/dist/Text.d.mts +1 -1
  207. package/dist/{TextArea-CQ1YNi2b.mjs → TextArea-BoVqMk8l.mjs} +2 -2
  208. package/dist/{TextArea-CQ1YNi2b.mjs.map → TextArea-BoVqMk8l.mjs.map} +1 -1
  209. package/dist/{TextUnderlineTooltip-Bd5e8KH3.d.mts → TextUnderlineTooltip-By1VVsSs.d.mts} +3 -3
  210. package/dist/TextUnderlineTooltip.d.mts +1 -1
  211. package/dist/Tile.d.mts +1 -1
  212. package/dist/{Toggle-CzHoIR-n.mjs → Toggle-BU7Faaud.mjs} +7 -7
  213. package/dist/{Toggle-CzHoIR-n.mjs.map → Toggle-BU7Faaud.mjs.map} +1 -1
  214. package/dist/{Tooltip-CVBxc1yf.mjs → Tooltip-C2VB8I6y.mjs} +4 -4
  215. package/dist/{Tooltip-CVBxc1yf.mjs.map → Tooltip-C2VB8I6y.mjs.map} +1 -1
  216. package/dist/{Tooltip-Ddy2Jq0K.d.mts → Tooltip-OxVvOfn8.d.mts} +3 -3
  217. package/dist/Tooltip.d.mts +1 -1
  218. package/dist/{TruncatedText-sr9Fhm3N.d.mts → TruncatedText-Dqj94BFK.d.mts} +2 -2
  219. package/dist/WizardModal.d.mts +1 -1
  220. package/dist/{clientFilterUtils-WH_Dqtv4.d.mts → clientFilterUtils-CI85xKUy.d.mts} +2 -2
  221. package/dist/clientFilterUtils.d.mts +1 -1
  222. package/dist/components/Accordion/index.mjs +5 -5
  223. package/dist/components/Attribute/index.mjs +6 -6
  224. package/dist/components/Badge/index.mjs +1 -1
  225. package/dist/components/Banner/index.mjs +3 -3
  226. package/dist/components/BottomPanel/index.mjs +7 -7
  227. package/dist/components/Breadcrumbs/index.mjs +1 -1
  228. package/dist/components/Button/index.d.mts +2 -2
  229. package/dist/components/Button/index.mjs +1 -1
  230. package/dist/components/ButtonGroup/index.mjs +3 -3
  231. package/dist/components/Card/index.d.mts +2 -2
  232. package/dist/components/CardV2/index.d.mts +1 -1
  233. package/dist/components/CardV2/index.mjs +1 -1
  234. package/dist/components/Checkbox/index.mjs +1 -1
  235. package/dist/components/CodeHighlight/index.mjs +4 -4
  236. package/dist/components/Combobox/index.d.mts +4 -4
  237. package/dist/components/Combobox/index.mjs +1 -1
  238. package/dist/components/ConfigFormGroup/index.mjs +2 -2
  239. package/dist/components/DataTable/TableControls/index.d.mts +20 -20
  240. package/dist/components/DataTable/TableControls/index.mjs +1 -1
  241. package/dist/components/DataTable/index.d.mts +5 -5
  242. package/dist/components/DataTable/index.mjs +1 -1
  243. package/dist/components/DataTable/types.d.mts +1 -1
  244. package/dist/components/DatePicker/index.mjs +1 -1
  245. package/dist/components/DropdownButton/index.mjs +1 -1
  246. package/dist/components/DropdownMenu/index.d.mts +1 -1
  247. package/dist/components/DropdownMenu/index.mjs +1 -1
  248. package/dist/components/FloatingPanel/index.mjs +7 -7
  249. package/dist/components/FloatingToolbar/index.mjs +1 -1
  250. package/dist/components/FormControl/index.d.mts +1 -1
  251. package/dist/components/FormControl/index.mjs +2 -2
  252. package/dist/components/FormField/index.d.mts +5 -5
  253. package/dist/components/FormField/index.mjs +1 -1
  254. package/dist/components/Grid/index.mjs +1 -1
  255. package/dist/components/HoverCopyableField/index.mjs +1 -1
  256. package/dist/components/ImageTile/index.mjs +8 -8
  257. package/dist/components/Input/index.d.mts +1 -1
  258. package/dist/components/Input/index.mjs +1 -1
  259. package/dist/components/Link/index.mjs +1 -1
  260. package/dist/components/ListBox/index.d.mts +3 -3
  261. package/dist/components/ListBox/index.mjs +1 -1
  262. package/dist/components/LoadingShimmer/index.mjs +1 -1
  263. package/dist/components/MaskedInput/index.mjs +1 -1
  264. package/dist/components/Menu/index.d.mts +1 -1
  265. package/dist/components/Menu/index.mjs +1 -1
  266. package/dist/components/Modal/index.d.mts +1 -1
  267. package/dist/components/Modal/index.mjs +1 -1
  268. package/dist/components/PageHeader/index.d.mts +1 -1
  269. package/dist/components/PageHeader/index.mjs +1 -1
  270. package/dist/components/Pagination/index.d.mts +1 -1
  271. package/dist/components/Pagination/index.mjs +1 -1
  272. package/dist/components/Pii/index.mjs +1 -1
  273. package/dist/components/Popover/index.mjs +1 -1
  274. package/dist/components/ProgressBar/index.mjs +2 -2
  275. package/dist/components/ProgressIndicator/index.mjs +1 -1
  276. package/dist/components/Radio/index.mjs +1 -1
  277. package/dist/components/RadioGroup/index.mjs +1 -1
  278. package/dist/components/RichTextEditor/index.mjs +10 -10
  279. package/dist/components/RightPanel/index.mjs +4 -4
  280. package/dist/components/SegmentedControl/index.mjs +1 -1
  281. package/dist/components/Select/index.d.mts +1 -1
  282. package/dist/components/Select/index.mjs +1 -1
  283. package/dist/components/SelectionCard/index.mjs +6 -6
  284. package/dist/components/Slider/index.mjs +4 -4
  285. package/dist/components/SmartTextInput/index.mjs +18 -14
  286. package/dist/components/SmartTextInput/index.mjs.map +1 -1
  287. package/dist/components/Spinner/index.mjs +1 -1
  288. package/dist/components/Stack/index.d.mts +1 -1
  289. package/dist/components/StatusIndicator/index.mjs +1 -1
  290. package/dist/components/Sticker/index.d.mts +1 -1
  291. package/dist/components/Sticker/index.mjs +1 -1
  292. package/dist/components/SwatchPicker/index.mjs +1 -1
  293. package/dist/components/TabBar/index.mjs +1 -1
  294. package/dist/components/Table/index.d.mts +1 -1
  295. package/dist/components/Table/index.mjs +1 -1
  296. package/dist/components/TableBox/index.d.mts +1 -1
  297. package/dist/components/TableBox/index.mjs +1 -1
  298. package/dist/components/TechnicalSticker/index.mjs +1 -1
  299. package/dist/components/Text/index.d.mts +1 -1
  300. package/dist/components/TextArea/index.mjs +1 -1
  301. package/dist/components/Tile/index.mjs +2 -2
  302. package/dist/components/Toast/index.mjs +4 -4
  303. package/dist/components/Toggle/index.mjs +1 -1
  304. package/dist/components/Tooltip/index.d.mts +3 -3
  305. package/dist/components/Tooltip/index.mjs +1 -1
  306. package/dist/components/VersionHistory/index.mjs +8 -8
  307. package/dist/compound-expression.d.mts +1 -1
  308. package/dist/{date-range-rule-value-DyLlMtjr.d.mts → date-range-rule-value-DY14Qlan.d.mts} +2 -2
  309. package/dist/date-range-rule-value.d.mts +1 -1
  310. package/dist/display.d.mts +1 -1
  311. package/dist/fieldPickerOptions.d.mts +2 -2
  312. package/dist/{filter-size-context-DVnjmuhk.d.mts → filter-size-context-BaFrCH_G.d.mts} +2 -2
  313. package/dist/filter-size-context.d.mts +1 -1
  314. package/dist/{filters-BXtKuft3.d.mts → filters-oNzv_Y5o.d.mts} +3 -3
  315. package/dist/filters.d.mts +1 -1
  316. package/dist/{helpers-gpO42h8t.d.mts → helpers-Cvy93JmP.d.mts} +2 -2
  317. package/dist/helpers.d.mts +1 -1
  318. package/dist/{index-DTM_t7OG.d.mts → index-Dh3UpnW5.d.mts} +2 -2
  319. package/dist/{index-bkzLg85W.d.mts → index-_ubFQdZK.d.mts} +3 -3
  320. package/dist/index2.d.mts +1 -1
  321. package/dist/index4.d.mts +3 -3
  322. package/dist/index5.d.mts +1 -1
  323. package/dist/index6.d.mts +13 -13
  324. package/dist/{inputFields-B7parF2l.d.mts → inputFields-CxgQOm9E.d.mts} +6 -6
  325. package/dist/inputFields.d.mts +1 -1
  326. package/dist/{intersperse-DvJsBw5D.mjs → intersperse--nD7mQCo.mjs} +1 -1
  327. package/dist/{intersperse-DvJsBw5D.mjs.map → intersperse--nD7mQCo.mjs.map} +1 -1
  328. package/dist/lib/MiddleTruncatedText.mjs +1 -1
  329. package/dist/lib/TruncatedText.d.mts +1 -1
  330. package/dist/lib/TruncatedTextWithTooltip.d.mts +1 -1
  331. package/dist/lib/TruncatedTextWithTooltip.mjs +1 -1
  332. package/dist/lib/colorMode.d.mts +1 -1
  333. package/dist/lib/useChain.d.mts +1 -1
  334. package/dist/mixins/focus.mjs +1 -1
  335. package/dist/mixins/hoverable.mjs +1 -1
  336. package/dist/mixins/input.mjs +2 -2
  337. package/dist/mixins/motion.mjs +1 -1
  338. package/dist/{operators-B8_k3r69.d.mts → operators-B8fgw6F_.d.mts} +2 -2
  339. package/dist/operators.d.mts +1 -1
  340. package/dist/patterns/CardGrouping/index.mjs +8 -8
  341. package/dist/patterns/IndexTableLayout/index.mjs +3 -3
  342. package/dist/patterns/LayoutLoadingShimmer/index.mjs +4 -4
  343. package/dist/patterns/LayoutLoadingSpinner/index.mjs +1 -1
  344. package/dist/patterns/PageLayout/index.d.mts +1 -1
  345. package/dist/patterns/PageLayout/index.mjs +1 -1
  346. package/dist/patterns/WizardModal/index.mjs +4 -4
  347. package/dist/relative-date-label.d.mts +1 -1
  348. package/dist/tone.d.mts +1 -1
  349. package/dist/{types-BvaXqjUm.d.mts → types-BwbQx3-v.d.mts} +2 -2
  350. package/dist/{types-BJqmRXFV.d.mts → types-CnqmdPXi.d.mts} +3 -2
  351. package/dist/{types-BOsCi-kZ.d.mts → types-Dl-tYxwE.d.mts} +2 -2
  352. package/dist/{types-CuH-sUJ2.d.mts → types-hhfBHo97.d.mts} +3 -3
  353. package/dist/types4.d.mts +1 -1
  354. package/dist/types5.d.mts +1 -1
  355. package/dist/types6.d.mts +1 -1
  356. package/dist/{url-state-CXPmXzIZ.d.mts → url-state-B5TJ9RJF.d.mts} +2 -2
  357. package/dist/url-state.d.mts +1 -1
  358. package/dist/{useChain-B--KAtdN.d.mts → useChain-x9fd9Fyq.d.mts} +2 -2
  359. package/dist/useChainAtCursor.d.mts +1 -1
  360. package/dist/useColumnConfiguration.d.mts +2 -2
  361. package/dist/useComboboxFooterAction.d.mts +1 -1
  362. package/dist/{useFilterStateV2-DiTS9DTg.d.mts → useFilterStateV2-Bo5NcLC9.d.mts} +3 -3
  363. package/dist/useFilterStateV2.d.mts +1 -1
  364. package/dist/{useFormField-pOVkb5BK.mjs → useFormField-Cd9sH-HM.mjs} +2 -2
  365. package/dist/{useFormField-pOVkb5BK.mjs.map → useFormField-Cd9sH-HM.mjs.map} +1 -1
  366. package/dist/{useFormGroup-DSQkoWLh.mjs → useFormGroup-CerJGY6Y.mjs} +1 -1
  367. package/dist/{useFormGroup-DSQkoWLh.mjs.map → useFormGroup-CerJGY6Y.mjs.map} +1 -1
  368. package/dist/{useTableColumns-I7StvoRs.d.mts → useTableColumns-D80uOKnT.d.mts} +2 -2
  369. package/dist/useTableColumns.d.mts +1 -1
  370. package/dist/useTruncation.d.mts +1 -1
  371. package/dist/utils.d.mts +1 -1
  372. package/dist/{validation-BDQdQ1cY.d.mts → validation-lepFD1Fr.d.mts} +3 -3
  373. package/dist/validation.d.mts +1 -1
  374. package/dist/{value-control-resolver-BFJZEWDn.d.mts → value-control-resolver-Dhmspfw-.d.mts} +2 -2
  375. package/dist/value-control-resolver.d.mts +1 -1
  376. package/dist/value-labels.d.mts +1 -1
  377. package/llms.txt +1 -1
  378. package/package.json +1 -1
  379. package/skills/ui-authoring/COMPONENTS.md +4 -1
  380. package/dist/Combobox-DmFQ5cAy.mjs.map +0 -1
  381. package/dist/TableControls-BwZl4TjJ.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Menu-BVn1jh46.mjs","names":["Card"],"sources":["../src/components/Menu/Menu.tsx"],"sourcesContent":["import * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentType,\n type ElementType,\n type FC,\n forwardRef,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport { DismissButton } from 'react-aria';\nimport styled, {\n css,\n type DefaultTheme,\n type StyledComponent,\n type StyledComponentPropsWithRef,\n} from 'styled-components';\n\nimport PDSProvider from '@persona/design-system/lib/PDSProvider';\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport Card from '#src/components/Card';\nimport { withAlpha } from '#src/lib/color';\nimport { isDisabled, isFocused, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { type MaybeSemanticTheme, semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { darkTheme, withPdsTheming } from '#src/theme';\nimport type { PersonaTheme } from '#src/theme';\n\ntype MenuTheme = PersonaTheme & MaybeSemanticTheme;\n\nconst legacyDarkTheme = withPdsTheming(darkTheme, 'off');\n\nconst hoverForeground = (theme: MenuTheme, variant: MenuItemProps['variant']) =>\n variant === 'danger'\n ? semanticColor(theme, 'FgDanger2', Color.CoreRed900)\n : semanticColor(theme, 'FgPrimary', theme.color.text.primary);\n\nconst hoverSurface = (theme: MenuTheme, variant: MenuItemProps['variant']) => {\n const tokens = semanticTokens(theme);\n if (variant === 'danger') {\n return tokens\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : theme.color.variants.danger.highlightLight;\n }\n return tokens ? tokens.SurfaceHover : theme.color.background.secondary;\n};\n\nconst selectedSurface = (theme: MenuTheme) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? withAlpha(tokens.SurfaceAccent, tokens.Opacity25)\n : theme.color.background.highlight;\n};\n\nexport const FloatingCard: StyledComponent<\n ComponentType<StyledComponentPropsWithRef<typeof Card>>,\n DefaultTheme\n> = styled(Card)`\n box-shadow: 0px 0px 14px 2px rgba(0, 0, 0, 0.12);\n outline: none;\n z-index: ${Z_INDICES.tooltip};\n`;\n\nexport const MenuList = styled.div.attrs<{ padding?: Spacing; doNotSetRole?: boolean }>(\n ({ role, doNotSetRole = false }) => ({\n role: doNotSetRole ? undefined : (role ?? 'menu'),\n }),\n)<{ padding?: Spacing }>`\n list-style: none;\n margin: 0;\n padding: ${({ padding }) => padding || Spacing[2]};\n outline: none;\n`;\n\nexport interface MenuItemProps<T extends ElementType = 'div'> {\n children: ReactNode;\n prefixIcon?: ReactNode;\n suffixIcon?: ReactNode;\n disabled?: boolean;\n variant?: 'basic' | 'danger';\n as?: T;\n stretchLabel?: boolean;\n subtitle?: string;\n focused?: boolean;\n selected?: boolean;\n size?: 'sm' | 'md';\n}\n\nexport const ListItem = styled.li<\n Pick<MenuItemProps, 'variant' | 'disabled' | 'focused' | 'selected' | 'size'>\n>`\n ${({ size }) => (size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n display: flex;\n align-items: center;\n padding: ${({ size }) => (size === 'sm' ? `${Spacing[1]} ${Spacing[2]}` : `${Spacing[2]}`)};\n border-radius: 4px;\n list-style: none;\n text-decoration: none;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n cursor: pointer;\n ${({ focused, selected, theme, variant }) => {\n if (!focused || selected) {\n return undefined;\n }\n const semantic = semanticTokens(theme) != null;\n return css`\n outline: none;\n color: ${semantic ? hoverForeground(theme, variant) : theme.color.text.primary};\n background-color: ${semantic ? hoverSurface(theme, variant) : theme.color.background.secondary};\n `;\n }}\n\n &${isNotDisabled}${isHovered}, &${isNotDisabled}${isFocused} {\n ${({ selected, variant }) =>\n !selected &&\n css`\n outline: none;\n color: ${({ theme }) => hoverForeground(theme, variant)};\n background-color: ${({ theme }) => hoverSurface(theme, variant)};\n `}\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => semanticColor(theme, 'BorderFocus', Color.BorderFocus)};\n outline-offset: 1px;\n }\n\n ${({ selected, theme }) =>\n selected &&\n css`\n outline: none;\n color: ${semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n background-color: ${selectedSurface(theme)};\n `}\n\n &${isDisabled} {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n cursor: default;\n pointer-events: none;\n }\n\n /* Variant Styling */\n ${({ theme, variant }) =>\n variant === 'danger' &&\n css`\n color: ${semanticColor(theme, 'FgDanger1', theme.color.variants[variant].default)};\n\n &${isNotDisabled}${isHovered}, &${isNotDisabled}${isFocused} {\n color: ${hoverForeground(theme, variant)};\n background-color: ${hoverSurface(theme, variant)};\n }\n\n &${isDisabled} {\n color: ${semanticColor(theme, 'FgDisabled', theme.color.variants[variant].disabled)};\n }\n `}\n`;\n\nexport const IconContainer = styled('div')<{ suffix?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: flex-end;\n margin-right: ${Spacing[2]};\n line-height: 1;\n\n ${({ suffix }) =>\n suffix &&\n css`\n margin-left: ${Spacing[2]};\n `}\n`;\n\nconst LabelContainer = styled('div')<{ stretchLabel: boolean }>`\n line-height: 16px;\n ${({ stretchLabel }) =>\n stretchLabel &&\n css`\n width: 100%;\n `}\n`;\n\n/**\n * https://stackoverflow.com/a/73795494\n */\nexport interface MenuItemType<T extends ElementType = 'div'> extends FC<\n MenuItemProps<T> & ComponentPropsWithRef<T>\n> {\n <T extends ElementType = 'div'>(\n props: MenuItemProps<T> & ComponentPropsWithoutRef<T>,\n ): ReturnType<FC<MenuItemProps<T> & ComponentPropsWithoutRef<T>>>;\n}\n\nexport const MenuItem: MenuItemType = forwardRef(function MenuItem(\n {\n children,\n disabled,\n variant,\n prefixIcon,\n suffixIcon,\n stretchLabel,\n selected,\n size,\n ...elemProps\n },\n ref: Ref<HTMLDivElement>,\n) {\n return (\n <ListItem\n disabled={disabled}\n variant={variant}\n selected={selected}\n ref={ref}\n aria-disabled={disabled}\n // aria-current is the correct a11y attribute for role=\"menuitem\" (not aria-selected).\n aria-current={selected ? 'true' : undefined}\n role='menuitem'\n tabIndex={disabled ? -1 : 0}\n size={size}\n {...elemProps}\n >\n {prefixIcon && <IconContainer>{prefixIcon}</IconContainer>}\n <LabelContainer stretchLabel={!!stretchLabel}>{children}</LabelContainer>\n {suffixIcon && <IconContainer suffix>{suffixIcon}</IconContainer>}\n </ListItem>\n );\n});\n\nconst StyledMenuDivider = styled.hr`\n height: 0px;\n padding: 0px;\n font-size: 0;\n margin: ${Spacing[2]} -${Spacing[2]};\n border: none;\n border-top: 1px solid ${({ theme }) => semanticColor(theme, 'BorderDivider', theme.color.border.primary)};\n`;\n\nexport const MenuDivider = (props: ComponentPropsWithoutRef<'hr'>) => (\n <DropdownMenu.Separator asChild>\n <StyledMenuDivider {...props} />\n </DropdownMenu.Separator>\n);\n\nexport interface MenuHeadingProps {\n size?: 'sm' | 'md';\n}\n\nexport const MenuHeading = styled.li<MenuHeadingProps>`\n ${paragraphMixins.smMono};\n text-transform: uppercase;\n padding: ${({ size }) => (size === 'sm' ? `${Spacing[1]} ${Spacing[2]}` : Spacing[2])};\n display: block;\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.secondary)};\n letter-spacing: 0.15px;\n`;\n\nexport interface MenuProps<T extends ElementType = 'div'> {\n children?: ReactNode;\n className?: string;\n variant?: 'light' | 'dark';\n as?: T;\n doNotSetRole?: boolean;\n containerProps?: ComponentPropsWithRef<'div'>;\n listRef?: RefObject<T>;\n itemProps?:\n | ComponentPropsWithoutRef<'li'>\n | ((\n props: ComponentPropsWithoutRef<'li'>,\n index: number,\n ) => Partial<ComponentPropsWithRef<'li'>>);\n onClose?: VoidFunction;\n}\n\nexport const Menu = <T extends ElementType = 'div'>({\n children,\n variant,\n containerProps,\n itemProps,\n listRef,\n className,\n onClose,\n as,\n ...props\n}: MenuProps<T> & ComponentPropsWithoutRef<T>) => {\n const menu = (\n <FloatingCard {...containerProps} className={className}>\n <MenuList {...props} as={as as any} ref={listRef}>\n {children}\n <DismissButton onDismiss={onClose} />\n </MenuList>\n </FloatingCard>\n );\n\n if (variant === 'dark') {\n return <PDSProvider theme={legacyDarkTheme}>{menu}</PDSProvider>;\n }\n\n return menu;\n};\n\nMenu.Heading = MenuHeading;\nMenu.Divider = MenuDivider;\nMenu.Item = MenuItem;\n\nexport default Menu;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Menu-DQPxDJ11.mjs","names":["Card"],"sources":["../src/components/Menu/Menu.tsx"],"sourcesContent":["import * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ComponentType,\n type ElementType,\n type FC,\n forwardRef,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport { DismissButton } from 'react-aria';\nimport styled, {\n css,\n type DefaultTheme,\n type StyledComponent,\n type StyledComponentPropsWithRef,\n} from 'styled-components';\n\nimport PDSProvider from '@persona/design-system/lib/PDSProvider';\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport Card from '#src/components/Card';\nimport { withAlpha } from '#src/lib/color';\nimport { isDisabled, isFocused, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { type MaybeSemanticTheme, semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { darkTheme, withPdsTheming } from '#src/theme';\nimport type { PersonaTheme } from '#src/theme';\n\ntype MenuTheme = PersonaTheme & MaybeSemanticTheme;\n\nconst legacyDarkTheme = withPdsTheming(darkTheme, 'off');\n\nconst hoverForeground = (theme: MenuTheme, variant: MenuItemProps['variant']) =>\n variant === 'danger'\n ? semanticColor(theme, 'FgDanger2', Color.CoreRed900)\n : semanticColor(theme, 'FgPrimary', theme.color.text.primary);\n\nconst hoverSurface = (theme: MenuTheme, variant: MenuItemProps['variant']) => {\n const tokens = semanticTokens(theme);\n if (variant === 'danger') {\n return tokens\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : theme.color.variants.danger.highlightLight;\n }\n return tokens ? tokens.SurfaceHover : theme.color.background.secondary;\n};\n\nconst selectedSurface = (theme: MenuTheme) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? withAlpha(tokens.SurfaceAccent, tokens.Opacity25)\n : theme.color.background.highlight;\n};\n\nexport const FloatingCard: StyledComponent<\n ComponentType<StyledComponentPropsWithRef<typeof Card>>,\n DefaultTheme\n> = styled(Card)`\n box-shadow: 0px 0px 14px 2px rgba(0, 0, 0, 0.12);\n outline: none;\n z-index: ${Z_INDICES.tooltip};\n`;\n\nexport const MenuList = styled.div.attrs<{ padding?: Spacing; doNotSetRole?: boolean }>(\n ({ role, doNotSetRole = false }) => ({\n role: doNotSetRole ? undefined : (role ?? 'menu'),\n }),\n)<{ padding?: Spacing }>`\n list-style: none;\n margin: 0;\n padding: ${({ padding }) => padding || Spacing[2]};\n outline: none;\n`;\n\nexport interface MenuItemProps<T extends ElementType = 'div'> {\n children: ReactNode;\n prefixIcon?: ReactNode;\n suffixIcon?: ReactNode;\n disabled?: boolean;\n variant?: 'basic' | 'danger';\n as?: T;\n stretchLabel?: boolean;\n subtitle?: string;\n focused?: boolean;\n selected?: boolean;\n size?: 'sm' | 'md';\n}\n\nexport const ListItem = styled.li<\n Pick<MenuItemProps, 'variant' | 'disabled' | 'focused' | 'selected' | 'size'>\n>`\n ${({ size }) => (size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n display: flex;\n align-items: center;\n padding: ${({ size }) => (size === 'sm' ? `${Spacing[1]} ${Spacing[2]}` : `${Spacing[2]}`)};\n border-radius: 4px;\n list-style: none;\n text-decoration: none;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n cursor: pointer;\n ${({ focused, selected, theme, variant }) => {\n if (!focused || selected) {\n return undefined;\n }\n const semantic = semanticTokens(theme) != null;\n return css`\n outline: none;\n color: ${semantic ? hoverForeground(theme, variant) : theme.color.text.primary};\n background-color: ${semantic ? hoverSurface(theme, variant) : theme.color.background.secondary};\n `;\n }}\n\n &${isNotDisabled}${isHovered}, &${isNotDisabled}${isFocused} {\n ${({ selected, variant }) =>\n !selected &&\n css`\n outline: none;\n color: ${({ theme }) => hoverForeground(theme, variant)};\n background-color: ${({ theme }) => hoverSurface(theme, variant)};\n `}\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => semanticColor(theme, 'BorderFocus', Color.BorderFocus)};\n outline-offset: 1px;\n }\n\n ${({ selected, theme }) =>\n selected &&\n css`\n outline: none;\n color: ${semanticColor(theme, 'FgAccent', theme.color.text.brand)};\n background-color: ${selectedSurface(theme)};\n `}\n\n &${isDisabled} {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n cursor: default;\n pointer-events: none;\n }\n\n /* Variant Styling */\n ${({ theme, variant }) =>\n variant === 'danger' &&\n css`\n color: ${semanticColor(theme, 'FgDanger1', theme.color.variants[variant].default)};\n\n &${isNotDisabled}${isHovered}, &${isNotDisabled}${isFocused} {\n color: ${hoverForeground(theme, variant)};\n background-color: ${hoverSurface(theme, variant)};\n }\n\n &${isDisabled} {\n color: ${semanticColor(theme, 'FgDisabled', theme.color.variants[variant].disabled)};\n }\n `}\n`;\n\nexport const IconContainer = styled('div')<{ suffix?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: flex-end;\n margin-right: ${Spacing[2]};\n line-height: 1;\n\n ${({ suffix }) =>\n suffix &&\n css`\n margin-left: ${Spacing[2]};\n `}\n`;\n\nconst LabelContainer = styled('div')<{ stretchLabel: boolean }>`\n line-height: 16px;\n ${({ stretchLabel }) =>\n stretchLabel &&\n css`\n width: 100%;\n `}\n`;\n\n/**\n * https://stackoverflow.com/a/73795494\n */\nexport interface MenuItemType<T extends ElementType = 'div'> extends FC<\n MenuItemProps<T> & ComponentPropsWithRef<T>\n> {\n <T extends ElementType = 'div'>(\n props: MenuItemProps<T> & ComponentPropsWithoutRef<T>,\n ): ReturnType<FC<MenuItemProps<T> & ComponentPropsWithoutRef<T>>>;\n}\n\nexport const MenuItem: MenuItemType = forwardRef(function MenuItem(\n {\n children,\n disabled,\n variant,\n prefixIcon,\n suffixIcon,\n stretchLabel,\n selected,\n size,\n ...elemProps\n },\n ref: Ref<HTMLDivElement>,\n) {\n return (\n <ListItem\n disabled={disabled}\n variant={variant}\n selected={selected}\n ref={ref}\n aria-disabled={disabled}\n // aria-current is the correct a11y attribute for role=\"menuitem\" (not aria-selected).\n aria-current={selected ? 'true' : undefined}\n role='menuitem'\n tabIndex={disabled ? -1 : 0}\n size={size}\n {...elemProps}\n >\n {prefixIcon && <IconContainer>{prefixIcon}</IconContainer>}\n <LabelContainer stretchLabel={!!stretchLabel}>{children}</LabelContainer>\n {suffixIcon && <IconContainer suffix>{suffixIcon}</IconContainer>}\n </ListItem>\n );\n});\n\nconst StyledMenuDivider = styled.hr`\n height: 0px;\n padding: 0px;\n font-size: 0;\n margin: ${Spacing[2]} -${Spacing[2]};\n border: none;\n border-top: 1px solid ${({ theme }) => semanticColor(theme, 'BorderDivider', theme.color.border.primary)};\n`;\n\nexport const MenuDivider = (props: ComponentPropsWithoutRef<'hr'>) => (\n <DropdownMenu.Separator asChild>\n <StyledMenuDivider {...props} />\n </DropdownMenu.Separator>\n);\n\nexport interface MenuHeadingProps {\n size?: 'sm' | 'md';\n}\n\nexport const MenuHeading = styled.li<MenuHeadingProps>`\n ${paragraphMixins.smMono};\n text-transform: uppercase;\n padding: ${({ size }) => (size === 'sm' ? `${Spacing[1]} ${Spacing[2]}` : Spacing[2])};\n display: block;\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.secondary)};\n letter-spacing: 0.15px;\n`;\n\nexport interface MenuProps<T extends ElementType = 'div'> {\n children?: ReactNode;\n className?: string;\n variant?: 'light' | 'dark';\n as?: T;\n doNotSetRole?: boolean;\n containerProps?: ComponentPropsWithRef<'div'>;\n listRef?: RefObject<T>;\n itemProps?:\n | ComponentPropsWithoutRef<'li'>\n | ((\n props: ComponentPropsWithoutRef<'li'>,\n index: number,\n ) => Partial<ComponentPropsWithRef<'li'>>);\n onClose?: VoidFunction;\n}\n\nexport const Menu = <T extends ElementType = 'div'>({\n children,\n variant,\n containerProps,\n itemProps,\n listRef,\n className,\n onClose,\n as,\n ...props\n}: MenuProps<T> & ComponentPropsWithoutRef<T>) => {\n const menu = (\n <FloatingCard {...containerProps} className={className}>\n <MenuList {...props} as={as as any} ref={listRef}>\n {children}\n <DismissButton onDismiss={onClose} />\n </MenuList>\n </FloatingCard>\n );\n\n if (variant === 'dark') {\n return <PDSProvider theme={legacyDarkTheme}>{menu}</PDSProvider>;\n }\n\n return menu;\n};\n\nMenu.Heading = MenuHeading;\nMenu.Divider = MenuDivider;\nMenu.Item = MenuItem;\n\nexport default Menu;\n"],"mappings":"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"}
package/dist/Menu.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as MenuDivider, c as MenuItem, d as MenuList, f as MenuProps, i as Menu, l as MenuItemProps, n as IconContainer, o as MenuHeading, r as ListItem, s as MenuHeadingProps, t as FloatingCard, u as MenuItemType } from "./Menu-DvzoR8e7.mjs";
1
+ import { a as MenuDivider, c as MenuItem, d as MenuList, f as MenuProps, i as Menu, l as MenuItemProps, n as IconContainer, o as MenuHeading, r as ListItem, s as MenuHeadingProps, t as FloatingCard, u as MenuItemType } from "./Menu-DNJMfxfw.mjs";
2
2
  export { FloatingCard, IconContainer, ListItem, Menu, Menu as default, MenuDivider, MenuHeading, MenuHeadingProps, MenuItem, MenuItemProps, MenuItemType, MenuList, MenuProps };
@@ -1,6 +1,6 @@
1
1
  import { a as styled } from "./styledComponentsInterop-Cs5CCPRy.mjs";
2
- import { useCallback, useLayoutEffect, useRef, useState } from "react";
3
2
  import { Typography } from "@persona/design-tokens";
3
+ import { useCallback, useLayoutEffect, useRef, useState } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/lib/middleTruncateText.ts
6
6
  const ELLIPSIS = "…";
@@ -168,4 +168,4 @@ const MiddleTruncatedText = ({ value, maxWidth = "96px", font, titleBehavior = "
168
168
  //#endregion
169
169
  export { MiddleTruncatedText as t };
170
170
 
171
- //# sourceMappingURL=MiddleTruncatedText-DicQsLDG.mjs.map
171
+ //# sourceMappingURL=MiddleTruncatedText--jzGTD00.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MiddleTruncatedText-DicQsLDG.mjs","names":[],"sources":["../src/lib/middleTruncateText.ts","../src/lib/MiddleTruncatedText.tsx"],"sourcesContent":["import { Typography } from '@persona/design-tokens';\n\nconst ELLIPSIS = '…';\nconst DEFAULT_FONT = `${Typography.TextMono.fontWeight} ${Typography.TextExtraSmall.fontSize} ${Typography.TextMono.fontFamily}`;\nconst MEASUREMENT_TOLERANCE_PX = 1;\n\nfunction createMeasurementCanvas(): [HTMLCanvasElement, () => void] {\n // oxlint-disable-next-line persona-web/document-create-element-canvas\n const canvas = document.createElement('canvas');\n const cleanup = () => {\n canvas.width = 0;\n canvas.height = 0;\n canvas.remove();\n };\n\n return [canvas, cleanup];\n}\n\nexport function buildMiddleTruncatedText(text: string, charsToShow: number): string {\n if (charsToShow >= text.length) {\n return text;\n }\n\n if (charsToShow <= ELLIPSIS.length) {\n return ELLIPSIS.slice(0, Math.max(charsToShow, 0));\n }\n\n const contentChars = charsToShow - ELLIPSIS.length;\n const front = Math.ceil(contentChars / 2);\n const back = Math.floor(contentChars / 2);\n\n return text.slice(0, front) + ELLIPSIS + text.slice(text.length - back);\n}\n\nexport function isMiddleTruncated(displayText: string, fullText: string): boolean {\n return displayText !== fullText;\n}\n\nexport function parseMaxWidthPx(maxWidth: number | string): number | null {\n if (typeof maxWidth === 'number') {\n return maxWidth;\n }\n\n if (maxWidth.endsWith('px')) {\n const parsed = Number.parseFloat(maxWidth);\n return Number.isNaN(parsed) ? null : parsed;\n }\n\n return null;\n}\n\nexport function measureTextWidth(text: string, font = DEFAULT_FONT): number {\n const [canvas, cleanupCanvas] = createMeasurementCanvas();\n\n try {\n const context = canvas.getContext('2d');\n\n if (!context) {\n return text.length * 6;\n }\n\n context.font = font;\n const measuredWidth = context.measureText(text).width;\n const minimumReasonableWidth = text.length * 4;\n\n if (measuredWidth === 0 || measuredWidth < minimumReasonableWidth) {\n return text.length * 6;\n }\n\n return measuredWidth;\n } finally {\n cleanupCanvas();\n }\n}\n\nexport function findMiddleTruncatedTextForWidth(\n text: string,\n maxWidthPx: number,\n font = DEFAULT_FONT,\n): string {\n const fitBudget = maxWidthPx + MEASUREMENT_TOLERANCE_PX;\n\n if (measureTextWidth(text, font) <= fitBudget) {\n return text;\n }\n\n let low = ELLIPSIS.length;\n let high = text.length;\n let bestDisplay = buildMiddleTruncatedText(text, ELLIPSIS.length);\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidate = buildMiddleTruncatedText(text, mid);\n\n if (measureTextWidth(candidate, font) <= fitBudget) {\n bestDisplay = candidate;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestDisplay;\n}\n\nexport function findMaxMiddleTruncatedCharsThatFit(\n element: HTMLElement,\n text: string,\n maxWidthPx?: number | null,\n font?: string,\n): { displayText: string; charsToShow: number } {\n const measuredWidth = element.clientWidth > 0 ? element.clientWidth : null;\n const parsedMaxWidth = maxWidthPx ?? parseMaxWidthPx(element.style.maxWidth);\n const widthBudget =\n measuredWidth != null && parsedMaxWidth != null\n ? Math.min(measuredWidth, parsedMaxWidth)\n : (measuredWidth ?? parsedMaxWidth);\n\n if (widthBudget != null && widthBudget > 0) {\n const displayText = findMiddleTruncatedTextForWidth(text, widthBudget, font);\n return { displayText, charsToShow: displayText.length };\n }\n\n element.textContent = text;\n if (element.scrollWidth <= element.clientWidth) {\n return { displayText: text, charsToShow: text.length };\n }\n\n let low = ELLIPSIS.length;\n let high = text.length;\n let bestCharsToShow = ELLIPSIS.length;\n let bestDisplay = buildMiddleTruncatedText(text, ELLIPSIS.length);\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidate = buildMiddleTruncatedText(text, mid);\n element.textContent = candidate;\n\n if (element.scrollWidth <= element.clientWidth) {\n bestCharsToShow = mid;\n bestDisplay = candidate;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return { displayText: bestDisplay, charsToShow: bestCharsToShow };\n}\n","import {\n type ComponentPropsWithoutRef,\n type FC,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport styled from 'styled-components';\n\nimport {\n findMaxMiddleTruncatedCharsThatFit,\n isMiddleTruncated,\n parseMaxWidthPx,\n} from './middleTruncateText';\n\nconst TruncationSpan = styled.span`\n display: block;\n overflow: hidden;\n white-space: nowrap;\n min-width: 0;\n position: relative;\n`;\n\nconst AccessibleText = styled.span`\n opacity: 0;\n user-select: text;\n`;\n\nconst VisualTruncatedText = styled.span`\n position: absolute;\n inset: 0;\n overflow: hidden;\n white-space: nowrap;\n color: inherit;\n pointer-events: none;\n`;\n\nexport interface MiddleTruncatedTextProps extends ComponentPropsWithoutRef<'span'> {\n value: string;\n maxWidth?: number | string;\n font?: string;\n titleBehavior?: 'always' | 'conditional' | 'never';\n onTruncatedChange?: (isTruncated: boolean) => void;\n}\n\nexport const MiddleTruncatedText: FC<MiddleTruncatedTextProps> = ({\n value,\n maxWidth = '96px',\n font,\n titleBehavior = 'conditional',\n onTruncatedChange,\n 'aria-label': ariaLabel,\n style,\n ...props\n}) => {\n const ref = useRef<HTMLSpanElement>(null);\n const [displayText, setDisplayText] = useState(value);\n const maxWidthPx = parseMaxWidthPx(maxWidth);\n\n const updateTruncation = useCallback(\n (element: HTMLElement) => {\n const { displayText: nextDisplayText } = findMaxMiddleTruncatedCharsThatFit(\n element,\n value,\n maxWidthPx,\n font,\n );\n setDisplayText((current) => (current === nextDisplayText ? current : nextDisplayText));\n onTruncatedChange?.(isMiddleTruncated(nextDisplayText, value));\n },\n [value, maxWidthPx, font, onTruncatedChange],\n );\n\n useLayoutEffect(() => {\n const element = ref.current;\n if (!element) {\n return;\n }\n\n updateTruncation(element);\n\n let cancelled = false;\n void document.fonts?.ready.then(() => {\n if (!cancelled) {\n updateTruncation(element);\n }\n });\n\n const resizeObserver =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => updateTruncation(element));\n resizeObserver?.observe(element);\n\n return () => {\n cancelled = true;\n resizeObserver?.disconnect();\n };\n }, [maxWidth, updateTruncation]);\n\n const isTruncated = isMiddleTruncated(displayText, value);\n\n return (\n <TruncationSpan\n style={{ ...style, maxWidth }}\n aria-label={ariaLabel ?? (isTruncated ? value : undefined)}\n title={\n titleBehavior !== 'never' && (titleBehavior === 'always' || isTruncated) ? value : undefined\n }\n {...props}\n // After the spread: on React 19 `ref` is an ordinary prop, so a `styled(MiddleTruncatedText)`\n // wrapper hands us `ref: null` in `props`, which would clobber the ref measured below.\n ref={ref}\n >\n {isTruncated ? (\n <>\n <AccessibleText>{value}</AccessibleText>\n <VisualTruncatedText aria-hidden='true'>{displayText}</VisualTruncatedText>\n </>\n ) : (\n displayText\n )}\n </TruncationSpan>\n );\n};\n\nexport default MiddleTruncatedText;\n"],"mappings":";;;;;AAEA,MAAM,WAAW;AACjB,MAAM,eAAe,GAAG,WAAW,SAAS,WAAW,GAAG,WAAW,eAAe,SAAS,GAAG,WAAW,SAAS;AACpH,MAAM,2BAA2B;AAEjC,SAAS,0BAA2D;CAElE,MAAM,SAAS,SAAS,cAAc,SAAS;CAC/C,MAAM,gBAAgB;AACpB,SAAO,QAAQ;AACf,SAAO,SAAS;AAChB,SAAO,QAAQ;;AAGjB,QAAO,CAAC,QAAQ,QAAQ;;AAG1B,SAAgB,yBAAyB,MAAc,aAA6B;AAClF,KAAI,eAAe,KAAK,OACtB,QAAO;AAGT,KAAI,eAAe,EACjB,QAAO,SAAS,MAAM,GAAG,KAAK,IAAI,aAAa,EAAE,CAAC;CAGpD,MAAM,eAAe,cAAc;CACnC,MAAM,QAAQ,KAAK,KAAK,eAAe,EAAE;CACzC,MAAM,OAAO,KAAK,MAAM,eAAe,EAAE;AAEzC,QAAO,KAAK,MAAM,GAAG,MAAM,GAAG,WAAW,KAAK,MAAM,KAAK,SAAS,KAAK;;AAGzE,SAAgB,kBAAkB,aAAqB,UAA2B;AAChF,QAAO,gBAAgB;;AAGzB,SAAgB,gBAAgB,UAA0C;AACxE,KAAI,OAAO,aAAa,SACtB,QAAO;AAGT,KAAI,SAAS,SAAS,KAAK,EAAE;EAC3B,MAAM,SAAS,OAAO,WAAW,SAAS;AAC1C,SAAO,OAAO,MAAM,OAAO,GAAG,OAAO;;AAGvC,QAAO;;AAGT,SAAgB,iBAAiB,MAAc,OAAO,cAAsB;CAC1E,MAAM,CAAC,QAAQ,iBAAiB,yBAAyB;AAEzD,KAAI;EACF,MAAM,UAAU,OAAO,WAAW,KAAK;AAEvC,MAAI,CAAC,QACH,QAAO,KAAK,SAAS;AAGvB,UAAQ,OAAO;EACf,MAAM,gBAAgB,QAAQ,YAAY,KAAK,CAAC;EAChD,MAAM,yBAAyB,KAAK,SAAS;AAE7C,MAAI,kBAAkB,KAAK,gBAAgB,uBACzC,QAAO,KAAK,SAAS;AAGvB,SAAO;WACC;AACR,iBAAe;;;AAInB,SAAgB,gCACd,MACA,YACA,OAAO,cACC;CACR,MAAM,YAAY,aAAa;AAE/B,KAAI,iBAAiB,MAAM,KAAK,IAAI,UAClC,QAAO;CAGT,IAAI,MAAM;CACV,IAAI,OAAO,KAAK;CAChB,IAAI,cAAc,yBAAyB,MAAM,EAAgB;AAEjE,QAAO,OAAO,MAAM;EAClB,MAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,EAAE;EACxC,MAAM,YAAY,yBAAyB,MAAM,IAAI;AAErD,MAAI,iBAAiB,WAAW,KAAK,IAAI,WAAW;AAClD,iBAAc;AACd,SAAM,MAAM;QAEZ,QAAO,MAAM;;AAIjB,QAAO;;AAGT,SAAgB,mCACd,SACA,MACA,YACA,MAC8C;CAC9C,MAAM,gBAAgB,QAAQ,cAAc,IAAI,QAAQ,cAAc;CACtE,MAAM,iBAAiB,cAAc,gBAAgB,QAAQ,MAAM,SAAS;CAC5E,MAAM,cACJ,iBAAiB,QAAQ,kBAAkB,OACvC,KAAK,IAAI,eAAe,eAAe,GACtC,iBAAiB;AAExB,KAAI,eAAe,QAAQ,cAAc,GAAG;EAC1C,MAAM,cAAc,gCAAgC,MAAM,aAAa,KAAK;AAC5E,SAAO;GAAE;GAAa,aAAa,YAAY;GAAQ;;AAGzD,SAAQ,cAAc;AACtB,KAAI,QAAQ,eAAe,QAAQ,YACjC,QAAO;EAAE,aAAa;EAAM,aAAa,KAAK;EAAQ;CAGxD,IAAI,MAAM;CACV,IAAI,OAAO,KAAK;CAChB,IAAI,kBAAkB;CACtB,IAAI,cAAc,yBAAyB,MAAM,EAAgB;AAEjE,QAAO,OAAO,MAAM;EAClB,MAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,EAAE;EACxC,MAAM,YAAY,yBAAyB,MAAM,IAAI;AACrD,UAAQ,cAAc;AAEtB,MAAI,QAAQ,eAAe,QAAQ,aAAa;AAC9C,qBAAkB;AAClB,iBAAc;AACd,SAAM,MAAM;QAEZ,QAAO,MAAM;;AAIjB,QAAO;EAAE,aAAa;EAAa,aAAa;EAAiB;;;;ACnInE,MAAM,iBAAiB,OAAO,IAAI;;;;;;;AAQlC,MAAM,iBAAiB,OAAO,IAAI;;;;AAKlC,MAAM,sBAAsB,OAAO,IAAI;;;;;;;;AAiBvC,MAAa,uBAAqD,EAChE,OACA,WAAW,QACX,MACA,gBAAgB,eAChB,mBACA,cAAc,WACd,OACA,GAAG,YACC;CACJ,MAAM,MAAM,OAAwB,KAAK;CACzC,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,aAAa,gBAAgB,SAAS;CAE5C,MAAM,mBAAmB,aACtB,YAAyB;EACxB,MAAM,EAAE,aAAa,oBAAoB,mCACvC,SACA,OACA,YACA,KACD;AACD,kBAAgB,YAAa,YAAY,kBAAkB,UAAU,gBAAiB;AACtF,sBAAoB,kBAAkB,iBAAiB,MAAM,CAAC;IAEhE;EAAC;EAAO;EAAY;EAAM;EAAkB,CAC7C;AAED,uBAAsB;EACpB,MAAM,UAAU,IAAI;AACpB,MAAI,CAAC,QACH;AAGF,mBAAiB,QAAQ;EAEzB,IAAI,YAAY;AACX,WAAS,OAAO,MAAM,WAAW;AACpC,OAAI,CAAC,UACH,kBAAiB,QAAQ;IAE3B;EAEF,MAAM,iBACJ,OAAO,mBAAmB,cACtB,OACA,IAAI,qBAAqB,iBAAiB,QAAQ,CAAC;AACzD,kBAAgB,QAAQ,QAAQ;AAEhC,eAAa;AACX,eAAY;AACZ,mBAAgB,YAAY;;IAE7B,CAAC,UAAU,iBAAiB,CAAC;CAEhC,MAAM,cAAc,kBAAkB,aAAa,MAAM;AAEzD,QACE,oBAAC,gBAAD;EACE,OAAO;GAAE,GAAG;GAAO;GAAU;EAC7B,cAAY,cAAc,cAAc,QAAQ,KAAA;EAChD,OACE,kBAAkB,YAAY,kBAAkB,YAAY,eAAe,QAAQ,KAAA;EAErF,GAAI;EAGC;YAEJ,cACC,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,gBAAD,EAAA,UAAiB,OAAuB,CAAA,EACxC,oBAAC,qBAAD;GAAqB,eAAY;aAAQ;GAAkC,CAAA,CAC1E,EAAA,CAAA,GAEH;EAEa,CAAA"}
1
+ {"version":3,"file":"MiddleTruncatedText--jzGTD00.mjs","names":[],"sources":["../src/lib/middleTruncateText.ts","../src/lib/MiddleTruncatedText.tsx"],"sourcesContent":["import { Typography } from '@persona/design-tokens';\n\nconst ELLIPSIS = '…';\nconst DEFAULT_FONT = `${Typography.TextMono.fontWeight} ${Typography.TextExtraSmall.fontSize} ${Typography.TextMono.fontFamily}`;\nconst MEASUREMENT_TOLERANCE_PX = 1;\n\nfunction createMeasurementCanvas(): [HTMLCanvasElement, () => void] {\n // oxlint-disable-next-line persona-web/document-create-element-canvas\n const canvas = document.createElement('canvas');\n const cleanup = () => {\n canvas.width = 0;\n canvas.height = 0;\n canvas.remove();\n };\n\n return [canvas, cleanup];\n}\n\nexport function buildMiddleTruncatedText(text: string, charsToShow: number): string {\n if (charsToShow >= text.length) {\n return text;\n }\n\n if (charsToShow <= ELLIPSIS.length) {\n return ELLIPSIS.slice(0, Math.max(charsToShow, 0));\n }\n\n const contentChars = charsToShow - ELLIPSIS.length;\n const front = Math.ceil(contentChars / 2);\n const back = Math.floor(contentChars / 2);\n\n return text.slice(0, front) + ELLIPSIS + text.slice(text.length - back);\n}\n\nexport function isMiddleTruncated(displayText: string, fullText: string): boolean {\n return displayText !== fullText;\n}\n\nexport function parseMaxWidthPx(maxWidth: number | string): number | null {\n if (typeof maxWidth === 'number') {\n return maxWidth;\n }\n\n if (maxWidth.endsWith('px')) {\n const parsed = Number.parseFloat(maxWidth);\n return Number.isNaN(parsed) ? null : parsed;\n }\n\n return null;\n}\n\nexport function measureTextWidth(text: string, font = DEFAULT_FONT): number {\n const [canvas, cleanupCanvas] = createMeasurementCanvas();\n\n try {\n const context = canvas.getContext('2d');\n\n if (!context) {\n return text.length * 6;\n }\n\n context.font = font;\n const measuredWidth = context.measureText(text).width;\n const minimumReasonableWidth = text.length * 4;\n\n if (measuredWidth === 0 || measuredWidth < minimumReasonableWidth) {\n return text.length * 6;\n }\n\n return measuredWidth;\n } finally {\n cleanupCanvas();\n }\n}\n\nexport function findMiddleTruncatedTextForWidth(\n text: string,\n maxWidthPx: number,\n font = DEFAULT_FONT,\n): string {\n const fitBudget = maxWidthPx + MEASUREMENT_TOLERANCE_PX;\n\n if (measureTextWidth(text, font) <= fitBudget) {\n return text;\n }\n\n let low = ELLIPSIS.length;\n let high = text.length;\n let bestDisplay = buildMiddleTruncatedText(text, ELLIPSIS.length);\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidate = buildMiddleTruncatedText(text, mid);\n\n if (measureTextWidth(candidate, font) <= fitBudget) {\n bestDisplay = candidate;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return bestDisplay;\n}\n\nexport function findMaxMiddleTruncatedCharsThatFit(\n element: HTMLElement,\n text: string,\n maxWidthPx?: number | null,\n font?: string,\n): { displayText: string; charsToShow: number } {\n const measuredWidth = element.clientWidth > 0 ? element.clientWidth : null;\n const parsedMaxWidth = maxWidthPx ?? parseMaxWidthPx(element.style.maxWidth);\n const widthBudget =\n measuredWidth != null && parsedMaxWidth != null\n ? Math.min(measuredWidth, parsedMaxWidth)\n : (measuredWidth ?? parsedMaxWidth);\n\n if (widthBudget != null && widthBudget > 0) {\n const displayText = findMiddleTruncatedTextForWidth(text, widthBudget, font);\n return { displayText, charsToShow: displayText.length };\n }\n\n element.textContent = text;\n if (element.scrollWidth <= element.clientWidth) {\n return { displayText: text, charsToShow: text.length };\n }\n\n let low = ELLIPSIS.length;\n let high = text.length;\n let bestCharsToShow = ELLIPSIS.length;\n let bestDisplay = buildMiddleTruncatedText(text, ELLIPSIS.length);\n\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const candidate = buildMiddleTruncatedText(text, mid);\n element.textContent = candidate;\n\n if (element.scrollWidth <= element.clientWidth) {\n bestCharsToShow = mid;\n bestDisplay = candidate;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n\n return { displayText: bestDisplay, charsToShow: bestCharsToShow };\n}\n","import {\n type ComponentPropsWithoutRef,\n type FC,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport styled from 'styled-components';\n\nimport {\n findMaxMiddleTruncatedCharsThatFit,\n isMiddleTruncated,\n parseMaxWidthPx,\n} from './middleTruncateText';\n\nconst TruncationSpan = styled.span`\n display: block;\n overflow: hidden;\n white-space: nowrap;\n min-width: 0;\n position: relative;\n`;\n\nconst AccessibleText = styled.span`\n opacity: 0;\n user-select: text;\n`;\n\nconst VisualTruncatedText = styled.span`\n position: absolute;\n inset: 0;\n overflow: hidden;\n white-space: nowrap;\n color: inherit;\n pointer-events: none;\n`;\n\nexport interface MiddleTruncatedTextProps extends ComponentPropsWithoutRef<'span'> {\n value: string;\n maxWidth?: number | string;\n font?: string;\n titleBehavior?: 'always' | 'conditional' | 'never';\n onTruncatedChange?: (isTruncated: boolean) => void;\n}\n\nexport const MiddleTruncatedText: FC<MiddleTruncatedTextProps> = ({\n value,\n maxWidth = '96px',\n font,\n titleBehavior = 'conditional',\n onTruncatedChange,\n 'aria-label': ariaLabel,\n style,\n ...props\n}) => {\n const ref = useRef<HTMLSpanElement>(null);\n const [displayText, setDisplayText] = useState(value);\n const maxWidthPx = parseMaxWidthPx(maxWidth);\n\n const updateTruncation = useCallback(\n (element: HTMLElement) => {\n const { displayText: nextDisplayText } = findMaxMiddleTruncatedCharsThatFit(\n element,\n value,\n maxWidthPx,\n font,\n );\n setDisplayText((current) => (current === nextDisplayText ? current : nextDisplayText));\n onTruncatedChange?.(isMiddleTruncated(nextDisplayText, value));\n },\n [value, maxWidthPx, font, onTruncatedChange],\n );\n\n useLayoutEffect(() => {\n const element = ref.current;\n if (!element) {\n return;\n }\n\n updateTruncation(element);\n\n let cancelled = false;\n void document.fonts?.ready.then(() => {\n if (!cancelled) {\n updateTruncation(element);\n }\n });\n\n const resizeObserver =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => updateTruncation(element));\n resizeObserver?.observe(element);\n\n return () => {\n cancelled = true;\n resizeObserver?.disconnect();\n };\n }, [maxWidth, updateTruncation]);\n\n const isTruncated = isMiddleTruncated(displayText, value);\n\n return (\n <TruncationSpan\n style={{ ...style, maxWidth }}\n aria-label={ariaLabel ?? (isTruncated ? value : undefined)}\n title={\n titleBehavior !== 'never' && (titleBehavior === 'always' || isTruncated) ? value : undefined\n }\n {...props}\n // After the spread: on React 19 `ref` is an ordinary prop, so a `styled(MiddleTruncatedText)`\n // wrapper hands us `ref: null` in `props`, which would clobber the ref measured below.\n ref={ref}\n >\n {isTruncated ? (\n <>\n <AccessibleText>{value}</AccessibleText>\n <VisualTruncatedText aria-hidden='true'>{displayText}</VisualTruncatedText>\n </>\n ) : (\n displayText\n )}\n </TruncationSpan>\n );\n};\n\nexport default MiddleTruncatedText;\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { r as ButtonProps } from "./Button-DjD8QxcY.mjs";
2
- import { ComponentProps, ComponentPropsWithoutRef, ReactNode } from "react";
1
+ import { r as ButtonProps } from "./Button-C4a4BTjL.mjs";
3
2
  import * as _$styled_components0 from "styled-components";
3
+ import { ComponentProps, ComponentPropsWithoutRef, ReactNode } from "react";
4
4
  import { Dialog, DialogTrigger, Pressable } from "react-aria-components";
5
5
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
6
6
 
@@ -154,4 +154,4 @@ declare const _default: (({
154
154
  };
155
155
  //#endregion
156
156
  export { ModalTitleProps as a, ModalRenderProps as i, ModalContent as n, ModalTrigger as o, ModalProps as r, _default as s, ModalClose as t };
157
- //# sourceMappingURL=Modal-IVXc4p8Y.d.mts.map
157
+ //# sourceMappingURL=Modal-7ZHanMzZ.d.mts.map
@@ -1,17 +1,17 @@
1
1
  import { a as styled, i as keyframes } from "./styledComponentsInterop-Cs5CCPRy.mjs";
2
2
  import { semanticColor, semanticOnly } from "./lib/semanticColor.mjs";
3
+ import { ReducedMotionFade } from "./variables/transitions.mjs";
4
+ import { semanticScrollbar } from "./mixins/scrollbar.mjs";
3
5
  import { l as usePDSStrings } from "./i18n-DaOKaFc2.mjs";
4
6
  import { t as Card_default } from "./Card-DuQHyroh.mjs";
5
7
  import { n as Heading$1 } from "./Text-D0vEReED.mjs";
6
- import { ReducedMotionFade } from "./variables/transitions.mjs";
7
8
  import useEmbeddedSurface, { useEmbeddedSurfaceGate, useEmbeddedSurfaceId } from "./lib/useEmbeddedSurface.mjs";
8
9
  import useModalInsetRight, { SIDEBAR_CLOSE_TRANSITION_MS, SIDEBAR_OPEN_TRANSITION_MS, SIDEBAR_TRANSITION_EASING } from "./lib/useModalInsetRight.mjs";
9
- import { semanticScrollbar } from "./mixins/scrollbar.mjs";
10
10
  import { n as Stack, t as HStack } from "./Stack-Bzom2BTR.mjs";
11
- import { n as Button$1 } from "./IconButton-Bj1fry_K.mjs";
12
- import { i as TabBar, r as Tab } from "./TabBar-d4sdknti.mjs";
13
- import { forwardRef, useContext, useEffect, useState } from "react";
11
+ import { n as Button$1 } from "./IconButton-kSjnfhWt.mjs";
12
+ import { i as TabBar, r as Tab } from "./TabBar-B7U2uVD3.mjs";
14
13
  import { Color, Spacing } from "@persona/design-tokens";
14
+ import { forwardRef, useContext, useEffect, useState } from "react";
15
15
  import { Dialog, DialogTrigger, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Pressable } from "react-aria-components";
16
16
  import { jsx, jsxs } from "react/jsx-runtime";
17
17
  import { XIcon } from "@persona/icons";
@@ -300,4 +300,4 @@ var Modal_default = Object.assign(Modal$1, { Title: ModalTitle });
300
300
  //#endregion
301
301
  export { Modal_default as i, ModalContent as n, ModalTrigger as r, ModalClose as t };
302
302
 
303
- //# sourceMappingURL=Modal-C_vSgqgl.mjs.map
303
+ //# sourceMappingURL=Modal-bsjGJxTM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal-C_vSgqgl.mjs","names":["AriaModal","Button","Heading","AriaHeading","Card","Modal"],"sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type MouseEvent,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport {\n Dialog,\n DialogTrigger,\n Heading as AriaHeading,\n Modal as AriaModal,\n ModalOverlay,\n type ModalOverlayProps,\n OverlayTriggerStateContext,\n Pressable,\n} from 'react-aria-components';\nimport { useOverlayTriggerState } from 'react-stately';\nimport styled, { keyframes } from 'styled-components';\n\nimport Button, { type ButtonProps } from '@persona/design-system/components/Button';\nimport Card from '@persona/design-system/components/Card';\nimport Stack, { HStack } from '@persona/design-system/components/Stack';\nimport TabBar, { Tab } from '@persona/design-system/components/TabBar';\nimport { Heading } from '@persona/design-system/components/Text';\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\nimport useEmbeddedSurface, {\n useEmbeddedSurfaceGate,\n useEmbeddedSurfaceId,\n} from '#src/lib/useEmbeddedSurface';\nimport useModalInsetRight, {\n SIDEBAR_CLOSE_TRANSITION_MS,\n SIDEBAR_OPEN_TRANSITION_MS,\n SIDEBAR_TRANSITION_EASING,\n} from '#src/lib/useModalInsetRight';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\nimport {\n ReducedMotionFade,\n TransitionDuration,\n TransitionEasing,\n} from '#src/variables/transitions';\n\nconst overlayEnter = keyframes`\n from {\n opacity: 0;\n }\n`;\n\nconst overlayExit = keyframes`\n to {\n opacity: 0;\n }\n`;\n\nconst modalRise = keyframes`\n from {\n transform: translateY(${Spacing[2]});\n }\n`;\n\n// The card's rise reads the overlay's embedded-surface gate through these inherited properties, so\n// the two start on the same frame. The exit is layered over the entrance rather than replacing it, so\n// it fades from wherever the entrance had got to; the entrance runs on so a pending gate can't hold\n// the exit open.\nconst StyledModalOverlay = styled(ModalOverlay)<{\n $hostPending: boolean;\n $animationDelayMs: number;\n $insetRight: string;\n $transitionMs: number;\n}>`\n --pds-modal-animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms;\n --pds-modal-animation-play-state: ${({ $hostPending }) => ($hostPending ? 'paused' : 'running')};\n background-color: rgba(0, 0, 0, 0.5);\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: ${({ $insetRight }) => $insetRight};\n transition: right ${({ $transitionMs }) => $transitionMs}ms ${SIDEBAR_TRANSITION_EASING};\n animation: ${overlayEnter} ${TransitionDuration.Fast} ${TransitionEasing.Enter} both;\n animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms;\n animation-play-state: ${({ $hostPending }) => ($hostPending ? 'paused' : 'running')};\n\n &[data-exiting] {\n animation:\n ${overlayEnter} ${TransitionDuration.Fast} ${TransitionEasing.Enter} both,\n ${overlayExit} ${TransitionDuration.Faster} ${TransitionEasing.Exit} both;\n animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms, 0ms;\n animation-play-state: running;\n }\n\n @media (prefers-reduced-motion: reduce) {\n &,\n &[data-exiting] {\n animation-duration: ${ReducedMotionFade.duration};\n animation-timing-function: ${ReducedMotionFade.easing};\n }\n }\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst StyledModal = styled(AriaModal)`\n z-index: 10001;\n outline: none;\n width: fit-content;\n max-width: 100%;\n /* No forwards fill: a held transform makes the card the containing block for portaled menus. */\n animation: ${modalRise} ${TransitionDuration.Fast} ${TransitionEasing.Enter} backwards;\n animation-delay: var(--pds-modal-animation-delay, 0ms);\n animation-play-state: var(--pds-modal-animation-play-state, running);\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n\n &[data-exiting] {\n animation: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n`;\n\n/**\n * React Aria keeps the overlay mounted through the exit animation, so announcing the surface from\n * here — rather than from the persistent gate below — releases the host's backdrop exactly when the\n * modal stops being painted.\n */\nconst EmbeddedSurfaceModal = forwardRef<HTMLDivElement, { children: ReactNode; surfaceId: string }>(\n function EmbeddedSurfaceModal({ children, surfaceId }, ref) {\n useEmbeddedSurface(surfaceId);\n return <StyledModal ref={ref}>{children}</StyledModal>;\n },\n);\n\ntype EmbeddedSurfaceOverlayProps = ModalOverlayProps & {\n $insetRight: string;\n $transitionMs: number;\n surfaceId: string;\n};\n\nconst EmbeddedSurfaceOverlay = ({ surfaceId, ...props }: EmbeddedSurfaceOverlayProps) => {\n const state = useContext(OverlayTriggerStateContext);\n const isOpen = state?.isOpen ?? false;\n const { ready, animationDelayMs } = useEmbeddedSurfaceGate(surfaceId, isOpen);\n\n const { $insetRight, $transitionMs, ...overlayProps } = props;\n return (\n <StyledModalOverlay\n {...overlayProps}\n $insetRight={$insetRight}\n $transitionMs={$transitionMs}\n $animationDelayMs={animationDelayMs}\n $hostPending={isOpen && !ready}\n />\n );\n};\n\nconst ModalCloseButton = styled(Button)`\n display: inline-flex;\n padding: ${Spacing[2]};\n border-radius: ${Spacing[1]};\n width: fit-content;\n min-width: unset;\n`;\n\nconst ModalFooter = styled(HStack).attrs({\n justify: 'flex-end',\n align: 'center',\n spacing: Spacing[2],\n})`\n padding: ${Spacing[3]} ${Spacing[4]};\n border-top: 1px solid ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n`;\n\nconst ModalHeaderTitle = styled.div`\n flex: 1;\n`;\n\nexport const ModalTrigger = DialogTrigger;\nexport const ModalContent = StyledModal;\n\nexport const ModalClose = ({ onClick, ...props }: ButtonProps) => {\n const state = useContext(OverlayTriggerStateContext);\n return (\n <ModalCloseButton\n variant='text'\n width='icon'\n size='md'\n {...props}\n onClick={(event: MouseEvent<HTMLButtonElement>) => {\n // Return the consumer's result so Button can await a returned Promise (pending state,\n // swallowed rejection). The modal still closes immediately, as it did before.\n const result = onClick?.(event);\n if (!event.defaultPrevented) {\n state?.close();\n }\n return result;\n }}\n >\n <XIcon />\n </ModalCloseButton>\n );\n};\n\nexport interface ModalTitleProps {\n children: ReactNode;\n className?: string;\n}\n\n/** Props passed to modal content render functions. */\nexport interface ModalRenderProps {\n /** Element that floating content should use as its portal container. */\n portalContainer: HTMLDivElement | null;\n}\n\ntype ModalRenderable = ReactNode | ((props: ModalRenderProps) => ReactNode);\n\nconst ModalTitle = ({ children, ...props }: ModalTitleProps) => {\n return (\n <Heading size='sm' color='primary' as={AriaHeading} slot='title' {...props}>\n {children}\n </Heading>\n );\n};\n\nconst ModalHeader = styled(HStack)<{ $hasTabs: boolean }>`\n border-bottom: ${({ $hasTabs, theme }) =>\n $hasTabs ? 'none' : `1px solid ${semanticColor(theme, 'BorderSubtle', Color.BorderDivider)}`};\n padding: ${({ $hasTabs }) =>\n $hasTabs\n ? `${Spacing[3]} ${Spacing[2]} ${Spacing[1]} ${Spacing[4]}`\n : `${Spacing[3]} ${Spacing[2]} ${Spacing[3]} ${Spacing[4]}`};\n`;\n\nconst ModalTabBar = styled(TabBar)`\n padding-left: ${Spacing[4]};\n`;\n\nconst StyledDialog = styled(Dialog)`\n outline: none;\n`;\n\nconst StyledCard = styled(Card)<{ $size?: 'auto' | 'md' | 'lg' | 'xl' | 'full' }>`\n position: relative;\n width: ${({ $size }) => {\n switch ($size) {\n case 'auto':\n return 'auto';\n case 'full':\n return 'calc(100vw - 160px)';\n default:\n return '90vw';\n }\n }};\n max-width: ${({ theme, $size }) => {\n switch ($size) {\n case 'auto':\n return 'auto';\n case 'full':\n return 'calc(100vw - 160px)';\n default:\n return theme.modal.width[$size];\n }\n }};\n /* TODO: Use breakpoints to make this responsive */\n max-height: ${({ $size }) => ($size === 'full' ? 'calc(100vh - 160px)' : '85vh')};\n display: flex;\n flex-direction: column;\n overflow: hidden;\n ${({ $size }) =>\n $size === 'full' &&\n `\n height: calc(100vh - 160px);\n `}\n margin-bottom: 0;\n`;\n\ninterface ModalCardProps extends ComponentPropsWithoutRef<typeof Dialog> {\n /**\n * Display X button to close popover\n */\n showCloseButton?: boolean;\n\n /**\n * Accessible label for the built-in close button. Defaults to the PDS closeModal string (\"Close\").\n */\n closeButtonLabel?: string;\n\n /**\n * Max width of the modal\n */\n size?: 'auto' | 'md' | 'lg' | 'xl' | 'full';\n\n /**\n * Footer content\n */\n footer?: ReactNode;\n\n /**\n * Renders tabs within the modal.\n * Adds a tab bar and will render the contents of the selected tab in a tabpanel.\n * Overrides `children`.\n * Tab contents can be render functions that receive the modal portal container.\n */\n tabs?: TabView[];\n\n /**\n * Title of the modal\n */\n title?: ReactNode;\n\n /**\n * Children content\n */\n children?: ReactNode;\n\n /**\n * When true, removes horizontal and vertical padding from the body. Defaults to false.\n */\n noBodyPadding?: boolean;\n\n /**\n * Additional props for the Dialog element\n */\n className?: string;\n}\n\ninterface ModalCardInternalProps extends ModalCardProps {\n portalContainer: HTMLDivElement | null;\n}\n\nconst StyledModalCardBody = styled(Card.Body)<{\n $noPadding?: boolean;\n $hidden?: boolean;\n}>`\n overflow-y: auto;\n ${semanticScrollbar}\n flex: 1;\n min-height: 0;\n ${({ $noPadding }) =>\n $noPadding\n ? 'padding: 0;'\n : `\n padding-left: ${Spacing[4]};\n padding-right: ${Spacing[4]};\n `}\n ${({ $hidden }) => $hidden && 'display: none;'}\n`;\n\n/**\n * Card to be used in Modal contexts. Inherits props from react-aria-components Dialog.\n */\nconst ModalCard = forwardRef<HTMLDivElement, ModalCardInternalProps>(function ModalCard(\n {\n title,\n children,\n showCloseButton = true,\n closeButtonLabel,\n size,\n footer,\n tabs,\n noBodyPadding = false,\n portalContainer,\n ...props\n },\n ref,\n) {\n const strings = usePDSStrings();\n const [selectedTabIdx, setSelectedTabIdx] = useState(0);\n const tabCount = tabs?.length ?? 0;\n\n useEffect(() => {\n setSelectedTabIdx(0);\n }, [tabCount]);\n\n const titleAndClose = (\n <ModalHeader justify='flex-start' align='center' spacing={Spacing[2]} $hasTabs={Boolean(tabs)}>\n <ModalHeaderTitle>{title ? <ModalTitle>{title}</ModalTitle> : null}</ModalHeaderTitle>\n {showCloseButton && <ModalClose aria-label={closeButtonLabel ?? strings.closeModal} />}\n </ModalHeader>\n );\n\n const modalHeader = tabs ? (\n <Stack>\n {titleAndClose}\n <ModalTabBar>\n {tabs.map((tab, idx) => (\n <Tab\n key={tab.name}\n selected={selectedTabIdx === idx}\n id={`pds-modal_tab-${idx}`}\n onClick={() => setSelectedTabIdx(idx)}\n aria-controls={`pds-modal_tab-panel-${idx}`}\n >\n {tab.name}\n </Tab>\n ))}\n </ModalTabBar>\n </Stack>\n ) : (\n titleAndClose\n );\n\n return (\n <StyledDialog {...props} ref={ref}>\n <StyledCard elevated $size={size}>\n {(showCloseButton || title) && modalHeader}\n {tabs ? (\n tabs.map((tab, idx) => (\n <StyledModalCardBody\n key={tab.name}\n $noPadding={noBodyPadding}\n $hidden={selectedTabIdx !== idx}\n role={tabs ? 'tabpanel' : undefined}\n id={`pds-modal_tab-panel-${tab.name}`}\n aria-labelledby={`pds-modal_tab-${tab.name}`}\n >\n {typeof tab.contents === 'function'\n ? tab.contents({ portalContainer })\n : tab.contents}\n </StyledModalCardBody>\n ))\n ) : (\n <StyledModalCardBody\n $noPadding={noBodyPadding}\n role={tabs ? 'tabpanel' : undefined}\n id={`pds-modal_tab-panel-${selectedTabIdx}`}\n aria-labelledby={`pds-modal_tab-${selectedTabIdx}`}\n >\n {children}\n </StyledModalCardBody>\n )}\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </StyledCard>\n </StyledDialog>\n );\n});\n\ninterface TabView {\n name: string;\n contents: ModalRenderable;\n badge?: React.ReactElement;\n disabled?: boolean;\n 'data-tour-target'?: string;\n}\n\nexport interface ModalProps {\n /**\n * Title of the Card\n */\n title?: string;\n\n /**\n * Component to use as trigger. React Aria trigger props will be merged with this element.\n */\n trigger?: ComponentProps<typeof Pressable>['children'];\n\n /**\n * Props to apply to Modal.Card within\n */\n contentProps?: ModalCardProps;\n\n /**\n * Max width of the modal\n */\n size?: 'auto' | 'md' | 'lg' | 'xl' | 'full';\n\n /**\n * Footer section intended for actions.\n * You can pass in Buttons directly and they will render in a HStack.\n */\n footer?: ReactNode;\n\n /**\n * Renders tabs within the modal.\n * Adds a tab bar and will render the contents of the selected tab in a tabpanel.\n * Overrides `children`.\n */\n tabs?: TabView[];\n\n /**\n * Children content\n */\n children?: ModalRenderable;\n\n /**\n * When true, removes horizontal and vertical padding from the body. Defaults to false.\n * Can also be set via contentProps.noBodyPadding.\n */\n noBodyPadding?: boolean;\n\n /**\n * Controls whether the modal is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Handler called when open state changes\n */\n onOpenChange?: (isOpen: boolean) => void;\n\n /**\n * Whether the modal can be dismissed by clicking outside or pressing escape\n */\n isDismissable?: boolean;\n\n /**\n * Whether pressing the escape key closes the modal\n */\n isKeyboardDismissDisabled?: boolean;\n\n /**\n * Element the modal overlay is portaled into. Defaults to `document.body`.\n */\n portalContainer?: HTMLElement | null;\n}\n\nconst Modal = ({\n children,\n trigger,\n contentProps,\n noBodyPadding = false,\n size = 'md',\n title,\n footer,\n tabs,\n defaultOpen,\n onOpenChange,\n isDismissable = false,\n isKeyboardDismissDisabled = false,\n open,\n portalContainer,\n}: ModalProps) => {\n const [modalElement, setModalElement] = useState<HTMLDivElement | null>(null);\n const overlayState = useOverlayTriggerState({\n isOpen: open,\n defaultOpen,\n onOpenChange,\n });\n const surfaceId = useEmbeddedSurfaceId();\n const { insetRight: modalInsetRight, panelState } = useModalInsetRight();\n const transitionMs =\n panelState === 'opening'\n ? SIDEBAR_OPEN_TRANSITION_MS\n : panelState === 'closing'\n ? SIDEBAR_CLOSE_TRANSITION_MS\n : 0;\n\n const content = (\n <ModalCard\n size={size}\n title={title}\n footer={footer}\n tabs={tabs}\n noBodyPadding={noBodyPadding}\n {...contentProps}\n portalContainer={modalElement}\n >\n {typeof children === 'function' ? children({ portalContainer: modalElement }) : children}\n </ModalCard>\n );\n\n // Wrap trigger element to ensure it works with react-aria-components\n const overlay = (\n <EmbeddedSurfaceOverlay\n surfaceId={surfaceId}\n $insetRight={modalInsetRight}\n $transitionMs={transitionMs}\n isDismissable={isDismissable}\n isKeyboardDismissDisabled={isKeyboardDismissDisabled}\n UNSTABLE_portalContainer={portalContainer ?? undefined}\n shouldCloseOnInteractOutside={(element) => !element.closest('[data-react-aria-top-layer]')}\n >\n <EmbeddedSurfaceModal ref={setModalElement} surfaceId={surfaceId}>\n {content}\n </EmbeddedSurfaceModal>\n </EmbeddedSurfaceOverlay>\n );\n\n // Without a trigger (controlled modals) DialogTrigger would render a PressResponder with no\n // pressable child, which react-aria warns about, so provide the overlay state directly.\n if (!trigger) {\n return (\n <OverlayTriggerStateContext.Provider value={overlayState}>\n {overlay}\n </OverlayTriggerStateContext.Provider>\n );\n }\n\n return (\n <DialogTrigger isOpen={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <Pressable>{trigger}</Pressable>\n {overlay}\n </DialogTrigger>\n );\n};\n\nexport default Object.assign(Modal, {\n Title: ModalTitle,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Modal-bsjGJxTM.mjs","names":["AriaModal","Button","Heading","AriaHeading","Card","Modal"],"sources":["../src/components/Modal/Modal.tsx"],"sourcesContent":["import {\n forwardRef,\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type MouseEvent,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport {\n Dialog,\n DialogTrigger,\n Heading as AriaHeading,\n Modal as AriaModal,\n ModalOverlay,\n type ModalOverlayProps,\n OverlayTriggerStateContext,\n Pressable,\n} from 'react-aria-components';\nimport { useOverlayTriggerState } from 'react-stately';\nimport styled, { keyframes } from 'styled-components';\n\nimport Button, { type ButtonProps } from '@persona/design-system/components/Button';\nimport Card from '@persona/design-system/components/Card';\nimport Stack, { HStack } from '@persona/design-system/components/Stack';\nimport TabBar, { Tab } from '@persona/design-system/components/TabBar';\nimport { Heading } from '@persona/design-system/components/Text';\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\nimport useEmbeddedSurface, {\n useEmbeddedSurfaceGate,\n useEmbeddedSurfaceId,\n} from '#src/lib/useEmbeddedSurface';\nimport useModalInsetRight, {\n SIDEBAR_CLOSE_TRANSITION_MS,\n SIDEBAR_OPEN_TRANSITION_MS,\n SIDEBAR_TRANSITION_EASING,\n} from '#src/lib/useModalInsetRight';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\nimport {\n ReducedMotionFade,\n TransitionDuration,\n TransitionEasing,\n} from '#src/variables/transitions';\n\nconst overlayEnter = keyframes`\n from {\n opacity: 0;\n }\n`;\n\nconst overlayExit = keyframes`\n to {\n opacity: 0;\n }\n`;\n\nconst modalRise = keyframes`\n from {\n transform: translateY(${Spacing[2]});\n }\n`;\n\n// The card's rise reads the overlay's embedded-surface gate through these inherited properties, so\n// the two start on the same frame. The exit is layered over the entrance rather than replacing it, so\n// it fades from wherever the entrance had got to; the entrance runs on so a pending gate can't hold\n// the exit open.\nconst StyledModalOverlay = styled(ModalOverlay)<{\n $hostPending: boolean;\n $animationDelayMs: number;\n $insetRight: string;\n $transitionMs: number;\n}>`\n --pds-modal-animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms;\n --pds-modal-animation-play-state: ${({ $hostPending }) => ($hostPending ? 'paused' : 'running')};\n background-color: rgba(0, 0, 0, 0.5);\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: ${({ $insetRight }) => $insetRight};\n transition: right ${({ $transitionMs }) => $transitionMs}ms ${SIDEBAR_TRANSITION_EASING};\n animation: ${overlayEnter} ${TransitionDuration.Fast} ${TransitionEasing.Enter} both;\n animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms;\n animation-play-state: ${({ $hostPending }) => ($hostPending ? 'paused' : 'running')};\n\n &[data-exiting] {\n animation:\n ${overlayEnter} ${TransitionDuration.Fast} ${TransitionEasing.Enter} both,\n ${overlayExit} ${TransitionDuration.Faster} ${TransitionEasing.Exit} both;\n animation-delay: ${({ $animationDelayMs }) => $animationDelayMs}ms, 0ms;\n animation-play-state: running;\n }\n\n @media (prefers-reduced-motion: reduce) {\n &,\n &[data-exiting] {\n animation-duration: ${ReducedMotionFade.duration};\n animation-timing-function: ${ReducedMotionFade.easing};\n }\n }\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst StyledModal = styled(AriaModal)`\n z-index: 10001;\n outline: none;\n width: fit-content;\n max-width: 100%;\n /* No forwards fill: a held transform makes the card the containing block for portaled menus. */\n animation: ${modalRise} ${TransitionDuration.Fast} ${TransitionEasing.Enter} backwards;\n animation-delay: var(--pds-modal-animation-delay, 0ms);\n animation-play-state: var(--pds-modal-animation-play-state, running);\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n\n &[data-exiting] {\n animation: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n`;\n\n/**\n * React Aria keeps the overlay mounted through the exit animation, so announcing the surface from\n * here — rather than from the persistent gate below — releases the host's backdrop exactly when the\n * modal stops being painted.\n */\nconst EmbeddedSurfaceModal = forwardRef<HTMLDivElement, { children: ReactNode; surfaceId: string }>(\n function EmbeddedSurfaceModal({ children, surfaceId }, ref) {\n useEmbeddedSurface(surfaceId);\n return <StyledModal ref={ref}>{children}</StyledModal>;\n },\n);\n\ntype EmbeddedSurfaceOverlayProps = ModalOverlayProps & {\n $insetRight: string;\n $transitionMs: number;\n surfaceId: string;\n};\n\nconst EmbeddedSurfaceOverlay = ({ surfaceId, ...props }: EmbeddedSurfaceOverlayProps) => {\n const state = useContext(OverlayTriggerStateContext);\n const isOpen = state?.isOpen ?? false;\n const { ready, animationDelayMs } = useEmbeddedSurfaceGate(surfaceId, isOpen);\n\n const { $insetRight, $transitionMs, ...overlayProps } = props;\n return (\n <StyledModalOverlay\n {...overlayProps}\n $insetRight={$insetRight}\n $transitionMs={$transitionMs}\n $animationDelayMs={animationDelayMs}\n $hostPending={isOpen && !ready}\n />\n );\n};\n\nconst ModalCloseButton = styled(Button)`\n display: inline-flex;\n padding: ${Spacing[2]};\n border-radius: ${Spacing[1]};\n width: fit-content;\n min-width: unset;\n`;\n\nconst ModalFooter = styled(HStack).attrs({\n justify: 'flex-end',\n align: 'center',\n spacing: Spacing[2],\n})`\n padding: ${Spacing[3]} ${Spacing[4]};\n border-top: 1px solid ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n`;\n\nconst ModalHeaderTitle = styled.div`\n flex: 1;\n`;\n\nexport const ModalTrigger = DialogTrigger;\nexport const ModalContent = StyledModal;\n\nexport const ModalClose = ({ onClick, ...props }: ButtonProps) => {\n const state = useContext(OverlayTriggerStateContext);\n return (\n <ModalCloseButton\n variant='text'\n width='icon'\n size='md'\n {...props}\n onClick={(event: MouseEvent<HTMLButtonElement>) => {\n // Return the consumer's result so Button can await a returned Promise (pending state,\n // swallowed rejection). The modal still closes immediately, as it did before.\n const result = onClick?.(event);\n if (!event.defaultPrevented) {\n state?.close();\n }\n return result;\n }}\n >\n <XIcon />\n </ModalCloseButton>\n );\n};\n\nexport interface ModalTitleProps {\n children: ReactNode;\n className?: string;\n}\n\n/** Props passed to modal content render functions. */\nexport interface ModalRenderProps {\n /** Element that floating content should use as its portal container. */\n portalContainer: HTMLDivElement | null;\n}\n\ntype ModalRenderable = ReactNode | ((props: ModalRenderProps) => ReactNode);\n\nconst ModalTitle = ({ children, ...props }: ModalTitleProps) => {\n return (\n <Heading size='sm' color='primary' as={AriaHeading} slot='title' {...props}>\n {children}\n </Heading>\n );\n};\n\nconst ModalHeader = styled(HStack)<{ $hasTabs: boolean }>`\n border-bottom: ${({ $hasTabs, theme }) =>\n $hasTabs ? 'none' : `1px solid ${semanticColor(theme, 'BorderSubtle', Color.BorderDivider)}`};\n padding: ${({ $hasTabs }) =>\n $hasTabs\n ? `${Spacing[3]} ${Spacing[2]} ${Spacing[1]} ${Spacing[4]}`\n : `${Spacing[3]} ${Spacing[2]} ${Spacing[3]} ${Spacing[4]}`};\n`;\n\nconst ModalTabBar = styled(TabBar)`\n padding-left: ${Spacing[4]};\n`;\n\nconst StyledDialog = styled(Dialog)`\n outline: none;\n`;\n\nconst StyledCard = styled(Card)<{ $size?: 'auto' | 'md' | 'lg' | 'xl' | 'full' }>`\n position: relative;\n width: ${({ $size }) => {\n switch ($size) {\n case 'auto':\n return 'auto';\n case 'full':\n return 'calc(100vw - 160px)';\n default:\n return '90vw';\n }\n }};\n max-width: ${({ theme, $size }) => {\n switch ($size) {\n case 'auto':\n return 'auto';\n case 'full':\n return 'calc(100vw - 160px)';\n default:\n return theme.modal.width[$size];\n }\n }};\n /* TODO: Use breakpoints to make this responsive */\n max-height: ${({ $size }) => ($size === 'full' ? 'calc(100vh - 160px)' : '85vh')};\n display: flex;\n flex-direction: column;\n overflow: hidden;\n ${({ $size }) =>\n $size === 'full' &&\n `\n height: calc(100vh - 160px);\n `}\n margin-bottom: 0;\n`;\n\ninterface ModalCardProps extends ComponentPropsWithoutRef<typeof Dialog> {\n /**\n * Display X button to close popover\n */\n showCloseButton?: boolean;\n\n /**\n * Accessible label for the built-in close button. Defaults to the PDS closeModal string (\"Close\").\n */\n closeButtonLabel?: string;\n\n /**\n * Max width of the modal\n */\n size?: 'auto' | 'md' | 'lg' | 'xl' | 'full';\n\n /**\n * Footer content\n */\n footer?: ReactNode;\n\n /**\n * Renders tabs within the modal.\n * Adds a tab bar and will render the contents of the selected tab in a tabpanel.\n * Overrides `children`.\n * Tab contents can be render functions that receive the modal portal container.\n */\n tabs?: TabView[];\n\n /**\n * Title of the modal\n */\n title?: ReactNode;\n\n /**\n * Children content\n */\n children?: ReactNode;\n\n /**\n * When true, removes horizontal and vertical padding from the body. Defaults to false.\n */\n noBodyPadding?: boolean;\n\n /**\n * Additional props for the Dialog element\n */\n className?: string;\n}\n\ninterface ModalCardInternalProps extends ModalCardProps {\n portalContainer: HTMLDivElement | null;\n}\n\nconst StyledModalCardBody = styled(Card.Body)<{\n $noPadding?: boolean;\n $hidden?: boolean;\n}>`\n overflow-y: auto;\n ${semanticScrollbar}\n flex: 1;\n min-height: 0;\n ${({ $noPadding }) =>\n $noPadding\n ? 'padding: 0;'\n : `\n padding-left: ${Spacing[4]};\n padding-right: ${Spacing[4]};\n `}\n ${({ $hidden }) => $hidden && 'display: none;'}\n`;\n\n/**\n * Card to be used in Modal contexts. Inherits props from react-aria-components Dialog.\n */\nconst ModalCard = forwardRef<HTMLDivElement, ModalCardInternalProps>(function ModalCard(\n {\n title,\n children,\n showCloseButton = true,\n closeButtonLabel,\n size,\n footer,\n tabs,\n noBodyPadding = false,\n portalContainer,\n ...props\n },\n ref,\n) {\n const strings = usePDSStrings();\n const [selectedTabIdx, setSelectedTabIdx] = useState(0);\n const tabCount = tabs?.length ?? 0;\n\n useEffect(() => {\n setSelectedTabIdx(0);\n }, [tabCount]);\n\n const titleAndClose = (\n <ModalHeader justify='flex-start' align='center' spacing={Spacing[2]} $hasTabs={Boolean(tabs)}>\n <ModalHeaderTitle>{title ? <ModalTitle>{title}</ModalTitle> : null}</ModalHeaderTitle>\n {showCloseButton && <ModalClose aria-label={closeButtonLabel ?? strings.closeModal} />}\n </ModalHeader>\n );\n\n const modalHeader = tabs ? (\n <Stack>\n {titleAndClose}\n <ModalTabBar>\n {tabs.map((tab, idx) => (\n <Tab\n key={tab.name}\n selected={selectedTabIdx === idx}\n id={`pds-modal_tab-${idx}`}\n onClick={() => setSelectedTabIdx(idx)}\n aria-controls={`pds-modal_tab-panel-${idx}`}\n >\n {tab.name}\n </Tab>\n ))}\n </ModalTabBar>\n </Stack>\n ) : (\n titleAndClose\n );\n\n return (\n <StyledDialog {...props} ref={ref}>\n <StyledCard elevated $size={size}>\n {(showCloseButton || title) && modalHeader}\n {tabs ? (\n tabs.map((tab, idx) => (\n <StyledModalCardBody\n key={tab.name}\n $noPadding={noBodyPadding}\n $hidden={selectedTabIdx !== idx}\n role={tabs ? 'tabpanel' : undefined}\n id={`pds-modal_tab-panel-${tab.name}`}\n aria-labelledby={`pds-modal_tab-${tab.name}`}\n >\n {typeof tab.contents === 'function'\n ? tab.contents({ portalContainer })\n : tab.contents}\n </StyledModalCardBody>\n ))\n ) : (\n <StyledModalCardBody\n $noPadding={noBodyPadding}\n role={tabs ? 'tabpanel' : undefined}\n id={`pds-modal_tab-panel-${selectedTabIdx}`}\n aria-labelledby={`pds-modal_tab-${selectedTabIdx}`}\n >\n {children}\n </StyledModalCardBody>\n )}\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </StyledCard>\n </StyledDialog>\n );\n});\n\ninterface TabView {\n name: string;\n contents: ModalRenderable;\n badge?: React.ReactElement;\n disabled?: boolean;\n 'data-tour-target'?: string;\n}\n\nexport interface ModalProps {\n /**\n * Title of the Card\n */\n title?: string;\n\n /**\n * Component to use as trigger. React Aria trigger props will be merged with this element.\n */\n trigger?: ComponentProps<typeof Pressable>['children'];\n\n /**\n * Props to apply to Modal.Card within\n */\n contentProps?: ModalCardProps;\n\n /**\n * Max width of the modal\n */\n size?: 'auto' | 'md' | 'lg' | 'xl' | 'full';\n\n /**\n * Footer section intended for actions.\n * You can pass in Buttons directly and they will render in a HStack.\n */\n footer?: ReactNode;\n\n /**\n * Renders tabs within the modal.\n * Adds a tab bar and will render the contents of the selected tab in a tabpanel.\n * Overrides `children`.\n */\n tabs?: TabView[];\n\n /**\n * Children content\n */\n children?: ModalRenderable;\n\n /**\n * When true, removes horizontal and vertical padding from the body. Defaults to false.\n * Can also be set via contentProps.noBodyPadding.\n */\n noBodyPadding?: boolean;\n\n /**\n * Controls whether the modal is open (controlled)\n */\n open?: boolean;\n\n /**\n * Default open state (uncontrolled)\n */\n defaultOpen?: boolean;\n\n /**\n * Handler called when open state changes\n */\n onOpenChange?: (isOpen: boolean) => void;\n\n /**\n * Whether the modal can be dismissed by clicking outside or pressing escape\n */\n isDismissable?: boolean;\n\n /**\n * Whether pressing the escape key closes the modal\n */\n isKeyboardDismissDisabled?: boolean;\n\n /**\n * Element the modal overlay is portaled into. Defaults to `document.body`.\n */\n portalContainer?: HTMLElement | null;\n}\n\nconst Modal = ({\n children,\n trigger,\n contentProps,\n noBodyPadding = false,\n size = 'md',\n title,\n footer,\n tabs,\n defaultOpen,\n onOpenChange,\n isDismissable = false,\n isKeyboardDismissDisabled = false,\n open,\n portalContainer,\n}: ModalProps) => {\n const [modalElement, setModalElement] = useState<HTMLDivElement | null>(null);\n const overlayState = useOverlayTriggerState({\n isOpen: open,\n defaultOpen,\n onOpenChange,\n });\n const surfaceId = useEmbeddedSurfaceId();\n const { insetRight: modalInsetRight, panelState } = useModalInsetRight();\n const transitionMs =\n panelState === 'opening'\n ? SIDEBAR_OPEN_TRANSITION_MS\n : panelState === 'closing'\n ? SIDEBAR_CLOSE_TRANSITION_MS\n : 0;\n\n const content = (\n <ModalCard\n size={size}\n title={title}\n footer={footer}\n tabs={tabs}\n noBodyPadding={noBodyPadding}\n {...contentProps}\n portalContainer={modalElement}\n >\n {typeof children === 'function' ? children({ portalContainer: modalElement }) : children}\n </ModalCard>\n );\n\n // Wrap trigger element to ensure it works with react-aria-components\n const overlay = (\n <EmbeddedSurfaceOverlay\n surfaceId={surfaceId}\n $insetRight={modalInsetRight}\n $transitionMs={transitionMs}\n isDismissable={isDismissable}\n isKeyboardDismissDisabled={isKeyboardDismissDisabled}\n UNSTABLE_portalContainer={portalContainer ?? undefined}\n shouldCloseOnInteractOutside={(element) => !element.closest('[data-react-aria-top-layer]')}\n >\n <EmbeddedSurfaceModal ref={setModalElement} surfaceId={surfaceId}>\n {content}\n </EmbeddedSurfaceModal>\n </EmbeddedSurfaceOverlay>\n );\n\n // Without a trigger (controlled modals) DialogTrigger would render a PressResponder with no\n // pressable child, which react-aria warns about, so provide the overlay state directly.\n if (!trigger) {\n return (\n <OverlayTriggerStateContext.Provider value={overlayState}>\n {overlay}\n </OverlayTriggerStateContext.Provider>\n );\n }\n\n return (\n <DialogTrigger isOpen={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <Pressable>{trigger}</Pressable>\n {overlay}\n </DialogTrigger>\n );\n};\n\nexport default Object.assign(Modal, {\n Title: ModalTitle,\n});\n"],"mappings":"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"}
package/dist/Modal.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ModalTitleProps, i as ModalRenderProps, n as ModalContent, o as ModalTrigger, r as ModalProps, s as _default, t as ModalClose } from "./Modal-IVXc4p8Y.mjs";
1
+ import { a as ModalTitleProps, i as ModalRenderProps, n as ModalContent, o as ModalTrigger, r as ModalProps, s as _default, t as ModalClose } from "./Modal-7ZHanMzZ.mjs";
2
2
  export { ModalClose, ModalContent, ModalProps, ModalRenderProps, ModalTitleProps, ModalTrigger, _default as default };
@@ -1,6 +1,6 @@
1
1
  import { r as BreadcrumbsProps } from "./Breadcrumbs-3MtvzTPi.mjs";
2
- import { ReactNode } from "react";
3
2
  import * as _$styled_components0 from "styled-components";
3
+ import { ReactNode } from "react";
4
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
6
6
  //#region src/components/PageHeader/PageHeader.d.ts
@@ -45,4 +45,4 @@ declare const PageHeader: ({
45
45
  }: PageHeaderProps) => _$react_jsx_runtime0.JSX.Element;
46
46
  //#endregion
47
47
  export { PageHeaderContainer as n, PageHeaderProps as r, PageHeader as t };
48
- //# sourceMappingURL=PageHeader-UPiqJpIF.d.mts.map
48
+ //# sourceMappingURL=PageHeader-BeBmYmUX.d.mts.map
@@ -1,7 +1,7 @@
1
1
  import { a as styled, r as css } from "./styledComponentsInterop-Cs5CCPRy.mjs";
2
2
  import { semanticColor, semanticOnly } from "./lib/semanticColor.mjs";
3
3
  import { i as Paragraph } from "./Text-D0vEReED.mjs";
4
- import { t as Breadcrumbs } from "./Breadcrumbs-DRs9eo1o.mjs";
4
+ import { t as Breadcrumbs } from "./Breadcrumbs-I4VWR3NE.mjs";
5
5
  import { Spacing } from "@persona/design-tokens";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/PageHeader/PageHeader.tsx
@@ -78,4 +78,4 @@ const PageHeader = ({ title, breadcrumbs, subtitle, level: _level, prepend, appe
78
78
  //#endregion
79
79
  export { PageHeaderContainer as n, PageHeader as t };
80
80
 
81
- //# sourceMappingURL=PageHeader-6KvtGED-.mjs.map
81
+ //# sourceMappingURL=PageHeader-jvLx6GUu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageHeader-6KvtGED-.mjs","names":[],"sources":["../src/components/PageHeader/PageHeader.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Breadcrumbs, { type BreadcrumbsProps } from '#src/components/Breadcrumbs';\nimport { Paragraph } from '#src/components/Text';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\n\nexport const PageHeaderContainer = styled.header`\n display: flex;\n width: 100%;\n justify-content: space-between;\n align-items: center;\n padding: ${Spacing[3]} ${Spacing[5]};\n background-color: ${({ theme }) => semanticColor(theme, 'SurfacePrimary', theme.color.background.primary)};\n border-bottom: 1px solid ${({ theme }) => semanticColor(theme, 'BorderDivider', theme.color.border.primary)};\n box-sizing: border-box;\n min-height: 56px;\n`;\n\nconst TitleContainer = styled.div`\n display: flex;\n flex: 0 1 auto;\n min-width: 0;\n align-items: center;\n h1 {\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n }\n`;\n\nconst LeftContainer = styled.div<{ $hasSubtitle: boolean }>`\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n gap: ${Spacing[2]};\n min-width: 0;\n & > :not(${TitleContainer}):not(p) {\n flex-shrink: 0;\n }\n > p {\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondary};`)}\n }\n /* Title and subtitle differ in size, so align their baselines rather than their boxes. */\n ${({ $hasSubtitle }) =>\n $hasSubtitle &&\n css`\n > ${TitleContainer}, > p {\n align-self: baseline;\n }\n `}\n`;\n\nconst RightContainer = styled.div`\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n margin-left: ${Spacing[3]};\n flex-shrink: 0;\n`;\n\ninterface PageHeaderCommonProps {\n /**\n * @deprecated Has no effect. Use `title` on index pages and `breadcrumbs` on detail pages.\n */\n level?: 'product' | 'detail';\n prepend?: ReactNode;\n append?: ReactNode;\n children?: ReactNode;\n}\n\n/** Exactly one heading source is required: either `title` or `breadcrumbs`. */\nexport type PageHeaderProps = PageHeaderCommonProps &\n (\n | { title: ReactNode; subtitle?: ReactNode; breadcrumbs?: never }\n | {\n title?: never;\n /**\n * The subtitle is sunset in the breadcrumbs variant (PX-1299); fold the value it\n * carried (e.g. an object ID) into the current crumb, with a copy action if useful.\n */\n subtitle?: never;\n /**\n * Renders in place of `title`; the current crumb becomes the page `h1`, at `lg` size.\n * For detail pages: pass the ancestor crumb(s) plus the current page. Pages without\n * ancestors should pass `title` instead of a single crumb.\n */\n breadcrumbs: BreadcrumbsProps;\n }\n );\n\nconst PageHeader = ({\n title,\n breadcrumbs,\n subtitle,\n level: _level,\n prepend,\n append,\n children,\n ...props\n}: PageHeaderProps) => (\n <PageHeaderContainer {...props}>\n <LeftContainer $hasSubtitle={Boolean(subtitle)}>\n {prepend}\n <TitleContainer>\n {breadcrumbs ? (\n <Breadcrumbs size='lg' {...breadcrumbs} />\n ) : (\n <Paragraph as='h1' size='lg' weight='bold' color='primary'>\n {title}\n </Paragraph>\n )}\n </TitleContainer>\n {append}\n {subtitle && <Paragraph size='md'>{subtitle}</Paragraph>}\n </LeftContainer>\n {children && <RightContainer>{children}</RightContainer>}\n </PageHeaderContainer>\n);\n\nexport default PageHeader;\n"],"mappings":";;;;;;;AASA,MAAa,sBAAsB,OAAO,MAAM;;;;;aAKnC,QAAQ,GAAG,GAAG,QAAQ,GAAG;uBACf,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,MAAM,WAAW,QAAQ,CAAC;8BAC9E,EAAE,YAAY,cAAc,OAAO,iBAAiB,MAAM,MAAM,OAAO,QAAQ,CAAC;;;;AAK9G,MAAM,iBAAiB,OAAO,GAAG;;;;;;MAM3B,cAAc,WAAW,UAAU,OAAO,UAAU,GAAG,CAAC;;;AAI9D,MAAM,gBAAgB,OAAO,GAA8B;;;;SAIlD,QAAQ,GAAG;;aAEP,eAAe;;;;MAItB,cAAc,WAAW,UAAU,OAAO,YAAY,GAAG,CAAC;;;KAG3D,EAAE,mBACH,gBACA,GAAG;UACG,eAAe;;;MAGnB;;AAGN,MAAM,iBAAiB,OAAO,GAAG;;;SAGxB,QAAQ,GAAG;iBACH,QAAQ,GAAG;;;AAkC5B,MAAM,cAAc,EAClB,OACA,aACA,UACA,OAAO,QACP,SACA,QACA,UACA,GAAG,YAEH,qBAAC,qBAAD;CAAqB,GAAI;WAAzB,CACE,qBAAC,eAAD;EAAe,cAAc,QAAQ,SAAS;YAA9C;GACG;GACD,oBAAC,gBAAD,EAAA,UACG,cACC,oBAAC,aAAD;IAAa,MAAK;IAAK,GAAI;IAAe,CAAA,GAE1C,oBAAC,WAAD;IAAW,IAAG;IAAK,MAAK;IAAK,QAAO;IAAO,OAAM;cAC9C;IACS,CAAA,EAEC,CAAA;GAChB;GACA,YAAY,oBAAC,WAAD;IAAW,MAAK;cAAM;IAAqB,CAAA;GAC1C;KACf,YAAY,oBAAC,gBAAD,EAAiB,UAA0B,CAAA,CACpC"}
1
+ {"version":3,"file":"PageHeader-jvLx6GUu.mjs","names":[],"sources":["../src/components/PageHeader/PageHeader.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Breadcrumbs, { type BreadcrumbsProps } from '#src/components/Breadcrumbs';\nimport { Paragraph } from '#src/components/Text';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\n\nexport const PageHeaderContainer = styled.header`\n display: flex;\n width: 100%;\n justify-content: space-between;\n align-items: center;\n padding: ${Spacing[3]} ${Spacing[5]};\n background-color: ${({ theme }) => semanticColor(theme, 'SurfacePrimary', theme.color.background.primary)};\n border-bottom: 1px solid ${({ theme }) => semanticColor(theme, 'BorderDivider', theme.color.border.primary)};\n box-sizing: border-box;\n min-height: 56px;\n`;\n\nconst TitleContainer = styled.div`\n display: flex;\n flex: 0 1 auto;\n min-width: 0;\n align-items: center;\n h1 {\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n }\n`;\n\nconst LeftContainer = styled.div<{ $hasSubtitle: boolean }>`\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n gap: ${Spacing[2]};\n min-width: 0;\n & > :not(${TitleContainer}):not(p) {\n flex-shrink: 0;\n }\n > p {\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondary};`)}\n }\n /* Title and subtitle differ in size, so align their baselines rather than their boxes. */\n ${({ $hasSubtitle }) =>\n $hasSubtitle &&\n css`\n > ${TitleContainer}, > p {\n align-self: baseline;\n }\n `}\n`;\n\nconst RightContainer = styled.div`\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n margin-left: ${Spacing[3]};\n flex-shrink: 0;\n`;\n\ninterface PageHeaderCommonProps {\n /**\n * @deprecated Has no effect. Use `title` on index pages and `breadcrumbs` on detail pages.\n */\n level?: 'product' | 'detail';\n prepend?: ReactNode;\n append?: ReactNode;\n children?: ReactNode;\n}\n\n/** Exactly one heading source is required: either `title` or `breadcrumbs`. */\nexport type PageHeaderProps = PageHeaderCommonProps &\n (\n | { title: ReactNode; subtitle?: ReactNode; breadcrumbs?: never }\n | {\n title?: never;\n /**\n * The subtitle is sunset in the breadcrumbs variant (PX-1299); fold the value it\n * carried (e.g. an object ID) into the current crumb, with a copy action if useful.\n */\n subtitle?: never;\n /**\n * Renders in place of `title`; the current crumb becomes the page `h1`, at `lg` size.\n * For detail pages: pass the ancestor crumb(s) plus the current page. Pages without\n * ancestors should pass `title` instead of a single crumb.\n */\n breadcrumbs: BreadcrumbsProps;\n }\n );\n\nconst PageHeader = ({\n title,\n breadcrumbs,\n subtitle,\n level: _level,\n prepend,\n append,\n children,\n ...props\n}: PageHeaderProps) => (\n <PageHeaderContainer {...props}>\n <LeftContainer $hasSubtitle={Boolean(subtitle)}>\n {prepend}\n <TitleContainer>\n {breadcrumbs ? (\n <Breadcrumbs size='lg' {...breadcrumbs} />\n ) : (\n <Paragraph as='h1' size='lg' weight='bold' color='primary'>\n {title}\n </Paragraph>\n )}\n </TitleContainer>\n {append}\n {subtitle && <Paragraph size='md'>{subtitle}</Paragraph>}\n </LeftContainer>\n {children && <RightContainer>{children}</RightContainer>}\n </PageHeaderContainer>\n);\n\nexport default PageHeader;\n"],"mappings":";;;;;;;AASA,MAAa,sBAAsB,OAAO,MAAM;;;;;aAKnC,QAAQ,GAAG,GAAG,QAAQ,GAAG;uBACf,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,MAAM,WAAW,QAAQ,CAAC;8BAC9E,EAAE,YAAY,cAAc,OAAO,iBAAiB,MAAM,MAAM,OAAO,QAAQ,CAAC;;;;AAK9G,MAAM,iBAAiB,OAAO,GAAG;;;;;;MAM3B,cAAc,WAAW,UAAU,OAAO,UAAU,GAAG,CAAC;;;AAI9D,MAAM,gBAAgB,OAAO,GAA8B;;;;SAIlD,QAAQ,GAAG;;aAEP,eAAe;;;;MAItB,cAAc,WAAW,UAAU,OAAO,YAAY,GAAG,CAAC;;;KAG3D,EAAE,mBACH,gBACA,GAAG;UACG,eAAe;;;MAGnB;;AAGN,MAAM,iBAAiB,OAAO,GAAG;;;SAGxB,QAAQ,GAAG;iBACH,QAAQ,GAAG;;;AAkC5B,MAAM,cAAc,EAClB,OACA,aACA,UACA,OAAO,QACP,SACA,QACA,UACA,GAAG,YAEH,qBAAC,qBAAD;CAAqB,GAAI;WAAzB,CACE,qBAAC,eAAD;EAAe,cAAc,QAAQ,SAAS;YAA9C;GACG;GACD,oBAAC,gBAAD,EAAA,UACG,cACC,oBAAC,aAAD;IAAa,MAAK;IAAK,GAAI;IAAe,CAAA,GAE1C,oBAAC,WAAD;IAAW,IAAG;IAAK,MAAK;IAAK,QAAO;IAAO,OAAM;cAC9C;IACS,CAAA,EAEC,CAAA;GAChB;GACA,YAAY,oBAAC,WAAD;IAAW,MAAK;cAAM;IAAqB,CAAA;GAC1C;KACf,YAAY,oBAAC,gBAAD,EAAiB,UAA0B,CAAA,CACpC"}
@@ -1,2 +1,2 @@
1
- import { n as PageHeaderContainer, r as PageHeaderProps, t as PageHeader } from "./PageHeader-UPiqJpIF.mjs";
1
+ import { n as PageHeaderContainer, r as PageHeaderProps, t as PageHeader } from "./PageHeader-BeBmYmUX.mjs";
2
2
  export { PageHeaderContainer, PageHeaderProps, PageHeader as default };
@@ -1,5 +1,5 @@
1
- import { ComponentPropsWithoutRef, ReactNode } from "react";
2
1
  import * as _$styled_components0 from "styled-components";
2
+ import { ComponentPropsWithoutRef, ReactNode } from "react";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/patterns/PageLayout/PageLayout.d.ts
@@ -13,4 +13,4 @@ declare const Container: ({
13
13
  declare const Section: _$styled_components0.StyledComponent<"div", any, {}, never>;
14
14
  //#endregion
15
15
  export { Container as n, Section as r, Backdrop as t };
16
- //# sourceMappingURL=PageLayout-BdVM37bV.d.mts.map
16
+ //# sourceMappingURL=PageLayout-BXM_pyrU.d.mts.map
@@ -1,9 +1,9 @@
1
1
  import { a as styled } from "./styledComponentsInterop-Cs5CCPRy.mjs";
2
2
  import { semanticColor } from "./lib/semanticColor.mjs";
3
3
  import { n as Stack } from "./Stack-Bzom2BTR.mjs";
4
- import { i as useGridBreakpoint, n as GRID_BREAKPOINTS, r as Grid, t as GridItem } from "./Grid-CYpOqTUu.mjs";
5
- import { useLayoutEffect, useRef, useState } from "react";
4
+ import { i as useGridBreakpoint, n as GRID_BREAKPOINTS, r as Grid, t as GridItem } from "./Grid-DVC0SSEZ.mjs";
6
5
  import { Spacing } from "@persona/design-tokens";
6
+ import { useLayoutEffect, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/patterns/PageLayout/PageLayout.tsx
9
9
  const Backdrop = styled.div`
@@ -131,4 +131,4 @@ const SplitColumnLayout = ({ main, aside, ...chrome }) => /* @__PURE__ */ jsx(Pa
131
131
  //#endregion
132
132
  export { Section as a, Container as i, SingleColumnLayout as n, Backdrop as r, SplitColumnLayout as t };
133
133
 
134
- //# sourceMappingURL=PageLayout-CPiVnS_r.mjs.map
134
+ //# sourceMappingURL=PageLayout-D_NZNEit.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout-CPiVnS_r.mjs","names":[],"sources":["../src/patterns/PageLayout/PageLayout.tsx","../src/patterns/PageLayout/PageLayoutFrame.tsx","../src/patterns/PageLayout/SingleColumnLayout.tsx","../src/patterns/PageLayout/SplitColumnLayout.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nexport const Backdrop = styled.div`\n position: relative;\n width: 100%;\n padding: ${Spacing[7]} ${Spacing[5]};\n\n display: flex;\n flex-direction: column;\n`;\n\nconst StyledContainer = styled('div')`\n position: relative;\n width: 100%;\n padding: 0;\n\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nexport const Container = ({\n children,\n ...rest\n}: { children: ReactNode } & ComponentPropsWithoutRef<'div'>) => {\n return <StyledContainer {...rest}>{children}</StyledContainer>;\n};\n\nexport const Section = styled('div')`\n width: 100%;\n padding: ${Spacing[7]};\n`;\n","import { type ReactNode, useLayoutEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Grid, { GRID_BREAKPOINTS, GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nexport type PageLayoutWidth = 'standard' | 'wide';\n\nexport interface PageLayoutChromeProps {\n /**\n * `standard` uses the fixed grid (centered, max 1408px). `wide` uses the fluid grid.\n *\n * @defaultValue 'standard'\n */\n width?: PageLayoutWidth;\n /** Tab group. Sits above the page notice and scrolls with the page. Omit to skip the region and its gap. */\n tabs?: ReactNode;\n /** Page notice under the tabs. Omit to skip the region and its gap. */\n pageNotice?: ReactNode;\n}\n\nconst topPadding = (condensed: boolean) => (condensed ? Spacing[5] : Spacing[6]);\n\nconst Root = styled.div<{ $condensed: boolean; $tabs: boolean }>`\n width: 100%;\n min-width: ${GRID_BREAKPOINTS.sm - 1}px;\n padding-top: ${({ $condensed, $tabs }) => ($tabs ? Spacing[5] : topPadding($condensed))};\n padding-bottom: ${({ $condensed }) => topPadding($condensed)};\n background-color: ${({ theme }) =>\n semanticColor(theme, 'SurfacePage', theme.color.background.secondary)};\n`;\n\nconst gridMode = (width: PageLayoutWidth): 'fixed' | 'fluid' =>\n width === 'wide' ? 'fluid' : 'fixed';\n\nconst FullWidthBand = ({ mode, children }: { mode: 'fixed' | 'fluid'; children: ReactNode }) => (\n <Grid mode={mode}>\n <GridItem span={12}>{children}</GridItem>\n </Grid>\n);\n\nexport const PageLayoutFrame = ({\n width = 'standard',\n tabs,\n pageNotice,\n children,\n}: PageLayoutChromeProps & { children: ReactNode }) => {\n const mode = gridMode(width);\n const ref = useRef<HTMLDivElement>(null);\n const [condensed, setCondensed] = useState(false);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) {\n return;\n }\n const update = () => setCondensed(node.offsetWidth < GRID_BREAKPOINTS.md);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n return (\n <Root ref={ref} $condensed={condensed} $tabs={Boolean(tabs)}>\n <Stack spacing={Spacing[5]}>\n {tabs && <FullWidthBand mode={mode}>{tabs}</FullWidthBand>}\n {pageNotice && <FullWidthBand mode={mode}>{pageNotice}</FullWidthBand>}\n <Grid mode={mode}>{children}</Grid>\n </Stack>\n </Root>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nexport interface SingleColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary page content. Direct children stack vertically. */\n main: ReactNode;\n}\n\nexport const SingleColumnLayout = ({ main, ...chrome }: SingleColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <GridItem span={12}>\n <Stack spacing={Spacing[4]}>{main}</Stack>\n </GridItem>\n </PageLayoutFrame>\n);\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem, type GridSpan, useGridBreakpoint } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nconst SPLIT_COLUMN_SPANS = { main: 8, aside: 4 } as const satisfies Record<string, GridSpan>;\n\nexport interface SplitColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary column. Direct children stack vertically and stay in this column. */\n main: ReactNode;\n /** Supporting column. Direct children stack vertically and stay in this column. */\n aside: ReactNode;\n}\n\nconst Region = ({ children }: { children: ReactNode }) => (\n <Stack spacing={Spacing[4]}>{children}</Stack>\n);\n\nconst SplitBody = ({ main, aside }: { main: ReactNode; aside: ReactNode }) => {\n const stacked = useGridBreakpoint() === 'xs';\n const mainSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.main;\n const asideSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.aside;\n\n return (\n <>\n <GridItem span={mainSpan}>\n <Region>{main}</Region>\n </GridItem>\n <GridItem span={asideSpan}>\n <aside>\n <Region>{aside}</Region>\n </aside>\n </GridItem>\n </>\n );\n};\n\nexport const SplitColumnLayout = ({ main, aside, ...chrome }: SplitColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <SplitBody main={main} aside={aside} />\n </PageLayoutFrame>\n);\n"],"mappings":";;;;;;;;AAKA,MAAa,WAAW,OAAO,GAAG;;;aAGrB,QAAQ,GAAG,GAAG,QAAQ,GAAG;;;;;AAMtC,MAAM,kBAAkB,OAAO,MAAM;;;;;;;;;AAUrC,MAAa,aAAa,EACxB,UACA,GAAG,WAC4D;AAC/D,QAAO,oBAAC,iBAAD;EAAiB,GAAI;EAAO;EAA2B,CAAA;;AAGhE,MAAa,UAAU,OAAO,MAAM;;aAEvB,QAAQ,GAAG;;;;ACTxB,MAAM,cAAc,cAAwB,YAAY,QAAQ,KAAK,QAAQ;AAE7E,MAAM,OAAO,OAAO,GAA4C;;eAEjD,iBAAiB,KAAK,EAAE;kBACrB,EAAE,YAAY,YAAa,QAAQ,QAAQ,KAAK,WAAW,WAAW,CAAE;qBACrE,EAAE,iBAAiB,WAAW,WAAW,CAAC;uBACxC,EAAE,YACrB,cAAc,OAAO,eAAe,MAAM,MAAM,WAAW,UAAU,CAAC;;AAG1E,MAAM,YAAY,UAChB,UAAU,SAAS,UAAU;AAE/B,MAAM,iBAAiB,EAAE,MAAM,eAC7B,oBAAC,MAAD;CAAY;WACV,oBAAC,UAAD;EAAU,MAAM;EAAK;EAAoB,CAAA;CACpC,CAAA;AAGT,MAAa,mBAAmB,EAC9B,QAAQ,YACR,MACA,YACA,eACqD;CACrD,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAM,MAAM,OAAuB,KAAK;CACxC,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;AAEjD,uBAAsB;EACpB,MAAM,OAAO,IAAI;AACjB,MAAI,CAAC,KACH;EAEF,MAAM,eAAe,aAAa,KAAK,cAAc,iBAAiB,GAAG;AACzE,UAAQ;EACR,MAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,WAAS,QAAQ,KAAK;AACtB,eAAa,SAAS,YAAY;IACjC,EAAE,CAAC;AAEN,QACE,oBAAC,MAAD;EAAW;EAAK,YAAY;EAAW,OAAO,QAAQ,KAAK;YACzD,qBAAC,OAAD;GAAO,SAAS,QAAQ;aAAxB;IACG,QAAQ,oBAAC,eAAD;KAAqB;eAAO;KAAqB,CAAA;IACzD,cAAc,oBAAC,eAAD;KAAqB;eAAO;KAA2B,CAAA;IACtE,oBAAC,MAAD;KAAY;KAAO;KAAgB,CAAA;IAC7B;;EACH,CAAA;;;;AC3DX,MAAa,sBAAsB,EAAE,MAAM,GAAG,aAC5C,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,OAAD;GAAO,SAAS,QAAQ;aAAK;GAAa,CAAA;EACjC,CAAA;CACK,CAAA;;;ACVpB,MAAM,qBAAqB;CAAE,MAAM;CAAG,OAAO;CAAG;AAShD,MAAM,UAAU,EAAE,eAChB,oBAAC,OAAD;CAAO,SAAS,QAAQ;CAAK;CAAiB,CAAA;AAGhD,MAAM,aAAa,EAAE,MAAM,YAAmD;CAC5E,MAAM,UAAU,mBAAmB,KAAK;CACxC,MAAM,WAAW,UAAU,KAAK,mBAAmB;CACnD,MAAM,YAAY,UAAU,KAAK,mBAAmB;AAEpD,QACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,QAAD,EAAA,UAAS,MAAc,CAAA;EACd,CAAA,EACX,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,SAAD,EAAA,UACE,oBAAC,QAAD,EAAA,UAAS,OAAe,CAAA,EAClB,CAAA;EACC,CAAA,CACV,EAAA,CAAA;;AAIP,MAAa,qBAAqB,EAAE,MAAM,OAAO,GAAG,aAClD,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,WAAD;EAAiB;EAAa;EAAS,CAAA;CACvB,CAAA"}
1
+ {"version":3,"file":"PageLayout-D_NZNEit.mjs","names":[],"sources":["../src/patterns/PageLayout/PageLayout.tsx","../src/patterns/PageLayout/PageLayoutFrame.tsx","../src/patterns/PageLayout/SingleColumnLayout.tsx","../src/patterns/PageLayout/SplitColumnLayout.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nexport const Backdrop = styled.div`\n position: relative;\n width: 100%;\n padding: ${Spacing[7]} ${Spacing[5]};\n\n display: flex;\n flex-direction: column;\n`;\n\nconst StyledContainer = styled('div')`\n position: relative;\n width: 100%;\n padding: 0;\n\n display: flex;\n flex-direction: column;\n align-items: center;\n`;\n\nexport const Container = ({\n children,\n ...rest\n}: { children: ReactNode } & ComponentPropsWithoutRef<'div'>) => {\n return <StyledContainer {...rest}>{children}</StyledContainer>;\n};\n\nexport const Section = styled('div')`\n width: 100%;\n padding: ${Spacing[7]};\n`;\n","import { type ReactNode, useLayoutEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport Grid, { GRID_BREAKPOINTS, GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nexport type PageLayoutWidth = 'standard' | 'wide';\n\nexport interface PageLayoutChromeProps {\n /**\n * `standard` uses the fixed grid (centered, max 1408px). `wide` uses the fluid grid.\n *\n * @defaultValue 'standard'\n */\n width?: PageLayoutWidth;\n /** Tab group. Sits above the page notice and scrolls with the page. Omit to skip the region and its gap. */\n tabs?: ReactNode;\n /** Page notice under the tabs. Omit to skip the region and its gap. */\n pageNotice?: ReactNode;\n}\n\nconst topPadding = (condensed: boolean) => (condensed ? Spacing[5] : Spacing[6]);\n\nconst Root = styled.div<{ $condensed: boolean; $tabs: boolean }>`\n width: 100%;\n min-width: ${GRID_BREAKPOINTS.sm - 1}px;\n padding-top: ${({ $condensed, $tabs }) => ($tabs ? Spacing[5] : topPadding($condensed))};\n padding-bottom: ${({ $condensed }) => topPadding($condensed)};\n background-color: ${({ theme }) =>\n semanticColor(theme, 'SurfacePage', theme.color.background.secondary)};\n`;\n\nconst gridMode = (width: PageLayoutWidth): 'fixed' | 'fluid' =>\n width === 'wide' ? 'fluid' : 'fixed';\n\nconst FullWidthBand = ({ mode, children }: { mode: 'fixed' | 'fluid'; children: ReactNode }) => (\n <Grid mode={mode}>\n <GridItem span={12}>{children}</GridItem>\n </Grid>\n);\n\nexport const PageLayoutFrame = ({\n width = 'standard',\n tabs,\n pageNotice,\n children,\n}: PageLayoutChromeProps & { children: ReactNode }) => {\n const mode = gridMode(width);\n const ref = useRef<HTMLDivElement>(null);\n const [condensed, setCondensed] = useState(false);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) {\n return;\n }\n const update = () => setCondensed(node.offsetWidth < GRID_BREAKPOINTS.md);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n return (\n <Root ref={ref} $condensed={condensed} $tabs={Boolean(tabs)}>\n <Stack spacing={Spacing[5]}>\n {tabs && <FullWidthBand mode={mode}>{tabs}</FullWidthBand>}\n {pageNotice && <FullWidthBand mode={mode}>{pageNotice}</FullWidthBand>}\n <Grid mode={mode}>{children}</Grid>\n </Stack>\n </Root>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nexport interface SingleColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary page content. Direct children stack vertically. */\n main: ReactNode;\n}\n\nexport const SingleColumnLayout = ({ main, ...chrome }: SingleColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <GridItem span={12}>\n <Stack spacing={Spacing[4]}>{main}</Stack>\n </GridItem>\n </PageLayoutFrame>\n);\n","import type { ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { GridItem, type GridSpan, useGridBreakpoint } from '#src/components/Grid';\nimport { Stack } from '#src/components/Stack';\n\nimport { PageLayoutFrame, type PageLayoutChromeProps } from './PageLayoutFrame';\n\nconst SPLIT_COLUMN_SPANS = { main: 8, aside: 4 } as const satisfies Record<string, GridSpan>;\n\nexport interface SplitColumnLayoutProps extends PageLayoutChromeProps {\n /** Primary column. Direct children stack vertically and stay in this column. */\n main: ReactNode;\n /** Supporting column. Direct children stack vertically and stay in this column. */\n aside: ReactNode;\n}\n\nconst Region = ({ children }: { children: ReactNode }) => (\n <Stack spacing={Spacing[4]}>{children}</Stack>\n);\n\nconst SplitBody = ({ main, aside }: { main: ReactNode; aside: ReactNode }) => {\n const stacked = useGridBreakpoint() === 'xs';\n const mainSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.main;\n const asideSpan = stacked ? 12 : SPLIT_COLUMN_SPANS.aside;\n\n return (\n <>\n <GridItem span={mainSpan}>\n <Region>{main}</Region>\n </GridItem>\n <GridItem span={asideSpan}>\n <aside>\n <Region>{aside}</Region>\n </aside>\n </GridItem>\n </>\n );\n};\n\nexport const SplitColumnLayout = ({ main, aside, ...chrome }: SplitColumnLayoutProps) => (\n <PageLayoutFrame {...chrome}>\n <SplitBody main={main} aside={aside} />\n </PageLayoutFrame>\n);\n"],"mappings":";;;;;;;;AAKA,MAAa,WAAW,OAAO,GAAG;;;aAGrB,QAAQ,GAAG,GAAG,QAAQ,GAAG;;;;;AAMtC,MAAM,kBAAkB,OAAO,MAAM;;;;;;;;;AAUrC,MAAa,aAAa,EACxB,UACA,GAAG,WAC4D;AAC/D,QAAO,oBAAC,iBAAD;EAAiB,GAAI;EAAO;EAA2B,CAAA;;AAGhE,MAAa,UAAU,OAAO,MAAM;;aAEvB,QAAQ,GAAG;;;;ACTxB,MAAM,cAAc,cAAwB,YAAY,QAAQ,KAAK,QAAQ;AAE7E,MAAM,OAAO,OAAO,GAA4C;;eAEjD,iBAAiB,KAAK,EAAE;kBACrB,EAAE,YAAY,YAAa,QAAQ,QAAQ,KAAK,WAAW,WAAW,CAAE;qBACrE,EAAE,iBAAiB,WAAW,WAAW,CAAC;uBACxC,EAAE,YACrB,cAAc,OAAO,eAAe,MAAM,MAAM,WAAW,UAAU,CAAC;;AAG1E,MAAM,YAAY,UAChB,UAAU,SAAS,UAAU;AAE/B,MAAM,iBAAiB,EAAE,MAAM,eAC7B,oBAAC,MAAD;CAAY;WACV,oBAAC,UAAD;EAAU,MAAM;EAAK;EAAoB,CAAA;CACpC,CAAA;AAGT,MAAa,mBAAmB,EAC9B,QAAQ,YACR,MACA,YACA,eACqD;CACrD,MAAM,OAAO,SAAS,MAAM;CAC5B,MAAM,MAAM,OAAuB,KAAK;CACxC,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;AAEjD,uBAAsB;EACpB,MAAM,OAAO,IAAI;AACjB,MAAI,CAAC,KACH;EAEF,MAAM,eAAe,aAAa,KAAK,cAAc,iBAAiB,GAAG;AACzE,UAAQ;EACR,MAAM,WAAW,IAAI,eAAe,OAAO;AAC3C,WAAS,QAAQ,KAAK;AACtB,eAAa,SAAS,YAAY;IACjC,EAAE,CAAC;AAEN,QACE,oBAAC,MAAD;EAAW;EAAK,YAAY;EAAW,OAAO,QAAQ,KAAK;YACzD,qBAAC,OAAD;GAAO,SAAS,QAAQ;aAAxB;IACG,QAAQ,oBAAC,eAAD;KAAqB;eAAO;KAAqB,CAAA;IACzD,cAAc,oBAAC,eAAD;KAAqB;eAAO;KAA2B,CAAA;IACtE,oBAAC,MAAD;KAAY;KAAO;KAAgB,CAAA;IAC7B;;EACH,CAAA;;;;AC3DX,MAAa,sBAAsB,EAAE,MAAM,GAAG,aAC5C,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,OAAD;GAAO,SAAS,QAAQ;aAAK;GAAa,CAAA;EACjC,CAAA;CACK,CAAA;;;ACVpB,MAAM,qBAAqB;CAAE,MAAM;CAAG,OAAO;CAAG;AAShD,MAAM,UAAU,EAAE,eAChB,oBAAC,OAAD;CAAO,SAAS,QAAQ;CAAK;CAAiB,CAAA;AAGhD,MAAM,aAAa,EAAE,MAAM,YAAmD;CAC5E,MAAM,UAAU,mBAAmB,KAAK;CACxC,MAAM,WAAW,UAAU,KAAK,mBAAmB;CACnD,MAAM,YAAY,UAAU,KAAK,mBAAmB;AAEpD,QACE,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,QAAD,EAAA,UAAS,MAAc,CAAA;EACd,CAAA,EACX,oBAAC,UAAD;EAAU,MAAM;YACd,oBAAC,SAAD,EAAA,UACE,oBAAC,QAAD,EAAA,UAAS,OAAe,CAAA,EAClB,CAAA;EACC,CAAA,CACV,EAAA,CAAA;;AAIP,MAAa,qBAAqB,EAAE,MAAM,OAAO,GAAG,aAClD,oBAAC,iBAAD;CAAiB,GAAI;WACnB,oBAAC,WAAD;EAAiB;EAAa;EAAS,CAAA;CACvB,CAAA"}
@@ -1,2 +1,2 @@
1
- import { n as Container, r as Section, t as Backdrop } from "./PageLayout-BdVM37bV.mjs";
1
+ import { n as Container, r as Section, t as Backdrop } from "./PageLayout-BXM_pyrU.mjs";
2
2
  export { Backdrop, Container, Section };
@@ -1,4 +1,4 @@
1
- import { n as HStackProps } from "./Stack-CODxfzhl.mjs";
1
+ import { n as HStackProps } from "./Stack-B6MrjJeW.mjs";
2
2
  import { t as PaginationParams } from "./types-CRymR_J9.mjs";
3
3
  import * as _$styled_components0 from "styled-components";
4
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
@@ -33,4 +33,4 @@ declare function PageSelector({
33
33
  }: PageSelectorProps): _$react_jsx_runtime0.JSX.Element;
34
34
  //#endregion
35
35
  export { PageInput as n, PageSelector as r, PAGE_LIMIT_BEFORE_SCROLL_MODE as t };
36
- //# sourceMappingURL=PageSelector-B5CcAzss.d.mts.map
36
+ //# sourceMappingURL=PageSelector-C14ABZVL.d.mts.map
@@ -1,2 +1,2 @@
1
- import { n as PageInput, r as PageSelector, t as PAGE_LIMIT_BEFORE_SCROLL_MODE } from "./PageSelector-B5CcAzss.mjs";
1
+ import { n as PageInput, r as PageSelector, t as PAGE_LIMIT_BEFORE_SCROLL_MODE } from "./PageSelector-C14ABZVL.mjs";
2
2
  export { PAGE_LIMIT_BEFORE_SCROLL_MODE, PageInput, PageSelector as default };
@@ -2,11 +2,11 @@ import { a as styled } from "./styledComponentsInterop-Cs5CCPRy.mjs";
2
2
  import { semanticColor } from "./lib/semanticColor.mjs";
3
3
  import { l as usePDSStrings } from "./i18n-DaOKaFc2.mjs";
4
4
  import { t as HStack } from "./Stack-Bzom2BTR.mjs";
5
- import { n as Button } from "./IconButton-Bj1fry_K.mjs";
6
- import { n as Input } from "./Input-DcbzPaax.mjs";
7
- import { n as Select, t as Option } from "./Select-DbWEgH5c.mjs";
8
- import { useEffect, useMemo, useState } from "react";
5
+ import { n as Button } from "./IconButton-kSjnfhWt.mjs";
6
+ import { n as Input } from "./Input-BIHbRmmU.mjs";
7
+ import { n as Select, t as Option } from "./Select-Bicuj8VD.mjs";
9
8
  import { Color, Spacing, Typography } from "@persona/design-tokens";
9
+ import { useEffect, useMemo, useState } from "react";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { debounce } from "lodash-es";
12
12
  //#region src/components/Pagination/constants.ts
@@ -198,4 +198,4 @@ var Pagination_default = Pagination;
198
198
  //#endregion
199
199
  export { MIN_PAGE_SIZE as a, DEFAULT_PAGE_SIZE_OPTIONS as i, PAGE_LIMIT_BEFORE_SCROLL_MODE as n, PageSelector as r, Pagination_default as t };
200
200
 
201
- //# sourceMappingURL=Pagination-CqFvnlXc.mjs.map
201
+ //# sourceMappingURL=Pagination-CgT2eQrk.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination-CqFvnlXc.mjs","names":[],"sources":["../src/components/Pagination/constants.ts","../src/components/Pagination/PageSelector.tsx","../src/components/Pagination/PageSizeSelector.tsx","../src/components/Pagination/Pagination.tsx","../src/components/Pagination/index.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 300];\nexport const MIN_PAGE_SIZE = 10;\n","import { debounce } from 'lodash-es';\nimport { useEffect, useMemo, useState } from 'react';\nimport styled from 'styled-components';\n\nimport Button from '@persona/design-system/components/Button';\nimport { Input } from '@persona/design-system/components/Input';\nimport { HStack } from '@persona/design-system/components/Stack';\nimport { Spacing } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\n\nimport type { PaginationParams } from './types';\n\n// After a certain limit, it no longer makes sense for someone\n// to jump to the last page. Deep paging has performance limitations. A collection\n// with exactly this many pages still gets the page input: servers that cap paging\n// at this limit (Kaminari's max_pages) report every page up to it as reachable.\nexport const PAGE_LIMIT_BEFORE_SCROLL_MODE = 100;\n\nconst PageSelectorStack = styled(HStack).attrs({ justify: 'flex-end' })`\n padding: ${Spacing[2]};\n`;\n\nexport const PageInput = styled(HStack).attrs({ align: 'center' })`\n white-space: nowrap;\n`;\n\ninterface PageSelectorProps {\n paginationParams: PaginationParams;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n /**\n * Called with the new page number after the page changes (next, prev, or\n * typed input). Lets the consumer react to page changes -- e.g. scroll the\n * page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n /**\n * `total-pages` is only a lower bound: render it as `13+` and keep Next enabled past it. See\n * `Pagination`'s prop of the same name.\n */\n totalIsLowerBound?: boolean;\n}\n\nexport default function PageSelector({\n paginationParams,\n handlePageLinkClick,\n isLoading,\n onPageChange,\n totalIsLowerBound = false,\n}: PageSelectorProps) {\n const strings = usePDSStrings();\n const {\n 'current-page': currentPage,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams ?? {};\n const [selectedPage, setSelectedPage] = useState<number | undefined>(currentPage);\n // Next stays enabled at the last page the totals know of when more may follow.\n const morePagesMayFollow = lowerBound || totalIsLowerBound;\n // Paged past a minimum page count, how many pages there are is no longer known.\n const totalUnknown = lowerBound || (totalIsLowerBound && currentPage > totalPages);\n\n // We don't use useDebounced to avoid function object reference issues.\n const handlePageLinkClickDebounced = useMemo(\n () => debounce(handlePageLinkClick, 500),\n [handlePageLinkClick],\n );\n\n // Keep input state synced to pagination state when other user action changes\n // pagination state.\n useEffect(() => {\n if (currentPage != null) {\n setSelectedPage(currentPage);\n }\n }, [currentPage]);\n\n if (!paginationParams) {\n return <div />;\n }\n\n return (\n <PageSelectorStack data-test='pagination__page-selector' id='pagination__page-selector'>\n <PageInput>\n {totalPages <= PAGE_LIMIT_BEFORE_SCROLL_MODE && !totalUnknown ? (\n <Input\n aria-label={strings.goToPageNumber}\n size='sm'\n inputSize={2}\n onChange={(e) => {\n const value = e.target.valueAsNumber;\n if (Number.isNaN(value)) {\n setSelectedPage(undefined);\n } else {\n // Setting unbounded value feels smoother as the value is not corrected until after the fetch via useEffect.\n setSelectedPage(value);\n const boundedValue = Math.min(Math.max(e.target.valueAsNumber, 1), totalPages);\n handlePageLinkClickDebounced(boundedValue);\n onPageChange?.(boundedValue);\n }\n }}\n onBlur={(e) => {\n // Fill blank value on blur.\n if (Number.isNaN(e.target.valueAsNumber)) {\n setSelectedPage(currentPage);\n }\n }}\n min={1}\n max={totalPages}\n type='number'\n disabled={isLoading}\n value={selectedPage ?? ''}\n />\n ) : (\n currentPage + ' '\n )}\n {strings.pageCount(\n currentPage,\n totalUnknown\n ? strings.many\n : totalIsLowerBound\n ? strings.atLeast(totalPages)\n : totalPages,\n )}\n </PageInput>\n <Button\n id='pagination__page-selector--left'\n disabled={currentPage === 1 || isLoading}\n onClick={() => {\n if (currentPage !== 1) {\n const prevPageNum = currentPage - 1;\n setSelectedPage(prevPageNum);\n handlePageLinkClick(prevPageNum);\n onPageChange?.(prevPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-left'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label={strings.previousPage}\n >\n {strings.previousShort}\n </Button>\n <Button\n id='pagination__page-selector--right'\n disabled={(currentPage === totalPages && !morePagesMayFollow) || isLoading}\n onClick={() => {\n if (currentPage !== totalPages || morePagesMayFollow) {\n const nextPageNum = currentPage + 1;\n setSelectedPage(nextPageNum);\n handlePageLinkClick(nextPageNum);\n onPageChange?.(nextPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-right'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label={strings.nextPage}\n >\n {strings.next}\n </Button>\n </PageSelectorStack>\n );\n}\n","import styled from 'styled-components';\n\nimport Select, { Option } from '@persona/design-system/components/Select';\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nconst Selector = styled('div')`\n padding: ${Spacing[2]};\n display: flex;\n justify-content: flex-end;\n`;\n\nconst Label = styled.label`\n display: flex;\n align-items: center;\n white-space: nowrap;\n gap: ${Spacing[2]};\n padding: ${Spacing[2]};\n`;\n\ninterface PageSizeOptionProps {\n currentPageSize: number;\n pageSizeOption: number;\n}\n\nexport const PageSizeOption = styled('div')<PageSizeOptionProps>`\n padding: 0 ${Spacing[1]};\n color: ${({ theme }) => semanticColor(theme, 'FgAccentStatic', Color.PrimaryPurple)};\n cursor: pointer;\n\n ${({ currentPageSize, pageSizeOption }) => {\n if (currentPageSize === pageSizeOption) {\n return `\n ${Typography.TextMediumBold};\n text-decoration: underline;\n `;\n }\n }};\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\ninterface PageSizeSelectorProps {\n pageSize: number;\n pageSizeOptions: number[];\n handlePageSizeClick: (pageSize: number) => void;\n /**\n * Element the options menu renders into. Pass a container inside the surrounding dialog when the\n * pager sits in a clipping container, where the menu would otherwise be cut off.\n */\n menuPortalContainer?: HTMLElement | null;\n}\n\nconst PageSizeSelector = ({\n pageSize,\n pageSizeOptions,\n handlePageSizeClick,\n menuPortalContainer,\n}: PageSizeSelectorProps) => {\n const strings = usePDSStrings();\n // Add pageSize to selector just in case it isn't part of the options so UI doesn't look weird\n const pageSizes = [\n ...pageSizeOptions,\n ...(pageSizeOptions.includes(pageSize) ? [] : [pageSize]),\n ].sort((a, b) => a - b);\n\n return (\n <Selector data-test='pagination__page-size-selector'>\n <Label>\n {strings.itemsPerPage}\n <Select\n value={pageSize.toString()}\n onValueChange={(val) => handlePageSizeClick(Number(val))}\n size='sm'\n portal={menuPortalContainer != null}\n portalContainer={menuPortalContainer}\n >\n {pageSizes.map((size) => (\n <Option key={size} value={size.toString()}>\n {size}\n </Option>\n ))}\n </Select>\n </Label>\n </Selector>\n );\n};\n\nexport default PageSizeSelector;\n","import styled from 'styled-components';\n\nimport { Color, Typography } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nimport { DEFAULT_PAGE_SIZE_OPTIONS } from './constants';\nimport PageSelector from './PageSelector';\nimport PageSizeSelector from './PageSizeSelector';\nimport type { PaginationParams } from './types';\n\n// NB: this is configured in config/initializers/kaminari.rb\nconst MAX_PAGES = 100;\n\nconst Container = styled('nav')`\n ${Typography.TextMedium};\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\n\nexport const PaginationInfo = styled('div')`\n display: flex;\n align-items: center;\n\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.TextPrimary)};\n`;\n\ninterface PaginationProps {\n pageSize?: number;\n pageSizeOptions?: number[];\n paginationParams?: PaginationParams;\n handlePageSizeClick: (pageSize: number) => void;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n showPageSizeSelector?: boolean;\n /**\n * Called with the new page number after the page changes. Lets the consumer\n * react to page changes -- e.g. scroll the page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n /**\n * Element the page-size menu renders into. Pass a container inside the surrounding dialog when\n * the pager sits in a clipping container, where the menu would otherwise be cut off.\n */\n menuPortalContainer?: HTMLElement | null;\n /**\n * The totals in `paginationParams` are only a lower bound: there are at least that many items\n * and pages, e.g. when the server counts a bounded number of pages ahead. They render as `650+`\n * and `13+`, any page up to `total-pages` can still be typed in, and Next stays enabled past it.\n * `lower-bound` in `paginationParams`, a total that is not known at all, takes precedence.\n */\n totalIsLowerBound?: boolean;\n}\n\nconst Pagination = ({\n pageSize,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationParams,\n handlePageSizeClick,\n handlePageLinkClick,\n isLoading,\n showPageSizeSelector = true,\n onPageChange,\n menuPortalContainer,\n totalIsLowerBound = false,\n}: PaginationProps) => {\n const strings = usePDSStrings();\n\n if (!paginationParams || !pageSize) {\n return <div />;\n }\n\n const {\n 'current-page': currentPage,\n 'total-count': totalCount,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams;\n\n // If the total number of pages is the same as MAX_PAGES, we guess that the total number of\n // items might be limited by max pages, and that the total could change based on page size.\n // To limit user confusion here, we use 'many' instead of a specific number.\n // Paged past the minimum the totals give, how many there are is no longer known: render it like\n // `lower-bound` rather than an item range that ends before it starts.\n const pastKnownTotal = totalIsLowerBound && !lowerBound && currentPage > totalPages;\n const totalUnknown = lowerBound || pastKnownTotal;\n const totalAtLeast = totalIsLowerBound && !totalUnknown;\n const totalCountDisplay =\n totalUnknown || totalPages >= MAX_PAGES\n ? strings.many\n : totalAtLeast\n ? strings.atLeast(totalCount)\n : totalCount;\n\n const lastItemIndex = totalUnknown\n ? currentPage * pageSize\n : Math.min(currentPage * pageSize, totalCount);\n const firstItemIndex = pageSize * (currentPage - 1) + 1;\n\n return (\n <Container role='navigation' aria-label={strings.pagination}>\n {showPageSizeSelector && (\n <PageSizeSelector\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n handlePageSizeClick={handlePageSizeClick}\n menuPortalContainer={menuPortalContainer}\n />\n )}\n {totalCount > 0 && (\n <>\n <div>{strings.showingItems(firstItemIndex, lastItemIndex, totalCountDisplay)}</div>\n <PaginationInfo>\n <PageSelector\n paginationParams={paginationParams}\n handlePageLinkClick={handlePageLinkClick}\n isLoading={isLoading}\n onPageChange={onPageChange}\n totalIsLowerBound={totalIsLowerBound && !lowerBound}\n />\n </PaginationInfo>\n </>\n )}\n </Container>\n );\n};\n\nexport default Pagination;\n","import Pagination from './Pagination';\n\nexport { default as PageSelector, PAGE_LIMIT_BEFORE_SCROLL_MODE } from './PageSelector';\nexport * from './constants';\nexport default Pagination;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination-CgT2eQrk.mjs","names":[],"sources":["../src/components/Pagination/constants.ts","../src/components/Pagination/PageSelector.tsx","../src/components/Pagination/PageSizeSelector.tsx","../src/components/Pagination/Pagination.tsx","../src/components/Pagination/index.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 300];\nexport const MIN_PAGE_SIZE = 10;\n","import { debounce } from 'lodash-es';\nimport { useEffect, useMemo, useState } from 'react';\nimport styled from 'styled-components';\n\nimport Button from '@persona/design-system/components/Button';\nimport { Input } from '@persona/design-system/components/Input';\nimport { HStack } from '@persona/design-system/components/Stack';\nimport { Spacing } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\n\nimport type { PaginationParams } from './types';\n\n// After a certain limit, it no longer makes sense for someone\n// to jump to the last page. Deep paging has performance limitations. A collection\n// with exactly this many pages still gets the page input: servers that cap paging\n// at this limit (Kaminari's max_pages) report every page up to it as reachable.\nexport const PAGE_LIMIT_BEFORE_SCROLL_MODE = 100;\n\nconst PageSelectorStack = styled(HStack).attrs({ justify: 'flex-end' })`\n padding: ${Spacing[2]};\n`;\n\nexport const PageInput = styled(HStack).attrs({ align: 'center' })`\n white-space: nowrap;\n`;\n\ninterface PageSelectorProps {\n paginationParams: PaginationParams;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n /**\n * Called with the new page number after the page changes (next, prev, or\n * typed input). Lets the consumer react to page changes -- e.g. scroll the\n * page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n /**\n * `total-pages` is only a lower bound: render it as `13+` and keep Next enabled past it. See\n * `Pagination`'s prop of the same name.\n */\n totalIsLowerBound?: boolean;\n}\n\nexport default function PageSelector({\n paginationParams,\n handlePageLinkClick,\n isLoading,\n onPageChange,\n totalIsLowerBound = false,\n}: PageSelectorProps) {\n const strings = usePDSStrings();\n const {\n 'current-page': currentPage,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams ?? {};\n const [selectedPage, setSelectedPage] = useState<number | undefined>(currentPage);\n // Next stays enabled at the last page the totals know of when more may follow.\n const morePagesMayFollow = lowerBound || totalIsLowerBound;\n // Paged past a minimum page count, how many pages there are is no longer known.\n const totalUnknown = lowerBound || (totalIsLowerBound && currentPage > totalPages);\n\n // We don't use useDebounced to avoid function object reference issues.\n const handlePageLinkClickDebounced = useMemo(\n () => debounce(handlePageLinkClick, 500),\n [handlePageLinkClick],\n );\n\n // Keep input state synced to pagination state when other user action changes\n // pagination state.\n useEffect(() => {\n if (currentPage != null) {\n setSelectedPage(currentPage);\n }\n }, [currentPage]);\n\n if (!paginationParams) {\n return <div />;\n }\n\n return (\n <PageSelectorStack data-test='pagination__page-selector' id='pagination__page-selector'>\n <PageInput>\n {totalPages <= PAGE_LIMIT_BEFORE_SCROLL_MODE && !totalUnknown ? (\n <Input\n aria-label={strings.goToPageNumber}\n size='sm'\n inputSize={2}\n onChange={(e) => {\n const value = e.target.valueAsNumber;\n if (Number.isNaN(value)) {\n setSelectedPage(undefined);\n } else {\n // Setting unbounded value feels smoother as the value is not corrected until after the fetch via useEffect.\n setSelectedPage(value);\n const boundedValue = Math.min(Math.max(e.target.valueAsNumber, 1), totalPages);\n handlePageLinkClickDebounced(boundedValue);\n onPageChange?.(boundedValue);\n }\n }}\n onBlur={(e) => {\n // Fill blank value on blur.\n if (Number.isNaN(e.target.valueAsNumber)) {\n setSelectedPage(currentPage);\n }\n }}\n min={1}\n max={totalPages}\n type='number'\n disabled={isLoading}\n value={selectedPage ?? ''}\n />\n ) : (\n currentPage + ' '\n )}\n {strings.pageCount(\n currentPage,\n totalUnknown\n ? strings.many\n : totalIsLowerBound\n ? strings.atLeast(totalPages)\n : totalPages,\n )}\n </PageInput>\n <Button\n id='pagination__page-selector--left'\n disabled={currentPage === 1 || isLoading}\n onClick={() => {\n if (currentPage !== 1) {\n const prevPageNum = currentPage - 1;\n setSelectedPage(prevPageNum);\n handlePageLinkClick(prevPageNum);\n onPageChange?.(prevPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-left'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label={strings.previousPage}\n >\n {strings.previousShort}\n </Button>\n <Button\n id='pagination__page-selector--right'\n disabled={(currentPage === totalPages && !morePagesMayFollow) || isLoading}\n onClick={() => {\n if (currentPage !== totalPages || morePagesMayFollow) {\n const nextPageNum = currentPage + 1;\n setSelectedPage(nextPageNum);\n handlePageLinkClick(nextPageNum);\n onPageChange?.(nextPageNum);\n }\n }}\n data-test='pagination__page-selector-paddle-right'\n variant='inverse'\n size='sm'\n width='auto'\n aria-label={strings.nextPage}\n >\n {strings.next}\n </Button>\n </PageSelectorStack>\n );\n}\n","import styled from 'styled-components';\n\nimport Select, { Option } from '@persona/design-system/components/Select';\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nconst Selector = styled('div')`\n padding: ${Spacing[2]};\n display: flex;\n justify-content: flex-end;\n`;\n\nconst Label = styled.label`\n display: flex;\n align-items: center;\n white-space: nowrap;\n gap: ${Spacing[2]};\n padding: ${Spacing[2]};\n`;\n\ninterface PageSizeOptionProps {\n currentPageSize: number;\n pageSizeOption: number;\n}\n\nexport const PageSizeOption = styled('div')<PageSizeOptionProps>`\n padding: 0 ${Spacing[1]};\n color: ${({ theme }) => semanticColor(theme, 'FgAccentStatic', Color.PrimaryPurple)};\n cursor: pointer;\n\n ${({ currentPageSize, pageSizeOption }) => {\n if (currentPageSize === pageSizeOption) {\n return `\n ${Typography.TextMediumBold};\n text-decoration: underline;\n `;\n }\n }};\n\n &:hover {\n text-decoration: underline;\n }\n`;\n\ninterface PageSizeSelectorProps {\n pageSize: number;\n pageSizeOptions: number[];\n handlePageSizeClick: (pageSize: number) => void;\n /**\n * Element the options menu renders into. Pass a container inside the surrounding dialog when the\n * pager sits in a clipping container, where the menu would otherwise be cut off.\n */\n menuPortalContainer?: HTMLElement | null;\n}\n\nconst PageSizeSelector = ({\n pageSize,\n pageSizeOptions,\n handlePageSizeClick,\n menuPortalContainer,\n}: PageSizeSelectorProps) => {\n const strings = usePDSStrings();\n // Add pageSize to selector just in case it isn't part of the options so UI doesn't look weird\n const pageSizes = [\n ...pageSizeOptions,\n ...(pageSizeOptions.includes(pageSize) ? [] : [pageSize]),\n ].sort((a, b) => a - b);\n\n return (\n <Selector data-test='pagination__page-size-selector'>\n <Label>\n {strings.itemsPerPage}\n <Select\n value={pageSize.toString()}\n onValueChange={(val) => handlePageSizeClick(Number(val))}\n size='sm'\n portal={menuPortalContainer != null}\n portalContainer={menuPortalContainer}\n >\n {pageSizes.map((size) => (\n <Option key={size} value={size.toString()}>\n {size}\n </Option>\n ))}\n </Select>\n </Label>\n </Selector>\n );\n};\n\nexport default PageSizeSelector;\n","import styled from 'styled-components';\n\nimport { Color, Typography } from '@persona/design-tokens';\n\nimport { usePDSStrings } from '#src/lib/i18n';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nimport { DEFAULT_PAGE_SIZE_OPTIONS } from './constants';\nimport PageSelector from './PageSelector';\nimport PageSizeSelector from './PageSizeSelector';\nimport type { PaginationParams } from './types';\n\n// NB: this is configured in config/initializers/kaminari.rb\nconst MAX_PAGES = 100;\n\nconst Container = styled('nav')`\n ${Typography.TextMedium};\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\n\nexport const PaginationInfo = styled('div')`\n display: flex;\n align-items: center;\n\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.TextPrimary)};\n`;\n\ninterface PaginationProps {\n pageSize?: number;\n pageSizeOptions?: number[];\n paginationParams?: PaginationParams;\n handlePageSizeClick: (pageSize: number) => void;\n handlePageLinkClick: (pageNumber: number) => void;\n isLoading?: boolean;\n showPageSizeSelector?: boolean;\n /**\n * Called with the new page number after the page changes. Lets the consumer\n * react to page changes -- e.g. scroll the page back to the top.\n */\n onPageChange?: (pageNumber: number) => void;\n /**\n * Element the page-size menu renders into. Pass a container inside the surrounding dialog when\n * the pager sits in a clipping container, where the menu would otherwise be cut off.\n */\n menuPortalContainer?: HTMLElement | null;\n /**\n * The totals in `paginationParams` are only a lower bound: there are at least that many items\n * and pages, e.g. when the server counts a bounded number of pages ahead. They render as `650+`\n * and `13+`, any page up to `total-pages` can still be typed in, and Next stays enabled past it.\n * `lower-bound` in `paginationParams`, a total that is not known at all, takes precedence.\n */\n totalIsLowerBound?: boolean;\n}\n\nconst Pagination = ({\n pageSize,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationParams,\n handlePageSizeClick,\n handlePageLinkClick,\n isLoading,\n showPageSizeSelector = true,\n onPageChange,\n menuPortalContainer,\n totalIsLowerBound = false,\n}: PaginationProps) => {\n const strings = usePDSStrings();\n\n if (!paginationParams || !pageSize) {\n return <div />;\n }\n\n const {\n 'current-page': currentPage,\n 'total-count': totalCount,\n 'total-pages': totalPages,\n 'lower-bound': lowerBound,\n } = paginationParams;\n\n // If the total number of pages is the same as MAX_PAGES, we guess that the total number of\n // items might be limited by max pages, and that the total could change based on page size.\n // To limit user confusion here, we use 'many' instead of a specific number.\n // Paged past the minimum the totals give, how many there are is no longer known: render it like\n // `lower-bound` rather than an item range that ends before it starts.\n const pastKnownTotal = totalIsLowerBound && !lowerBound && currentPage > totalPages;\n const totalUnknown = lowerBound || pastKnownTotal;\n const totalAtLeast = totalIsLowerBound && !totalUnknown;\n const totalCountDisplay =\n totalUnknown || totalPages >= MAX_PAGES\n ? strings.many\n : totalAtLeast\n ? strings.atLeast(totalCount)\n : totalCount;\n\n const lastItemIndex = totalUnknown\n ? currentPage * pageSize\n : Math.min(currentPage * pageSize, totalCount);\n const firstItemIndex = pageSize * (currentPage - 1) + 1;\n\n return (\n <Container role='navigation' aria-label={strings.pagination}>\n {showPageSizeSelector && (\n <PageSizeSelector\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n handlePageSizeClick={handlePageSizeClick}\n menuPortalContainer={menuPortalContainer}\n />\n )}\n {totalCount > 0 && (\n <>\n <div>{strings.showingItems(firstItemIndex, lastItemIndex, totalCountDisplay)}</div>\n <PaginationInfo>\n <PageSelector\n paginationParams={paginationParams}\n handlePageLinkClick={handlePageLinkClick}\n isLoading={isLoading}\n onPageChange={onPageChange}\n totalIsLowerBound={totalIsLowerBound && !lowerBound}\n />\n </PaginationInfo>\n </>\n )}\n </Container>\n );\n};\n\nexport default Pagination;\n","import Pagination from './Pagination';\n\nexport { default as PageSelector, PAGE_LIMIT_BEFORE_SCROLL_MODE } from './PageSelector';\nexport * from './constants';\nexport default Pagination;\n"],"mappings":";;;;;;;;;;;;AAAA,MAAa,4BAA4B;CAAC;CAAI;CAAI;CAAI;CAAK;CAAI;AAC/D,MAAa,gBAAgB;;;ACgB7B,MAAa,gCAAgC;AAE7C,MAAM,oBAAoB,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC;aAC1D,QAAQ,GAAG;;AAGxB,MAAa,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC;;;AAqBlE,SAAwB,aAAa,EACnC,kBACA,qBACA,WACA,cACA,oBAAoB,SACA;CACpB,MAAM,UAAU,eAAe;CAC/B,MAAM,EACJ,gBAAgB,aAChB,eAAe,YACf,eAAe,eACb,oBAAoB,EAAE;CAC1B,MAAM,CAAC,cAAc,mBAAmB,SAA6B,YAAY;CAEjF,MAAM,qBAAqB,cAAc;CAEzC,MAAM,eAAe,cAAe,qBAAqB,cAAc;CAGvE,MAAM,+BAA+B,cAC7B,SAAS,qBAAqB,IAAI,EACxC,CAAC,oBAAoB,CACtB;AAID,iBAAgB;AACd,MAAI,eAAe,KACjB,iBAAgB,YAAY;IAE7B,CAAC,YAAY,CAAC;AAEjB,KAAI,CAAC,iBACH,QAAO,oBAAC,OAAD,EAAO,CAAA;AAGhB,QACE,qBAAC,mBAAD;EAAmB,aAAU;EAA4B,IAAG;YAA5D;GACE,qBAAC,WAAD,EAAA,UAAA,CACG,cAAA,OAA+C,CAAC,eAC/C,oBAAC,OAAD;IACE,cAAY,QAAQ;IACpB,MAAK;IACL,WAAW;IACX,WAAW,MAAM;KACf,MAAM,QAAQ,EAAE,OAAO;AACvB,SAAI,OAAO,MAAM,MAAM,CACrB,iBAAgB,KAAA,EAAU;UACrB;AAEL,sBAAgB,MAAM;MACtB,MAAM,eAAe,KAAK,IAAI,KAAK,IAAI,EAAE,OAAO,eAAe,EAAE,EAAE,WAAW;AAC9E,mCAA6B,aAAa;AAC1C,qBAAe,aAAa;;;IAGhC,SAAS,MAAM;AAEb,SAAI,OAAO,MAAM,EAAE,OAAO,cAAc,CACtC,iBAAgB,YAAY;;IAGhC,KAAK;IACL,KAAK;IACL,MAAK;IACL,UAAU;IACV,OAAO,gBAAgB;IACvB,CAAA,GAEF,cAAc,KAEf,QAAQ,UACP,aACA,eACI,QAAQ,OACR,oBACE,QAAQ,QAAQ,WAAW,GAC3B,WACP,CACS,EAAA,CAAA;GACZ,oBAAC,QAAD;IACE,IAAG;IACH,UAAU,gBAAgB,KAAK;IAC/B,eAAe;AACb,SAAI,gBAAgB,GAAG;MACrB,MAAM,cAAc,cAAc;AAClC,sBAAgB,YAAY;AAC5B,0BAAoB,YAAY;AAChC,qBAAe,YAAY;;;IAG/B,aAAU;IACV,SAAQ;IACR,MAAK;IACL,OAAM;IACN,cAAY,QAAQ;cAEnB,QAAQ;IACF,CAAA;GACT,oBAAC,QAAD;IACE,IAAG;IACH,UAAW,gBAAgB,cAAc,CAAC,sBAAuB;IACjE,eAAe;AACb,SAAI,gBAAgB,cAAc,oBAAoB;MACpD,MAAM,cAAc,cAAc;AAClC,sBAAgB,YAAY;AAC5B,0BAAoB,YAAY;AAChC,qBAAe,YAAY;;;IAG/B,aAAU;IACV,SAAQ;IACR,MAAK;IACL,OAAM;IACN,cAAY,QAAQ;cAEnB,QAAQ;IACF,CAAA;GACS;;;;;AC3JxB,MAAM,WAAW,OAAO,MAAM;aACjB,QAAQ,GAAG;;;;AAKxB,MAAM,QAAQ,OAAO,KAAK;;;;SAIjB,QAAQ,GAAG;aACP,QAAQ,GAAG;;AAQM,OAAO,MAAM;eAC5B,QAAQ,GAAG;YACd,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,cAAc,CAAC;;;KAGjF,EAAE,iBAAiB,qBAAqB;AACzC,KAAI,oBAAoB,eACtB,QAAO;UACH,WAAW,eAAe;;;EAIhC;;;;;;AAkBJ,MAAM,oBAAoB,EACxB,UACA,iBACA,qBACA,0BAC2B;CAC3B,MAAM,UAAU,eAAe;CAE/B,MAAM,YAAY,CAChB,GAAG,iBACH,GAAI,gBAAgB,SAAS,SAAS,GAAG,EAAE,GAAG,CAAC,SAAS,CACzD,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAEvB,QACE,oBAAC,UAAD;EAAU,aAAU;YAClB,qBAAC,OAAD,EAAA,UAAA,CACG,QAAQ,cACT,oBAAC,QAAD;GACE,OAAO,SAAS,UAAU;GAC1B,gBAAgB,QAAQ,oBAAoB,OAAO,IAAI,CAAC;GACxD,MAAK;GACL,QAAQ,uBAAuB;GAC/B,iBAAiB;aAEhB,UAAU,KAAK,SACd,oBAAC,QAAD;IAAmB,OAAO,KAAK,UAAU;cACtC;IACM,EAFI,KAEJ,CACT;GACK,CAAA,CACH,EAAA,CAAA;EACC,CAAA;;;;AC3Ef,MAAM,YAAY;AAElB,MAAM,YAAY,OAAO,MAAM;IAC3B,WAAW,WAAW;;;;;AAM1B,MAAa,iBAAiB,OAAO,MAAM;;;;YAI/B,EAAE,YAAY,cAAc,OAAO,aAAa,MAAM,YAAY,CAAC;;AA8B/E,MAAM,cAAc,EAClB,UACA,kBAAkB,2BAClB,kBACA,qBACA,qBACA,WACA,uBAAuB,MACvB,cACA,qBACA,oBAAoB,YACC;CACrB,MAAM,UAAU,eAAe;AAE/B,KAAI,CAAC,oBAAoB,CAAC,SACxB,QAAO,oBAAC,OAAD,EAAO,CAAA;CAGhB,MAAM,EACJ,gBAAgB,aAChB,eAAe,YACf,eAAe,YACf,eAAe,eACb;CAQJ,MAAM,eAAe,cADE,qBAAqB,CAAC,cAAc,cAAc;CAGzE,MAAM,oBACJ,gBAAgB,cAAc,YAC1B,QAAQ,OAHO,qBAAqB,CAAC,eAKnC,QAAQ,QAAQ,WAAW,GAC3B;CAER,MAAM,gBAAgB,eAClB,cAAc,WACd,KAAK,IAAI,cAAc,UAAU,WAAW;CAChD,MAAM,iBAAiB,YAAY,cAAc,KAAK;AAEtD,QACE,qBAAC,WAAD;EAAW,MAAK;EAAa,cAAY,QAAQ;YAAjD,CACG,wBACC,oBAAC,kBAAD;GACY;GACO;GACI;GACA;GACrB,CAAA,EAEH,aAAa,KACZ,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,OAAD,EAAA,UAAM,QAAQ,aAAa,gBAAgB,eAAe,kBAAkB,EAAO,CAAA,EACnF,oBAAC,gBAAD,EAAA,UACE,oBAAC,cAAD;GACoB;GACG;GACV;GACG;GACd,mBAAmB,qBAAqB,CAAC;GACzC,CAAA,EACa,CAAA,CAChB,EAAA,CAAA,CAEK;;;;;ACzHhB,IAAA,qBAAe"}
@@ -1,4 +1,4 @@
1
- import { n as Sticker } from "./Sticker-4VdGEFAu.mjs";
1
+ import { n as Sticker } from "./Sticker-jfOM4Yi6.mjs";
2
2
  import { Fragment, jsx } from "react/jsx-runtime";
3
3
  //#region src/components/Pii/Pii.tsx
4
4
  const Pii = ({ children, isRedacted, hideOnRedacted }) => {
@@ -16,4 +16,4 @@ var Pii_default = Pii;
16
16
  //#endregion
17
17
  export { Pii_default as t };
18
18
 
19
- //# sourceMappingURL=Pii-BYPkrBuT.mjs.map
19
+ //# sourceMappingURL=Pii-x1UInvWe.mjs.map