@persona/design-system 0.10.10 → 0.10.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/{Action-CHWYwpYR.d.mts → Action-sLO73eKq.d.mts} +2 -2
- package/dist/Action.d.mts +1 -1
- package/dist/AdvancedFilterRuleRow.d.mts +2 -2
- package/dist/AdvancedFilterRulesPopover.d.mts +2 -2
- package/dist/ArrayValueControl.d.mts +1 -1
- package/dist/Attribute.d.mts +2 -2
- package/dist/{Badge-BCdsVKuj.mjs → Badge-DZq6ByIU.mjs} +2 -2
- package/dist/{Badge-BCdsVKuj.mjs.map → Badge-DZq6ByIU.mjs.map} +1 -1
- package/dist/BooleanValueControl.d.mts +1 -1
- package/dist/{Breadcrumbs-CMf3Uvow.mjs → Breadcrumbs-DpsNZWF9.mjs} +9 -9
- package/dist/Breadcrumbs-DpsNZWF9.mjs.map +1 -0
- package/dist/{Button-DjD8QxcY.d.mts → Button-C4a4BTjL.d.mts} +2 -2
- package/dist/Button.d.mts +1 -1
- package/dist/CalendarBase.d.mts +1 -1
- package/dist/{Card-DiUHtYg_.d.mts → Card-CPV4_mHk.d.mts} +4 -4
- package/dist/Card.d.mts +1 -1
- package/dist/Card2.d.mts +1 -1
- package/dist/CardGrouping.d.mts +1 -1
- package/dist/{CardV2-CrV6eEQb.mjs → CardV2-DCoDfEvr.mjs} +16 -13
- package/dist/CardV2-DCoDfEvr.mjs.map +1 -0
- package/dist/ChartFrame.d.mts +61 -0
- package/dist/ChartLegend.d.mts +60 -0
- package/dist/ChartPopover.d.mts +155 -0
- package/dist/{Checkbox-Dr4LMKHV.mjs → Checkbox-C3z7UUSC.mjs} +8 -8
- package/dist/Checkbox-C3z7UUSC.mjs.map +1 -0
- package/dist/{CheckboxGroupField-Bpu2j6G2.d.mts → CheckboxGroupField-BT87OVOF.d.mts} +2 -2
- package/dist/CheckboxGroupField.d.mts +1 -1
- package/dist/ChoicesValueControl.d.mts +1 -1
- package/dist/{Combobox-Gb_j1dg6.mjs → Combobox-BkK_tosd.mjs} +300 -116
- package/dist/Combobox-BkK_tosd.mjs.map +1 -0
- package/dist/Combobox-aOJDTjzC.d.mts +12 -0
- package/dist/Combobox.d.mts +3 -3
- package/dist/{ComboboxBase-BPXqJHaQ.d.mts → ComboboxBase-Brgv5nxk.d.mts} +65 -25
- package/dist/ComboboxBase.d.mts +2 -2
- package/dist/{ComboboxMultiSelect-BwkkSymj.d.mts → ComboboxMultiSelect-DJyAv0Eg.d.mts} +10 -6
- package/dist/ComboboxMultiSelect.d.mts +2 -2
- package/dist/{ComboboxSingleSelect-CdNNJNkp.d.mts → ComboboxSingleSelect-CP8-HLKl.d.mts} +8 -6
- package/dist/ComboboxSingleSelect.d.mts +2 -2
- package/dist/{CompactBar-BLZZWtIE.d.mts → CompactBar-B0LhjrYV.d.mts} +2 -2
- package/dist/CompactBar.d.mts +1 -1
- package/dist/{ConfigFormGroup-BCTWCws5.mjs → ConfigFormGroup-DAUqAhJW.mjs} +2 -2
- package/dist/{ConfigFormGroup-BCTWCws5.mjs.map → ConfigFormGroup-DAUqAhJW.mjs.map} +1 -1
- package/dist/{DataTable-BE9inUi-.d.mts → DataTable-CSl5Jn3E.d.mts} +18 -8
- package/dist/{DataTable-CIZJ1vO8.mjs → DataTable-DiwzhNMt.mjs} +41 -28
- package/dist/DataTable-DiwzhNMt.mjs.map +1 -0
- package/dist/DataTable.d.mts +1 -1
- package/dist/{DatePicker-C9redLBr.mjs → DatePicker-BK7ioKBm.mjs} +410 -410
- package/dist/DatePicker-BK7ioKBm.mjs.map +1 -0
- package/dist/DateRangeValueControl.d.mts +1 -1
- package/dist/DateValueControl.d.mts +1 -1
- package/dist/{DropdownButton-DpLG-cIj.mjs → DropdownButton-Dp-MZ5tA.mjs} +3 -3
- package/dist/{DropdownButton-DpLG-cIj.mjs.map → DropdownButton-Dp-MZ5tA.mjs.map} +1 -1
- package/dist/DropdownButton.d.mts +2 -2
- package/dist/{DropdownMenu-B6D4stkF.d.mts → DropdownMenu-BnHPeHOm.d.mts} +3 -3
- package/dist/{DropdownMenu-c8XK2Lr4.mjs → DropdownMenu-jJSHQaih.mjs} +4 -2
- package/dist/DropdownMenu-jJSHQaih.mjs.map +1 -0
- package/dist/DropdownMenu.d.mts +1 -1
- package/dist/{FieldRegistry-C2NVPhMO.d.mts → FieldRegistry-CJwGpUVK.d.mts} +2 -2
- package/dist/FieldRegistry.d.mts +1 -1
- package/dist/{FilterBar-BE_gBM0H.d.mts → FilterBar-DDyk14sx.d.mts} +4 -4
- package/dist/FilterBar.d.mts +1 -1
- package/dist/FilterPickerMenu.d.mts +2 -2
- package/dist/FilterPill.d.mts +1 -1
- package/dist/FilterPopover.d.mts +1 -1
- package/dist/FloatValueControl.d.mts +3 -2
- package/dist/{FloatingToolbar-DLRaE0o7.mjs → FloatingToolbar-rfKurDs8.mjs} +36 -39
- package/dist/FloatingToolbar-rfKurDs8.mjs.map +1 -0
- package/dist/{FormControl-BztNXLn6.mjs → FormControl--pbTH3bY.mjs} +3 -3
- package/dist/{FormControl-BztNXLn6.mjs.map → FormControl--pbTH3bY.mjs.map} +1 -1
- package/dist/{FormControl-BQe3GRhi.d.mts → FormControl-DPYbLcBK.d.mts} +2 -2
- package/dist/FormControl.d.mts +1 -1
- package/dist/FormControlLabel.d.mts +2 -2
- package/dist/{FormField-BW5uMzId.d.mts → FormField-CYNGm2bJ.d.mts} +2 -2
- package/dist/{FormField-Cf1VMvoa.mjs → FormField-DMxjftFw.mjs} +14 -14
- package/dist/{FormField-Cf1VMvoa.mjs.map → FormField-DMxjftFw.mjs.map} +1 -1
- package/dist/FormField.d.mts +1 -1
- package/dist/{Grid-CYpOqTUu.mjs → Grid-DVC0SSEZ.mjs} +2 -2
- package/dist/{Grid-CYpOqTUu.mjs.map → Grid-DVC0SSEZ.mjs.map} +1 -1
- package/dist/{Header-CV0Lcf0C.d.mts → Header-DaaUprCL.d.mts} +2 -2
- package/dist/Header.d.mts +1 -1
- package/dist/{HelperTooltip-BNM3pTM-.d.mts → HelperTooltip-C5BDdJSI.d.mts} +2 -2
- package/dist/HelperTooltip.d.mts +1 -1
- package/dist/HighlightedText.d.mts +1 -1
- package/dist/{HoverCopyableField-XHC_n9tp.mjs → HoverCopyableField-B2-xlwUt.mjs} +12 -7
- package/dist/HoverCopyableField-B2-xlwUt.mjs.map +1 -0
- package/dist/{IconButton-C_ReZm8v.d.mts → IconButton-7k-wjvH3.d.mts} +2 -2
- package/dist/{IconButton-DxHB2g80.mjs → IconButton-kSjnfhWt.mjs} +11 -10
- package/dist/IconButton-kSjnfhWt.mjs.map +1 -0
- package/dist/IconButton.d.mts +1 -1
- package/dist/ImageTile.d.mts +1 -1
- package/dist/IndexTableLayout.d.mts +4 -4
- package/dist/InlineCombobox.d.mts +1 -1
- package/dist/InlineInput.d.mts +1 -1
- package/dist/{Input-DH-5dKor.d.mts → Input-CwvrBsiS.d.mts} +3 -3
- package/dist/{Input-RHXujO9u.mjs → Input-TRmTBEav.mjs} +5 -5
- package/dist/{Input-RHXujO9u.mjs.map → Input-TRmTBEav.mjs.map} +1 -1
- package/dist/Input.d.mts +1 -1
- package/dist/IntegerValueControl.d.mts +3 -2
- package/dist/{Link-D_kCyLYX.mjs → Link-XvzUN8sY.mjs} +6 -6
- package/dist/Link-XvzUN8sY.mjs.map +1 -0
- package/dist/{ListBox-DpFcM-dM.d.mts → ListBox-BePQBYR7.d.mts} +3 -3
- package/dist/{ListBox-BZp6exb8.mjs → ListBox-DahM1PgU.mjs} +12 -12
- package/dist/{ListBox-BZp6exb8.mjs.map → ListBox-DahM1PgU.mjs.map} +1 -1
- package/dist/ListBox.d.mts +1 -1
- package/dist/{ListBoxField-DL6Zk8TU.d.mts → ListBoxField-lj7JN1BX.d.mts} +4 -4
- package/dist/ListBoxField.d.mts +1 -1
- package/dist/{LoadingShimmer-oPIv2ESr.mjs → LoadingShimmer-CpfKTSUs.mjs} +4 -3
- package/dist/LoadingShimmer-CpfKTSUs.mjs.map +1 -0
- package/dist/LoadingShimmer.d.mts +1 -1
- package/dist/{LogicRow-BakOUtzx.d.mts → LogicRow-Do7t7Suf.d.mts} +2 -2
- package/dist/LogicRow.d.mts +1 -1
- package/dist/MaskedInput.d.mts +2 -2
- package/dist/MatchHighlight.d.mts +1 -1
- package/dist/{Menu-BVn1jh46.mjs → Menu-BvMzSH2I.mjs} +5 -5
- package/dist/{Menu-BVn1jh46.mjs.map → Menu-BvMzSH2I.mjs.map} +1 -1
- package/dist/{Menu-D6OrKCTC.d.mts → Menu-Ca5ftvo6.d.mts} +4 -4
- package/dist/Menu.d.mts +1 -1
- package/dist/{MiddleTruncatedText-DicQsLDG.mjs → MiddleTruncatedText--jzGTD00.mjs} +2 -2
- package/dist/{MiddleTruncatedText-DicQsLDG.mjs.map → MiddleTruncatedText--jzGTD00.mjs.map} +1 -1
- package/dist/{Modal-De5_bPJ_.mjs → Modal-B6X5AgWj.mjs} +54 -25
- package/dist/{Modal-De5_bPJ_.mjs.map → Modal-B6X5AgWj.mjs.map} +1 -1
- package/dist/{Modal-CujB7DuB.d.mts → Modal-BPfFyzkw.d.mts} +3 -3
- package/dist/Modal.d.mts +1 -1
- package/dist/{PageHeader-UPiqJpIF.d.mts → PageHeader-BeBmYmUX.d.mts} +2 -2
- package/dist/{PageHeader-7_Hf6rHl.mjs → PageHeader-bhQTjuZF.mjs} +2 -2
- package/dist/{PageHeader-7_Hf6rHl.mjs.map → PageHeader-bhQTjuZF.mjs.map} +1 -1
- package/dist/PageHeader.d.mts +1 -1
- package/dist/{PageLayout-BdVM37bV.d.mts → PageLayout-BXM_pyrU.d.mts} +2 -2
- package/dist/{PageLayout-DjtGrvJa.mjs → PageLayout-DgEGcZgB.mjs} +3 -3
- package/dist/{PageLayout-DjtGrvJa.mjs.map → PageLayout-DgEGcZgB.mjs.map} +1 -1
- package/dist/PageLayout.d.mts +1 -1
- package/dist/{PageSelector-B5CcAzss.d.mts → PageSelector-C14ABZVL.d.mts} +2 -2
- package/dist/PageSelector.d.mts +1 -1
- package/dist/{Pagination-DMH2IaV0.mjs → Pagination-DE8wT55m.mjs} +5 -5
- package/dist/{Pagination-DMH2IaV0.mjs.map → Pagination-DE8wT55m.mjs.map} +1 -1
- package/dist/{Pii-24D_nSRQ.mjs → Pii-C42ZY88Y.mjs} +2 -2
- package/dist/{Pii-24D_nSRQ.mjs.map → Pii-C42ZY88Y.mjs.map} +1 -1
- package/dist/{PillShell-B7Bm-dsE.d.mts → PillShell-Bkyu5FXB.d.mts} +2 -2
- package/dist/PillShell.d.mts +1 -1
- package/dist/{Popover-DordjYNM.mjs → Popover-DuFjaSoq.mjs} +4 -2
- package/dist/Popover-DuFjaSoq.mjs.map +1 -0
- package/dist/Popover.d.mts +1 -1
- package/dist/ProgressBar.d.mts +1 -1
- package/dist/{ProgressIndicator-zt3ndT9U.mjs → ProgressIndicator-hy1P-RG1.mjs} +3 -3
- package/dist/{ProgressIndicator-zt3ndT9U.mjs.map → ProgressIndicator-hy1P-RG1.mjs.map} +1 -1
- package/dist/{Radio-BlEtetrr.mjs → Radio-B4TBAho6.mjs} +5 -5
- package/dist/Radio-B4TBAho6.mjs.map +1 -0
- package/dist/{RadioGroup-CMrXmmn4.mjs → RadioGroup-Bf24GKOb.mjs} +3 -3
- package/dist/{RadioGroup-CMrXmmn4.mjs.map → RadioGroup-Bf24GKOb.mjs.map} +1 -1
- package/dist/RichTextEditor.d.mts +1 -1
- package/dist/RuleEditorFields.d.mts +2 -2
- package/dist/RulesPill.d.mts +1 -1
- package/dist/SectionHeading.d.mts +1 -1
- package/dist/{SegmentedControl-D_DA-MU1.mjs → SegmentedControl-BpR7sUWO.mjs} +6 -3
- package/dist/SegmentedControl-BpR7sUWO.mjs.map +1 -0
- package/dist/{Select-CR9TjFfo.d.mts → Select-DYdn73Nh.d.mts} +2 -2
- package/dist/{Select-DOlw_LPR.mjs → Select-RdTT2KoH.mjs} +10 -8
- package/dist/Select-RdTT2KoH.mjs.map +1 -0
- package/dist/Select.d.mts +1 -1
- package/dist/SmartTextInput.d.mts +1 -1
- package/dist/SmartTextInputField.d.mts +2 -2
- package/dist/SmartTextInputFunctionDialog.d.mts +1 -1
- package/dist/SmartTextInputPopover.d.mts +1 -1
- package/dist/{Spinner-CXb-KUs1.mjs → Spinner-vcApnJzv.mjs} +2 -2
- package/dist/{Spinner-CXb-KUs1.mjs.map → Spinner-vcApnJzv.mjs.map} +1 -1
- package/dist/{Stack-CODxfzhl.d.mts → Stack-B6MrjJeW.d.mts} +2 -2
- package/dist/Stack.d.mts +1 -1
- package/dist/{StatusIndicator-CzRaEFSz.mjs → StatusIndicator-lwt35J6B.mjs} +3 -3
- package/dist/{StatusIndicator-CzRaEFSz.mjs.map → StatusIndicator-lwt35J6B.mjs.map} +1 -1
- package/dist/{Sticker-CLvRB8V5.d.mts → Sticker-C7Wv3Obx.d.mts} +4 -4
- package/dist/{Sticker-C1_6I08u.mjs → Sticker-jfOM4Yi6.mjs} +5 -5
- package/dist/{Sticker-C1_6I08u.mjs.map → Sticker-jfOM4Yi6.mjs.map} +1 -1
- package/dist/Sticker.d.mts +1 -1
- package/dist/StringValueControl.d.mts +2 -1
- package/dist/Tab.d.mts +2 -2
- package/dist/{TabBar-BCFO38E0.mjs → TabBar-DwHgbIQ6.mjs} +8 -8
- package/dist/TabBar-DwHgbIQ6.mjs.map +1 -0
- package/dist/{Table-DPi4Dt5H.mjs → Table-SMJAWqoe.mjs} +21 -13
- package/dist/Table-SMJAWqoe.mjs.map +1 -0
- package/dist/{TableBox-DNQsgQ8x.mjs → TableBox-DS8mpN3-.mjs} +21 -17
- package/dist/TableBox-DS8mpN3-.mjs.map +1 -0
- package/dist/TableBox.d.mts +1 -1
- package/dist/{TableBoxCell-CsRt_5gP.d.mts → TableBoxCell-Bo5xYEmR.d.mts} +6 -6
- package/dist/TableBoxCell.d.mts +1 -1
- package/dist/{TableBoxField-Db0Vjo6Z.d.mts → TableBoxField-CdgjSGLK.d.mts} +5 -5
- package/dist/TableBoxField.d.mts +1 -1
- package/dist/{TableBoxRow-exMlZyc4.d.mts → TableBoxRow-DuWS2iRC.d.mts} +2 -2
- package/dist/TableBoxRow.d.mts +1 -1
- package/dist/{TableBoxRowActions-UO9YN34k.d.mts → TableBoxRowActions-zW74DkXt.d.mts} +2 -2
- package/dist/TableBoxRowActions.d.mts +1 -1
- package/dist/{TableCell-CQsF7t4e.d.mts → TableCell-uv_jqT5e.d.mts} +2 -2
- package/dist/TableCell.d.mts +1 -1
- package/dist/{TableControls-Clo_0Mty.d.mts → TableControls-9vz-HfDu.d.mts} +4 -4
- package/dist/{TableControls-BrP_BqnF.mjs → TableControls-CX7BvgD2.mjs} +107 -43
- package/dist/TableControls-CX7BvgD2.mjs.map +1 -0
- package/dist/TableControls.d.mts +1 -1
- package/dist/{TableControlsContext-BNd6z9mD.d.mts → TableControlsContext-D0Hn3rwL.d.mts} +2 -2
- package/dist/TableControlsContext.d.mts +1 -1
- package/dist/{TableViewConfigurationDropdown-Cp7ausV_.d.mts → TableViewConfigurationDropdown-CZcLH8uR.d.mts} +2 -2
- package/dist/TableViewConfigurationDropdown.d.mts +1 -1
- package/dist/{TechnicalSticker-Cq5jzYKQ.mjs → TechnicalSticker-DrN45Vut.mjs} +9 -7
- package/dist/TechnicalSticker-DrN45Vut.mjs.map +1 -0
- package/dist/{Text-CvaqognH.d.mts → Text-CdHeSHCc.d.mts} +2 -2
- package/dist/Text.d.mts +1 -1
- package/dist/{TextArea-Dro-HH8O.mjs → TextArea-CQ1YNi2b.mjs} +4 -5
- package/dist/TextArea-CQ1YNi2b.mjs.map +1 -0
- package/dist/{TextUnderlineTooltip-Bd5e8KH3.d.mts → TextUnderlineTooltip-By1VVsSs.d.mts} +3 -3
- package/dist/TextUnderlineTooltip.d.mts +1 -1
- package/dist/Tile.d.mts +1 -1
- package/dist/{Toggle-D9MzTIZs.mjs → Toggle-DjmkjJlw.mjs} +13 -9
- package/dist/Toggle-DjmkjJlw.mjs.map +1 -0
- package/dist/{Tooltip-YViXzMdm.mjs → Tooltip-C2VB8I6y.mjs} +18 -5
- package/dist/Tooltip-C2VB8I6y.mjs.map +1 -0
- package/dist/{Tooltip-Ddy2Jq0K.d.mts → Tooltip-OxVvOfn8.d.mts} +3 -3
- package/dist/Tooltip.d.mts +1 -1
- package/dist/{TruncatedText-sr9Fhm3N.d.mts → TruncatedText-Dqj94BFK.d.mts} +2 -2
- package/dist/WizardModal.d.mts +1 -1
- package/dist/chartColors.d.mts +92 -0
- package/dist/chartFrameLayout.d.mts +46 -0
- package/dist/{clientFilterUtils-CGHYF5NE.d.mts → clientFilterUtils-CMLuN8kK.d.mts} +2 -2
- package/dist/clientFilterUtils.d.mts +1 -1
- package/dist/components/Accordion/index.mjs +25 -16
- package/dist/components/Accordion/index.mjs.map +1 -1
- package/dist/components/Attribute/index.mjs +8 -6
- package/dist/components/Attribute/index.mjs.map +1 -1
- package/dist/components/Badge/index.mjs +1 -1
- package/dist/components/Banner/index.mjs +3 -3
- package/dist/components/BottomPanel/index.mjs +10 -8
- package/dist/components/BottomPanel/index.mjs.map +1 -1
- package/dist/components/Breadcrumbs/index.mjs +1 -1
- package/dist/components/Button/index.d.mts +2 -2
- package/dist/components/Button/index.mjs +1 -1
- package/dist/components/ButtonGroup/index.mjs +2 -2
- package/dist/components/Card/index.d.mts +2 -2
- package/dist/components/CardV2/index.d.mts +1 -1
- package/dist/components/CardV2/index.mjs +1 -1
- package/dist/components/Chart/index.d.mts +9 -0
- package/dist/components/Chart/index.mjs +680 -0
- package/dist/components/Chart/index.mjs.map +1 -0
- package/dist/components/Checkbox/index.mjs +1 -1
- package/dist/components/CodeHighlight/index.mjs +4 -4
- package/dist/components/Combobox/index.d.mts +5 -3
- package/dist/components/Combobox/index.mjs +1 -1
- package/dist/components/ConfigFormGroup/index.mjs +1 -1
- package/dist/components/DataTable/TableControls/index.d.mts +20 -20
- package/dist/components/DataTable/TableControls/index.mjs +2 -2
- package/dist/components/DataTable/index.d.mts +5 -5
- package/dist/components/DataTable/index.mjs +1 -1
- package/dist/components/DataTable/types.d.mts +1 -1
- package/dist/components/DatePicker/index.mjs +1 -1
- package/dist/components/DropdownButton/index.mjs +1 -1
- package/dist/components/DropdownMenu/index.d.mts +1 -1
- package/dist/components/DropdownMenu/index.mjs +1 -1
- package/dist/components/FloatingPanel/index.mjs +20 -18
- package/dist/components/FloatingPanel/index.mjs.map +1 -1
- package/dist/components/FloatingToolbar/index.mjs +1 -1
- package/dist/components/FormControl/index.d.mts +1 -1
- package/dist/components/FormControl/index.mjs +1 -1
- package/dist/components/FormField/index.d.mts +5 -5
- package/dist/components/FormField/index.mjs +1 -1
- package/dist/components/Grid/index.mjs +1 -1
- package/dist/components/HoverCopyableField/index.mjs +1 -1
- package/dist/components/ImageTile/index.mjs +10 -10
- package/dist/components/ImageTile/index.mjs.map +1 -1
- package/dist/components/Input/index.d.mts +1 -1
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Link/index.mjs +1 -1
- package/dist/components/ListBox/index.d.mts +3 -3
- package/dist/components/ListBox/index.mjs +1 -1
- package/dist/components/LoadingShimmer/index.mjs +1 -1
- package/dist/components/MaskedInput/index.mjs +1 -1
- package/dist/components/Menu/index.d.mts +1 -1
- package/dist/components/Menu/index.mjs +1 -1
- package/dist/components/Modal/index.d.mts +1 -1
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/PageHeader/index.d.mts +1 -1
- package/dist/components/PageHeader/index.mjs +1 -1
- package/dist/components/Pagination/index.d.mts +1 -1
- package/dist/components/Pagination/index.mjs +1 -1
- package/dist/components/Pii/index.mjs +1 -1
- package/dist/components/Popover/index.mjs +1 -1
- package/dist/components/ProgressBar/index.mjs +20 -3
- package/dist/components/ProgressBar/index.mjs.map +1 -1
- package/dist/components/ProgressIndicator/index.mjs +1 -1
- package/dist/components/Radio/index.mjs +1 -1
- package/dist/components/RadioGroup/index.mjs +1 -1
- package/dist/components/RichTextEditor/index.mjs +9 -9
- package/dist/components/RightPanel/index.mjs +30 -15
- package/dist/components/RightPanel/index.mjs.map +1 -1
- package/dist/components/SegmentedControl/index.mjs +1 -1
- package/dist/components/Select/index.d.mts +1 -1
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/SelectionCard/index.mjs +5 -5
- package/dist/components/Slider/index.mjs +5 -4
- package/dist/components/Slider/index.mjs.map +1 -1
- package/dist/components/SmartTextInput/index.mjs +11 -18
- package/dist/components/SmartTextInput/index.mjs.map +1 -1
- package/dist/components/Spinner/index.mjs +1 -1
- package/dist/components/Stack/index.d.mts +1 -1
- package/dist/components/StatusIndicator/index.mjs +1 -1
- package/dist/components/Sticker/index.d.mts +1 -1
- package/dist/components/Sticker/index.mjs +1 -1
- package/dist/components/SwatchPicker/index.mjs +2 -1
- package/dist/components/SwatchPicker/index.mjs.map +1 -1
- package/dist/components/TabBar/index.mjs +1 -1
- package/dist/components/Table/index.d.mts +1 -1
- package/dist/components/Table/index.mjs +1 -1
- package/dist/components/TableBox/index.d.mts +1 -1
- package/dist/components/TableBox/index.mjs +1 -1
- package/dist/components/TechnicalSticker/index.mjs +1 -1
- package/dist/components/Text/index.d.mts +1 -1
- package/dist/components/TextArea/index.mjs +1 -1
- package/dist/components/Tile/index.mjs +2 -2
- package/dist/components/Toast/index.mjs +19 -13
- package/dist/components/Toast/index.mjs.map +1 -1
- package/dist/components/Toggle/index.mjs +1 -1
- package/dist/components/Tooltip/index.d.mts +3 -3
- package/dist/components/Tooltip/index.mjs +1 -1
- package/dist/components/VersionHistory/index.mjs +8 -8
- package/dist/compound-expression.d.mts +1 -1
- package/dist/{date-range-rule-value-ASr06ClE.d.mts → date-range-rule-value-DyLlMtjr.d.mts} +2 -2
- package/dist/date-range-rule-value.d.mts +1 -1
- package/dist/display.d.mts +1 -1
- package/dist/duration-token.d.mts +11 -0
- package/dist/exit-motion.d.mts +7 -0
- package/dist/fieldPickerOptions.d.mts +2 -2
- package/dist/{filter-size-context-CmFyIPCm.d.mts → filter-size-context-DVnjmuhk.d.mts} +2 -2
- package/dist/filter-size-context.d.mts +1 -1
- package/dist/{filters-DTBc0mE7.d.mts → filters-By_TYKAZ.d.mts} +3 -3
- package/dist/filters.d.mts +1 -1
- package/dist/{helpers-CBJ2AqGZ.d.mts → helpers-BIHsqdyX.d.mts} +2 -2
- package/dist/helpers.d.mts +1 -1
- package/dist/{index-kIon1vPp.d.mts → index-BozzRwby.d.mts} +2 -2
- package/dist/{index-OkdnW-u5.d.mts → index-CZJp4Af6.d.mts} +3 -3
- package/dist/index2.d.mts +1 -1
- package/dist/index4.d.mts +3 -3
- package/dist/index5.d.mts +1 -1
- package/dist/index6.d.mts +14 -14
- package/dist/{inputFields-DpHeZiFX.d.mts → inputFields-BqO2H-Kj.d.mts} +6 -6
- package/dist/inputFields.d.mts +1 -1
- package/dist/lib/MiddleTruncatedText.mjs +1 -1
- package/dist/lib/TruncatedText.d.mts +1 -1
- package/dist/lib/TruncatedTextWithTooltip.d.mts +1 -1
- package/dist/lib/TruncatedTextWithTooltip.mjs +1 -1
- package/dist/lib/colorMode.d.mts +1 -1
- package/dist/lib/useChain.d.mts +1 -1
- package/dist/lib/useModalInsetRight.d.mts +4 -3
- package/dist/lib/useModalInsetRight.mjs +7 -5
- package/dist/lib/useModalInsetRight.mjs.map +1 -1
- package/dist/lint/THIRD_PARTY_NOTICES.md +30 -0
- package/dist/lint/index.mjs +696 -11
- package/dist/lint/index.mjs.map +1 -1
- package/dist/lint/recommended.json +7 -1
- package/dist/mixins/focus.mjs +1 -1
- package/dist/mixins/hoverable.mjs +2 -2
- package/dist/mixins/hoverable.mjs.map +1 -1
- package/dist/mixins/input.mjs +3 -2
- package/dist/mixins/input.mjs.map +1 -1
- package/dist/mixins/menuItem.mjs +2 -0
- package/dist/mixins/menuItem.mjs.map +1 -1
- package/dist/mixins/motion.d.mts +24 -0
- package/dist/mixins/motion.mjs +44 -0
- package/dist/mixins/motion.mjs.map +1 -0
- package/dist/motion-origin.d.mts +7 -0
- package/dist/motion.d.mts +63 -0
- package/dist/no-layout-motion.d.mts +7 -0
- package/dist/no-transition-all.d.mts +7 -0
- package/dist/{operators-BHxKZcpD.d.mts → operators-B8_k3r69.d.mts} +10 -3
- package/dist/operators.d.mts +2 -2
- package/dist/overlay-motion.d.mts +7 -0
- package/dist/patterns/CardGrouping/index.mjs +9 -9
- package/dist/patterns/CardGrouping/index.mjs.map +1 -1
- package/dist/patterns/IndexTableLayout/index.mjs +3 -3
- package/dist/patterns/LayoutLoadingShimmer/index.mjs +4 -4
- package/dist/patterns/LayoutLoadingSpinner/index.mjs +3 -1
- package/dist/patterns/LayoutLoadingSpinner/index.mjs.map +1 -1
- package/dist/patterns/PageLayout/index.d.mts +1 -1
- package/dist/patterns/PageLayout/index.mjs +1 -1
- package/dist/patterns/WizardModal/index.mjs +4 -4
- package/dist/relative-date-label.d.mts +1 -1
- package/dist/tone.d.mts +1 -1
- package/dist/{types-DLnCkvTt.d.mts → types-BJqmRXFV.d.mts} +15 -1
- package/dist/{types-CqcbWyUY.d.mts → types-BOsCi-kZ.d.mts} +8 -2
- package/dist/{types-BEdERA4v.d.mts → types-C_CncajO.d.mts} +2 -2
- package/dist/{types-BiqzeNsa.d.mts → types-D5txFacG.d.mts} +3 -3
- package/dist/types4.d.mts +1 -1
- package/dist/types5.d.mts +1 -1
- package/dist/types6.d.mts +1 -1
- package/dist/{url-state-CXUuK3_r.d.mts → url-state-CXPmXzIZ.d.mts} +2 -2
- package/dist/url-state.d.mts +1 -1
- package/dist/{useChain-B--KAtdN.d.mts → useChain-x9fd9Fyq.d.mts} +2 -2
- package/dist/useChainAtCursor.d.mts +1 -1
- package/dist/useChartColors.d.mts +30 -0
- package/dist/useChartSeriesVisibility.d.mts +22 -0
- package/dist/useChartStyles.d.mts +108 -0
- package/dist/useColumnConfiguration.d.mts +2 -2
- package/dist/useComboboxFooterAction.d.mts +1 -1
- package/dist/{useFilterStateV2-DBpbxAEC.d.mts → useFilterStateV2-DiTS9DTg.d.mts} +3 -3
- package/dist/useFilterStateV2.d.mts +1 -1
- package/dist/{useTableColumns-Xd14vx_h.d.mts → useTableColumns-BEKJNrb1.d.mts} +2 -2
- package/dist/useTableColumns.d.mts +1 -1
- package/dist/useTruncation.d.mts +1 -1
- package/dist/useValueControlError.d.mts +26 -0
- package/dist/utils.d.mts +1 -1
- package/dist/{validation-Tgg3AhuP.d.mts → validation-BDQdQ1cY.d.mts} +3 -3
- package/dist/validation.d.mts +1 -1
- package/dist/{value-control-resolver-XQbGCdsP.d.mts → value-control-resolver-BFJZEWDn.d.mts} +9 -3
- package/dist/value-control-resolver.d.mts +1 -1
- package/dist/variables/keyframes.d.mts +2 -1
- package/dist/variables/keyframes.mjs +9 -1
- package/dist/variables/keyframes.mjs.map +1 -1
- package/dist/variables/transitions.d.mts +31 -1
- package/dist/variables/transitions.mjs +50 -1
- package/dist/variables/transitions.mjs.map +1 -1
- package/llms.txt +1 -0
- package/package.json +14 -4
- package/skills/new-screen/SKILL.md +33 -0
- package/skills/ui-authoring/COMPONENTS.md +18 -0
- package/skills/ui-authoring/PATTERNS.md +51 -34
- package/skills/ui-authoring/STANDARD.md +68 -4
- package/skills/ui-authoring/TOKENS.md +27 -24
- package/dist/Breadcrumbs-CMf3Uvow.mjs.map +0 -1
- package/dist/CardV2-CrV6eEQb.mjs.map +0 -1
- package/dist/Checkbox-Dr4LMKHV.mjs.map +0 -1
- package/dist/Combobox-CIKqTYZt.d.mts +0 -11
- package/dist/Combobox-Gb_j1dg6.mjs.map +0 -1
- package/dist/DataTable-CIZJ1vO8.mjs.map +0 -1
- package/dist/DatePicker-C9redLBr.mjs.map +0 -1
- package/dist/DropdownMenu-c8XK2Lr4.mjs.map +0 -1
- package/dist/FloatingToolbar-DLRaE0o7.mjs.map +0 -1
- package/dist/HoverCopyableField-XHC_n9tp.mjs.map +0 -1
- package/dist/IconButton-DxHB2g80.mjs.map +0 -1
- package/dist/Link-D_kCyLYX.mjs.map +0 -1
- package/dist/LoadingShimmer-oPIv2ESr.mjs.map +0 -1
- package/dist/Popover-DordjYNM.mjs.map +0 -1
- package/dist/Radio-BlEtetrr.mjs.map +0 -1
- package/dist/SegmentedControl-D_DA-MU1.mjs.map +0 -1
- package/dist/Select-DOlw_LPR.mjs.map +0 -1
- package/dist/TabBar-BCFO38E0.mjs.map +0 -1
- package/dist/Table-DPi4Dt5H.mjs.map +0 -1
- package/dist/TableBox-DNQsgQ8x.mjs.map +0 -1
- package/dist/TableControls-BrP_BqnF.mjs.map +0 -1
- package/dist/TechnicalSticker-Cq5jzYKQ.mjs.map +0 -1
- package/dist/TextArea-Dro-HH8O.mjs.map +0 -1
- package/dist/Toggle-D9MzTIZs.mjs.map +0 -1
- package/dist/Tooltip-YViXzMdm.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingToolbar-DLRaE0o7.mjs","names":["Input","DropdownMenu"],"sources":["../src/components/FloatingToolbar/FloatingToolbar.tsx"],"sourcesContent":["import { PluginKey } from '@tiptap/pm/state';\nimport type { EditorView } from '@tiptap/pm/view';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { BubbleMenu } from '@tiptap/react/menus';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\nimport {\n BoldIcon,\n CheckIcon,\n GridIcon,\n ItalicIcon,\n LinkIcon,\n ListIcon,\n UnlinkIcon,\n XIcon,\n} from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport Input from '#src/components/Input';\nimport Stack from '#src/components/Stack';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { TransitionDuration } from '#src/variables/transitions';\n\n// Core* colors throughout this file are intentional: the bubble toolbar is an\n// always-dark inverse surface floating over the editor, so it must not track\n// the semantic surface theme.\nconst BubbleMenuBar = styled(Stack)`\n padding: ${Spacing[1]} ${Spacing[2]};\n background-color: ${Color.CoreSlate1100};\n border-radius: ${BorderRadius.Lg};\n`;\n\nconst IconContainer = styled(motion.div)`\n display: flex;\n gap: ${Spacing[1]};\n`;\n\nconst InverseIconButton = styled(IconButton)<{ $selected?: boolean }>`\n background-color: ${({ $selected }) => ($selected ? Color.CoreSlate900 : 'transparent')};\n color: ${Color.PrimaryWhite};\n transition: background-color ${TransitionDuration.ExtraFast} ease-out;\n\n &:hover:not(:disabled) {\n background-color: ${Color.CoreSlate800};\n }\n\n &:disabled {\n background-color: transparent;\n opacity: 0.35;\n }\n`;\n\nconst InverseInput = styled(Input)`\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n\n :focus-within {\n border-color: ${Color.CoreBlue700};\n }\n ::placeholder {\n color: ${Color.TextDisabled};\n }\n\n input {\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n }\n`;\n\nconst StyledDropdownItem = styled(DropdownMenu.Item)`\n width: 100%;\n height: 30px;\n font-size: small;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n`;\n\n// Floating UI takes its offset as numbers while the spacing tokens are CSS lengths.\nconst TOOLBAR_GAP = parseInt(Spacing[1]);\n\n// Anchored to the field, the toolbar lines up with the input's left edge; over a\n// selection it sits back a notch so it does not crowd the first selected glyph.\nconst FIELD_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: 0 };\nconst SELECTION_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: -parseInt(Spacing[2]) };\n\n// The element EditorContent mounts the editor into — the visible field. Tiptap\n// types `options.element` loosely, so fall back to the editable root.\nconst getFieldElement = (editor: Editor): Element =>\n editor.options.element instanceof Element ? editor.options.element : editor.view.dom;\n\n// Schemes we trust as link targets. Anything else (no scheme, or an unsafe one\n// like javascript:/data:/vbscript:) is treated as a bare host and forced onto\n// https, which both preserves host:port input and neutralizes script schemes.\nconst SAFE_LINK_SCHEME = /^(https?|mailto|tel):/i;\nconst URI_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nexport const ensureProtocol = (url: string): string => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) {\n return '';\n }\n // Handlebars placeholders (e.g. {{inquiry.id}}) are legitimate link targets in\n // templated messages — the template render produces the final URL, so pass\n // the expression through unvalidated. Only when nothing before the first\n // placeholder looks like an unsafe scheme: javascript:alert(1)//{{x}} would\n // otherwise smuggle a script href past the allowlist. URL parsers strip C0\n // controls, tabs and spaces before reading the scheme, so normalize the\n // prefix the same way first — java\\tscript:...{{x}} must not slip through.\n if (trimmedUrl.includes('{{')) {\n const beforePlaceholder = trimmedUrl\n .slice(0, trimmedUrl.indexOf('{{'))\n // eslint-disable-next-line no-control-regex -- mirrors how URL parsers strip C0/space before reading the scheme\n .replace(/[\\u0000-\\u0020]/g, '');\n if (!URI_SCHEME.test(beforePlaceholder) || SAFE_LINK_SCHEME.test(beforePlaceholder)) {\n return trimmedUrl;\n }\n return '';\n }\n const candidate = SAFE_LINK_SCHEME.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;\n // Re-parse so malformed input — including an unsafe scheme that can't survive\n // the https prefix — is dropped instead of applied as a broken href.\n return URL.canParse(candidate) ? candidate : '';\n};\n\ninterface FloatingToolbarProps {\n /** TipTap editor instance to operate on. */\n editor: Editor | null;\n /**\n * Keep the toolbar up the whole time the editor is focused instead of only\n * while text is selected, so the formatting actions are discoverable without\n * knowing to select first.\n */\n showOnFocus?: boolean;\n}\n\n/**\n * Floating bubble toolbar that appears on text selection or inside a table, or —\n * with `showOnFocus` — for as long as the editor is focused.\n * Keyboard shortcut: Cmd/Ctrl+Shift+U opens the link-edit row.\n */\nfunction FloatingToolbar({ editor, showOnFocus = false }: FloatingToolbarProps) {\n const [linkURL, setLinkURL] = useState('');\n const [editingLink, setEditingLink] = useState(false);\n const linkInputRef = useRef<HTMLInputElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const savedSelection = useRef<{ from: number; to: number } | null>(null);\n const editingLinkRef = useRef(editingLink);\n const blurTimeout = useRef<ReturnType<typeof setTimeout>>();\n // Lets the toolbar close its own bubble menu plugin via a `hide` meta.\n const [pluginKey] = useState(() => new PluginKey('floatingToolbar'));\n\n useEffect(() => () => clearTimeout(blurTimeout.current), []);\n\n useEffect(() => {\n editingLinkRef.current = editingLink;\n }, [editingLink]);\n\n const restoreSelection = useCallback(() => {\n if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }, [editor]);\n\n const openLinkEditingMode = useCallback(() => {\n if (!editor) {\n return;\n }\n if (!editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run()) {\n return;\n }\n\n const { from, to } = editor.state.selection;\n savedSelection.current = { from, to };\n\n const linkAttr = editor.getAttributes('link');\n if (linkAttr.href) {\n setLinkURL(linkAttr.href);\n }\n\n editor.chain().focus().setTextSelection({ from, to }).run();\n setEditingLink(true);\n\n setTimeout(() => {\n linkInputRef.current?.focus();\n }, 250);\n }, [editor]);\n\n // Cmd/Ctrl+Shift+U → open link mode; Escape inside link mode → cancel.\n useEffect(() => {\n if (!editor) {\n return undefined;\n }\n const dom = editor.view.dom;\n const handler = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === 'u') {\n event.preventDefault();\n openLinkEditingMode();\n return;\n }\n if (event.key === 'Escape' && editingLinkRef.current) {\n event.preventDefault();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n }\n };\n dom.addEventListener('keydown', handler);\n return () => {\n dom.removeEventListener('keydown', handler);\n };\n }, [editor, openLinkEditingMode]);\n\n // Keep selection highlighted while focus is in the link input.\n useEffect(() => {\n if (!editingLink || !editor || !savedSelection.current) {\n return undefined;\n }\n restoreSelection();\n const timeoutId = setTimeout(() => {\n restoreSelection();\n editor.view.dom?.focus();\n }, 0);\n return () => clearTimeout(timeoutId);\n }, [editingLink, restoreSelection, editor]);\n\n // Pressing a toolbar button focuses that button, and the command's own\n // transaction re-runs this check before the chained `.focus()` hands focus\n // back to the editor. Ignoring focus held inside the toolbar therefore tears\n // the bar down for a frame mid-click, taking the pressed button with it.\n const isFocusWithinToolbar = useCallback(\n () => !!toolbarRef.current?.contains(document.activeElement),\n [],\n );\n\n // BubbleMenu dispatches an options-update transaction whenever these props\n // change identity, and editors that re-render per transaction would then\n // loop — so keep them stable across renders.\n const bubbleMenuOptions = useMemo(\n () => ({\n placement: 'top-start' as const,\n offset: showOnFocus ? FIELD_OFFSET : SELECTION_OFFSET,\n }),\n [showOnFocus],\n );\n\n // Sitting above the field rather than the selection: a toolbar that is up\n // for the whole time the field is focused looks jumpy if it chases the\n // caret and hops between selections.\n const getReferencedVirtualElement = useMemo(\n () =>\n showOnFocus && editor\n ? () => ({ getBoundingClientRect: () => getFieldElement(editor).getBoundingClientRect() })\n : undefined,\n [editor, showOnFocus],\n );\n\n const shouldShow = useCallback(\n ({\n editor: e,\n view,\n from,\n to,\n }: {\n editor: Editor;\n view: EditorView;\n from: number;\n to: number;\n }) => {\n if (!e.isEditable) {\n return false;\n }\n if (e.isActive('mention')) {\n return false;\n }\n // The toolbar carries the table-actions dropdown — a collapsed caret\n // inside a table must still show it or row/column controls are\n // unreachable.\n if (e.isActive('table')) {\n return true;\n }\n if (from !== to) {\n return true;\n }\n return showOnFocus && (view.hasFocus() || isFocusWithinToolbar());\n },\n [isFocusWithinToolbar, showOnFocus],\n );\n\n // Self-subscribe: standalone use can't rely on the host's useEditor options (shouldRerenderOnTransaction is off by default in Tiptap 3).\n const editorState = useEditorState({\n editor,\n selector: (snapshot) =>\n snapshot.editor && {\n isBold: snapshot.editor.isActive('bold'),\n canBold: snapshot.editor.can().chain().toggleBold().run(),\n isItalic: snapshot.editor.isActive('italic'),\n canItalic: snapshot.editor.can().chain().toggleItalic().run(),\n isLink: snapshot.editor.isActive('link'),\n isBulletList: snapshot.editor.isActive('bulletList'),\n canLink: snapshot.editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run(),\n isTable: snapshot.editor.isActive('table'),\n canInsertTable: snapshot.editor\n .can()\n .chain()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run(),\n },\n });\n\n if (!editor || !editorState) {\n return null;\n }\n\n // The plugin closes the toolbar off the editor's blur, which cannot fire again\n // once focus has moved in here, so leaving from the toolbar has to close it.\n // Focus only lands on its next target after this event, hence the tick.\n const handleToolbarBlur = () => {\n blurTimeout.current = setTimeout(() => {\n if (editor.isDestroyed || isFocusWithinToolbar() || editor.view.hasFocus()) {\n return;\n }\n editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'hide'));\n });\n };\n\n return (\n <BubbleMenu\n editor={editor}\n pluginKey={pluginKey}\n options={bubbleMenuOptions}\n getReferencedVirtualElement={getReferencedVirtualElement}\n shouldShow={shouldShow}\n // Floating UI sets no z-index on the portaled menu (Tippy used 9999).\n style={{ zIndex: Z_INDICES.modalElevated }}\n >\n <AnimatePresence>\n <BubbleMenuBar\n ref={toolbarRef}\n role='toolbar'\n aria-label='Text formatting'\n direction='horizontal'\n spacing={Spacing[1]}\n onBlur={handleToolbarBlur}\n >\n {!editingLink ? (\n <IconContainer\n key='main-toolbar'\n layout\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n >\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n $selected={editorState.isBulletList}\n size='sm'\n type='button'\n aria-label='Toggle bullet list'\n data-rte-menu-bar-item\n >\n <ListIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n disabled={!editorState.canBold}\n $selected={editorState.isBold}\n size='sm'\n type='button'\n aria-label='Toggle bold'\n data-rte-menu-bar-item\n >\n <BoldIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n $selected={editorState.isItalic}\n disabled={!editorState.canItalic}\n type='button'\n size='sm'\n aria-label='Toggle italic'\n data-rte-menu-bar-item\n >\n <ItalicIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n openLinkEditingMode();\n }}\n $selected={editorState.isLink}\n disabled={!editorState.canLink}\n size='sm'\n type='button'\n aria-label='Toggle link'\n data-rte-menu-bar-item\n >\n <LinkIcon />\n </InverseIconButton>\n {editorState.isTable ? (\n <DropdownMenu\n contentProps={{\n // @ts-expect-error data attribute on dropdown menu\n 'data-rte-menu-bar-item': 'table-actions-dropdown-menu',\n onCloseAutoFocus: (event) => {\n event.preventDefault();\n editor.commands.focus();\n },\n }}\n trigger={\n <InverseIconButton\n size='sm'\n type='button'\n aria-label='Table actions'\n data-rte-menu-bar-item\n $selected\n >\n <GridIcon />\n </InverseIconButton>\n }\n >\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-after'\n onClick={() => editor.chain().focus().addRowAfter().run()}\n >\n Add row below\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-before'\n onClick={() => editor.chain().focus().addRowBefore().run()}\n >\n Add row above\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-after'\n onClick={() => editor.chain().focus().addColumnAfter().run()}\n >\n Add column right\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-before'\n onClick={() => editor.chain().focus().addColumnBefore().run()}\n >\n Add column left\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteRow'\n variant='basic'\n data-rte-menu-bar-item='table-delete-row'\n onClick={() => editor.chain().focus().deleteRow().run()}\n >\n Delete row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteColumn'\n variant='basic'\n data-rte-menu-bar-item='table-delete-column'\n onClick={() => editor.chain().focus().deleteColumn().run()}\n >\n Delete column\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableToggleHeaderRow'\n variant='basic'\n data-rte-menu-bar-item='table-toggle-header-row'\n onClick={() => editor.chain().focus().toggleHeaderRow().run()}\n >\n Toggle header row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDelete'\n variant='basic'\n data-rte-menu-bar-item='table-delete'\n onClick={() => editor.chain().focus().deleteTable().run()}\n >\n Delete table\n </StyledDropdownItem>\n </DropdownMenu>\n ) : (\n <InverseIconButton\n onClick={() =>\n editor\n .chain()\n .focus()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run()\n }\n disabled={!editorState.canInsertTable}\n size='sm'\n type='button'\n aria-label='Insert table'\n data-rte-menu-bar-item\n >\n <GridIcon />\n </InverseIconButton>\n )}\n </IconContainer>\n ) : (\n <IconContainer\n key='link-toolbar'\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n aria-label='Link toolbar'\n onAnimationComplete={() => {\n if (editor && savedSelection.current) {\n setTimeout(() => {\n restoreSelection();\n linkInputRef.current?.focus();\n }, 10);\n }\n }}\n >\n <InverseInput\n ref={linkInputRef}\n size='sm'\n value={linkURL}\n onChange={(e) => setLinkURL(e.target.value)}\n placeholder='Click to enter URL...'\n aria-label='Link input'\n data-rte-menu-bar-item\n onClick={() => {\n linkInputRef.current?.focus();\n }}\n onFocus={() => {\n if (savedSelection.current && editor) {\n const { from, to } = savedSelection.current;\n editor.chain().setTextSelection({ from, to }).run();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && linkURL.trim() && editor && savedSelection.current) {\n e.preventDefault();\n e.stopPropagation();\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n const { from, to } = editor.state.selection;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }}\n />\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL) {\n editor.chain().focus().unsetLink().run();\n }\n restoreSelection();\n setLinkURL('');\n savedSelection.current = null;\n setEditingLink(false);\n }}\n size='sm'\n type='button'\n aria-label='Cancel link'\n data-rte-menu-bar-item\n >\n {linkURL && editorState.isLink ? <UnlinkIcon /> : <XIcon />}\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL.trim() && editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n } else if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).unsetLink().run();\n }\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n }}\n size='sm'\n type='button'\n aria-label='Apply link'\n data-rte-menu-bar-item\n >\n <CheckIcon />\n </InverseIconButton>\n </IconContainer>\n )}\n </BubbleMenuBar>\n </AnimatePresence>\n </BubbleMenu>\n );\n}\n\nexport default FloatingToolbar;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCopyableField-XHC_n9tp.mjs","names":["Card","Popover"],"sources":["../src/components/HoverCopyableField/HoverCopyableField.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\nimport { CopyIcon } from '@persona/icons';\n\nimport Button from '#src/components/Button';\nimport Card from '#src/components/Card';\nimport Popover from '#src/components/Popover';\nimport { Paragraph } from '#src/components/Text';\nimport useToggle from '#src/lib/useToggle';\nimport { fadeIn } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nexport type CopySuccessDetail = {\n text: string;\n clientX: number;\n clientY: number;\n};\n\nexport type HoverCopyableFieldProps = {\n copyValue: string | undefined;\n confirmationText?: string;\n /**\n * Called after a successful clipboard write. When provided, the Copied\n * popover is skipped so the host can own post-copy UX.\n */\n onCopySuccess?: (detail: CopySuccessDetail) => void;\n children: ReactNode;\n};\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if ('clipboard' in navigator) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n return document.execCommand('copy', true, text);\n }\n } catch {\n return false;\n }\n};\n\nconst clickOrigin = (e: MouseEvent<HTMLButtonElement>): { clientX: number; clientY: number } => {\n const rect = e.currentTarget.getBoundingClientRect();\n const hasPointer = e.clientX !== 0 || e.clientY !== 0;\n return {\n clientX: hasPointer ? e.clientX : rect.left + rect.width / 2,\n clientY: rect.top,\n };\n};\n\nconst CopyableFieldContainer = styled.div`\n display: flex;\n gap: ${Spacing[1]};\n align-items: center;\n`;\n\nconst CopyButton = styled(Button).attrs(() => ({\n type: 'button',\n variant: 'inverse',\n width: 'icon',\n}))<{ isActive: boolean }>`\n height: ${Spacing[5]};\n width: ${Spacing[5]};\n visibility: ${({ isActive }) => (isActive ? 'visible' : 'hidden')};\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nconst StyledCard = styled(Card)`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n padding: 6px;\n margin: 0;\n`;\n\nconst HoverCopyableField = ({\n copyValue,\n confirmationText = 'Copied',\n onCopySuccess,\n children,\n}: HoverCopyableFieldProps) => {\n const [copyButtonActive, { enable: showCopyButton, disable: hideCopyButton }] = useToggle(false);\n const [confirmationActive, { enable: showConfirmation, disable: hideConfirmation }] =\n useToggle(false);\n\n const copyTextToClipboard = async (origin: { clientX: number; clientY: number }) => {\n if (copyValue == null) {\n return;\n }\n const copyWasSuccessful = await copyToClipboard(copyValue);\n if (!copyWasSuccessful) {\n return;\n }\n if (onCopySuccess) {\n onCopySuccess({ text: copyValue, ...origin });\n hideCopyButton();\n return;\n }\n showConfirmation();\n setTimeout(() => {\n hideCopyButton();\n hideConfirmation();\n }, 1200);\n };\n\n const copyField = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n void copyTextToClipboard(clickOrigin(e));\n };\n\n return copyValue != null && copyValue.trim().length > 0 ? (\n <CopyableFieldContainer onMouseEnter={showCopyButton} onMouseLeave={hideCopyButton}>\n {children}\n <Popover open={confirmationActive}>\n <Popover.Anchor asChild>\n <CopyButton\n id='hover-copyable-field__copy-button'\n isActive={copyButtonActive || confirmationActive}\n onClick={copyField}\n >\n <CopyIcon width={16} height={16} />\n </CopyButton>\n </Popover.Anchor>\n <Popover.Content side='top' align='center' style={{ zIndex: 2 }}>\n <StyledCard elevated>\n <Paragraph>{confirmationText}</Paragraph>\n </StyledCard>\n </Popover.Content>\n </Popover>\n </CopyableFieldContainer>\n ) : null;\n};\n\nexport default HoverCopyableField;\n"],"mappings":";;;;;;;;;;;;AA+BA,MAAM,kBAAkB,OAAO,SAAmC;AAChE,KAAI;AACF,MAAI,eAAe,WAAW;AAC5B,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAO;QAEP,QAAO,SAAS,YAAY,QAAQ,MAAM,KAAK;SAE3C;AACN,SAAO;;;AAIX,MAAM,eAAe,MAA2E;CAC9F,MAAM,OAAO,EAAE,cAAc,uBAAuB;AAEpD,QAAO;EACL,SAFiB,EAAE,YAAY,KAAK,EAAE,YAAY,IAE5B,EAAE,UAAU,KAAK,OAAO,KAAK,QAAQ;EAC3D,SAAS,KAAK;EACf;;AAGH,MAAM,yBAAyB,OAAO,GAAG;;SAEhC,QAAQ,GAAG;;;AAIpB,MAAM,aAAa,OAAO,OAAO,CAAC,aAAa;CAC7C,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAAE;YACS,QAAQ,GAAG;WACZ,QAAQ,GAAG;iBACL,EAAE,eAAgB,WAAW,YAAY,SAAU;eACrD,OAAO,GAAA,QAA6B;;;;;;AAOnD,MAAM,aAAa,OAAOA,aAAK;;;;;eAKhB,OAAO,GAAA,QAA6B;;;;AAKnD,MAAM,sBAAsB,EAC1B,WACA,mBAAmB,UACnB,eACA,eAC6B;CAC7B,MAAM,CAAC,kBAAkB,EAAE,QAAQ,gBAAgB,SAAS,oBAAoB,UAAU,MAAM;CAChG,MAAM,CAAC,oBAAoB,EAAE,QAAQ,kBAAkB,SAAS,sBAC9D,UAAU,MAAM;CAElB,MAAM,sBAAsB,OAAO,WAAiD;AAClF,MAAI,aAAa,KACf;AAGF,MAAI,CAAC,MAD2B,gBAAgB,UAAU,CAExD;AAEF,MAAI,eAAe;AACjB,iBAAc;IAAE,MAAM;IAAW,GAAG;IAAQ,CAAC;AAC7C,mBAAgB;AAChB;;AAEF,oBAAkB;AAClB,mBAAiB;AACf,mBAAgB;AAChB,qBAAkB;KACjB,KAAK;;CAGV,MAAM,aAAa,MAAqC;AACtD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACd,sBAAoB,YAAY,EAAE,CAAC;;AAG1C,QAAO,aAAa,QAAQ,UAAU,MAAM,CAAC,SAAS,IACpD,qBAAC,wBAAD;EAAwB,cAAc;EAAgB,cAAc;YAApE,CACG,UACD,qBAACC,iBAAD;GAAS,MAAM;aAAf,CACE,oBAACA,gBAAQ,QAAT;IAAgB,SAAA;cACd,oBAAC,YAAD;KACE,IAAG;KACH,UAAU,oBAAoB;KAC9B,SAAS;eAET,oBAAC,UAAD;MAAU,OAAO;MAAI,QAAQ;MAAM,CAAA;KACxB,CAAA;IACE,CAAA,EACjB,oBAACA,gBAAQ,SAAT;IAAiB,MAAK;IAAM,OAAM;IAAS,OAAO,EAAE,QAAQ,GAAG;cAC7D,oBAAC,YAAD;KAAY,UAAA;eACV,oBAAC,WAAD,EAAA,UAAY,kBAA6B,CAAA;KAC9B,CAAA;IACG,CAAA,CACV;KACa;MACvB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton-DxHB2g80.mjs","names":["noop"],"sources":["../src/components/Button/palette.ts","../src/components/Button/Button.tsx","../src/components/Button/IconButton.tsx"],"sourcesContent":["import type { Color } from '@persona/design-tokens';\n\nimport { type PdsColor, transparent, withAlpha } from '#src/lib/color';\nimport { semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme } from '#src/theme';\nimport type { SemanticTokens } from '#src/variables/semantic';\n\nexport type ButtonVariant = 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n\nexport interface ButtonPalette {\n default: PdsColor;\n hover: Color;\n active: Color;\n disabled: PdsColor;\n text: Color;\n textDisabled: PdsColor;\n /** Set only under semantic theming; legacy leaves disabled icon colour to the stroke rules. */\n iconDisabled?: PdsColor;\n highlightDark: Color;\n}\n\nconst buildSemanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n const neutral = {\n hover: tokens.ActionNeutralHover,\n active: tokens.ActionNeutralActive,\n text: tokens.FgPrimary,\n textDisabled: tokens.FgDisabled,\n iconDisabled: tokens.FgDisabled,\n highlightDark: tokens.FgDisabled,\n };\n return {\n basic: {\n ...neutral,\n default: tokens.ActionNeutral,\n disabled: withAlpha(tokens.ActionNeutral, tokens.Opacity65),\n },\n text: { ...neutral, default: transparent, disabled: transparent },\n outline: {\n ...neutral,\n default: transparent,\n hover: tokens.ActionOutlineHover,\n active: tokens.ActionOutlineActive,\n disabled: transparent,\n },\n primary: {\n default: tokens.ActionPrimary,\n hover: tokens.ActionPrimaryHover,\n active: tokens.ActionPrimaryActive,\n disabled: tokens.ActionPrimary,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n danger: {\n default: tokens.ActionDanger,\n hover: tokens.ActionDangerHover,\n active: tokens.ActionDangerActive,\n disabled: tokens.ActionDanger,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n inverse: {\n default: tokens.ActionInverse,\n hover: tokens.ActionInverseHover,\n active: tokens.ActionInverseActive,\n disabled: withAlpha(tokens.ActionInverse, tokens.Opacity65),\n text: tokens.FgPrimaryStatic,\n textDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n iconDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n highlightDark: tokens.ActionNeutralActive,\n },\n };\n};\n\nconst semanticPaletteCache = new WeakMap<SemanticTokens, Record<ButtonVariant, ButtonPalette>>();\n\nconst semanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n let palettes = semanticPaletteCache.get(tokens);\n if (!palettes) {\n palettes = buildSemanticPalettes(tokens);\n semanticPaletteCache.set(tokens, palettes);\n }\n return palettes;\n};\n\nexport const buttonPalette = (theme: PersonaTheme, variant: ButtonVariant): ButtonPalette => {\n const tokens = semanticTokens(theme);\n return tokens ? semanticPalettes(tokens)[variant] : theme.color.variants[variant];\n};\n","import { isEmpty, isFunction } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type HTMLAttributeAnchorTarget,\n type MouseEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from 'react';\nimport styled, {\n css,\n type DefaultTheme,\n type FlattenInterpolation,\n type ThemeProps,\n} from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LoaderIcon } from '@persona/icons';\n\nimport { opacityOf, withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { RouterLink, type To } from '#src/lib/router';\nimport { semanticColor, semanticOnly, semanticTokens } from '#src/lib/semanticColor';\nimport useToggle from '#src/lib/useToggle';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport { paragraphMixins } from '#src/mixins/text';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { rotate } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport { type ButtonVariant, buttonPalette } from './palette';\n\nconst noop = (): void => undefined;\n\n// TODO(joseph): Bring this fix back to pseudoClass\nconst isActive = ({ active }: PseudoClassProps) => (active ? '' : ':active:enabled');\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst sizeStyles: Record<ButtonProps['size'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n md: css`\n ${paragraphMixins.md}\n height: ${({ theme }) => theme.button.height.md};\n padding: ${Spacing[2]};\n svg {\n height: 16px;\n width: 16px;\n }\n `,\n sm: css`\n ${paragraphMixins.sm}\n height: ${({ theme }) => theme.button.height.sm};\n padding: ${Spacing[1]} 6px;\n svg {\n height: 12px;\n width: 12px;\n }\n `,\n};\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst widthStyles: Record<ButtonProps['width'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n full: css`\n width: 100%;\n `,\n auto: css`\n width: auto;\n `,\n // TODO: rename this prop to 'element' as a standard unresponsive element width\n button: css`\n width: ${({ theme }) => theme.element.width.md};\n `,\n icon: css<ButtonProps>`\n width: ${({ theme, size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return theme.button.height[size];\n }};\n padding: 0;\n flex: none;\n `,\n};\n\ninterface ButtonPropsWithTransientProps extends Omit<ButtonProps, 'isPending'> {\n $isPending: boolean;\n $onSecondaryBackground?: boolean;\n}\n\nexport const StyledButton = styled.button.attrs<ButtonPropsWithTransientProps>(({ to, target }) => {\n if (isEmpty(to)) {\n return 'button';\n } else if (typeof to === 'string' && to.startsWith('https://')) {\n return {\n as: 'a',\n href: to,\n target: target ?? '_blank',\n rel: 'noreferrer',\n };\n } else {\n return {\n as: RouterLink,\n };\n }\n})<ButtonPropsWithTransientProps>`\n cursor: pointer;\n border: none;\n box-sizing: border-box;\n white-space: nowrap;\n ${({ theme, variant = 'primary' }) => {\n const palette = buttonPalette(theme, variant);\n const tokens = semanticTokens(theme);\n return css`\n &:disabled {\n background-color: ${palette.disabled};\n color: ${palette.textDisabled};\n ${\n tokens &&\n (variant === 'primary' || variant === 'danger') &&\n css`\n opacity: ${opacityOf(tokens.Opacity65)};\n `\n }\n ${\n palette.iconDisabled &&\n css`\n svg {\n color: ${palette.iconDisabled};\n }\n `\n }\n svg path {\n stroke: ${palette.iconDisabled ?? palette.textDisabled};\n }\n\n /* For backwards compatibility with current coloring scheme (targeting stroke property) */\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n /* Support icons with stroke */\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n user-select: none;\n }\n `;\n }}\n\n ${({ theme, variant }) =>\n variant === 'outline' &&\n css`\n border: 1px solid ${semanticColor(theme, 'BorderDefault', theme.color.border.input)};\n `}\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n /* To properly position loading spinner */\n position: relative;\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n\n transition-duration: ${TransitionDuration.Fast};\n transition-property: background-color, color, border-color, width, height;\n\n ${({ size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return sizeStyles[size];\n }}\n ${({ width }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return widthStyles[width];\n }}\n\n /* Variant styling */\n ${({ theme, variant = 'primary', $isPending, $onSecondaryBackground }) => {\n let palette = buttonPalette(theme, variant);\n\n if (variant === 'basic' && $onSecondaryBackground) {\n const tokens = semanticTokens(theme);\n palette = tokens\n ? {\n ...palette,\n default: tokens.ActionNeutralHover,\n hover: tokens.ActionNeutralActive,\n active: tokens.ActionNeutralActive,\n disabled: withAlpha(tokens.ActionNeutralHover, tokens.Opacity65),\n }\n : {\n ...palette,\n default: Color.CoreSlate300,\n hover: Color.CoreSlate400,\n active: Color.CoreSlate400,\n disabled: Color.CoreSlate100,\n };\n }\n\n return css`\n background-color: ${palette.default};\n color: ${palette.text};\n svg path {\n stroke: ${palette.text};\n }\n\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${palette.hover};\n }\n\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n &${isActive} {\n background-color: ${palette.active};\n }\n\n ${focusOutlineControlled}\n\n ${\n $isPending &&\n css`\n cursor: default;\n background-color: ${palette.active};\n &:disabled {\n background-color: ${buttonPalette(theme, variant).active};\n user-select: none;\n ${semanticOnly(() => 'opacity: 1;')}\n }\n\n svg path {\n stroke: ${palette.highlightDark};\n }\n\n // For backwards compatibility with current coloring scheme (targeting stroke property)\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n `\n }\n `;\n }}\n\n\n ${printMixins.hide}\n`;\n\ntype WithPendingProps = Pick<ButtonProps, 'isPending'>;\n\nconst LoaderContainer = styled.div<WithPendingProps>`\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 2s;\n opacity: ${({ isPending }) => (isPending ? '1' : '0')};\n`;\n\nconst Loader = styled(LoaderIcon)`\n animation: ${rotate} linear 1s infinite;\n`;\n\nexport const ButtonChildren = styled('div').attrs(({ isPending }: WithPendingProps) => ({\n ['aria-hidden']: isPending,\n}))<WithPendingProps>`\n width: 100%;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: center;\n transition: opacity ${TransitionDuration.Fast};\n opacity: ${({ isPending }) => (isPending ? '0' : '1')};\n gap: ${Spacing[1]};\n`;\n\nconst PrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst InheritPrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n\n & svg {\n width: inherit;\n height: inherit;\n }\n`;\n\nexport const SuffixIconContainer = styled(PrefixIconContainer)`\n margin-right: 0;\n flex-grow: 1;\n justify-content: flex-end;\n`;\n\nconst ButtonText = styled.span<{ size: 'md' | 'sm'; width: 'full' | 'auto' | 'button' | 'icon' }>`\n position: relative;\n\n /* Needed to align for browsers that don't support text-box yet\n (which at this time, is firefox, and opera, and a few niche browsers)\n This checks firefox. Otherwise, it will default back to the original\n which is a slightly misaligned button\n */\n\n /* Was trying to use this with @supports not, but genuinely could not figure out why this wouldn't\n work */\n\n line-height: ${({ width }) => (width === 'icon' ? '0' : 'inherit')};\n @-moz-document url-prefix() {\n top: ${({ size }) => (size === 'md' ? '1px' : '0.5px')};\n }\n\n @supports (text-box: cap alphabetic) {\n text-box: ${({ width }) => (width === 'icon' ? 'normal' : 'cap alphabetic')};\n }\n`;\n\ntype MaybePromise =\n | ((e: MouseEvent<HTMLButtonElement>) => void)\n | ((e: MouseEvent<HTMLButtonElement>) => Promise<void>);\n\nexport interface ButtonProps\n extends ComponentPropsWithoutRef<'button'>, Omit<PseudoClassProps, 'checked'> {\n /**\n * Visual style of the button.\n *\n * - `primary` – filled brand colour, for the primary action on a surface.\n * - `basic` – subtle grey fill, for secondary actions.\n * - `outline` – transparent with a border, alternative secondary style.\n * - `text` – no background or border, for tertiary / inline actions.\n * - `inverse` – inverted fill for use on dark/coloured backgrounds.\n * - `danger` – red fill, for destructive actions.\n *\n * @defaultValue 'primary'\n */\n variant?: ButtonVariant;\n /**\n * Shows a loading spinner and disables the button. Also triggers automatically\n * when `onClick` returns a Promise, clearing once the promise settles.\n */\n isPending?: boolean;\n /**\n * Icon rendered to the left of the button label.\n * Import from `@persona/icons`.\n */\n prefixIcon?: ReactNode;\n /**\n * Controls how the prefix icon inherits sizing.\n *\n * - `basic` – icon is rendered inside a fixed-size container.\n * - `inherit` – icon stretches to fill the surrounding element's dimensions.\n *\n * @defaultValue 'basic'\n */\n prefixIconType?: 'basic' | 'inherit';\n\n /**\n * Icon rendered to the right of the button label.\n * Import from `@persona/icons`.\n */\n suffixIcon?: ReactNode;\n\n /**\n * Height and typography scale of the button.\n *\n * @defaultValue 'md'\n */\n size?: 'md' | 'sm';\n\n /**\n * Changes the button into a link.\n * A relative path renders a router-aware link (PDS `RouterProvider` adapter,\n * react-router when present, otherwise a plain `<a>`); an absolute `https://`\n * URL renders an `<a>` that opens in a new tab.\n */\n to?: To;\n\n /**\n * Overrides the target of the link if `to` is provided and is an external link.\n */\n target?: HTMLAttributeAnchorTarget;\n\n /**\n * History state attached to the navigation when `to` is an internal link.\n */\n state?: unknown;\n\n /**\n * Replaces the current history entry instead of pushing, when `to` is an internal link.\n */\n replace?: boolean;\n\n /**\n * Note: we may want to default this to 'button' in the future, but many instances of this Button component\n * in dashboard currently rely on the default 'submit' behavior that occurs when using this in redux-form\n * so we'll have to comb through and manually add the type='submit' prop.\n */\n type?: 'button' | 'reset' | 'submit';\n /**\n * Controls the width of the button.\n *\n * - `full` – stretches to fill its container (`width: 100%`).\n * - `auto` – shrinks to fit its content.\n * - `button` – a fixed medium element width (from design tokens).\n * - `icon` – square, sized to match the button height; use for icon-only buttons.\n *\n * @defaultValue 'full'\n */\n width?: 'full' | 'auto' | 'button' | 'icon';\n onClick?: MaybePromise;\n ref?: Ref<HTMLButtonElement>;\n\n /**\n * In some cases we render a button on a secondary background, which needs an adjustment\n * for certain variants.\n */\n onSecondaryBackground?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n id,\n children,\n prefixIcon,\n suffixIcon,\n disabled,\n isPending,\n type = 'button',\n prefixIconType = 'basic',\n variant = 'primary',\n size = 'md',\n width = 'full',\n onClick,\n onSecondaryBackground,\n to,\n target,\n state,\n replace,\n ...props\n }: ButtonProps,\n ref,\n) {\n const [isResolving, { enable, disable }] = useToggle(false);\n const innerOnClick: MaybePromise = isFunction(onClick) ? onClick : noop;\n const loading = isPending || isResolving;\n const isInternalLink = !isEmpty(to) && !(typeof to === 'string' && to.startsWith('https://'));\n\n const handleClick = useCallback(\n async (e: MouseEvent<HTMLButtonElement>) => {\n if (loading) {\n return;\n }\n\n const maybePromise = innerOnClick(e);\n\n if (maybePromise instanceof Promise) {\n enable();\n try {\n await maybePromise;\n } catch {\n // A failed action should not leave the button pending.\n } finally {\n disable();\n }\n }\n },\n [loading, innerOnClick],\n );\n\n return (\n <StyledButton\n id={id}\n type={type}\n data-test={'button__' + variant}\n variant={variant}\n size={size}\n width={width}\n disabled={disabled || loading}\n $isPending={loading}\n $onSecondaryBackground={onSecondaryBackground}\n to={to}\n target={target}\n {...(isInternalLink ? { state, replace } : {})}\n {...props}\n onClick={handleClick}\n ref={ref}\n >\n {loading && (\n <LoaderContainer isPending={loading}>\n <Loader aria-label={`Loading ${props['aria-label'] || ''}`} />\n </LoaderContainer>\n )}\n <ButtonChildren isPending={loading}>\n {prefixIcon != null && (\n <>\n {prefixIconType === 'basic' && <PrefixIconContainer>{prefixIcon}</PrefixIconContainer>}\n {prefixIconType === 'inherit' && (\n <InheritPrefixIconContainer>{prefixIcon}</InheritPrefixIconContainer>\n )}\n </>\n )}\n {children && (\n <ButtonText width={width} size={size}>\n {children}\n </ButtonText>\n )}\n {suffixIcon != null && <SuffixIconContainer>{suffixIcon}</SuffixIconContainer>}\n </ButtonChildren>\n </StyledButton>\n );\n});\n\nexport default Button;\n","import { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\n\nimport { semanticOnly } from '#src/lib/semanticColor';\n\nimport Button, { type ButtonProps } from './Button';\n\nconst BUTTON_SIZE_MAP = {\n xs: '16px',\n sm: '24px',\n md: '32px',\n};\n\nconst ICON_SIZE_MAP = {\n xs: '12px',\n sm: '16px',\n md: '16px',\n};\n\ntype IconBtnSize = keyof typeof BUTTON_SIZE_MAP;\n\nconst IconBtn = styled(Button).attrs({\n width: 'icon',\n variant: 'basic',\n})`\n background-color: transparent;\n padding: 0;\n border-radius: ${BorderRadius.Md};\n\n ${semanticOnly(\n () => css`\n &:disabled {\n background-color: transparent;\n }\n `,\n )}\n\n ${({ size }) => css`\n height: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n width: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n\n svg {\n width: ${ICON_SIZE_MAP[size as IconBtnSize]};\n height: ${ICON_SIZE_MAP[size as IconBtnSize]};\n }\n `}\n`;\n\nexport interface IconButtonProps extends Omit<\n ButtonProps,\n 'width' | 'prefixIcon' | 'prefixIconType' | 'suffixIcon' | 'variant' | 'size'\n> {\n /**\n * `xs` - 16px. `sm` - 24px. `md` - 32px.\n * Pair with a PDS icon in the prescribed size.\n */\n size?: IconBtnSize;\n}\n\n/**\n * Use to render icon-only buttons. Ensure buttons have proper aria properties.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { size = 'xs', ...props },\n ref,\n) {\n return <IconBtn size={size as ButtonProps['size']} ref={ref} {...props} />;\n});\n\nexport default IconButton;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Link-D_kCyLYX.mjs","names":[],"sources":["../src/components/Link/Link.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LinkExternalIcon } from '@persona/icons';\n\nimport { RouterLink, type RouterLinkComponentProps } from '#src/lib/router';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { focusOutline } from '#src/mixins/focus';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { TransitionDuration } from '#src/variables/transitions';\n\ntype Target = '_blank' | '_self' | '_parent' | '_top';\n\ninterface BaseLinkProps {\n /**\n * The content to display inside the link.\n *\n */\n children?: ReactNode;\n /**\n * Provides an accessible name for the link when the visible text alone\n * isn't descriptive enough for screen reader users\n */\n 'aria-label'?: string;\n}\n\ninterface ExternalLinkProps extends BaseLinkProps, AnchorHTMLAttributes<HTMLAnchorElement> {\n /**\n * The URL to navigate to. Can be internal (e.g., \"/settings\") or external (e.g., \"https://example.com\").\n */\n url: string;\n\n /**\n * Where to open the link. Use \"_blank\" for external links to open in a new tab.\n */\n target?: Target;\n}\n\ninterface InternalLinkProps\n extends BaseLinkProps, Omit<RouterLinkComponentProps, 'to' | 'children'> {\n /**\n * The URL to navigate to. Should be an internal route (e.g., \"/settings\").\n */\n url: string;\n}\n\nexport type LinkProps = ExternalLinkProps | InternalLinkProps;\n\nconst IconContainer = styled.span`\n display: inline-block;\n vertical-align: middle;\n /* Uses padding here since we can't define flex on the element for multiline support */\n padding-left: 2px;\n /* Needed to reset the height of the container for SVG */\n line-height: 0;\n position: relative;\n /* Optical alignment adjustments */\n bottom: 1px;\n`;\n\nconst baseLinkStyles = css`\n ${paragraphMixins.md};\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', Color.CorePurple600)};\n width: fit-content;\n position: relative;\n overflow: hidden;\n text-decoration: underline;\n\n transition:\n color ${TransitionDuration.ExtraFast} ease-out,\n text-underline-offset ${TransitionDuration.ExtraFast} ease-out;\n text-underline-offset: 2px;\n\n &:hover {\n color: ${({ theme }) => semanticColor(theme, 'FgAccentHover', Color.CorePurple800)};\n text-underline-offset: ${Spacing[1]};\n }\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n ${focusOutline}\n\n &:active {\n color: ${({ theme }) => semanticColor(theme, 'FgAccentActive', Color.CorePurple900)};\n }\n`;\n\nconst StyledAnchor = styled.a`\n ${baseLinkStyles}\n`;\n\nconst StyledRouterLink = styled(RouterLink)`\n ${baseLinkStyles}\n`;\n\nexport const Link = ({ children, url, ...props }: LinkProps) => {\n // Check if the URL is external by looking at the protocol or if target is _blank\n const isAbsoluteUrl = /^https?:\\/\\//.test(url);\n const hasBlankTarget = props.target === '_blank';\n const isExternal = isAbsoluteUrl || hasBlankTarget;\n\n if (isExternal) {\n const { 'aria-label': ariaLabel, ...anchorProps } = props;\n const externalProps = {\n href: url,\n target: '_blank',\n rel: 'noopener noreferrer',\n 'aria-label': ariaLabel,\n // Automatically inform screen readers that link opens in new window\n title: ariaLabel ? undefined : 'Opens in new window',\n ...anchorProps,\n };\n\n return (\n <StyledAnchor {...externalProps}>\n {children}\n <IconContainer>\n <LinkExternalIcon size={12} />\n </IconContainer>\n </StyledAnchor>\n );\n }\n\n const { 'aria-label': ariaLabel, ...routerProps } = props;\n const internalProps = {\n to: url,\n 'aria-label': ariaLabel,\n\n ...routerProps,\n };\n\n return <StyledRouterLink {...internalProps}>{children}</StyledRouterLink>;\n};\n\nexport default Link;\n"],"mappings":";;;;;;;;;;AAiDA,MAAM,gBAAgB,OAAO,IAAI;;;;;;;;;;;AAYjC,MAAM,iBAAiB,GAAG;IACtB,gBAAgB,GAAG;YACX,EAAE,YAAY,cAAc,OAAO,YAAY,MAAM,cAAc,CAAC;;;;;;;oBAOvC;oCACgB;;;;cAI3C,EAAE,YAAY,cAAc,OAAO,iBAAiB,MAAM,cAAc,CAAC;6BAC1D,QAAQ,GAAG;;;oBAGpB,EAAE,YAAY,MAAM,OAAO,aAAa;IACxD,aAAa;;;cAGH,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,cAAc,CAAC;;;AAIxF,MAAM,eAAe,OAAO,CAAC;IACzB,eAAe;;AAGnB,MAAM,mBAAmB,OAAO,WAAW;IACvC,eAAe;;AAGnB,MAAa,QAAQ,EAAE,UAAU,KAAK,GAAG,YAAuB;CAE9D,MAAM,gBAAgB,eAAe,KAAK,IAAI;CAC9C,MAAM,iBAAiB,MAAM,WAAW;AAGxC,KAFmB,iBAAiB,gBAEpB;EACd,MAAM,EAAE,cAAc,WAAW,GAAG,gBAAgB;AAWpD,SACE,qBAAC,cAAD;GAVA,MAAM;GACN,QAAQ;GACR,KAAK;GACL,cAAc;GAEd,OAAO,YAAY,KAAA,IAAY;GAC/B,GAAG;aAIH,CACG,UACD,oBAAC,eAAD,EAAA,UACE,oBAAC,kBAAD,EAAkB,MAAM,IAAM,CAAA,EAChB,CAAA,CACH;;;CAInB,MAAM,EAAE,cAAc,WAAW,GAAG,gBAAgB;AAQpD,QAAO,oBAAC,kBAAD;EANL,IAAI;EACJ,cAAc;EAEd,GAAG;EAGwC;EAA4B,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingShimmer-oPIv2ESr.mjs","names":[],"sources":["../src/components/LoadingShimmer/LoadingShimmer.tsx"],"sourcesContent":["import { motion } from 'framer-motion';\nimport type { ComponentPropsWithoutRef, FC } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color } from '@persona/design-tokens';\n\nimport { type CssColor, withAlpha } from '#src/lib/color';\nimport { type MaybeSemanticTheme, semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport type { HeadingSize, ParagraphSize } from '#src/mixins/text';\n\n// A one-off colour predating the token set; no primitive matches it exactly.\n// oxlint-disable-next-line persona-web/no-raw-hex-colors\nconst LEGACY_SECONDARY_BAR = '#eaeaea' as CssColor;\n\n// Relay renders this under its own theme, which has neither a semantic namespace nor `theme.color`,\n// so each fallback is a constant rather than a theme expression — the latter would throw there.\nconst shimmerColors = (theme: MaybeSemanticTheme, variant: 'primary' | 'secondary') => {\n if (variant === 'secondary') {\n return {\n bar: semanticColor(theme, 'FeedbackNeutral2', LEGACY_SECONDARY_BAR),\n highlight: semanticColor(theme, 'FeedbackNeutral1', Color.CoreSlate50),\n };\n }\n\n const tokens = semanticTokens(theme);\n\n return {\n bar: semanticColor(theme, 'FeedbackNeutral1', Color.CoreSlate50),\n highlight: tokens ? withAlpha(tokens.SurfaceSecondary, tokens.Opacity25) : Color.CoreSlate25,\n };\n};\n\ninterface LoadingShimmerProps extends ComponentPropsWithoutRef<'span'> {\n height?: string;\n width?: string;\n variant?: 'primary' | 'secondary';\n}\n\ntype ShimmerContainerProps = {\n width?: string;\n height?: string;\n $variant: 'primary' | 'secondary';\n};\nconst ShimmerContainer = styled.span<ShimmerContainerProps>`\n position: relative;\n display: inline-block;\n background-color: ${({ theme, $variant }) => shimmerColors(theme, $variant).bar};\n width: ${({ width }) => width ?? '100px'};\n height: ${({ height }) => height ?? 'auto'};\n border-radius: ${BorderRadius.Md};\n overflow: hidden;\n`;\n\ntype ShimmerProps = {\n $variant: 'primary' | 'secondary';\n};\nconst Shimmer = styled(motion.span)<ShimmerProps>`\n position: absolute;\n width: 100%;\n height: 100%;\n background: ${({ theme, $variant }) =>\n `linear-gradient(90deg, transparent 0%, ${shimmerColors(theme, $variant).highlight} 50%, transparent 100%)`};\n filter: blur(4px);\n`;\n\n/**\n * Base class of all Loading Shimmer components.\n */\nexport function LoadingShimmer({\n width,\n height,\n variant = 'primary',\n ...props\n}: LoadingShimmerProps) {\n return (\n <ShimmerContainer\n width={width}\n height={height}\n $variant={variant}\n aria-live='polite'\n aria-busy='true'\n data-test='loading-shimmer'\n data-loading-indicator='true'\n {...props}\n >\n <Shimmer\n initial={{ x: '-100%', skew: -30 }}\n animate={{ x: '100%', skew: -30 }}\n $variant={variant}\n transition={{ repeat: Infinity, duration: 1, ease: 'easeOut' }}\n />\n </ShimmerContainer>\n );\n}\n\nexport interface LoadingShimmerHeadingProps extends LoadingShimmerProps {\n size?: HeadingSize;\n}\n\nexport const LoadingShimmerHeading = styled(LoadingShimmer)<LoadingShimmerHeadingProps>`\n height: ${({ theme, size = 'lg' }) => theme.text.heading[size].fontSize};\n`;\n\ninterface LoadingShimmerParagraphProps extends LoadingShimmerProps {\n size?: ParagraphSize;\n // eg. 200px\n width?: string;\n}\n\nexport const LoadingShimmerParagraph = styled(LoadingShimmer)<LoadingShimmerParagraphProps>`\n height: ${({ theme, size = 'md' }) => theme.text.paragraph[size].fontSize};\n`;\n\n// A \"maybe\" shimmer block that is shimmering if the `isLoading`\n// value is set to true and otherwise just displays its children\ninterface MaybeLoadingShimmerProps {\n isLoading: boolean;\n height?: string;\n width?: string;\n}\n\nexport const MaybeLoadingShimmer: FC<MaybeLoadingShimmerProps> = ({\n isLoading,\n children,\n height,\n width,\n}) => (isLoading ? <LoadingShimmer height={height} width={width} /> : <>{children}</>);\n"],"mappings":";;;;;;;AAYA,MAAM,uBAAuB;AAI7B,MAAM,iBAAiB,OAA2B,YAAqC;AACrF,KAAI,YAAY,YACd,QAAO;EACL,KAAK,cAAc,OAAO,oBAAoB,qBAAqB;EACnE,WAAW,cAAc,OAAO,oBAAoB,MAAM,YAAY;EACvE;CAGH,MAAM,SAAS,eAAe,MAAM;AAEpC,QAAO;EACL,KAAK,cAAc,OAAO,oBAAoB,MAAM,YAAY;EAChE,WAAW,SAAS,UAAU,OAAO,kBAAkB,OAAO,UAAU,GAAG,MAAM;EAClF;;AAcH,MAAM,mBAAmB,OAAO,IAA2B;;;uBAGpC,EAAE,OAAO,eAAe,cAAc,OAAO,SAAS,CAAC,IAAI;YACtE,EAAE,YAAY,SAAS,QAAQ;aAC9B,EAAE,aAAa,UAAU,OAAO;mBAC1B,aAAa,GAAG;;;AAOnC,MAAM,UAAU,OAAO,OAAO,KAAK;;;;iBAIlB,EAAE,OAAO,eACtB,0CAA0C,cAAc,OAAO,SAAS,CAAC,UAAU,yBAAyB;;;;;;AAOhH,SAAgB,eAAe,EAC7B,OACA,QACA,UAAU,WACV,GAAG,SACmB;AACtB,QACE,oBAAC,kBAAD;EACS;EACC;EACR,UAAU;EACV,aAAU;EACV,aAAU;EACV,aAAU;EACV,0BAAuB;EACvB,GAAI;YAEJ,oBAAC,SAAD;GACE,SAAS;IAAE,GAAG;IAAS,MAAM;IAAK;GAClC,SAAS;IAAE,GAAG;IAAQ,MAAM;IAAK;GACjC,UAAU;GACV,YAAY;IAAE,QAAQ;IAAU,UAAU;IAAG,MAAM;IAAW;GAC9D,CAAA;EACe,CAAA;;AAQvB,MAAa,wBAAwB,OAAO,eAAe;aAC9C,EAAE,OAAO,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,SAAS;;AAS1E,MAAa,0BAA0B,OAAO,eAAe;aAChD,EAAE,OAAO,OAAO,WAAW,MAAM,KAAK,UAAU,MAAM,SAAS;;AAW5E,MAAa,uBAAqD,EAChE,WACA,UACA,QACA,YACK,YAAY,oBAAC,gBAAD;CAAwB;CAAe;CAAS,CAAA,GAAG,oBAAA,UAAA,EAAG,UAAY,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Popover-DordjYNM.mjs","names":["Card"],"sources":["../src/components/Popover/Popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { Children, forwardRef, isValidElement, type ReactElement } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport type { Spacing } from '@persona/design-tokens';\nimport { XIcon } from '@persona/icons';\n\nimport Card from '#src/components/Card';\nimport { Paragraph } from '#src/components/Text';\nimport { letPointerDownReachDocument } from '#src/lib/letPointerDownReachDocument';\nimport { semanticOnly } from '#src/lib/semanticColor';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\nexport const PopoverAnchor = PopoverPrimitive.Anchor;\nexport const PopoverPortal = PopoverPrimitive.Portal;\n\nexport const PopoverContent = forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n PopoverPrimitive.PopoverContentProps\n>(function PopoverContent({ onPointerDownCapture, ...props }, ref) {\n return (\n <PopoverPrimitive.Content\n {...props}\n ref={ref}\n onPointerDownCapture={(event) => {\n onPointerDownCapture?.(event);\n letPointerDownReachDocument(event);\n }}\n />\n );\n});\n\nconst PopoverContentStyled = styled(PopoverContent)<{ zIndex?: number; $maxHeight?: string }>`\n z-index: ${({ zIndex }) => zIndex || 'inherit'};\n ${({ $maxHeight }) =>\n $maxHeight &&\n css`\n max-height: ${$maxHeight};\n overflow: auto;\n ${semanticScrollbar}\n `}\n`;\n\nconst PopoverCloseButton = styled(PopoverPrimitive.Close)<{ isHeader?: boolean }>`\n ${({ isHeader }) =>\n !isHeader &&\n css`\n position: absolute;\n top: 8px;\n right: 8px;\n `}\n ${({ isHeader }) =>\n isHeader &&\n css`\n height: 16px;\n `}\n background: transparent;\n border: 0;\n cursor: pointer;\n`;\n\nconst PopoverPanel = styled(Card)`\n ${semanticOnly((tokens) => `background-color: ${tokens.SurfaceElevated};`)}\n`;\n\nconst HeadingContainer = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n`;\n\nexport const PopoverClose = (\n props: PopoverPrimitive.PopoverCloseProps & { isHeader?: boolean },\n) => {\n return (\n <PopoverCloseButton {...props}>\n <XIcon />\n </PopoverCloseButton>\n );\n};\n\nexport interface PopoverCardProps extends PopoverPrimitive.PopoverContentProps {\n /**\n * Display X button to close popover\n */\n showCloseButton?: boolean;\n\n /**\n * Remove padding from Card\n */\n noPadding?: boolean;\n\n padding?: Spacing;\n\n /**\n * Text to display in the header of the card\n */\n heading?: string;\n\n /**\n * Z-index to apply to the popover content\n */\n zIndex?: number;\n\n /**\n * Maximum height for the popover content.\n */\n maxHeight?: string;\n}\n\n/**\n * Card to be used in Popover contexts. Inherits props from Radix UI Popper.Content.\n */\nexport const PopoverCard = forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n PopoverCardProps\n>(function PopoverCard(\n { children, showCloseButton, heading, noPadding, padding, zIndex, maxHeight, ...props },\n ref,\n) {\n const header = heading && (\n <HeadingContainer>\n <Paragraph size='md' weight='bold' color='primary'>\n {heading}\n </Paragraph>\n {showCloseButton && <PopoverClose aria-label='Close' isHeader />}\n </HeadingContainer>\n );\n return (\n <PopoverContentStyled\n asChild\n sideOffset={8}\n collisionPadding={8}\n zIndex={zIndex}\n $maxHeight={maxHeight}\n {...props}\n ref={ref}\n >\n <PopoverPanel elevated>\n {!heading && showCloseButton && <PopoverClose aria-label='Close' />}\n {noPadding ? (\n <>\n {heading && header}\n {children}\n </>\n ) : (\n <Card.Body padding={padding}>\n {heading && header}\n {children}\n </Card.Body>\n )}\n </PopoverPanel>\n </PopoverContentStyled>\n );\n});\n\ninterface PopoverProps extends PopoverPrimitive.PopoverProps {\n /**\n * Component to use as trigger. Radix UI trigger component props will be merged with this element.\n */\n trigger?: ReactElement;\n\n /**\n * Props to apply to Popover.Trigger within\n */\n triggerProps?: PopoverPrimitive.PopoverTriggerProps;\n\n /**\n * An optional element to position the Popover.Content against.\n * If this part is not used, the content will position alongside the trigger.\n */\n anchor?: ReactElement<PopoverPrimitive.PopoverAnchorProps>;\n\n /**\n * Props to apply to Popover.Card within\n */\n contentProps?: PopoverCardProps;\n\n /**\n * Render content within a portal\n */\n portal?: boolean;\n\n /**\n * Props applied to Radix UI Portal component\n */\n portalProps?: PopoverPrimitive.PopoverPortalProps;\n}\n\nconst Popover = ({\n children,\n trigger,\n triggerProps,\n contentProps,\n anchor,\n portal = true,\n portalProps,\n ...props\n}: PopoverProps) => {\n let triggerElem;\n let contentElem;\n let anchorElem = anchor;\n\n const renderChildren = Children.toArray(children).filter((child) => {\n if (isValidElement(child)) {\n switch (child.type) {\n case PopoverPrimitive.Trigger:\n triggerElem = child;\n return false;\n case PopoverCard:\n case PopoverContent:\n case PopoverPrimitive.Content:\n contentElem = child;\n break;\n case PopoverPrimitive.Anchor:\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n anchorElem = child;\n return false;\n }\n }\n\n return true;\n });\n\n const content = contentElem || <PopoverCard {...contentProps}>{renderChildren}</PopoverCard>;\n\n return (\n <PopoverPrimitive.Root {...props}>\n {triggerElem ||\n (trigger && (\n <PopoverTrigger asChild {...triggerProps}>\n {trigger}\n </PopoverTrigger>\n ))}\n {anchorElem}\n {portal ? <PopoverPortal {...portalProps}>{content}</PopoverPortal> : content}\n </PopoverPrimitive.Root>\n );\n};\n\nexport default Object.assign(Popover, {\n Trigger: PopoverTrigger,\n Anchor: PopoverAnchor,\n Portal: PopoverPortal,\n Content: PopoverContent,\n Card: PopoverCard,\n Close: PopoverClose,\n});\n"],"mappings":";;;;;;;;;;;AAaA,MAAa,iBAAiB,iBAAiB;AAC/C,MAAa,gBAAgB,iBAAiB;AAC9C,MAAa,gBAAgB,iBAAiB;AAE9C,MAAa,iBAAiB,WAG5B,SAAS,eAAe,EAAE,sBAAsB,GAAG,SAAS,KAAK;AACjE,QACE,oBAAC,iBAAiB,SAAlB;EACE,GAAI;EACC;EACL,uBAAuB,UAAU;AAC/B,0BAAuB,MAAM;AAC7B,+BAA4B,MAAM;;EAEpC,CAAA;EAEJ;AAEF,MAAM,uBAAuB,OAAO,eAAe;cACrC,EAAE,aAAa,UAAU,UAAU;KAC5C,EAAE,iBACH,cACA,GAAG;oBACa,WAAW;;QAEvB,kBAAkB;MACpB;;AAGN,MAAM,qBAAqB,OAAO,iBAAiB,MAAM;KACpD,EAAE,eACH,CAAC,YACD,GAAG;;;;MAID;KACD,EAAE,eACH,YACA,GAAG;;MAED;;;;;AAMN,MAAM,eAAe,OAAOA,aAAK;IAC7B,cAAc,WAAW,qBAAqB,OAAO,gBAAgB,GAAG,CAAC;;AAG7E,MAAM,mBAAmB,OAAO,GAAG;;;;;AAMnC,MAAa,gBACX,UACG;AACH,QACE,oBAAC,oBAAD;EAAoB,GAAI;YACtB,oBAAC,OAAD,EAAS,CAAA;EACU,CAAA;;;;;AAoCzB,MAAa,cAAc,WAGzB,SAAS,YACT,EAAE,UAAU,iBAAiB,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG,SAChF,KACA;CACA,MAAM,SAAS,WACb,qBAAC,kBAAD,EAAA,UAAA,CACE,oBAAC,WAAD;EAAW,MAAK;EAAK,QAAO;EAAO,OAAM;YACtC;EACS,CAAA,EACX,mBAAmB,oBAAC,cAAD;EAAc,cAAW;EAAQ,UAAA;EAAW,CAAA,CAC/C,EAAA,CAAA;AAErB,QACE,oBAAC,sBAAD;EACE,SAAA;EACA,YAAY;EACZ,kBAAkB;EACV;EACR,YAAY;EACZ,GAAI;EACC;YAEL,qBAAC,cAAD;GAAc,UAAA;aAAd,CACG,CAAC,WAAW,mBAAmB,oBAAC,cAAD,EAAc,cAAW,SAAU,CAAA,EAClE,YACC,qBAAA,YAAA,EAAA,UAAA,CACG,WAAW,QACX,SACA,EAAA,CAAA,GAEH,qBAACA,aAAK,MAAN;IAAoB;cAApB,CACG,WAAW,QACX,SACS;MAED;;EACM,CAAA;EAEzB;AAmCF,MAAM,WAAW,EACf,UACA,SACA,cACA,cACA,QACA,SAAS,MACT,aACA,GAAG,YACe;CAClB,IAAI;CACJ,IAAI;CACJ,IAAI,aAAa;CAEjB,MAAM,iBAAiB,SAAS,QAAQ,SAAS,CAAC,QAAQ,UAAU;AAClE,MAAI,eAAe,MAAM,CACvB,SAAQ,MAAM,MAAd;GACE,KAAK,iBAAiB;AACpB,kBAAc;AACd,WAAO;GACT,KAAK;GACL,KAAK;GACL,KAAK,iBAAiB;AACpB,kBAAc;AACd;GACF,KAAK,iBAAiB;AAEpB,iBAAa;AACb,WAAO;;AAIb,SAAO;GACP;CAEF,MAAM,UAAU,eAAe,oBAAC,aAAD;EAAa,GAAI;YAAe;EAA6B,CAAA;AAE5F,QACE,qBAAC,iBAAiB,MAAlB;EAAuB,GAAI;YAA3B;GACG,eACE,WACC,oBAAC,gBAAD;IAAgB,SAAA;IAAQ,GAAI;cACzB;IACc,CAAA;GAEpB;GACA,SAAS,oBAAC,eAAD;IAAe,GAAI;cAAc;IAAwB,CAAA,GAAG;GAChD;;;AAI5B,IAAA,kBAAe,OAAO,OAAO,SAAS;CACpC,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,MAAM;CACN,OAAO;CACR,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Radio-BlEtetrr.mjs","names":[],"sources":["../src/components/Radio/Radio.tsx"],"sourcesContent":["import { uniqueId } from 'lodash-es';\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useMemo,\n} from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nimport useFormField from '#src/components/FormControl/useFormField';\nimport { opacityOf } from '#src/lib/color';\nimport {\n isChecked,\n isDisabled,\n isFocusedVisible,\n isHovered,\n isNotDisabled,\n} from '#src/lib/pseudoClass';\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\nimport { focusStyle } from '#src/mixins/focus';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nconst Container = styled.div<{ size: 'md' | 'sm'; disabled?: boolean }>`\n cursor: pointer;\n display: flex;\n align-items: flex-start;\n flex-wrap: nowrap;\n position: relative;\n\n ${({ size }) =>\n size === 'sm' &&\n css`\n align-items: center;\n height: 16px;\n `}\n\n &${isDisabled} {\n cursor: default;\n }\n`;\n\nconst Label = styled.label<{ disabled: boolean; size: 'md' | 'sm' }>`\n cursor: inherit;\n padding: 0 ${Spacing[2]};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.TextSecondary)};\n\n ${({ size }) =>\n size === 'sm'\n ? css`\n ${Typography.TextSmall};\n line-height: 16px;\n `\n : css`\n ${Typography.TextMedium};\n `}\n\n ${({ theme, disabled }) =>\n disabled &&\n css`\n cursor: default;\n color: ${semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n `}\n`;\n\nconst RadioCircle = styled.div<{ size: 'md' | 'sm' }>`\n cursor: pointer;\n display: flex;\n justify-content: center;\n align-items: center;\n transition: box-shadow ${TransitionDuration.Fast};\n border-radius: 100%;\n height: ${Spacing[4]};\n width: ${Spacing[4]};\n flex: 0 0 16px;\n box-sizing: border-box;\n margin-top: ${({ size }) => (size === 'sm' ? 0 : '2px')};\n border: 1px solid ${({ theme }) => semanticColor(theme, 'InputBorderStrong', Color.BorderInputCheckbox)};\n background: ${({ theme }) => semanticColor(theme, 'InputSurfaceDefault', Color.PrimaryWhite)};\n`;\n\nconst RadioInput = styled.input<{ $size: 'md' | 'sm' }>`\n cursor: inherit;\n height: ${Spacing[4]};\n width: ${Spacing[4]};\n margin: 0;\n border: 0;\n opacity: 0;\n overflow: hidden;\n position: absolute;\n top: ${({ $size }) => ($size === 'sm' ? 0 : '2px')};\n border-radius: 100%;\n z-index: 10; // this needs to be above the dot in the checked input\n\n &${isHovered}${isNotDisabled} ~ ${RadioCircle} {\n border-color: ${({ theme }) =>\n semanticColor(theme, 'InputBorderHoverStrong', Color.BorderInputCheckboxHover)};\n ${semanticOnly((tokens) => `background: ${tokens.InputSurfaceHover};`)}\n }\n\n &${isChecked}, &:checked {\n &${isHovered}${isNotDisabled} ~ ${RadioCircle} {\n background: ${({ theme }) => semanticColor(theme, 'InputSurfaceAccentHover', Color.BackgroundInputActiveHover)};\n border-color: ${({ theme }) => semanticColor(theme, 'InputSurfaceAccentHover', Color.BackgroundInputActiveHover)};\n }\n }\n\n &${isFocusedVisible}${isNotDisabled} ~ ${RadioCircle} {\n ${focusStyle}\n }\n\n // RadioCircle state styles; Uses pure CSS\n &${isDisabled} + ${RadioCircle} {\n cursor: default;\n background: ${({ theme }) =>\n semanticColor(theme, 'InputSurfaceDisabled', Color.BackgroundInputDisabled)};\n border-color: ${({ theme }) =>\n semanticColor(theme, 'InputBorderDisabled', Color.BorderInputDisabled)};\n ${semanticOnly((tokens) => `opacity: ${opacityOf(tokens.Opacity65)};`)}\n }\n\n &:checked + ${RadioCircle}, &${isChecked} + ${RadioCircle} {\n border-color: ${({ theme }) => semanticColor(theme, 'InputBorderAccent', Color.BackgroundInputActive)};\n background: ${({ theme }) => semanticColor(theme, 'InputSurfaceAccent', Color.BackgroundInputActive)};\n\n &::after {\n background: ${({ theme }) => semanticColor(theme, 'FgInverseStatic', Color.BackgroundInputDefault)};\n height: 6px;\n width: 6px;\n border-radius: 100%;\n content: '';\n position: absolute;\n }\n }\n\n &:checked${isDisabled} + ${RadioCircle}, &${isChecked}${isDisabled} + ${RadioCircle} {\n border-color: ${({ theme }) => semanticColor(theme, 'InputSurfaceAccentDisabled', Color.BackgroundInputActiveDisabled)};\n background: ${({ theme }) => semanticColor(theme, 'InputSurfaceAccentDisabled', Color.BackgroundInputActiveDisabled)};\n }\n`;\n\nexport interface RadioProps extends Omit<ComponentPropsWithoutRef<'input'>, 'size'> {\n /**\n * If not provided, a unique ID will be generated.\n */\n id?: string;\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void;\n label?: ReactNode;\n disabled?: boolean;\n checked?: boolean;\n value: string;\n 'data-test'?: string;\n size?: 'md' | 'sm';\n}\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n {\n id,\n label,\n className,\n value,\n disabled,\n checked,\n defaultChecked,\n onChange,\n 'data-test': dataTest,\n size = 'md',\n ...elemProps\n },\n ref,\n) {\n const field = useFormField({ disabled });\n const generatedId = useMemo(() => uniqueId('pds_radio__'), []);\n\n return (\n <Container className={className} disabled={disabled} data-test={dataTest} size={size}>\n <RadioInput\n id={id || generatedId}\n disabled={field.disabled}\n onChange={onChange}\n type='radio'\n value={value}\n checked={checked}\n defaultChecked={defaultChecked}\n ref={ref}\n $size={size}\n {...elemProps}\n />\n <RadioCircle size={size} />\n {label && (\n <Label htmlFor={id || generatedId} disabled={disabled ?? false} size={size}>\n {label}\n </Label>\n )}\n </Container>\n );\n});\n\nexport default Radio;\n"],"mappings":";;;;;;;;;;;;AAyBA,MAAM,YAAY,OAAO,GAA8C;;;;;;;KAOlE,EAAE,WACH,SAAS,QACT,GAAG;;;MAGD;;KAED,WAAW;;;;AAKhB,MAAM,QAAQ,OAAO,KAA+C;;eAErD,QAAQ,GAAG;YACd,EAAE,YAAY,cAAc,OAAO,eAAe,MAAM,cAAc,CAAC;;KAE9E,EAAE,WACH,SAAS,OACL,GAAG;YACC,WAAW,UAAU;;YAGzB,GAAG;YACC,WAAW,WAAW;UACxB;;KAEL,EAAE,OAAO,eACV,YACA,GAAG;;eAEQ,cAAc,OAAO,cAAc,MAAM,MAAM,KAAK,SAAS,CAAC;MACvE;;AAGN,MAAM,cAAc,OAAO,GAA0B;;;;;mCAKF;;YAEvC,QAAQ,GAAG;WACZ,QAAQ,GAAG;;;iBAGL,EAAE,WAAY,SAAS,OAAO,IAAI,MAAO;uBACnC,EAAE,YAAY,cAAc,OAAO,qBAAqB,MAAM,oBAAoB,CAAC;iBACzF,EAAE,YAAY,cAAc,OAAO,uBAAuB,MAAM,aAAa,CAAC;;AAG/F,MAAM,aAAa,OAAO,KAA6B;;YAE3C,QAAQ,GAAG;WACZ,QAAQ,GAAG;;;;;;UAMZ,EAAE,YAAa,UAAU,OAAO,IAAI,MAAO;;;;KAIhD,YAAY,cAAc,KAAK,YAAY;qBAC3B,EAAE,YACjB,cAAc,OAAO,0BAA0B,MAAM,yBAAyB,CAAC;MAC/E,cAAc,WAAW,eAAe,OAAO,kBAAkB,GAAG,CAAC;;;KAGtE,UAAU;OACR,YAAY,cAAc,KAAK,YAAY;qBAC7B,EAAE,YAAY,cAAc,OAAO,2BAA2B,MAAM,2BAA2B,CAAC;uBAC9F,EAAE,YAAY,cAAc,OAAO,2BAA2B,MAAM,2BAA2B,CAAC;;;;KAIlH,mBAAmB,cAAc,KAAK,YAAY;MACjD,WAAW;;;;KAIZ,WAAW,KAAK,YAAY;;mBAEd,EAAE,YACf,cAAc,OAAO,wBAAwB,MAAM,wBAAwB,CAAC;qBAC7D,EAAE,YACjB,cAAc,OAAO,uBAAuB,MAAM,oBAAoB,CAAC;MACvE,cAAc,WAAW,YAAY,UAAU,OAAO,UAAU,CAAC,GAAG,CAAC;;;gBAG3D,YAAY,KAAK,UAAU,KAAK,YAAY;qBACvC,EAAE,YAAY,cAAc,OAAO,qBAAqB,MAAM,sBAAsB,CAAC;mBACvF,EAAE,YAAY,cAAc,OAAO,sBAAsB,MAAM,sBAAsB,CAAC;;;qBAGpF,EAAE,YAAY,cAAc,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;;;;;;;;;aAS5F,WAAW,KAAK,YAAY,KAAK,YAAY,WAAW,KAAK,YAAY;qBACjE,EAAE,YAAY,cAAc,OAAO,8BAA8B,MAAM,8BAA8B,CAAC;mBACxG,EAAE,YAAY,cAAc,OAAO,8BAA8B,MAAM,8BAA8B,CAAC;;;AAkBzH,MAAa,QAAQ,WAAyC,SAAS,MACrE,EACE,IACA,OACA,WACA,OACA,UACA,SACA,gBACA,UACA,aAAa,UACb,OAAO,MACP,GAAG,aAEL,KACA;CACA,MAAM,QAAQ,aAAa,EAAE,UAAU,CAAC;CACxC,MAAM,cAAc,cAAc,SAAS,cAAc,EAAE,EAAE,CAAC;AAE9D,QACE,qBAAC,WAAD;EAAsB;EAAqB;EAAU,aAAW;EAAgB;YAAhF;GACE,oBAAC,YAAD;IACE,IAAI,MAAM;IACV,UAAU,MAAM;IACN;IACV,MAAK;IACE;IACE;IACO;IACX;IACL,OAAO;IACP,GAAI;IACJ,CAAA;GACF,oBAAC,aAAD,EAAmB,MAAQ,CAAA;GAC1B,SACC,oBAAC,OAAD;IAAO,SAAS,MAAM;IAAa,UAAU,YAAY;IAAa;cACnE;IACK,CAAA;GAEA;;EAEd"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedControl-D_DA-MU1.mjs","names":[],"sources":["../src/components/SegmentedControl/SegmentedControl.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n type Key,\n type ReactNode,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\nimport { ToggleButton, ToggleButtonGroup, type ToggleButtonProps } from 'react-aria-components';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Spacing } from '@persona/design-tokens';\n\nimport useFormField from '#src/components/FormControl/useFormField';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\n\nconst SegmentedControlSizeContext = createContext<'sm' | 'md'>('md');\n\nexport interface SegmentedControlProps {\n id?: string;\n className?: string;\n\n /**\n * Current selected key (controlled)\n */\n selectedKey?: Key;\n\n /**\n * Default selected key (uncontrolled)\n */\n defaultSelectedKey?: Key;\n\n /**\n * Callback when selection changes\n */\n onSelectionChange?: (key: Key) => void;\n\n /**\n * Whether the entire component is disabled\n */\n disabled?: boolean;\n\n /**\n * Whether the component should take full width\n */\n fullWidth?: boolean;\n\n /**\n * Size of the segmented control\n */\n size?: 'sm' | 'md';\n\n /**\n * Accessible label for the group\n */\n 'aria-label'?: string;\n 'aria-required'?: boolean;\n\n /**\n * Segment components\n */\n children: ReactNode;\n}\n\ninterface StyledSegmentedControlProps {\n id?: string;\n $fullWidth?: boolean;\n $size?: 'sm' | 'md';\n}\n\nconst StyledSegmentedControl = styled(ToggleButtonGroup)<StyledSegmentedControlProps>`\n display: inline-flex;\n background-color: ${({ theme }) =>\n semanticColor(theme, 'ActionNeutral', theme.color.variants.basic.default)};\n border-radius: 5px;\n padding: 1px;\n width: ${({ $fullWidth }) => ($fullWidth ? '100%' : 'auto')};\n height: ${({ $size = 'md' }) => ($size === 'sm' ? '20px' : '24px')};\n`;\n\n/**\n * A segmented control component that allows users to select between multiple options.\n * Built with React Aria for accessibility and keyboard navigation.\n */\nexport const SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControl(\n {\n id,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n disabled,\n fullWidth = false,\n size = 'md',\n className,\n 'aria-label': ariaLabel,\n 'aria-required': ariaRequired,\n children,\n ...props\n },\n ref,\n ) {\n const field = useFormField({ inputId: id, disabled });\n const segmentedControlRef = useRef<HTMLDivElement>(null);\n const isRequired = ariaRequired;\n\n useImperativeHandle(ref, () => segmentedControlRef.current!, []);\n // react-aria-components filters aria-required from DOM props, so it is applied imperatively.\n useEffect(() => {\n if (isRequired) {\n segmentedControlRef.current?.setAttribute('aria-required', 'true');\n } else {\n segmentedControlRef.current?.removeAttribute('aria-required');\n }\n }, [isRequired]);\n\n return (\n <SegmentedControlSizeContext.Provider value={size}>\n <StyledSegmentedControl\n ref={segmentedControlRef}\n className={className}\n selectionMode='single'\n selectedKeys={selectedKey ? [selectedKey] : undefined}\n defaultSelectedKeys={defaultSelectedKey ? [defaultSelectedKey] : undefined}\n onSelectionChange={(keys) => {\n const key = Array.from(keys)[0];\n if (key && onSelectionChange) {\n onSelectionChange(key);\n }\n }}\n isDisabled={field.disabled}\n aria-label={ariaLabel}\n aria-labelledby={field.labelId}\n aria-describedby={field.helperTextId}\n aria-errormessage={field.hasError ? field.helperTextId : undefined}\n aria-invalid={field.hasError}\n $fullWidth={fullWidth}\n $size={size}\n {...props}\n id={field.inputId}\n >\n {children}\n </StyledSegmentedControl>\n </SegmentedControlSizeContext.Provider>\n );\n },\n);\n\nconst StyledSegment = styled(ToggleButton)<{ $size?: 'sm' | 'md' }>`\n ${paragraphMixins.sm};\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: transparent;\n border: none;\n border-radius: ${BorderRadius.Md};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.secondary)};\n cursor: pointer;\n flex: 1;\n line-height: 1;\n\n & * {\n cursor: inherit;\n }\n padding: 0 ${({ $size = 'md' }) => ($size === 'sm' ? Spacing[1] : Spacing[2])};\n position: relative;\n transition: all 0.15s ease-in-out;\n white-space: nowrap;\n\n /* Hover state */\n &[data-hovered] {\n background-color: ${({ theme }) => semanticColor(theme, 'ActionNeutralHover', theme.color.variants.basic.hover)};\n }\n\n /* Selected state */\n &[data-selected] {\n background-color: ${({ theme }) => semanticColor(theme, 'SurfacePrimary', theme.color.primary.white)};\n box-shadow: inset 0 0 0 1px ${({ theme }) => semanticColor(theme, 'BorderDefault', theme.color.border.input)};\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n }\n\n /* Disabled state */\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n /* Remove focus outline unless we're using a keyboard */\n &[data-focused]:not([data-focus-visible]) {\n outline: none;\n }\n`;\n\nexport interface SegmentedControlItemProps extends Omit<\n ToggleButtonProps,\n 'isDisabled' | 'style' | 'isSelected' | 'defaultSelected'\n> {\n /**\n * Whether this control item is disabled\n */\n disabled?: boolean;\n}\n\n/**\n * A segment item component for use within SegmentedControl.\n */\nconst SegmentedControlItem = forwardRef<HTMLButtonElement, SegmentedControlItemProps>(\n function SegmentedControlItem({ disabled, children, ...props }, ref) {\n const size = useContext(SegmentedControlSizeContext);\n return (\n <StyledSegment ref={ref} isDisabled={disabled} $size={size} {...props}>\n {children}\n </StyledSegment>\n );\n },\n);\n\nexport default SegmentedControl;\nexport { SegmentedControlItem };\n"],"mappings":";;;;;;;;;AAmBA,MAAM,8BAA8B,cAA2B,KAAK;AAsDpE,MAAM,yBAAyB,OAAO,kBAAkB;;uBAEjC,EAAE,YACrB,cAAc,OAAO,iBAAiB,MAAM,MAAM,SAAS,MAAM,QAAQ,CAAC;;;YAGlE,EAAE,iBAAkB,aAAa,SAAS,OAAQ;aACjD,EAAE,QAAQ,WAAY,UAAU,OAAO,SAAS,OAAQ;;;;;;AAOrE,MAAa,mBAAmB,WAC9B,SAAS,iBACP,EACE,IACA,aACA,oBACA,mBACA,UACA,YAAY,OACZ,OAAO,MACP,WACA,cAAc,WACd,iBAAiB,cACjB,UACA,GAAG,SAEL,KACA;CACA,MAAM,QAAQ,aAAa;EAAE,SAAS;EAAI;EAAU,CAAC;CACrD,MAAM,sBAAsB,OAAuB,KAAK;CACxD,MAAM,aAAa;AAEnB,qBAAoB,WAAW,oBAAoB,SAAU,EAAE,CAAC;AAEhE,iBAAgB;AACd,MAAI,WACF,qBAAoB,SAAS,aAAa,iBAAiB,OAAO;MAElE,qBAAoB,SAAS,gBAAgB,gBAAgB;IAE9D,CAAC,WAAW,CAAC;AAEhB,QACE,oBAAC,4BAA4B,UAA7B;EAAsC,OAAO;YAC3C,oBAAC,wBAAD;GACE,KAAK;GACM;GACX,eAAc;GACd,cAAc,cAAc,CAAC,YAAY,GAAG,KAAA;GAC5C,qBAAqB,qBAAqB,CAAC,mBAAmB,GAAG,KAAA;GACjE,oBAAoB,SAAS;IAC3B,MAAM,MAAM,MAAM,KAAK,KAAK,CAAC;AAC7B,QAAI,OAAO,kBACT,mBAAkB,IAAI;;GAG1B,YAAY,MAAM;GAClB,cAAY;GACZ,mBAAiB,MAAM;GACvB,oBAAkB,MAAM;GACxB,qBAAmB,MAAM,WAAW,MAAM,eAAe,KAAA;GACzD,gBAAc,MAAM;GACpB,YAAY;GACZ,OAAO;GACP,GAAI;GACJ,IAAI,MAAM;GAET;GACsB,CAAA;EACY,CAAA;EAG5C;AAED,MAAM,gBAAgB,OAAO,aAAa;IACtC,gBAAgB,GAAG;;;;;;mBAMJ,aAAa,GAAG;YACvB,EAAE,YAAY,cAAc,OAAO,eAAe,MAAM,MAAM,KAAK,UAAU,CAAC;;;;;;;;gBAQ1E,EAAE,QAAQ,WAAY,UAAU,OAAO,QAAQ,KAAK,QAAQ,GAAI;;;;;;;yBAOvD,EAAE,YAAY,cAAc,OAAO,sBAAsB,MAAM,MAAM,SAAS,MAAM,MAAM,CAAC;;;;;yBAK3F,EAAE,YAAY,cAAc,OAAO,kBAAkB,MAAM,MAAM,QAAQ,MAAM,CAAC;mCACtE,EAAE,YAAY,cAAc,OAAO,iBAAiB,MAAM,MAAM,OAAO,MAAM,CAAC;cACnG,EAAE,YAAY,cAAc,OAAO,aAAa,MAAM,MAAM,KAAK,QAAQ,CAAC;;;;;;;;;;;;;;;;;AA4BxF,MAAM,uBAAuB,WAC3B,SAAS,qBAAqB,EAAE,UAAU,UAAU,GAAG,SAAS,KAAK;AAEnE,QACE,oBAAC,eAAD;EAAoB;EAAK,YAAY;EAAU,OAFpC,WAAW,4BAEoC;EAAE,GAAI;EAC7D;EACa,CAAA;EAGrB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Select-DOlw_LPR.mjs","names":["DropdownMenu"],"sources":["../src/components/Select/Select.tsx"],"sourcesContent":["import * as SelectPrimitive from '@radix-ui/react-select';\nimport type { Property } from 'csstype';\nimport { forwardRef, type ReactNode } from 'react';\nimport { useId } from 'react-aria';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { CaretDownIcon, MoreIcon } from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport useFormField from '#src/components/FormControl/useFormField';\nimport Menu, {\n MenuHeading,\n MenuItem,\n type MenuItemProps,\n MenuList,\n type MenuProps,\n} from '#src/components/Menu';\nimport { HStack } from '#src/components/Stack';\nimport { Paragraph } from '#src/components/Text';\nimport { isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport inputMixin, { type InputMixinProps, type InputSizes } from '#src/mixins/input';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\nimport { paragraphMixins } from '#src/mixins/text';\n\nexport interface SelectProps extends InputMixinProps, Omit<SelectPrimitive.SelectProps, 'value'> {\n 'aria-label'?: string;\n placeholder?: string;\n\n /**\n * id will be applied to trigger\n */\n id?: string;\n\n /**\n * Class name will be applied to trigger\n */\n className?: string;\n\n /**\n * Max height of options menu\n */\n maxHeight?: number;\n\n /**\n * Min width of the select\n */\n minWidth?: number;\n\n /**\n * Width of the selected value container\n */\n valueContainerWidth?: 'auto' | '100%';\n\n /**\n * Render dropdown menu in a portal.\n */\n portal?: boolean;\n\n /**\n * Element the portalled menu renders into. Defaults to `document.body`. Pass a container inside\n * the current dialog so the menu escapes clipping ancestors without leaving the dialog's\n * dismiss scope, which would close it on click. Requires `portal`.\n */\n portalContainer?: HTMLElement | null;\n\n /**\n * Props to apply to Radix Select.Trigger within\n */\n triggerProps?: SelectPrimitive.SelectTriggerProps;\n\n /**\n * Props to apply to Radix Select.Content within\n */\n contentProps?: SelectPrimitive.SelectContentProps;\n\n /**\n * Callback meant for use with `react-hook-form`'s `useForm` (or Persona's `useFormSecurely`)\n */\n onChange?: (event: { target: { value: string } }) => void;\n\n size?: InputSizes;\n\n value?: string | null;\n\n width?: string;\n\n header?: ReactNode;\n\n footer?: ReactNode;\n\n /**\n * z-index of content. Please use sparingly.\n */\n zIndex?: Property.ZIndex;\n}\n\ninterface SelectButtonProps extends InputMixinProps {\n isSelectingPlaceholder: boolean;\n $width?: string;\n $minWidth?: number;\n}\n\nconst SelectButton = styled('button')<SelectButtonProps>`\n ${inputMixin};\n display: inline-flex;\n position: relative;\n align-items: center;\n outline: none;\n appearance: none;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n padding-right: ${Spacing[6]};\n width: ${({ $width }) => $width ?? '100%'};\n min-width: ${({ $minWidth }) => ($minWidth != null ? `${$minWidth}px` : 'auto')};\n\n &${isNotDisabled} {\n cursor: pointer;\n }\n\n ${({ theme, isSelectingPlaceholder, disabled }) =>\n isSelectingPlaceholder &&\n !disabled &&\n css`\n color: ${semanticColor(theme, 'FgSecondary', theme.color.text.secondary)};\n `}\n`;\n\ninterface SelectValueContainerProps {\n width?: string;\n}\n\nconst SelectValueContainer = styled.span<SelectValueContainerProps>`\n text-overflow: ellipsis;\n min-width: 0px;\n overflow: hidden;\n text-align: start;\n\n ${({ width }) =>\n width &&\n css`\n width: ${width};\n `}\n`;\n\nconst OptionSubtitle = styled.div`\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.secondary)};\n font-size: ${({ theme }) => theme.text.paragraph.sm.fontSize};\n margin-top: ${Spacing[1]};\n`;\n\ninterface OptionsMenuProps {\n maxHeight?: number;\n size?: InputSizes;\n}\n\nconst OptionsMenu = styled(Menu)<OptionsMenuProps>`\n width: var(--radix-select-trigger-width);\n max-height: ${({ maxHeight }) => maxHeight ?? '225px !important'};\n overflow-y: auto;\n ${semanticScrollbar}\n margin-bottom: 0;\n\n ${({ size }) => {\n switch (size) {\n case 'md': {\n return css`\n ${MenuList} {\n padding: ${Spacing[2]};\n }\n\n ${OptionItem} {\n ${paragraphMixins.md};\n padding: ${Spacing[2]};\n }\n\n ${MenuHeading} {\n padding: ${Spacing[2]};\n }\n `;\n }\n case 'sm': {\n return css`\n ${MenuList} {\n padding: ${Spacing[1]};\n }\n\n ${OptionItem} {\n ${paragraphMixins.sm};\n padding: ${Spacing[1]};\n }\n\n ${MenuHeading} {\n padding: ${Spacing[1]};\n }\n `;\n }\n }\n }}\n`;\n\nconst SelectContent = styled(SelectPrimitive.Content)<{ $zIndex?: number | string }>`\n z-index: ${({ $zIndex }) => $zIndex || Z_INDICES.dropdown};\n`;\n\nconst SelectHeaderContainer = styled(HStack)`\n display: flex;\n justify-content: space-between;\n padding: ${Spacing[1]} ${Spacing[1]} 0 ${Spacing[1]};\n margin-bottom: ${Spacing[1]};\n`;\n\nconst SelectFooter = styled.div`\n padding: ${Spacing[1]} 0;\n margin-top: ${Spacing[1]};\n border-top: 1px solid ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n`;\n\nconst SelectMenu = forwardRef<HTMLUListElement, MenuProps & OptionsMenuProps>(function SelectMenu(\n props: MenuProps,\n forwardedRef,\n) {\n return <OptionsMenu listRef={forwardedRef} {...props} />;\n});\n\nconst OptionItem = styled(MenuItem)`\n ${paragraphMixins.md};\n padding: ${Spacing[4]};\n`;\n\nconst SelectItem = forwardRef<HTMLDivElement, MenuItemProps>(function SelectItem(\n props: MenuItemProps,\n forwardedRef,\n) {\n return <OptionItem ref={forwardedRef} {...props} />;\n});\n\nconst StyledIconContainer = styled(SelectPrimitive.Icon)<{ disabled?: boolean }>`\n position: absolute;\n right: ${Spacing[2]};\n display: flex;\n justify-content: center;\n\n ${({ theme, disabled }) => css`\n color: ${\n disabled\n ? semanticColor(theme, 'FgDisabled', Color.BorderIconDisabled)\n : semanticColor(theme, 'FgPrimary', Color.BorderIconPrimary)\n };\n `}\n`;\n\ninterface SelectHeaderProps {\n title?: ReactNode;\n menuItems?: ReactNode;\n menuTriggerLabel?: string;\n}\n\nexport const SelectHeader = ({ title, menuItems, menuTriggerLabel }: SelectHeaderProps) => {\n const uniqueId = useId();\n\n return (\n <SelectHeaderContainer align='center'>\n {title && (\n <Paragraph color='primary' weight='bold' size='md'>\n {title}\n </Paragraph>\n )}\n {menuItems && (\n <DropdownMenu\n portal={true}\n trigger={\n <IconButton>\n <MoreIcon />\n </IconButton>\n }\n triggerProps={{\n 'aria-label': menuTriggerLabel,\n id: `select-header-menu-trigger-${uniqueId}`,\n }}\n side='right'\n align='start'\n zIndex={Z_INDICES.layeredDropdown}\n contentProps={{\n // Fix for Radix UI 2.1.15 upgrade breaking changes:\n // 1. Portal rendering causes pointer-events issues preventing dropdown interaction\n // 2. Portal timing causes onFocusOutside to fire immediately, closing dropdown\n style: {\n pointerEvents: 'auto', // Ensure dropdown items receive mouse events\n },\n onFocusOutside: (event) => event.preventDefault(), // Prevent immediate portal closing\n }}\n >\n {menuItems}\n </DropdownMenu>\n )}\n </SelectHeaderContainer>\n );\n};\n\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n { portal = false, portalContainer, size = 'md', ...props }: SelectProps,\n forwardedRef,\n) {\n const {\n 'aria-label': ariaLabel,\n hasError,\n hasWarning,\n focused,\n active,\n hovered,\n disabled,\n placeholder,\n maxHeight,\n children,\n triggerProps,\n contentProps,\n id,\n className,\n onChange,\n onValueChange,\n value,\n width,\n header,\n footer,\n minWidth,\n valueContainerWidth,\n zIndex,\n } = props;\n\n const field = useFormField({ inputId: props.id, disabled, hasWarning, hasError });\n\n const content = (\n <SelectContent\n position='popper'\n side='bottom'\n sideOffset={8}\n $zIndex={zIndex}\n {...contentProps}\n >\n <SelectMenu maxHeight={maxHeight} size={size}>\n {header}\n <SelectPrimitive.Viewport>{children}</SelectPrimitive.Viewport>\n {footer && (\n <>\n <SelectFooter>{footer}</SelectFooter>\n </>\n )}\n </SelectMenu>\n </SelectContent>\n );\n\n return (\n <SelectPrimitive.Root\n {...props}\n onValueChange={(value) => {\n onChange?.({ target: { value } });\n onValueChange?.(value);\n }}\n // Custom behavior to consider null as empty value\n value={value === null ? '' : value}\n >\n <SelectPrimitive.Trigger\n ref={forwardedRef}\n asChild\n id={id}\n className={className}\n disabled={field.disabled}\n aria-describedby={field.helperTextId}\n aria-errormessage={field.hasError ? field.helperTextId : undefined}\n aria-invalid={field.hasError}\n aria-label={ariaLabel}\n {...triggerProps}\n >\n <SelectButton\n hasWarning={field.hasWarning}\n hasError={field.hasError}\n hovered={hovered}\n focused={focused}\n active={active}\n disabled={field.disabled}\n placeholder={placeholder}\n isSelectingPlaceholder={props.value === '' || props.value == null}\n $minWidth={minWidth}\n $size={size}\n $width={width}\n >\n <SelectValueContainer width={valueContainerWidth}>\n <SelectPrimitive.Value placeholder={placeholder} />\n </SelectValueContainer>\n <StyledIconContainer disabled={field.disabled}>\n <CaretDownIcon />\n </StyledIconContainer>\n </SelectButton>\n </SelectPrimitive.Trigger>\n {portal ? (\n <SelectPrimitive.Portal container={portalContainer}>{content}</SelectPrimitive.Portal>\n ) : (\n content\n )}\n </SelectPrimitive.Root>\n );\n});\n\nexport default Select;\n\nexport const Option = forwardRef<HTMLDivElement, SelectPrimitive.SelectItemProps & MenuItemProps>(\n function Option({ children, subtitle, ...props }, forwardedRef) {\n return (\n <SelectPrimitive.Item {...props} ref={forwardedRef} asChild>\n <SelectItem {...props}>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n {subtitle && <OptionSubtitle>{subtitle}</OptionSubtitle>}\n </SelectItem>\n </SelectPrimitive.Item>\n );\n },\n);\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TabBar-BCFO38E0.mjs","names":["TabBarContext","TabBarContext"],"sources":["../src/components/TabBar/TabBarContext.ts","../src/components/TabBar/TabBar.tsx","../src/components/TabBar/Tab.tsx","../src/components/TabBar/TabBarIconButton.tsx"],"sourcesContent":["import { createContext } from 'react';\n\nexport default createContext<{ maxTabChars?: number; size?: 'md' | 'sm' }>({});\n","import { mergeRefs } from '@react-aria/utils';\nimport {\n type ComponentPropsWithoutRef,\n type ForwardedRef,\n forwardRef,\n type KeyboardEventHandler,\n type ReactNode,\n useRef,\n} from 'react';\nimport styled from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport TabBarContext from '#src/components/TabBar/TabBarContext';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\n\nconst TabBarContainer = styled.div`\n display: flex;\n height: ${Spacing[6]};\n position: relative;\n box-sizing: border-box;\n border-bottom: 1px solid\n ${({ theme }) => semanticColor(theme, 'BorderSubtle', Color.BorderDivider)};\n justify-content: space-between;\n gap: ${Spacing[4]};\n`;\n\nconst RightActions = styled.div`\n align-self: center;\n`;\n\nconst TitleTab = styled.div`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n ${paragraphMixins.mdBold};\n`;\n\nconst StyledTabContainer = styled.div<{ $size?: 'md' | 'sm' }>`\n display: flex;\n gap: ${({ $size = 'md' }) => ($size === 'sm' ? Spacing[3] : Spacing[4])};\n // These two lines prevent the overflow hidden from hiding the bottom border of the selected tab\n margin-bottom: -2px;\n padding-bottom: 2px;\n overflow: hidden;\n flex-wrap: wrap;\n`;\n\ninterface TabContainerProps extends ComponentPropsWithoutRef<'div'> {\n children: ReactNode;\n /**\n * Truncate tab text to the specified number of characters.\n */\n maxTabChars?: number;\n /**\n * Size of the tabs. Affects font size.\n */\n size?: 'md' | 'sm';\n}\n\nexport const TabContainer = forwardRef<HTMLDivElement, TabContainerProps>(function TabContainer(\n { children, maxTabChars, size, ...props },\n forwardedRef,\n) {\n const tabListRef = useRef<HTMLDivElement>(null);\n\n const getIndexOfCurrentTab = (list: Element[]) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return getIndex(list, document.activeElement);\n };\n\n const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (e) => {\n // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n const list = getTabList(tabListRef.current.children);\n\n if (document.activeElement && !list.includes(document.activeElement)) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft': {\n // Go to previous tab\n const curIndex = getIndexOfCurrentTab(list);\n const nextIndex = curIndex === 0 ? list.length - 1 : curIndex - 1;\n (list[nextIndex] as HTMLElement).focus();\n break;\n }\n case 'ArrowRight': {\n // Go to next tab\n const curIndex = getIndexOfCurrentTab(list);\n (list[(curIndex + 1) % list.length] as HTMLElement).focus();\n break;\n }\n case 'Home': {\n // Go to first tab\n (list[0] as HTMLElement).focus();\n break;\n }\n case 'End': {\n // Go to last tab\n (list[list.length - 1] as HTMLElement).focus();\n break;\n }\n default:\n break;\n }\n };\n\n return (\n <TabBarContext.Provider value={{ maxTabChars, size }}>\n <StyledTabContainer\n role='tablist'\n ref={mergeRefs<HTMLDivElement>(tabListRef, forwardedRef)}\n onKeyDown={handleKeyDown}\n $size={size}\n {...props}\n >\n {children}\n </StyledTabContainer>\n </TabBarContext.Provider>\n );\n});\n\nconst getIndex = (children: Element[], element: Element) => {\n return children.indexOf(element);\n};\n\n// A `data-tab-slot` child that wraps its tab (e.g. the tab plus a sibling button) navigates to the tab.\nconst getTabList = (list: HTMLCollection) =>\n Array.from(list)\n .map((element) =>\n element.hasAttribute('data-tab-slot')\n ? (element.querySelector('[role=\"tab\"]') ?? element)\n : element,\n )\n .filter(\n (element) => !(element.getAttribute('aria-disabled') || element.getAttribute('disabled')),\n );\n\nexport interface TabBarProps extends ComponentPropsWithoutRef<'div'> {\n actions?: ReactNode;\n title?: string;\n 'data-tour-target'?: string;\n /**\n * Truncate tab text to the specified number of characters.\n */\n maxTabChars?: number;\n /**\n * Size of the tabs. Affects font size.\n */\n size?: 'md' | 'sm';\n}\n\nexport const TabBar = forwardRef<HTMLDivElement, TabBarProps>(function TabBar(\n {\n children,\n actions,\n title,\n 'data-tour-target': dataTourTarget,\n maxTabChars,\n size,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...elemProps\n },\n forwardedRef: ForwardedRef<HTMLDivElement>,\n) {\n return (\n <TabBarContainer {...elemProps}>\n <TabContainer\n ref={forwardedRef}\n maxTabChars={maxTabChars}\n size={size}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {title && <TitleTab data-tour-target={dataTourTarget}>{title}</TitleTab>}\n {children}\n </TabContainer>\n {actions && <RightActions>{actions}</RightActions>}\n </TabBarContainer>\n );\n});\n\nexport default TabBar;\n","import {\n cloneElement,\n type ComponentPropsWithoutRef,\n type ElementType,\n type ReactElement,\n useContext,\n} from 'react';\nimport styled, {\n css,\n type DefaultTheme,\n type FlattenInterpolation,\n type ThemeProps,\n} from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport Badge from '#src/components/Badge';\nimport Button from '#src/components/Button';\nimport TabBarContext from '#src/components/TabBar/TabBarContext';\nimport { isActive, isFocused, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { TransitionDuration } from '#src/variables/transitions';\n\n/** A tab carries either a count or a label beside its text, never both. */\ntype TabAdornment =\n | { badge?: ReactElement; sticker?: never }\n | { badge?: never; sticker?: ReactElement };\n\ninterface TabBaseProps<T extends ElementType = 'button'> extends ComponentPropsWithoutRef<\n typeof Button\n> {\n selected?: boolean;\n as?: T;\n size?: 'md' | 'sm';\n}\n\ntype TabProps<T extends ElementType = 'button'> = TabBaseProps<T> & TabAdornment;\n\nconst AdornmentContainer = styled.span`\n display: inline-flex;\n vertical-align: middle;\n /* Align the atomic badge with the label's cap midpoint, not its x-height midpoint. */\n transform: translateY(calc((1ex - 1cap) / 2));\n padding: 0;\n margin-left: ${Spacing[1]};\n`;\n\nconst sizeStyles: Record<\n NonNullable<TabBaseProps['size']>,\n FlattenInterpolation<ThemeProps<DefaultTheme>>\n> = {\n md: css`\n ${paragraphMixins.md}\n `,\n sm: css`\n ${paragraphMixins.sm}\n `,\n};\n\nconst tabSelectedStyle = css`\n color: ${({ theme }) => semanticColor(theme, 'FgAccent', theme.color.primary.brand)};\n border-bottom-color: ${({ theme }) => semanticColor(theme, 'BorderAccent', theme.color.primary.brand)};\n box-shadow: none;\n &:after {\n transition: border-bottom-color ${TransitionDuration.Fast};\n border-bottom-color: ${({ theme }) => semanticColor(theme, 'BorderAccent', theme.color.primary.brand)};\n }\n`;\n\nexport const StyledTab = styled(Button).attrs<TabBaseProps>({\n width: 'auto',\n variant: 'basic',\n})<TabBaseProps>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n white-space: nowrap;\n background-color: transparent;\n color: ${({ theme, disabled }) =>\n disabled\n ? semanticColor(theme, 'FgDisabled', theme.color.variants.basic.textDisabled)\n : semanticColor(theme, 'FgSecondary', theme.color.text.tertiary)};\n transition: color ${TransitionDuration.Fast} ease-out;\n height: 32px;\n margin: 0;\n padding: 0;\n ${({ size }) => sizeStyles[size || 'md']};\n outline: none;\n border-radius: ${({ theme }) => theme.button.borderRadius};\n\n a {\n color: currentColor;\n }\n\n /* remove default button focused/hovered box shadow */\n &${isActive}${isNotDisabled} {\n background-color: unset;\n }\n &${isHovered}${isNotDisabled} {\n background-color: unset;\n ${({ selected, theme }) =>\n !selected &&\n css`\n color: ${semanticColor(theme, 'FgPrimary', Color.TextPrimary)};\n `}\n }\n &${isFocused}${isNotDisabled} {\n box-shadow: none;\n background-color: unset;\n }\n &${isHovered}${isFocused}${isNotDisabled} {\n background-color: unset;\n }\n &:disabled {\n background-color: unset;\n }\n\n &:after {\n position: absolute;\n bottom: 0px;\n width: 100%;\n border-bottom: 1px solid transparent;\n content: '';\n }\n\n &.selected,\n &.active {\n ${tabSelectedStyle}\n }\n\n ${({ selected }) => selected && tabSelectedStyle}\n\n ${({ disabled }) =>\n disabled &&\n css`\n cursor: default;\n `}\n\n a& {\n text-decoration: none;\n }\n`;\n\n/**\n * Helper function to truncate text if it exceeds maxCharacters\n */\nconst truncateText = (text: string, maxCharacters: number): string => {\n if (text.length <= maxCharacters) {\n return text;\n }\n return `${text.substring(0, maxCharacters).trimEnd()}...`;\n};\n\nconst Tab = <T extends ElementType = 'button'>({\n selected,\n disabled,\n children,\n badge,\n sticker,\n as,\n size,\n ...elemProps\n}: TabProps<T> & ComponentPropsWithoutRef<T>) => {\n const { maxTabChars, size: contextSize } = useContext(TabBarContext);\n const finalSize = size || contextSize || 'md';\n\n // Truncate text if maxTabChars is provided and children is a string\n const hasTruncation = maxTabChars && typeof children === 'string';\n const displayChildren = hasTruncation ? truncateText(children, maxTabChars) : children;\n\n return (\n <StyledTab\n role='tab'\n selected={selected}\n aria-selected={selected}\n aria-disabled={disabled}\n disabled={disabled}\n as={as as ElementType}\n size={finalSize}\n title={hasTruncation ? children : undefined}\n {...elemProps}\n >\n {displayChildren}\n {badge && (\n <AdornmentContainer>\n {badge.type === Badge\n ? cloneElement(badge, {\n variant: selected ? 'active' : 'basic',\n })\n : badge}\n </AdornmentContainer>\n )}\n {sticker && <AdornmentContainer>{sticker}</AdornmentContainer>}\n </StyledTab>\n );\n};\n\nexport default Tab;\n","import styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\n\nimport { IconButton } from '#src/components/Button';\nimport { isActive, isFocused, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor } from '#src/lib/semanticColor';\n\nexport default styled(IconButton).attrs({\n size: 'sm',\n})`\n padding-left: ${Spacing[2]};\n padding-right: ${Spacing[2]};\n border-radius: ${BorderRadius.Sm};\n\n // remove default button focused/hovered box shadow\n &${isActive}${isNotDisabled} {\n background-color: transparent;\n }\n &${isHovered}${isNotDisabled} {\n box-shadow: none;\n }\n &${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n &${isHovered}${isFocused}${isNotDisabled} {\n box-shadow: none;\n }\n &:disabled {\n background-color: transparent;\n }\n &:focus-visible${isNotDisabled}, &${isHovered}${isNotDisabled}:focus-visible {\n box-shadow: 0 0 0 3px ${({ theme }) => semanticColor(theme, 'ActionNeutralActive', theme.color.variants.basic.highlight)};\n }\n\n svg {\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', Color.CoreSlate800)};\n }\n\n &:hover {\n svg {\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', Color.CoreSlate900)};\n }\n }\n`;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Table-DPi4Dt5H.mjs","names":["slideKeyframes"],"sources":["../src/components/Table/Table.tsx","../src/components/Table/TableHeaderCell.tsx","../src/components/Table/TableRow.tsx","../src/components/Table/TableTH.tsx","../src/components/Table/TableCell.tsx","../src/components/Table/TableHead.tsx","../src/components/Table/TableBody.tsx","../src/components/Table/TableLayout.tsx"],"sourcesContent":["import styled, { css, keyframes } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\n\ninterface TableProps {\n size?: 'sm' | 'md';\n isLoading?: boolean;\n}\n\nconst slideKeyframes = keyframes`\n 0% {\n transform: translateX(-50%) scaleX(0);\n }\n 50% {\n transform: translateX(0) scaleX(1);\n }\n 100% {\n transform: translateX(50%) scaleX(0);\n }\n`;\n\nexport const Table = styled.table.attrs({ role: 'table' })<TableProps>`\n display: table;\n width: 100%;\n border-spacing: 0;\n ${paragraphMixins.md};\n\n ${({ size }) =>\n size === 'sm' &&\n css`\n td,\n th {\n padding: ${Spacing[2]};\n }\n `}\n\n ${({ isLoading }) =>\n isLoading &&\n css`\n thead {\n &:after {\n content: '';\n display: block;\n position: absolute;\n bottom: 0;\n left: 0;\n width: 100%;\n border-bottom: 3px solid ${({ theme }) => semanticColor(theme, 'FeedbackAccent3', theme.color.primary.brand)};\n animation: ${slideKeyframes} 3s infinite cubic-bezier(0.5, 0, 0.5, 1);\n }\n }\n `}\n`;\n\nexport default Table;\n","import { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\nimport { CaretDownIcon, CaretUpIcon } from '@persona/icons';\n\nimport { semanticColor, semanticOnly } from '#src/lib/semanticColor';\nimport { focusOutline } from '#src/mixins/focus';\nimport { paragraphMixins } from '#src/mixins/text';\nimport { BASE } from '#src/variables/spacing';\n\ninterface TableHeaderCellProps {\n size?: 'sm' | 'md';\n sortable?: boolean;\n width?: 'auto' | 'min' | 'max' | string;\n isSticky?: boolean;\n align?: 'left' | 'right';\n trailing?: ReactNode;\n}\n\nconst StyledTableHeaderCell = styled.th<TableHeaderCellProps>`\n display: table-cell;\n /* Self-contained box model: don't depend on a consumer's global\n border-box reset, so header padding + border are included in the\n declared width/height. */\n box-sizing: border-box;\n\n background-color: ${({ theme }) => semanticColor(theme, 'SurfaceSecondary', theme.color.background.secondary)};\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n padding: ${({ size }) => (size === 'sm' ? BASE : BASE * 1.5)}px;\n text-align: left;\n white-space: nowrap;\n ${({ size }) => (size === 'sm' ? paragraphMixins.sm : paragraphMixins.md)};\n line-height: 1;\n width: ${({ width }) => {\n switch (width) {\n case 'min':\n return '1px';\n case 'max':\n return '100%';\n default:\n if (width) {\n return width;\n } else {\n return 'auto';\n }\n }\n }};\n\n &:first-child {\n border-radius: ${({ theme }) =>\n `${theme.element.borderRadius} 0 0 ${theme.element.borderRadius}`};\n }\n\n &:last-child {\n border-radius: ${({ theme }) =>\n `0 ${theme.element.borderRadius} ${theme.element.borderRadius} 0`};\n }\n\n ${({ sortable }) =>\n sortable &&\n css`\n cursor: pointer;\n\n &:hover ${TableIconContainer} {\n display: inline;\n visibility: visible;\n }\n\n ${SortButton}:focus-visible ${TableIconContainer} {\n display: inline;\n visibility: visible;\n }\n `};\n\n ${({ isSticky }) =>\n isSticky\n ? css`\n position: sticky;\n top: 0;\n z-index: 1;\n `\n : css`\n position: relative;\n `}\n`;\n\nconst VerticalAlign = styled.div<{ $align?: TableHeaderCellProps['align'] }>`\n display: flex;\n align-items: center;\n gap: ${Spacing[1]};\n flex-direction: ${({ $align }) => ($align === 'right' ? 'row-reverse' : 'row')};\n`;\n\nconst SortButton = styled.button`\n background: none;\n border: 0;\n padding: 0;\n margin: 0;\n font: inherit;\n color: inherit;\n text-align: inherit;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: ${Spacing[1]};\n min-width: 0;\n ${focusOutline}\n`;\n\ninterface TableIconContainerProps {\n sortDirection?: 'asc' | 'desc' | false;\n}\n\nconst TableIconContainer = styled('div')<TableIconContainerProps>`\n display: inline-block;\n\n ${({ sortDirection }) => {\n if (sortDirection) {\n return css`\n display: inline;\n `;\n } else {\n return css`\n display: inline;\n visibility: hidden;\n color: ${({ theme }) => semanticColor(theme, 'FgTertiary', theme.color.text.disabled)};\n `;\n }\n }};\n`;\n\nconst TableHeaderCell = forwardRef<\n HTMLTableCellElement,\n ComponentPropsWithoutRef<'th'> & TableHeaderCellProps & TableIconContainerProps\n>(function TableHeaderCell(\n { sortable, sortDirection, children, align, trailing, onClick, ...elemProps },\n ref,\n) {\n let ariaSort: 'none' | 'ascending' | 'descending' | undefined;\n\n if (sortable && sortDirection) {\n ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending';\n } else if (sortable) {\n ariaSort = 'none';\n }\n\n return (\n <StyledTableHeaderCell\n sortable={sortable}\n aria-sort={ariaSort}\n onClick={sortable ? undefined : onClick}\n {...elemProps}\n ref={ref}\n >\n <VerticalAlign $align={align}>\n {sortable ? (\n <SortButton type='button' onClick={onClick}>\n {children}\n <TableIconContainer aria-hidden='true' sortDirection={sortDirection}>\n {sortDirection === 'asc' ? <CaretUpIcon /> : <CaretDownIcon />}\n </TableIconContainer>\n </SortButton>\n ) : (\n children\n )}\n {trailing}\n </VerticalAlign>\n </StyledTableHeaderCell>\n );\n});\n\nexport default TableHeaderCell;\n","import styled, { css } from 'styled-components';\n\nimport { withAlpha } from '#src/lib/color';\nimport { isFocusedVisible, isHovered } from '#src/lib/pseudoClass';\nimport { semanticTokens } from '#src/lib/semanticColor';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nexport interface TableRowProps extends PseudoClassProps {\n disableHoverBackground?: boolean;\n}\n\nconst TableRow = styled.tr.attrs({\n role: 'row',\n})<TableRowProps>`\n display: table-row;\n\n ${({ onClick }) =>\n onClick != null &&\n css`\n cursor: pointer;\n `}\n\n ${({ disableHoverBackground, theme }) => {\n if (disableHoverBackground) {\n return null;\n }\n const tokens = semanticTokens(theme);\n return css`\n &${isHovered} {\n background-color: ${\n tokens\n ? withAlpha(tokens.ActionAccent, tokens.Opacity25)\n : theme.color.background.highlight\n };\n ${tokens ? `color: ${tokens.FgPrimary};` : ''}\n transition-duration: ${TransitionDuration.Fast};\n }\n `;\n }}\n\n ${isFocusedVisible}\n`;\n\nexport default TableRow;\n","import { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { TableHeaderCell } from '@persona/design-system/components/Table';\nimport { HelperTooltip } from '@persona/design-system/components/Tooltip';\nimport { Spacing } from '@persona/design-tokens';\n\nconst StyledHelperTooltip = styled(HelperTooltip)`\n height: 14px;\n margin-left: ${Spacing[1]};\n`;\n\nexport interface TableTHProps extends ComponentPropsWithoutRef<typeof TableHeaderCell> {\n canSort?: boolean;\n isSorted?: boolean;\n isDescending?: boolean;\n isSticky?: boolean;\n /**\n * Display help icon and tooltip for column header\n */\n helpText?: ReactNode;\n align?: 'left' | 'right';\n size?: 'sm' | 'md';\n}\n\nconst TableTH = forwardRef<HTMLTableCellElement, TableTHProps>(function TableTH(\n { children, canSort, isSorted, isSticky, isDescending, helpText, align, size, ...props },\n ref,\n) {\n return (\n <TableHeaderCell\n sortable={canSort}\n sortDirection={canSort && isSorted ? (isDescending ? 'desc' : 'asc') : false}\n ref={ref}\n isSticky={isSticky}\n align={align}\n size={size}\n trailing={helpText && <StyledHelperTooltip size='sm'>{helpText}</StyledHelperTooltip>}\n {...props}\n >\n {/* We have to wrap the children to make it easier to use tooltips */}\n <span className='th__text'>{children}</span>\n </TableHeaderCell>\n );\n});\n\nexport default TableTH;\n","import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport { Paragraph } from '#src/components/Text';\nimport { withAlpha } from '#src/lib/color';\nimport { isHovered } from '#src/lib/pseudoClass';\nimport {\n type MaybeSemanticTheme,\n semanticColor,\n semanticOnly,\n semanticTokens,\n} from '#src/lib/semanticColor';\nimport { paragraphMixins } from '#src/mixins/text';\nimport type { PersonaTheme } from '#src/theme';\nimport { BASE } from '#src/variables/spacing';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport TableRow from './TableRow';\nimport TableTH from './TableTH';\n\nexport interface TableCellProps {\n breakWord?: boolean;\n size?: 'sm' | 'md';\n}\n\nconst TableCell = styled.td.attrs({ role: 'cell' })<TableCellProps>`\n display: table-cell;\n vertical-align: middle;\n /* Self-contained box model: don't depend on a consumer's global\n border-box reset, so a fixed cell height includes its padding + border\n and rows stay compact. */\n box-sizing: border-box;\n\n border-bottom: 1px solid ${({ theme }) => semanticColor(theme, 'BorderDivider', theme.color.border.primary)};\n text-align: left;\n padding: ${({ size }) => (size === 'sm' ? BASE : BASE * 1.5)}px;\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n white-space: nowrap;\n ${paragraphMixins.md};\n line-height: 1;\n ${({ breakWord }) =>\n breakWord\n ? `white-space: normal;\n overflow-wrap: break-word;`\n : ''}\n`;\n\nexport default TableCell;\n\nconst CellTitleContainer = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nconst CellTitle = styled(Paragraph).attrs({ color: 'primary' })`\n ${semanticOnly(() => 'color: inherit;')}\n display: flex;\n align-items: center;\n gap: ${Spacing[2]};\n`;\n\nconst CellSubtitle = styled(Paragraph)`\n ${semanticOnly((tokens) => `color: ${tokens.FgSecondary};`)}\n`;\n\nconst activeHighlight = (theme: PersonaTheme & MaybeSemanticTheme) =>\n semanticColor(theme, 'ActionAccent', theme.color.background.highlight);\n\nconst hoverHighlight = (theme: PersonaTheme & MaybeSemanticTheme) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? withAlpha(tokens.ActionAccent, tokens.Opacity25)\n : theme.color.background.highlight;\n};\n\n// Same page color unpinned cells show through, painted opaquely so scrolled text stays covered.\nconst pinnedBodyBackground = (theme: PersonaTheme & MaybeSemanticTheme) =>\n semanticColor(\n theme,\n theme.color.text.primary === Color.TextInverse ? 'SurfacePage' : 'SurfacePrimary',\n theme.color.background.primary,\n );\n\ninterface TableCellTitleProps extends ComponentPropsWithoutRef<'div'> {\n subtitle?: ReactNode;\n}\n\nexport const TableCellTitle = ({ children, subtitle, ...elemProps }: TableCellTitleProps) => {\n return (\n <CellTitleContainer {...elemProps}>\n <CellTitle>{children}</CellTitle>\n {subtitle && <CellSubtitle>{subtitle}</CellSubtitle>}\n </CellTitleContainer>\n );\n};\n\nexport const TableTD = styled(TableCell)<{ unclickable?: boolean }>`\n white-space: normal;\n overflow-wrap: break-word;\n ${(props) =>\n props.unclickable &&\n css`\n cursor: default;\n `}\n`;\n\nexport const TableIconTD = styled(TableTD)`\n text-align: right;\n line-height: 0; /* To center icon; cannot use flex here */\n padding: 0;\n padding-left: ${Spacing[4]};\n width: 36px;\n`;\n\nexport const TableActionTD = styled(TableTD)`\n text-align: right;\n padding: 0;\n padding-right: ${Spacing[4]};\n width: 48px;\n`;\n\nexport const StickyTD = styled(TableTD)<{\n left?: number;\n hasRightBorder?: boolean;\n}>`\n position: sticky;\n left: ${({ left = 0 }) => `${left}px`}; // Default to 0 if not specified\n background-color: ${({ theme }) => pinnedBodyBackground(theme)};\n\n ${({ hasRightBorder, theme }) =>\n hasRightBorder &&\n `border-right: 2px solid ${semanticColor(theme, 'BorderDivider', theme.color.border.primary)};`}\n z-index: 2;\n`;\n\nexport const StickyTH = styled(TableTH)<{\n left?: number;\n hasRightBorder?: boolean;\n size?: 'sm' | 'md';\n}>`\n position: sticky;\n left: ${({ left = 0 }) => `${left}px`}; // Default to 0 if not specified\n z-index: 2;\n max-width: 10%;\n background-color: ${({ theme }) => semanticColor(theme, 'SurfaceSecondary', theme.color.background.secondary)};\n ${({ hasRightBorder, theme }) =>\n hasRightBorder &&\n `border-right: 2px solid ${semanticColor(theme, 'BorderDivider', theme.color.border.primary)};`}\n`;\n\nexport const TableTR = styled(TableRow)<{ disableHoverBackground?: boolean; $isActive?: boolean }>`\n ${({ disableHoverBackground }) =>\n disableHoverBackground &&\n css`\n &:hover {\n background-color: transparent !important;\n }\n `}\n\n ${({ $isActive }) =>\n $isActive &&\n css`\n background-color: ${({ theme }) => activeHighlight(theme)};\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n ${StickyTD} {\n background-color: ${({ theme }) => activeHighlight(theme)};\n }\n &:hover {\n background-color: ${({ theme }) => activeHighlight(theme)};\n }\n &:hover ${StickyTD} {\n background-color: ${({ theme }) => activeHighlight(theme)};\n background-image: none;\n }\n `}\n\n ${({ disableHoverBackground, $isActive }) =>\n !disableHoverBackground &&\n !$isActive &&\n css`\n &${isHovered} ${StickyTD} {\n background-image: linear-gradient(\n ${({ theme }) => hoverHighlight(theme)},\n ${({ theme }) => hoverHighlight(theme)}\n );\n }\n `}\n\n ${({ onClick, disableHoverBackground, $isActive }) =>\n onClick != null &&\n !disableHoverBackground &&\n !$isActive &&\n css`\n cursor: pointer;\n :hover {\n background-color: ${({ theme }) => hoverHighlight(theme)};\n ${semanticOnly((tokens) => `color: ${tokens.FgPrimary};`)}\n }\n transition-duration: ${TransitionDuration.Fast};\n `}\n`;\n","import styled, { css } from 'styled-components';\n\ninterface TableHeadProps {\n sticky?: boolean;\n}\n\nconst TableHead = styled.thead.attrs({ role: 'rowgroup' })<TableHeadProps>`\n display: table-header-group;\n ${({ sticky }) =>\n sticky &&\n css`\n position: sticky;\n top: 0;\n z-index: 1;\n `}\n`;\n\nexport default TableHead;\n","import styled from 'styled-components';\n\nconst TableBody = styled.tbody.attrs({ role: 'rowgroup' })`\n display: table-row-group;\n`;\n\nexport default TableBody;\n","import type { FC, PropsWithChildren, ReactNode } from 'react';\nimport styled, { keyframes } from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\n\nimport { Spinner } from '#src/components/Spinner';\nimport Table, { TableBody, TableHead, TableRow } from '#src/components/Table';\nimport { semanticColor } from '#src/lib/semanticColor';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { semanticScrollbar } from '#src/mixins/scrollbar';\nimport { fadeIn } from '#src/variables/keyframes';\n\n// `visible` rather than a narrower opt-out because CSS blockifies the other axis: any\n// `overflow-x` other than `visible`/`clip` forces `overflow-y` to compute to `auto` too, which\n// makes this element the scrollport that descendant sticky offsets resolve against.\nconst Container = styled.div<{ maxHeight?: number; $scrollsHorizontally: boolean }>`\n position: relative;\n z-index: 0;\n overflow-x: ${({ $scrollsHorizontally }) => ($scrollsHorizontally ? 'auto' : 'visible')};\n ${semanticScrollbar}\n ${({ maxHeight }) => {\n if (maxHeight != null) {\n return `max-height: ${maxHeight}px;`;\n }\n }}\n `;\n\nconst slideKeyframes = keyframes`\n 0% {\n transform: translateX(-50%) scaleX(0);\n }\n 50% {\n transform: translateX(0) scaleX(1);\n }\n 100% {\n transform: translateX(50%) scaleX(0);\n }\n `;\n\nconst Loader = styled.div`\n position: absolute;\n z-index: ${Z_INDICES.loadingOverlays};\n border-bottom: 3px solid ${({ theme }) => semanticColor(theme, 'BorderAccent', theme.color.primary.brand)};\n width: 100%;\n \n animation: ${slideKeyframes} 3s infinite cubic-bezier(0.5, 0, 0.5, 1);\n `;\n\nconst Overlay = styled.div`\n position: absolute;\n z-index: ${Z_INDICES.loadingOverlays};\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${({ theme }) => semanticColor(theme, 'SurfacePrimary', theme.color.primary.white)};\n opacity: 50%;\n `;\n\nconst SpinnerWrapper = styled.div`\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: ${Spacing[5]} 0;\n animation: ${fadeIn} 1s;\n animation-delay: 0.5s;\n animation-fill-mode: backwards;\n `;\n\nconst TableSpinner = styled(Spinner)`\n svg {\n width: 120px;\n height: 120px;\n }\n \n path {\n stroke: ${({ theme }) => semanticColor(theme, 'FeedbackAccent3', Color.CorePurple500)};\n stroke-width: 0.46;\n }\n `;\n\ninterface TableLayoutProps {\n className?: string;\n containerMaxHeight?: number;\n /**\n * When false, the container does not scroll horizontally and an ancestor is expected to.\n * Sticky offsets inside the table then resolve against that ancestor's scrollport rather\n * than against the container.\n */\n containerScrollsHorizontally?: boolean;\n dataTest?: string;\n headerTR: JSX.Element;\n isEmpty?: boolean;\n isLoading?: boolean;\n nullState: ReactNode;\n showHeader?: boolean;\n size?: 'sm' | 'md';\n stickyHeader?: boolean;\n}\n\nconst TableLayout: FC<PropsWithChildren<TableLayoutProps>> = ({\n children,\n className,\n containerMaxHeight,\n containerScrollsHorizontally = true,\n dataTest,\n headerTR,\n isEmpty,\n isLoading,\n nullState,\n showHeader,\n size = 'md',\n stickyHeader = false,\n}) => {\n if (isEmpty && !showHeader) {\n if (isLoading) {\n return (\n <SpinnerWrapper\n role='status'\n aria-live='polite'\n aria-busy='true'\n aria-label='Loading...'\n data-loading-indicator='true'\n >\n <TableSpinner size='md' />\n </SpinnerWrapper>\n );\n } else {\n return (\n <Container data-test={dataTest} $scrollsHorizontally={containerScrollsHorizontally}>\n {nullState}\n </Container>\n );\n }\n }\n\n return (\n <Container\n data-test={dataTest}\n maxHeight={containerMaxHeight}\n className={className}\n $scrollsHorizontally={containerScrollsHorizontally}\n >\n {isLoading && <Loader data-test='table-layout__loader' />}\n {isLoading && <Overlay />}\n\n <Table size={size} aria-busy={isLoading || undefined}>\n <TableHead sticky={stickyHeader}>\n <TableRow>{headerTR}</TableRow>\n </TableHead>\n {!isEmpty && <TableBody>{children}</TableBody>}\n </Table>\n\n {isEmpty && nullState}\n </Container>\n );\n};\n\nexport default TableLayout;\n"],"mappings":"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"}
|