@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
package/dist/lint/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["message"],"sources":["../../src/lint/shared.ts","../../src/lint/rules/complete-typography.ts","../../src/lint/rules/min-copy-size.ts","../../src/lint/rules/no-raw-table.ts","../../src/lint/rules/reduced-motion.ts","../../src/lint/rules/semantic-color.ts","../../src/lint/index.ts"],"sourcesContent":["import type { Context, ESTree, RuleDocs } from '@oxlint/plugins';\n\nconst STANDARD_URL =\n 'https://github.com/persona-id/persona-design-system/blob/master/packages/design-system/skills/ui-authoring/STANDARD.md#lint-rules';\n\nexport const docs = (description: string): RuleDocs => ({ description, url: STANDARD_URL });\n\n/** The tags that make a template literal CSS: styled-components' `styled`, `css`, `keyframes`, `createGlobalStyle`. */\nconst CSS_TAGS = new Set(['styled', 'css', 'keyframes', 'createGlobalStyle']);\n\n/** The identifier a chain of member accesses and calls starts from: `styled` in `styled(Box).attrs({})`. */\nexport function rootIdentifier(node: ESTree.Expression): string | null {\n let current: ESTree.Expression = node;\n for (;;) {\n switch (current.type) {\n case 'Identifier':\n return current.name;\n case 'MemberExpression':\n current = current.object;\n break;\n case 'CallExpression':\n current = current.callee;\n break;\n default:\n return null;\n }\n }\n}\n\nexport const isCssTemplate = (node: ESTree.TaggedTemplateExpression): boolean => {\n const root = rootIdentifier(node.tag);\n return root !== null && CSS_TAGS.has(root);\n};\n\n/** The name of a non-computed identifier key or a string-literal key, else null. */\nexport function propertyName(property: ESTree.ObjectProperty): string | null {\n const { key } = property;\n if (key.type === 'Identifier' && !property.computed) {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\n/** The name of `node.<name>`, or null for a computed or private access. */\nexport const staticMemberName = (node: ESTree.MemberExpression): string | null =>\n !node.computed && node.property.type === 'Identifier' ? node.property.name : null;\n\n/** The rightmost name of `a.b.c` or `c`: `c`. */\nexport function lastName(node: ESTree.Expression): string | null {\n if (node.type === 'Identifier') {\n return node.name;\n }\n return node.type === 'MemberExpression' ? staticMemberName(node) : null;\n}\n\nconst blank = (text: string): string => text.replace(/[^\\n]/g, ' ');\n\n/**\n * Blank CSS comments (`/* *\\/`, and `//` at the start of a line or after whitespace, so `https://` in a\n * url is kept), leaving line breaks so that offsets and line numbers stay the same.\n */\nexport const blankCssComments = (text: string): string =>\n text\n .replace(/\\/\\*[\\s\\S]*?(?:\\*\\/|$)/g, blank)\n .replace(\n /(^|[ \\t])\\/\\/[^\\n]*/gm,\n (match, lead: string) => lead + blank(match.slice(lead.length)),\n );\n\nfunction isCssTemplateElement(node: ESTree.Node): boolean {\n if (node.type !== 'TemplateElement') {\n return false;\n }\n const literal = node.parent;\n if (literal.type !== 'TemplateLiteral') {\n return false;\n }\n const tagged = literal.parent;\n return (\n tagged.type === 'TaggedTemplateExpression' && tagged.quasi === literal && isCssTemplate(tagged)\n );\n}\n\n/** The source text of `node`; for the text of a CSS template, with its comments blanked. */\nexport function sourceText(context: Context, node: ESTree.Node): string {\n const [start, end] = node.range;\n const text = context.sourceCode.text.slice(start, end);\n return isCssTemplateElement(node) ? blankCssComments(text) : text;\n}\n\n/** Report each match of `pattern` in the source of `node`, at the match rather than the node. */\nexport function reportMatches(\n context: Context,\n node: ESTree.Node,\n pattern: RegExp,\n message: (match: RegExpExecArray) => string,\n accept: (match: RegExpExecArray) => boolean = () => true,\n): void {\n const { sourceCode } = context;\n const [start] = node.range;\n for (const match of sourceText(context, node).matchAll(pattern)) {\n if (!accept(match)) {\n continue;\n }\n const index = start + match.index;\n context.report({\n message: message(match),\n loc: {\n start: sourceCode.getLocFromIndex(index),\n end: sourceCode.getLocFromIndex(index + match[0].length),\n },\n });\n }\n}\n\nexport const toPx = (value: number, unit: string | undefined, rootFontPx: number): number =>\n unit === 'rem' || unit === 'em' ? value * rootFontPx : value;\n\n/** A bare number under 1 is a unitless multiplier, not a size. */\nexport const isSmallSize = (size: number, unit: string | undefined, minPx: number): boolean =>\n size < minPx && (unit !== undefined || size >= 1);\n\n/** A JSX attribute's value when it is a string, written either way: `\"x\"` or `{\"x\"}`. */\nexport function jsxStringValue(attribute: ESTree.JSXAttribute): string | null {\n const { value } = attribute;\n if (value === null) {\n return null;\n }\n const inner = value.type === 'JSXExpressionContainer' ? value.expression : value;\n return inner.type === 'Literal' && typeof inner.value === 'string' ? inner.value : null;\n}\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, isCssTemplate, propertyName, reportMatches } from '../shared';\n\nconst FONT_PROPERTIES = new Set([\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'lineHeight',\n 'letterSpacing',\n 'font-size',\n 'font-weight',\n 'font-family',\n 'line-height',\n 'letter-spacing',\n]);\nconst FONT_DECLARATION =\n /(?<![\\w-])(?:font-size|font-weight|font-family|line-height|letter-spacing)\\s*:/g;\n\nconst message = (name: string) =>\n `Individual font property \\`${name}\\`: use a complete \\`Typography\\` style.`;\n\nexport const completeTypography: Rule = {\n meta: {\n type: 'problem',\n docs: docs('Use a complete `Typography` style, not an individual font property.'),\n },\n createOnce(context: Context) {\n return {\n ObjectExpression(node: ESTree.ObjectExpression) {\n for (const property of node.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n const name = propertyName(property);\n if (name !== null && FONT_PROPERTIES.has(name)) {\n context.report({ node: property.key, message: message(name) });\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n for (const quasi of node.quasi.quasis) {\n reportMatches(context, quasi, FONT_DECLARATION, (match) =>\n message(match[0].replace(/\\s*:$/, '')),\n );\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n docs,\n isCssTemplate,\n isSmallSize,\n jsxStringValue,\n lastName,\n propertyName,\n reportMatches,\n staticMemberName,\n toPx,\n} from '../shared';\n\nconst DEFAULT_MIN_PX = 11;\nconst DEFAULT_ROOT_FONT_PX = 16;\n\nconst EXTRA_SMALL_STYLES = new Set(['TextExtraSmall', 'TextExtraSmallMono']);\nconst PARAGRAPH_SCALES = new Set(['paragraph', 'paragraphMixins']);\nconst SIZED_COMPONENTS = new Set(['Paragraph', 'Label']);\nconst FONT_SIZE_PROPERTIES = new Set(['fontSize', 'font-size']);\nconst RAW_FONT_SIZE = /font-size\\s*:\\s*(\\d*\\.?\\d+)\\s*(px|rem|em)?(?![\\w.])/g;\nconst SIZE_VALUE = /^\\s*(\\d*\\.?\\d+)\\s*(px|rem|em)?\\s*$/;\n\n/** The rule's options, which oxlint has already checked against the schema. */\nfunction readSettings(options: unknown): { minPx: number; rootFontPx: number } {\n const read = (key: string, fallback: number): number => {\n const value: unknown =\n typeof options === 'object' && options !== null ? Reflect.get(options, key) : undefined;\n return typeof value === 'number' ? value : fallback;\n };\n return {\n minPx: read('minPx', DEFAULT_MIN_PX),\n rootFontPx: read('rootFontPx', DEFAULT_ROOT_FONT_PX),\n };\n}\n\nconst small = (what: string) =>\n `${what}: text under the minimum size. Fine for a label inside a graphic (8 px); copy uses \\`TextSmall\\` (12 px).`;\n\n/** The text of a font-size value written as a number, a string or a plain template. */\nfunction sizeText(value: ESTree.Expression): string | null {\n if (value.type === 'Literal') {\n return typeof value.value === 'number' || typeof value.value === 'string'\n ? String(value.value)\n : null;\n }\n if (value.type === 'TemplateLiteral' && value.expressions.length === 0) {\n return value.quasis[0]?.value.cooked ?? null;\n }\n return null;\n}\n\nexport const minCopySize: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Copy is at least 11 CSS px. Fine for a label inside a graphic (8 px); copy uses `TextSmall` (12 px).',\n ),\n schema: [\n {\n type: 'object',\n properties: { minPx: { type: 'number' }, rootFontPx: { type: 'number' } },\n additionalProperties: false,\n },\n ],\n },\n createOnce(context: Context) {\n const settings = () => readSettings(context.options[0]);\n return {\n MemberExpression(node: ESTree.MemberExpression) {\n const name = staticMemberName(node);\n if (name === null) {\n return;\n }\n if (EXTRA_SMALL_STYLES.has(name)) {\n context.report({ node, message: small(`\\`${name}\\``) });\n } else if (name === 'xs') {\n const scale = lastName(node.object);\n if (scale !== null && PARAGRAPH_SCALES.has(scale)) {\n context.report({ node, message: small(`\\`${scale}.xs\\``) });\n }\n }\n },\n JSXOpeningElement(node: ESTree.JSXOpeningElement) {\n if (node.name.type !== 'JSXIdentifier' || !SIZED_COMPONENTS.has(node.name.name)) {\n return;\n }\n for (const attribute of node.attributes) {\n if (\n attribute.type === 'JSXAttribute' &&\n attribute.name.type === 'JSXIdentifier' &&\n attribute.name.name === 'size' &&\n jsxStringValue(attribute) === 'xs'\n ) {\n context.report({\n node: attribute,\n message: small(`\\`<${node.name.name} size=\"xs\">\\``),\n });\n }\n }\n },\n ObjectExpression(node: ESTree.ObjectExpression) {\n const { minPx, rootFontPx } = settings();\n for (const property of node.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n const name = propertyName(property);\n if (name === null || !FONT_SIZE_PROPERTIES.has(name)) {\n continue;\n }\n const text = sizeText(property.value);\n const match = text === null ? null : SIZE_VALUE.exec(text);\n const size = match?.[1];\n const unit = match?.[2];\n if (\n size !== undefined &&\n isSmallSize(toPx(Number(size), unit, rootFontPx), unit, minPx)\n ) {\n context.report({ node: property, message: small(`font-size ${size}${unit ?? 'px'}`) });\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n const { minPx, rootFontPx } = settings();\n for (const quasi of node.quasi.quasis) {\n reportMatches(\n context,\n quasi,\n RAW_FONT_SIZE,\n (match) => small(`font-size ${match[1]}${match[2] ?? 'px'}`),\n (match) => isSmallSize(toPx(Number(match[1]), match[2], rootFontPx), match[2], minPx),\n );\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, staticMemberName } from '../shared';\n\nconst TABLE_ELEMENTS = new Set(['table', 'th', 'td']);\n\nconst message = (what: string) =>\n `Hand-rolled table markup (${what}). Use \\`Table\\`, \\`DataTable\\` or \\`IndexTableLayout\\`.`;\n\nexport const noRawTable: Rule = {\n meta: {\n type: 'problem',\n docs: docs('Use `Table`, `DataTable` or `IndexTableLayout`, not hand-rolled table markup.'),\n },\n createOnce(context: Context) {\n return {\n JSXOpeningElement(node: ESTree.JSXOpeningElement) {\n if (node.name.type === 'JSXIdentifier' && TABLE_ELEMENTS.has(node.name.name)) {\n context.report({ node: node.name, message: message(`<${node.name.name}>`) });\n }\n },\n MemberExpression(node: ESTree.MemberExpression) {\n const name = staticMemberName(node);\n if (\n name !== null &&\n TABLE_ELEMENTS.has(name) &&\n node.object.type === 'Identifier' &&\n node.object.name === 'styled'\n ) {\n context.report({ node, message: message(`styled.${name}`) });\n }\n },\n CallExpression(node: ESTree.CallExpression) {\n const [argument] = node.arguments;\n if (\n node.callee.type === 'Identifier' &&\n node.callee.name === 'styled' &&\n argument?.type === 'Literal' &&\n typeof argument.value === 'string' &&\n TABLE_ELEMENTS.has(argument.value)\n ) {\n context.report({ node, message: message(`styled('${argument.value}')`) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Location, Rule } from '@oxlint/plugins';\n\nimport { docs, isCssTemplate, propertyName, rootIdentifier, sourceText } from '../shared';\n\nconst MOTION_PROPERTIES = new Set([\n 'animation',\n 'animationName',\n 'transition',\n 'transitionProperty',\n 'animation-name',\n 'transition-property',\n]);\nconst MOTION_DECLARATION =\n /@keyframes\\b|(?<![\\w-])(?:animation|animation-name|transition|transition-property)\\s*:/g;\nconst REDUCED_MOTION = 'prefers-reduced-motion';\n\nconst MESSAGE =\n 'Animation or transition in a file with no `prefers-reduced-motion` block. Add one that turns it off.';\n\nexport const reducedMotion: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Animation or transition only in a file with a `prefers-reduced-motion` block. Reported once per file, at the first one.',\n ),\n },\n createOnce(context: Context) {\n let first: Location | null = null;\n let hasReducedMotion = false;\n const note = (location: Location) => {\n first ??= location;\n };\n const noteReducedMotion = (text: string) => {\n if (text.includes(REDUCED_MOTION)) {\n hasReducedMotion = true;\n }\n };\n return {\n before() {\n first = null;\n hasReducedMotion = false;\n },\n Literal(node) {\n if (typeof node.value === 'string') {\n noteReducedMotion(node.value);\n }\n },\n TemplateElement(node) {\n noteReducedMotion(sourceText(context, node));\n },\n ObjectExpression(node: ESTree.ObjectExpression) {\n for (const property of node.properties) {\n const name = property.type === 'Property' ? propertyName(property) : null;\n if (property.type === 'Property' && name !== null && MOTION_PROPERTIES.has(name)) {\n note(property.key.loc);\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n if (rootIdentifier(node.tag) === 'keyframes') {\n note(node.loc);\n }\n const { sourceCode } = context;\n for (const quasi of node.quasi.quasis) {\n const [start] = quasi.range;\n for (const match of sourceText(context, quasi).matchAll(MOTION_DECLARATION)) {\n const index = start + match.index;\n note({\n start: sourceCode.getLocFromIndex(index),\n end: sourceCode.getLocFromIndex(index + match[0].length),\n });\n }\n }\n },\n after() {\n if (first !== null && !hasReducedMotion) {\n context.report({ message: MESSAGE, loc: first });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, reportMatches, staticMemberName } from '../shared';\n\nconst HEX = /(?<![\\w&/#])#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4})\\b/g;\nconst LINK_ATTRIBUTES = new Set(['href', 'to']);\nconst MODULE_PARENTS = new Set([\n 'ImportDeclaration',\n 'ExportNamedDeclaration',\n 'ExportAllDeclaration',\n 'ImportExpression',\n]);\n\nconst isSemanticColorCall = (node: ESTree.CallExpression): boolean =>\n node.callee.type === 'Identifier' && node.callee.name === 'semanticColor';\n\nconst isLinkAttribute = (node: ESTree.JSXAttribute): boolean =>\n node.name.type === 'JSXIdentifier' && LINK_ATTRIBUTES.has(node.name.name);\n\nexport const semanticColor: Rule = {\n meta: {\n type: 'problem',\n docs: docs(\n 'Paint with a semantic token (`semanticColor`), not a hex value or a `Color.*` outside its fallback.',\n ),\n },\n createOnce(context: Context) {\n let insideSemanticColor = 0;\n let insideLink = 0;\n const checkText = (node: ESTree.Node) => {\n if (insideLink === 0) {\n reportMatches(\n context,\n node,\n HEX,\n (match) => `Hex colour ${match[0]}: paint with a semantic token (\\`semanticColor\\`).`,\n );\n }\n };\n return {\n before() {\n insideSemanticColor = 0;\n insideLink = 0;\n },\n CallExpression(node) {\n if (isSemanticColorCall(node)) {\n insideSemanticColor++;\n }\n },\n 'CallExpression:exit'(node) {\n if (isSemanticColorCall(node)) {\n insideSemanticColor--;\n }\n },\n JSXAttribute(node) {\n if (isLinkAttribute(node)) {\n insideLink++;\n }\n },\n 'JSXAttribute:exit'(node) {\n if (isLinkAttribute(node)) {\n insideLink--;\n }\n },\n Literal(node) {\n if (typeof node.value === 'string' && !MODULE_PARENTS.has(node.parent.type)) {\n checkText(node);\n }\n },\n TemplateElement: checkText,\n MemberExpression(node) {\n const name = staticMemberName(node);\n if (\n insideSemanticColor === 0 &&\n name !== null &&\n node.object.type === 'Identifier' &&\n node.object.name === 'Color' &&\n /^[A-Z]\\w*$/.test(name)\n ) {\n context.report({\n node,\n message: `\\`Color.${name}\\` outside \\`semanticColor\\`: paint with a semantic token, with this as its fallback.`,\n });\n }\n },\n };\n },\n};\n","import type { Plugin } from '@oxlint/plugins';\n\nimport { completeTypography } from './rules/complete-typography';\nimport { minCopySize } from './rules/min-copy-size';\nimport { noRawTable } from './rules/no-raw-table';\nimport { reducedMotion } from './rules/reduced-motion';\nimport { semanticColor } from './rules/semantic-color';\n\n/**\n * The product UI standard's automated checks as an oxlint JS plugin. Load it with\n * `\"jsPlugins\": [\"@persona/design-system/lint\"]` and enable rules as `pds/<rule>`.\n */\nconst plugin: Plugin = {\n meta: { name: 'pds' },\n rules: {\n 'semantic-color': semanticColor,\n 'complete-typography': completeTypography,\n 'min-copy-size': minCopySize,\n 'reduced-motion': reducedMotion,\n 'no-raw-table': noRawTable,\n },\n};\n\nexport default plugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["message","MOTION_DECLARATION","LOOP","MOTION_DECLARATION","FIXED","MOTION_DECLARATION","KEYFRAMES_BLOCK","message","TRANSITION_PROPERTIES","message","MOTION_DECLARATION","message","MESSAGE","MOTION_DECLARATION"],"sources":["../../src/lint/shared.ts","../../src/lint/rules/complete-typography.ts","../../src/lint/motion.ts","../../src/lint/rules/duration-token.ts","../../src/lint/rules/exit-motion.ts","../../src/lint/rules/min-copy-size.ts","../../src/lint/rules/motion-origin.ts","../../src/lint/rules/no-layout-motion.ts","../../src/lint/rules/no-raw-table.ts","../../src/lint/rules/no-transition-all.ts","../../src/lint/rules/overlay-motion.ts","../../src/lint/rules/reduced-motion.ts","../../src/lint/rules/semantic-color.ts","../../src/lint/index.ts"],"sourcesContent":["import type { Context, ESTree, RuleDocs } from '@oxlint/plugins';\n\nconst STANDARD_URL =\n 'https://github.com/persona-id/persona-design-system/blob/master/packages/design-system/skills/ui-authoring/STANDARD.md#lint-rules';\n\nexport const docs = (description: string): RuleDocs => ({ description, url: STANDARD_URL });\n\n/** The tags that make a template literal CSS: styled-components' `styled`, `css`, `keyframes`, `createGlobalStyle`. */\nconst CSS_TAGS = new Set(['styled', 'css', 'keyframes', 'createGlobalStyle']);\n\n/** The identifier a chain of member accesses and calls starts from: `styled` in `styled(Box).attrs({})`. */\nexport function rootIdentifier(node: ESTree.Expression): string | null {\n let current: ESTree.Expression = node;\n for (;;) {\n switch (current.type) {\n case 'Identifier':\n return current.name;\n case 'MemberExpression':\n current = current.object;\n break;\n case 'CallExpression':\n current = current.callee;\n break;\n default:\n return null;\n }\n }\n}\n\nexport const isCssTemplate = (node: ESTree.TaggedTemplateExpression): boolean => {\n const root = rootIdentifier(node.tag);\n return root !== null && CSS_TAGS.has(root);\n};\n\n/** The name of a non-computed identifier key or a string-literal key, else null. */\nexport function propertyName(property: ESTree.ObjectProperty): string | null {\n const { key } = property;\n if (key.type === 'Identifier' && !property.computed) {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\n/** The name of `node.<name>`, or null for a computed or private access. */\nexport const staticMemberName = (node: ESTree.MemberExpression): string | null =>\n !node.computed && node.property.type === 'Identifier' ? node.property.name : null;\n\n/** The rightmost name of `a.b.c` or `c`: `c`. */\nexport function lastName(node: ESTree.Expression): string | null {\n if (node.type === 'Identifier') {\n return node.name;\n }\n return node.type === 'MemberExpression' ? staticMemberName(node) : null;\n}\n\nconst blank = (text: string): string => text.replace(/[^\\n]/g, ' ');\n\n/**\n * Blank CSS comments (`/* *\\/`, and `//` at the start of a line or after whitespace, so `https://` in a\n * url is kept), leaving line breaks so that offsets and line numbers stay the same.\n */\nexport const blankCssComments = (text: string): string =>\n text\n .replace(/\\/\\*[\\s\\S]*?(?:\\*\\/|$)/g, blank)\n .replace(\n /(^|[ \\t])\\/\\/[^\\n]*/gm,\n (match, lead: string) => lead + blank(match.slice(lead.length)),\n );\n\nfunction isCssTemplateElement(node: ESTree.Node): boolean {\n if (node.type !== 'TemplateElement') {\n return false;\n }\n const literal = node.parent;\n if (literal.type !== 'TemplateLiteral') {\n return false;\n }\n const tagged = literal.parent;\n return (\n tagged.type === 'TaggedTemplateExpression' && tagged.quasi === literal && isCssTemplate(tagged)\n );\n}\n\n/** The source text of `node`; for the text of a CSS template, with its comments blanked. */\nexport function sourceText(context: Context, node: ESTree.Node): string {\n const [start, end] = node.range;\n const text = context.sourceCode.text.slice(start, end);\n return isCssTemplateElement(node) ? blankCssComments(text) : text;\n}\n\n/** Report each match of `pattern` in the source of `node`, at the match rather than the node. */\nexport function reportMatches(\n context: Context,\n node: ESTree.Node,\n pattern: RegExp,\n message: (match: RegExpExecArray) => string,\n accept: (match: RegExpExecArray) => boolean = () => true,\n): void {\n const { sourceCode } = context;\n const [start] = node.range;\n for (const match of sourceText(context, node).matchAll(pattern)) {\n if (!accept(match)) {\n continue;\n }\n const index = start + match.index;\n context.report({\n message: message(match),\n loc: {\n start: sourceCode.getLocFromIndex(index),\n end: sourceCode.getLocFromIndex(index + match[0].length),\n },\n });\n }\n}\n\nexport const toPx = (value: number, unit: string | undefined, rootFontPx: number): number =>\n unit === 'rem' || unit === 'em' ? value * rootFontPx : value;\n\n/** A bare number under 1 is a unitless multiplier, not a size. */\nexport const isSmallSize = (size: number, unit: string | undefined, minPx: number): boolean =>\n size < minPx && (unit !== undefined || size >= 1);\n\n/** A JSX attribute's value when it is a string, written either way: `\"x\"` or `{\"x\"}`. */\nexport function jsxStringValue(attribute: ESTree.JSXAttribute): string | null {\n const { value } = attribute;\n if (value === null) {\n return null;\n }\n const inner = value.type === 'JSXExpressionContainer' ? value.expression : value;\n return inner.type === 'Literal' && typeof inner.value === 'string' ? inner.value : null;\n}\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, isCssTemplate, propertyName, reportMatches } from '../shared';\n\nconst FONT_PROPERTIES = new Set([\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'lineHeight',\n 'letterSpacing',\n 'font-size',\n 'font-weight',\n 'font-family',\n 'line-height',\n 'letter-spacing',\n]);\nconst FONT_DECLARATION =\n /(?<![\\w-])(?:font-size|font-weight|font-family|line-height|letter-spacing)\\s*:/g;\n\nconst message = (name: string) =>\n `Individual font property \\`${name}\\`: use a complete \\`Typography\\` style.`;\n\nexport const completeTypography: Rule = {\n meta: {\n type: 'problem',\n docs: docs('Use a complete `Typography` style, not an individual font property.'),\n },\n createOnce(context: Context) {\n return {\n ObjectExpression(node: ESTree.ObjectExpression) {\n for (const property of node.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n const name = propertyName(property);\n if (name !== null && FONT_PROPERTIES.has(name)) {\n context.report({ node: property.key, message: message(name) });\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n for (const quasi of node.quasi.quasis) {\n reportMatches(context, quasi, FONT_DECLARATION, (match) =>\n message(match[0].replace(/\\s*:$/, '')),\n );\n }\n },\n };\n },\n};\n","/*\n * The motion rules adapt checks from the transitions.dev Motion Agent\n * (https://github.com/Jakubantalik/transitions.dev, agent/lib/rules.mjs, components.mjs, catalog.mjs).\n * Copyright (c) 2026 Jakub Antalik / Transitions.dev. MIT License; the full notice is in\n * THIRD_PARTY_NOTICES.md, which ships beside the built plugin.\n */\nimport type { Context, ESTree } from '@oxlint/plugins';\n\nimport { blankCssComments, isCssTemplate, lastName } from './shared';\n\n/** A CSS template's text with each `${…}` filled with `_` and comments blanked, so offsets match the source. */\nexport interface CssText {\n text: string;\n start: number;\n}\n\nconst cssTextCache = new WeakMap<ESTree.TemplateLiteral, CssText>();\n\nexport function cssText(context: Context, literal: ESTree.TemplateLiteral): CssText {\n const cached = cssTextCache.get(literal);\n if (cached !== undefined) {\n return cached;\n }\n const [start, end] = literal.range;\n const source = context.sourceCode.text.slice(start, end);\n const parts: string[] = [];\n let at = 0;\n for (const expression of literal.expressions) {\n const from = source.lastIndexOf('${', expression.range[0] - start);\n const to = source.indexOf('}', expression.range[1] - start) + 1;\n parts.push(source.slice(at, from), '_'.repeat(to - from));\n at = to;\n }\n parts.push(source.slice(at));\n const result = { text: blankCssComments(parts.join('')), start };\n cssTextCache.set(literal, result);\n return result;\n}\n\n/** A block that still styles the element itself: `&[data-entering]`, `&.open`, `&:hover`, `@media`. */\nconst OWN_BLOCK = /^\\s*(?:&(?![\\s>+~_,])|@media\\b|@supports\\b)/;\n\n/**\n * The element's own declarations, its states and media queries included, with the blocks for its\n * children (`& li:hover`, `${Item}`) and `@keyframes` blanked. Offsets stay the same.\n */\nexport function ownDeclarations(text: string): string {\n const kept: boolean[] = [];\n let out = '';\n let selectorStart = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text[i]!;\n const keeping = kept.every(Boolean);\n if (c === '{') {\n const selector = text.slice(selectorStart, i).split(/[;{}]/).at(-1) ?? '';\n kept.push(keeping && OWN_BLOCK.test(selector));\n if (!kept.at(-1) && keeping) {\n out = out.slice(0, out.length - selector.length) + selector.replace(/[^\\n]/g, ' ');\n }\n out += ' ';\n selectorStart = i + 1;\n } else if (c === '}') {\n kept.pop();\n out += ' ';\n selectorStart = i + 1;\n } else {\n if (c === ';') {\n selectorStart = i + 1;\n }\n out += keeping || c === '\\n' ? c : ' ';\n }\n }\n return out;\n}\n\n/** An interpolated mixin whose name says it carries motion: `${overlayMotion}`, `${fadeInMixin}`. */\nconst MOTION_MIXIN = /motion|transition|animat|fade|slide|zoom|reveal/i;\n\n/**\n * True when the template's own text, a nested template in it (`${(p) => p.$open && css`…`}`) or a\n * motion-named mixin it interpolates has a transition or animation.\n */\nexport function hasMotion(context: Context, css: CssTemplate): boolean {\n const [start, end] = css.node.quasi.range;\n if (\n /(?<![\\w-])(?:transition|animation)(?:-[a-z]+)?\\s*:/.test(\n blankCssComments(context.sourceCode.text.slice(start, end)),\n )\n ) {\n return true;\n }\n return css.node.quasi.expressions.some((expression) => {\n const name = expression.type === 'SpreadElement' ? null : lastName(expression);\n return name !== null && MOTION_MIXIN.test(name);\n });\n}\n\n/** Each CSS template in the file, with the name it is declared as (`const Name = styled…`), if any. */\nexport interface CssTemplate extends CssText {\n node: ESTree.TaggedTemplateExpression;\n name: string | null;\n nameNode: ESTree.Node | null;\n}\n\nexport function cssTemplate(\n context: Context,\n node: ESTree.TaggedTemplateExpression,\n): CssTemplate | null {\n if (!isCssTemplate(node)) {\n return null;\n }\n const { parent } = node;\n const declared =\n parent.type === 'VariableDeclarator' && parent.init === node && parent.id.type === 'Identifier'\n ? parent.id\n : null;\n return {\n ...cssText(context, node.quasi),\n node,\n name: declared?.name ?? null,\n nameNode: declared,\n };\n}\n\nexport function reportAt(context: Context, index: number, length: number, message: string): void {\n const { sourceCode } = context;\n context.report({\n message,\n loc: {\n start: sourceCode.getLocFromIndex(index),\n end: sourceCode.getLocFromIndex(index + length),\n },\n });\n}\n\n/**\n * Properties whose animation moves the content around them. Narrower than the source's list:\n * `grid-template-rows` is the source's own accordion fix, and type and radius don't reflow a page.\n */\nexport const LAYOUT_PROPERTIES = new Set([\n 'width',\n 'height',\n 'min-width',\n 'min-height',\n 'max-width',\n 'max-height',\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'inset',\n 'inset-block',\n 'inset-inline',\n 'margin',\n 'margin-top',\n 'margin-right',\n 'margin-bottom',\n 'margin-left',\n 'margin-block',\n 'margin-inline',\n 'padding',\n 'padding-top',\n 'padding-right',\n 'padding-bottom',\n 'padding-left',\n 'padding-block',\n 'padding-inline',\n 'flex-basis',\n 'gap',\n]);\n\n/** A string value, written `'…'` or as a template literal with no `${…}`. */\nexport function stringValue(node: ESTree.Node): string | null {\n if (node.type === 'Literal') {\n return typeof node.value === 'string' ? node.value : null;\n }\n return node.type === 'TemplateLiteral' && node.expressions.length === 0\n ? (node.quasis[0]?.value.cooked ?? null)\n : null;\n}\n\n/** `fontSize` → `font-size`. */\nexport const kebab = (name: string): string => name.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);\n\n/** The comma-separated items of a CSS value, ignoring commas inside parentheses, with their offsets. */\nexport function splitList(value: string): { item: string; offset: number }[] {\n const items: { item: string; offset: number }[] = [];\n let depth = 0;\n let from = 0;\n for (let i = 0; i <= value.length; i++) {\n const c = value[i];\n if (c === '(') {\n depth++;\n } else if (c === ')') {\n depth--;\n } else if ((c === ',' && depth === 0) || i === value.length) {\n items.push({ item: value.slice(from, i), offset: from });\n from = i + 1;\n }\n }\n return items;\n}\n\n/** `transition`, `transition-property`, `animation` and friends, with the value up to `;`, `{` or `}`. */\nexport const MOTION_DECLARATION =\n /(?<![\\w-])(transition|animation)(-property|-duration|-name)?\\s*:\\s*([^;{}]*)/g;\n\nconst OPENING_WORDS = new Set([\n 'Modal',\n 'Dialog',\n 'Drawer',\n 'Sheet',\n 'Popover',\n 'Tooltip',\n 'Toast',\n 'Snackbar',\n 'Dropdown',\n 'Menu',\n 'Popup',\n 'Flyout',\n]);\n/** A layer over something: a page scrim when fixed, but often a tile's hover layer or a text highlight. */\nconst LAYER_WORDS = new Set(['Overlay', 'Backdrop', 'Scrim']);\n/** Shells like `ModalWrapper` or `DropdownContainer` aren't here: they hold the surface that moves. */\nconst SURFACE_WORDS = new Set(['Content', 'Panel', 'Surface', 'Box', 'List', 'Card', 'Window']);\nconst TRIGGERED_WORDS = new Set(['Menu', 'Dropdown', 'Popover', 'Popup', 'Flyout']);\n/** A part of a surface, or a persistent surface: `ModalCloseButtonContainer`, `SideMenuPanel`. */\nconst NOT_OVERLAY_WORDS = new Set([\n 'Item',\n 'Items',\n 'Option',\n 'Options',\n 'Trigger',\n 'Button',\n 'Btn',\n 'Icon',\n 'Label',\n 'Link',\n 'Divider',\n 'Separator',\n 'Chevron',\n 'Arrow',\n 'Caret',\n 'Title',\n 'Heading',\n 'Header',\n 'Footer',\n 'Close',\n 'Action',\n 'Actions',\n 'Description',\n 'Input',\n 'Field',\n 'Avatar',\n 'Anchor',\n 'Toggle',\n 'Tab',\n 'Row',\n 'Cell',\n 'Text',\n 'Hint',\n 'Caption',\n 'Tag',\n 'Section',\n 'Group',\n 'Side',\n 'Sidebar',\n 'Nav',\n 'Navigation',\n 'Bar',\n]);\n\n/**\n * What a declared name says it is: `triggered` for a surface that opens from a trigger\n * (`DropdownMenu`, `PopoverContent`), `overlay` for another surface that opens (`ModalOverlay`,\n * `ToastContent`), `layer` for only a layer (`Backdrop`, `SelectionOverlay`), else null. Parts\n * of a surface (`MenuItem`, `ModalHeader`) are null.\n */\nexport function overlayKind(name: string | null): 'triggered' | 'overlay' | 'layer' | null {\n const words = name?.match(/[A-Z][a-z0-9]*|^[a-z0-9]+/g);\n const last = words?.at(-1);\n if (\n !words ||\n !last ||\n (!OPENING_WORDS.has(last) && !LAYER_WORDS.has(last) && !SURFACE_WORDS.has(last)) ||\n words.some((word) => NOT_OVERLAY_WORDS.has(word))\n ) {\n return null;\n }\n if (words.some((word) => TRIGGERED_WORDS.has(word))) {\n return 'triggered';\n }\n if (words.some((word) => OPENING_WORDS.has(word))) {\n return 'overlay';\n }\n return words.some((word) => LAYER_WORDS.has(word)) ? 'layer' : null;\n}\n\n/** Libraries and hooks that animate mounting and unmounting from outside the CSS. */\nexport const PRESENCE_LIBRARY =\n /framer-motion|\\bmotion\\/react\\b|AnimatePresence|react-transition-group|CSSTransition|TransitionGroup|@react-spring|react-spring/;\n\nexport const isMotionTag = (context: Context, node: ESTree.TaggedTemplateExpression): boolean => {\n const [start, end] = node.tag.range;\n return /\\b(?:motion|m)\\.\\w|\\banimated\\.\\w/.test(context.sourceCode.text.slice(start, end));\n};\n\n/** `styled(Popover)`: the template styles a component, which may bring its own motion. */\nexport function wrapsComponent(node: ESTree.TaggedTemplateExpression): boolean {\n let tag: ESTree.Expression = node.tag;\n while (\n tag.type === 'MemberExpression' ||\n (tag.type === 'CallExpression' && tag.callee.type === 'MemberExpression')\n ) {\n tag = tag.type === 'MemberExpression' ? tag.object : tag.callee;\n }\n const argument = tag.type === 'CallExpression' ? tag.arguments[0] : undefined;\n const name =\n argument !== undefined && argument.type !== 'SpreadElement' ? lastName(argument) : null;\n return name !== null && /^[A-Z]/.test(name);\n}\n\n/**\n * The animation names a template uses: each word, or `${identifier}`, in an `animation` or\n * `animation-name` value. Other interpolations (`${ModalClose}:hover`) aren't animations.\n */\nexport function animationNames(css: CssTemplate): string[] {\n const names: string[] = [];\n const expressions = css.node.quasi.expressions;\n for (const match of css.text.matchAll(/(?<![\\w-])animation(?:-name)?\\s*:\\s*([^;{}]*)/g)) {\n const valueStart = css.start + match.index + match[0].length - match[1]!.length;\n const valueEnd = valueStart + match[1]!.length;\n for (const expression of expressions) {\n if (\n expression.type === 'Identifier' &&\n expression.range[0] >= valueStart &&\n expression.range[1] <= valueEnd\n ) {\n names.push(expression.name);\n }\n }\n for (const item of splitList(match[1]!)) {\n const word = /^\\s*([A-Za-z][\\w-]*)/.exec(item.item)?.[1];\n if (word !== undefined && word !== 'none') {\n names.push(word);\n }\n }\n }\n return names;\n}\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n type CssText,\n cssTemplate,\n MOTION_DECLARATION,\n reportAt,\n splitList,\n stringValue,\n} from '../motion';\nimport { docs, propertyName } from '../shared';\n\n// Adapted from transitions.dev's `hardcoded-duration` check (MIT; see ../THIRD_PARTY_NOTICES.md), pointed\n// at PDS's own scale in `variables/transitions`.\n\n/** `TransitionDuration`, mirrored here because the plugin has no runtime imports. */\nexport const DURATION_TOKENS: Record<number, string> = {\n 100: 'ExtraFast',\n 150: 'Faster',\n 200: 'Fast',\n 300: 'MediumFast',\n 400: 'Medium',\n 1000: 'OneSecond',\n};\n/** `TransitionDurationInSeconds`, the same steps. */\nexport const SECONDS_TOKENS: Record<number, string> = { ...DURATION_TOKENS };\n/** At or under this, a duration is a reduced-motion override or an instant change, not motion. */\nconst INSTANT_MS = 20;\n\nconst TIME = /(?<![\\w.$-])(\\d*\\.?\\d+)(ms|s)(?![\\w-])/;\n/** A spinner's or shimmer's period isn't a state change, so the scale doesn't apply. */\nconst LOOP = /\\binfinite\\b/;\nconst STRING_PROPERTIES = new Set([\n 'transition',\n 'transitionDuration',\n 'animation',\n 'animationDuration',\n]);\n\nconst toMs = (value: string, unit: string): number => Number(value) * (unit === 's' ? 1000 : 1);\n\nfunction cssMessage(literal: string, ms: number): string {\n const token = DURATION_TOKENS[ms];\n return token\n ? `Literal duration ${literal}: use \\`TransitionDuration.${token}\\` from \\`@persona/design-system/variables/transitions\\`.`\n : `Literal duration ${literal} is off the PDS scale: use a \\`TransitionDuration\\` token (100, 150, 200, 300, 400 or 1000 ms) from \\`@persona/design-system/variables/transitions\\`.`;\n}\n\nfunction secondsMessage(seconds: number): string {\n const token = SECONDS_TOKENS[Math.round(seconds * 1000)];\n return token\n ? `Literal duration ${seconds}: use \\`TransitionDurationInSeconds.${token}\\` from \\`@persona/design-system/variables/transitions\\`.`\n : `Literal duration ${seconds} is off the PDS scale: use a \\`TransitionDurationInSeconds\\` token (0.1 to 0.4, or 1) from \\`@persona/design-system/variables/transitions\\`.`;\n}\n\n/** The first time in each item of a `transition` or `animation` list: its duration, not its delay. */\nfunction durations(value: string): { literal: string; ms: number; offset: number }[] {\n return splitList(value).flatMap(({ item, offset }) => {\n const match = TIME.exec(item);\n if (!match || LOOP.test(item)) {\n return [];\n }\n const ms = toMs(match[1]!, match[2]!);\n return ms > INSTANT_MS ? [{ literal: match[0], ms, offset: offset + match.index }] : [];\n });\n}\n\n/** An interpolation that is itself a duration: `${TransitionDuration.Fast}`, `${OPEN_MS}`, `${ms}ms`. */\nconst DURATION_EXPRESSION = /duration|_MS\\b|Ms\\b|\\bms\\b/i;\nconst UNIT_AFTER = /^\\s*\\}m?s(?![\\w-])/;\n\n/**\n * The CSS text with each duration interpolation written as `0ms`, so it holds the item's duration\n * slot and a literal after it (a delay) isn't read as the duration.\n */\nfunction markDurationExpressions(\n context: Context,\n node: ESTree.TaggedTemplateExpression,\n css: CssText,\n): string {\n const source = context.sourceCode.text;\n let { text } = css;\n for (const expression of node.quasi.expressions) {\n const [start, end] = expression.range;\n if (\n !DURATION_EXPRESSION.test(source.slice(start, end)) &&\n !UNIT_AFTER.test(source.slice(end))\n ) {\n continue;\n }\n let from = start - css.start;\n let to = end - css.start;\n while (from > 0 && text[from - 1] === '_') {\n from--;\n }\n while (to < text.length && text[to] === '_') {\n to++;\n }\n text = text.slice(0, from) + '0ms'.padEnd(to - from) + text.slice(to);\n }\n return text;\n}\n\n/**\n * True when `node` is the value of a `transition` key or a `transition={…}` JSX attribute, or a\n * per-value transition inside one (`transition={{ opacity: { duration } }}`).\n */\nfunction isTransitionObject(node: ESTree.Node, depth = 0): boolean {\n const { parent } = node;\n if (parent.type === 'Property' && parent.value === node) {\n return (\n propertyName(parent) === 'transition' || (depth === 0 && isTransitionObject(parent.parent, 1))\n );\n }\n if (parent.type === 'JSXExpressionContainer') {\n const attribute = parent.parent;\n return (\n attribute.type === 'JSXAttribute' &&\n attribute.name.type === 'JSXIdentifier' &&\n attribute.name.name === 'transition'\n );\n }\n return false;\n}\n\nexport const durationToken: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Transition and animation durations come from `TransitionDuration` (CSS) or `TransitionDurationInSeconds` (Framer Motion), not literals.',\n ),\n },\n createOnce(context: Context) {\n return {\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n if (css === null) {\n return;\n }\n for (const match of markDurationExpressions(context, node, css).matchAll(\n MOTION_DECLARATION,\n )) {\n if (\n match[2] === '-property' ||\n match[2] === '-name' ||\n (match[2] === '-duration' && LOOP.test(css.text))\n ) {\n continue;\n }\n const valueStart = match.index + match[0].length - match[3]!.length;\n for (const { literal, ms, offset } of durations(match[3]!)) {\n reportAt(\n context,\n css.start + valueStart + offset,\n literal.length,\n cssMessage(literal, ms),\n );\n }\n }\n },\n Property(node: ESTree.ObjectProperty) {\n const name = propertyName(node);\n const { value } = node;\n const text = stringValue(value);\n if (name === null) {\n return;\n }\n if (STRING_PROPERTIES.has(name) && text !== null) {\n for (const { literal, ms } of durations(text)) {\n context.report({ node, message: cssMessage(literal, ms) });\n }\n } else if (\n name === 'duration' &&\n value.type === 'Literal' &&\n typeof value.value === 'number' &&\n value.value * 1000 > INSTANT_MS &&\n node.parent.type === 'ObjectExpression' &&\n isTransitionObject(node.parent) &&\n !node.parent.properties.some(\n (item) => item.type === 'Property' && propertyName(item) === 'repeat',\n )\n ) {\n context.report({ node, message: secondsMessage(value.value) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n animationNames,\n type CssTemplate,\n cssTemplate,\n MOTION_DECLARATION,\n overlayKind,\n ownDeclarations,\n} from '../motion';\nimport { docs, rootIdentifier } from '../shared';\n\n// Adapted from transitions.dev's `recipe-mismatch` \"has no exit animation\" and \"unmounts\n// instantly\" checks (MIT; see ../THIRD_PARTY_NOTICES.md).\n\nconst NO_ANIMATION = /^\\s*(?:none|initial|inherit|unset|revert)?\\s*$/;\nconst LOOP = /\\binfinite\\b/;\nconst FIXED = /(?<![\\w-])position\\s*:\\s*fixed\\b/;\nconst KEYFRAMES_NAME = /@keyframes\\s+([\\w-]+)/g;\n/** `fadeOut`, `fade-out`, `exit`: an animation name that reads as an exit (not `layout`). */\nconst EXIT_NAME =\n /(?:^|[-_])(?:out|exit|hide|close|leave|disappear)$|[a-z0-9](?:Out|Exit|Hide|Close|Leave|Disappear)$/;\n/** Ways a file can hold an overlay on screen while it animates out. */\nconst EXIT_MARKERS =\n /AnimatePresence|CSSTransition|TransitionGroup|react-spring|onAnimationEnd|onTransitionEnd|animationend|transitionend|data-state\\W{1,4}closed|data-exiting|isExiting|\\b[iI]sClosing\\b|\\bexit=/;\n\nconst styledMessage = (name: string) =>\n `\\`${name}\\` animates in but disappears instantly. Give it an exit (React Aria: style \\`[data-exiting]\\`; Radix: \\`[data-state='closed']\\`), shorter than the enter.`;\nconst MOTION_MESSAGE =\n 'Mounts with an enter animation but unmounts instantly. Add `exit` (inside `AnimatePresence`), shorter than the enter.';\n\nfunction isMotionElement(name: ESTree.JSXElementName): boolean {\n return (\n name.type === 'JSXMemberExpression' &&\n name.object.type === 'JSXIdentifier' &&\n (name.object.name === 'motion' || name.object.name === 'm')\n );\n}\n\nfunction attribute(node: ESTree.JSXOpeningElement, name: string): ESTree.JSXAttribute | null {\n for (const item of node.attributes) {\n if (\n item.type === 'JSXAttribute' &&\n item.name.type === 'JSXIdentifier' &&\n item.name.name === name\n ) {\n return item;\n }\n }\n return null;\n}\n\nconst isFalse = (item: ESTree.JSXAttribute): boolean =>\n item.value?.type === 'JSXExpressionContainer' &&\n item.value.expression.type === 'Literal' &&\n item.value.expression.value === false;\n\n/** An `animation` or `animation-name` that plays once: an enter, not a loop or a reset. */\nfunction hasEnterAnimation(css: CssTemplate): boolean {\n for (const match of ownDeclarations(css.text).matchAll(MOTION_DECLARATION)) {\n if (\n match[1] === 'animation' &&\n (match[2] === undefined || match[2] === '-name') &&\n !NO_ANIMATION.test(match[3]!) &&\n !LOOP.test(match[3]!)\n ) {\n return true;\n }\n }\n return false;\n}\n\n/** The node with any grouping parentheses around it. */\nfunction outermost(node: ESTree.Node): ESTree.Node {\n let at = node;\n while (at.parent?.type === 'ParenthesizedExpression') {\n at = at.parent;\n }\n return at;\n}\n\nfunction unwrap(node: ESTree.Node): ESTree.Node {\n let at = node;\n while (at.type === 'ParenthesizedExpression') {\n at = at.expression;\n }\n return at;\n}\n\n/** `{open && <X />}` or `{open ? <X /> : null}`: rendered only while something is true. */\nfunction isConditional(node: ESTree.JSXElement): boolean {\n const self = outermost(node);\n const { parent } = self;\n return (\n (parent?.type === 'LogicalExpression' && parent.operator === '&&' && parent.right === self) ||\n (parent?.type === 'ConditionalExpression' && parent.test !== self)\n );\n}\n\n/** `{tab === 1 ? <motion.div …/> : <B />}` outside `<AnimatePresence>`: a content swap, not an unmount. */\nfunction isSwap(node: ESTree.JSXElement): boolean {\n const self = outermost(node);\n const { parent } = self;\n if (parent?.type !== 'ConditionalExpression' || insidePresence(node)) {\n return false;\n }\n const other = unwrap(parent.consequent === self ? parent.alternate : parent.consequent);\n return other.type === 'JSXElement' || other.type === 'JSXFragment';\n}\n\nfunction insidePresence(node: ESTree.Node): boolean {\n for (let at: ESTree.Node | null = node.parent; at !== null; at = at.parent) {\n if (\n at.type === 'JSXElement' &&\n at.openingElement.name.type === 'JSXIdentifier' &&\n at.openingElement.name.name === 'AnimatePresence'\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport const exitMotion: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'An overlay that animates in also animates out: a styled overlay with an enter animation has an exit, and a conditionally rendered `motion.*` element with `initial` has `exit`.',\n ),\n },\n createOnce(context: Context) {\n let candidates: CssTemplate[] = [];\n let names = new Set<string>();\n return {\n before() {\n candidates = [];\n names = new Set();\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n if (css === null) {\n return;\n }\n if (rootIdentifier(node.tag) === 'keyframes' && css.name !== null) {\n names.add(css.name);\n }\n for (const name of animationNames(css)) {\n names.add(name);\n }\n for (const match of css.text.matchAll(KEYFRAMES_NAME)) {\n names.add(match[1]!);\n }\n const kind = overlayKind(css.name);\n if (\n kind !== null &&\n (kind !== 'layer' || FIXED.test(ownDeclarations(css.text))) &&\n hasEnterAnimation(css)\n ) {\n candidates.push(css);\n }\n },\n JSXElement(node: ESTree.JSXElement) {\n const opening = node.openingElement;\n const initial = attribute(opening, 'initial');\n if (\n isMotionElement(opening.name) &&\n initial !== null &&\n !isFalse(initial) &&\n attribute(opening, 'exit') === null &&\n !opening.attributes.some((item) => item.type === 'JSXSpreadAttribute') &&\n isConditional(node) &&\n !isSwap(node)\n ) {\n context.report({ node: opening.name, message: MOTION_MESSAGE });\n }\n },\n after() {\n if (\n candidates.length === 0 ||\n EXIT_MARKERS.test(context.sourceCode.text) ||\n [...names].some((name) => EXIT_NAME.test(name))\n ) {\n return;\n }\n for (const css of candidates) {\n context.report({ node: css.nameNode!, message: styledMessage(css.name!) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n docs,\n isCssTemplate,\n isSmallSize,\n jsxStringValue,\n lastName,\n propertyName,\n reportMatches,\n staticMemberName,\n toPx,\n} from '../shared';\n\nconst DEFAULT_MIN_PX = 11;\nconst DEFAULT_ROOT_FONT_PX = 16;\n\nconst EXTRA_SMALL_STYLES = new Set(['TextExtraSmall', 'TextExtraSmallMono']);\nconst PARAGRAPH_SCALES = new Set(['paragraph', 'paragraphMixins']);\nconst SIZED_COMPONENTS = new Set(['Paragraph', 'Label']);\nconst FONT_SIZE_PROPERTIES = new Set(['fontSize', 'font-size']);\nconst RAW_FONT_SIZE = /font-size\\s*:\\s*(\\d*\\.?\\d+)\\s*(px|rem|em)?(?![\\w.])/g;\nconst SIZE_VALUE = /^\\s*(\\d*\\.?\\d+)\\s*(px|rem|em)?\\s*$/;\n\n/** The rule's options, which oxlint has already checked against the schema. */\nfunction readSettings(options: unknown): { minPx: number; rootFontPx: number } {\n const read = (key: string, fallback: number): number => {\n const value: unknown =\n typeof options === 'object' && options !== null ? Reflect.get(options, key) : undefined;\n return typeof value === 'number' ? value : fallback;\n };\n return {\n minPx: read('minPx', DEFAULT_MIN_PX),\n rootFontPx: read('rootFontPx', DEFAULT_ROOT_FONT_PX),\n };\n}\n\nconst small = (what: string) =>\n `${what}: text under the minimum size. Fine for a label inside a graphic (8 px); copy uses \\`TextSmall\\` (12 px).`;\n\n/** The text of a font-size value written as a number, a string or a plain template. */\nfunction sizeText(value: ESTree.Expression): string | null {\n if (value.type === 'Literal') {\n return typeof value.value === 'number' || typeof value.value === 'string'\n ? String(value.value)\n : null;\n }\n if (value.type === 'TemplateLiteral' && value.expressions.length === 0) {\n return value.quasis[0]?.value.cooked ?? null;\n }\n return null;\n}\n\nexport const minCopySize: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Copy is at least 11 CSS px. Fine for a label inside a graphic (8 px); copy uses `TextSmall` (12 px).',\n ),\n schema: [\n {\n type: 'object',\n properties: { minPx: { type: 'number' }, rootFontPx: { type: 'number' } },\n additionalProperties: false,\n },\n ],\n },\n createOnce(context: Context) {\n const settings = () => readSettings(context.options[0]);\n return {\n MemberExpression(node: ESTree.MemberExpression) {\n const name = staticMemberName(node);\n if (name === null) {\n return;\n }\n if (EXTRA_SMALL_STYLES.has(name)) {\n context.report({ node, message: small(`\\`${name}\\``) });\n } else if (name === 'xs') {\n const scale = lastName(node.object);\n if (scale !== null && PARAGRAPH_SCALES.has(scale)) {\n context.report({ node, message: small(`\\`${scale}.xs\\``) });\n }\n }\n },\n JSXOpeningElement(node: ESTree.JSXOpeningElement) {\n if (node.name.type !== 'JSXIdentifier' || !SIZED_COMPONENTS.has(node.name.name)) {\n return;\n }\n for (const attribute of node.attributes) {\n if (\n attribute.type === 'JSXAttribute' &&\n attribute.name.type === 'JSXIdentifier' &&\n attribute.name.name === 'size' &&\n jsxStringValue(attribute) === 'xs'\n ) {\n context.report({\n node: attribute,\n message: small(`\\`<${node.name.name} size=\"xs\">\\``),\n });\n }\n }\n },\n ObjectExpression(node: ESTree.ObjectExpression) {\n const { minPx, rootFontPx } = settings();\n for (const property of node.properties) {\n if (property.type !== 'Property') {\n continue;\n }\n const name = propertyName(property);\n if (name === null || !FONT_SIZE_PROPERTIES.has(name)) {\n continue;\n }\n const text = sizeText(property.value);\n const match = text === null ? null : SIZE_VALUE.exec(text);\n const size = match?.[1];\n const unit = match?.[2];\n if (\n size !== undefined &&\n isSmallSize(toPx(Number(size), unit, rootFontPx), unit, minPx)\n ) {\n context.report({ node: property, message: small(`font-size ${size}${unit ?? 'px'}`) });\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n const { minPx, rootFontPx } = settings();\n for (const quasi of node.quasi.quasis) {\n reportMatches(\n context,\n quasi,\n RAW_FONT_SIZE,\n (match) => small(`font-size ${match[1]}${match[2] ?? 'px'}`),\n (match) => isSmallSize(toPx(Number(match[1]), match[2], rootFontPx), match[2], minPx),\n );\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n animationNames,\n type CssTemplate,\n cssTemplate,\n overlayKind,\n ownDeclarations,\n} from '../motion';\nimport { docs, rootIdentifier } from '../shared';\n\n// Adapted from transitions.dev's `recipe-mismatch` \"grows from its center, not from its trigger\"\n// check (MIT; see ../THIRD_PARTY_NOTICES.md).\n\n/** A scale below 1, as an opening surface grows from: `scale(0.95)`, `scaleY(0)`, `scale: 0.96`. */\nconst SCALES =\n /(?<![\\w-])scale(?:[XYZ]|3d)?\\(\\s*(?:0?\\.\\d|0(?![.\\d]))|(?<![\\w-])scale\\s*:\\s*(?:0?\\.\\d|0(?![.\\d]))/;\nconst KEYFRAMES_BLOCK = /@keyframes\\s+([\\w-]+)\\s*\\{((?:[^{}]*\\{[^{}]*\\})*[^{}]*)\\}/g;\nconst ORIGIN = /transform-origin|transformOrigin/;\n\nconst message = (name: string) =>\n `\\`${name}\\` scales from its centre. A menu or popover grows from its trigger: set \\`transform-origin\\` (React Aria: \\`var(--trigger-anchor-point)\\`; Radix: \\`var(--radix-popover-content-transform-origin)\\`).`;\n\nexport const motionOrigin: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'A menu, dropdown or popover that scales sets `transform-origin`, so it grows from its trigger rather than its centre.',\n ),\n },\n createOnce(context: Context) {\n let candidates: { css: CssTemplate; references: string[] }[] = [];\n let scaling = new Set<string>();\n return {\n before() {\n candidates = [];\n scaling = new Set();\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n if (css === null) {\n return;\n }\n if (\n rootIdentifier(node.tag) === 'keyframes' &&\n css.name !== null &&\n SCALES.test(css.text)\n ) {\n scaling.add(css.name);\n }\n for (const match of css.text.matchAll(KEYFRAMES_BLOCK)) {\n if (SCALES.test(match[2]!)) {\n scaling.add(match[1]!);\n }\n }\n if (overlayKind(css.name) === 'triggered') {\n candidates.push({ css, references: animationNames(css) });\n }\n },\n after() {\n if (ORIGIN.test(context.sourceCode.text)) {\n return;\n }\n for (const { css, references } of candidates) {\n if (\n SCALES.test(ownDeclarations(css.text)) ||\n references.some((name) => scaling.has(name))\n ) {\n context.report({ node: css.nameNode!, message: message(css.name!) });\n }\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n cssTemplate,\n kebab,\n LAYOUT_PROPERTIES,\n MOTION_DECLARATION,\n reportAt,\n splitList,\n stringValue,\n} from '../motion';\nimport { docs, propertyName, rootIdentifier } from '../shared';\n\n// Adapted from transitions.dev's `layout-animation` and `recipe-mismatch` (\"animates … (layout)\")\n// checks (MIT; see ../THIRD_PARTY_NOTICES.md).\n\nconst TRANSITION_PROPERTIES = new Set(['transition', 'transitionProperty', 'transition-property']);\nconst KEYFRAMES_BLOCK = /@keyframes\\s+[\\w-]+\\s*\\{((?:[^{}]*\\{[^{}]*\\})*[^{}]*)\\}/g;\nconst DECLARATION = /(?<![\\w-])([a-z-]+)\\s*:/g;\n/** `height 0s`: a duration of zero switches the value rather than animating it. */\nconst INSTANT = /^\\s*[a-z-]+\\s+0?\\.?0*m?s\\b/;\n\nconst message = (property: string) =>\n `Animating \\`${property}\\` runs layout on every frame and can shift the content around it. Animate \\`transform\\` or \\`opacity\\` instead; to expand a section, animate \\`grid-template-rows\\` from \\`0fr\\` to \\`1fr\\`.`;\n\n/** Each layout property a transition list names, with its offset in `value`. */\nfunction layoutItems(value: string): { property: string; offset: number }[] {\n return splitList(value).flatMap(({ item, offset }) => {\n const match = /^\\s*([a-z-]+)/.exec(item);\n const property = match?.[1];\n return property !== undefined && LAYOUT_PROPERTIES.has(property) && !INSTANT.test(item)\n ? [{ property, offset: offset + match![0].length - property.length }]\n : [];\n });\n}\n\nfunction reportKeyframes(context: Context, text: string, start: number) {\n for (const match of text.matchAll(DECLARATION)) {\n const property = match[1]!;\n if (LAYOUT_PROPERTIES.has(property)) {\n reportAt(\n context,\n start + match.index + match[0].indexOf(property),\n property.length,\n message(property),\n );\n }\n }\n}\n\nexport const noLayoutMotion: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Transitions and keyframes animate `transform` and `opacity`, not layout properties such as `height`, `width`, `top` or `margin`.',\n ),\n },\n createOnce(context: Context) {\n return {\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n if (css === null) {\n return;\n }\n if (rootIdentifier(node.tag) === 'keyframes') {\n reportKeyframes(context, css.text, css.start);\n return;\n }\n for (const match of css.text.matchAll(KEYFRAMES_BLOCK)) {\n const body = match[1]!;\n reportKeyframes(context, body, css.start + match.index + match[0].indexOf(body));\n }\n for (const match of css.text.matchAll(MOTION_DECLARATION)) {\n if (match[1] !== 'transition' || (match[2] !== undefined && match[2] !== '-property')) {\n continue;\n }\n const valueStart = match.index + match[0].length - match[3]!.length;\n for (const { property, offset } of layoutItems(match[3]!)) {\n reportAt(context, css.start + valueStart + offset, property.length, message(property));\n }\n }\n },\n Property(node: ESTree.ObjectProperty) {\n const name = propertyName(node);\n const text = stringValue(node.value);\n if (name === null || !TRANSITION_PROPERTIES.has(name) || text === null) {\n return;\n }\n for (const { property } of layoutItems(kebab(text))) {\n context.report({ node, message: message(property) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, staticMemberName } from '../shared';\n\nconst TABLE_ELEMENTS = new Set(['table', 'th', 'td']);\n\nconst message = (what: string) =>\n `Hand-rolled table markup (${what}). Use \\`Table\\`, \\`DataTable\\` or \\`IndexTableLayout\\`.`;\n\nexport const noRawTable: Rule = {\n meta: {\n type: 'problem',\n docs: docs('Use `Table`, `DataTable` or `IndexTableLayout`, not hand-rolled table markup.'),\n },\n createOnce(context: Context) {\n return {\n JSXOpeningElement(node: ESTree.JSXOpeningElement) {\n if (node.name.type === 'JSXIdentifier' && TABLE_ELEMENTS.has(node.name.name)) {\n context.report({ node: node.name, message: message(`<${node.name.name}>`) });\n }\n },\n MemberExpression(node: ESTree.MemberExpression) {\n const name = staticMemberName(node);\n if (\n name !== null &&\n TABLE_ELEMENTS.has(name) &&\n node.object.type === 'Identifier' &&\n node.object.name === 'styled'\n ) {\n context.report({ node, message: message(`styled.${name}`) });\n }\n },\n CallExpression(node: ESTree.CallExpression) {\n const [argument] = node.arguments;\n if (\n node.callee.type === 'Identifier' &&\n node.callee.name === 'styled' &&\n argument?.type === 'Literal' &&\n typeof argument.value === 'string' &&\n TABLE_ELEMENTS.has(argument.value)\n ) {\n context.report({ node, message: message(`styled('${argument.value}')`) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { cssTemplate, MOTION_DECLARATION, reportAt, splitList, stringValue } from '../motion';\nimport { docs, propertyName } from '../shared';\n\n// Adapted from transitions.dev's `transition-all` check (MIT; see ../THIRD_PARTY_NOTICES.md).\n\nconst TRANSITION_PROPERTIES = new Set(['transition', 'transitionProperty', 'transition-property']);\nconst TAILWIND_ALL = /(?:^|\\s)(?:[\\w-]+:)*transition-all(?=\\s|$)/;\nconst MESSAGE =\n '`transition: all` animates every property, layout included. Name the ones the states change (`opacity`, `transform`, `background-color`).';\n\n/** The offset, in `value`, of each list item that transitions `all`. */\nfunction allOffsets(value: string): number[] {\n return splitList(value).flatMap(({ item, offset }) => {\n const match = /^\\s*all(?![\\w-])/.exec(item);\n return match ? [offset + match[0].indexOf('all')] : [];\n });\n}\n\nexport const noTransitionAll: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Transition named properties, never `all`, which animates layout too and costs more to paint.',\n ),\n },\n createOnce(context: Context) {\n return {\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n if (css === null) {\n return;\n }\n for (const match of css.text.matchAll(MOTION_DECLARATION)) {\n if (match[1] !== 'transition' || (match[2] !== undefined && match[2] !== '-property')) {\n continue;\n }\n const valueStart = match.index + match[0].length - match[3]!.length;\n for (const offset of allOffsets(match[3]!)) {\n reportAt(context, css.start + valueStart + offset, 3, MESSAGE);\n }\n }\n },\n Property(node: ESTree.ObjectProperty) {\n const name = propertyName(node);\n const text = stringValue(node.value);\n if (\n name !== null &&\n TRANSITION_PROPERTIES.has(name) &&\n text !== null &&\n allOffsets(text).length > 0\n ) {\n context.report({ node, message: MESSAGE });\n }\n },\n // Class strings reach the DOM through `className`, `cn()`, `cva()` and template literals alike.\n Literal(node: ESTree.Literal) {\n if (typeof node.value === 'string' && TAILWIND_ALL.test(node.value)) {\n context.report({ node, message: MESSAGE });\n }\n },\n TemplateElement(node: ESTree.TemplateElement) {\n if (TAILWIND_ALL.test(node.value.cooked ?? node.value.raw)) {\n context.report({ node, message: MESSAGE });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport {\n type CssTemplate,\n cssTemplate,\n hasMotion,\n isMotionTag,\n overlayKind,\n ownDeclarations,\n PRESENCE_LIBRARY,\n wrapsComponent,\n} from '../motion';\nimport { docs } from '../shared';\n\n// Adapted from transitions.dev's `untransitioned-overlay` check (MIT; see ../THIRD_PARTY_NOTICES.md). The\n// source keys on JSX tags like `<Modal>`; in a PDS app those are PDS components that bring their own\n// motion, so this keys on hand-rolled overlays declared as styled components instead.\n\nconst FLOATING = /(?<![\\w-])position\\s*:\\s*(?:fixed|absolute)\\b/;\nconst FIXED = /(?<![\\w-])position\\s*:\\s*fixed\\b/;\n\nconst message = (name: string) =>\n `\\`${name}\\` is an overlay with no transition or animation, so it pops in and out. Fade it in and out (a menu or popover also scales a little from its trigger), or use the PDS component.`;\n\nexport const overlayMotion: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'A hand-rolled overlay (a fixed or absolute styled component named like a modal, drawer, popover, menu, tooltip or toast, or a fixed backdrop) has a transition or animation.',\n ),\n },\n createOnce(context: Context) {\n let candidates: CssTemplate[] = [];\n return {\n before() {\n candidates = [];\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n const css = cssTemplate(context, node);\n const kind = css === null ? null : overlayKind(css.name);\n if (\n css !== null &&\n kind !== null &&\n (kind === 'layer' ? FIXED : FLOATING).test(ownDeclarations(css.text)) &&\n !hasMotion(context, css) &&\n !isMotionTag(context, node) &&\n !wrapsComponent(node)\n ) {\n candidates.push(css);\n }\n },\n after() {\n if (candidates.length === 0 || PRESENCE_LIBRARY.test(context.sourceCode.text)) {\n return;\n }\n for (const css of candidates) {\n context.report({ node: css.nameNode!, message: message(css.name!) });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Location, Rule } from '@oxlint/plugins';\n\nimport { docs, isCssTemplate, propertyName, rootIdentifier, sourceText } from '../shared';\n\nconst MOTION_PROPERTIES = new Set([\n 'animation',\n 'animationName',\n 'transition',\n 'transitionProperty',\n 'animation-name',\n 'transition-property',\n]);\nconst MOTION_DECLARATION =\n /@keyframes\\b|(?<![\\w-])(?:animation|animation-name|transition|transition-property)\\s*:/g;\nconst REDUCED_MOTION = 'prefers-reduced-motion';\n\nconst MESSAGE =\n 'Animation or transition in a file with no `prefers-reduced-motion` block. Add one that keeps the change as a short opacity fade (`ReducedMotionFade`: 150 ms) with no movement, rather than turning it off.';\n\nexport const reducedMotion: Rule = {\n meta: {\n type: 'suggestion',\n docs: docs(\n 'Animation or transition only in a file with a `prefers-reduced-motion` block. Reported once per file, at the first one.',\n ),\n },\n createOnce(context: Context) {\n let first: Location | null = null;\n let hasReducedMotion = false;\n const note = (location: Location) => {\n first ??= location;\n };\n const noteReducedMotion = (text: string) => {\n if (text.includes(REDUCED_MOTION)) {\n hasReducedMotion = true;\n }\n };\n return {\n before() {\n first = null;\n hasReducedMotion = false;\n },\n Literal(node) {\n if (typeof node.value === 'string') {\n noteReducedMotion(node.value);\n }\n },\n TemplateElement(node) {\n noteReducedMotion(sourceText(context, node));\n },\n ObjectExpression(node: ESTree.ObjectExpression) {\n for (const property of node.properties) {\n const name = property.type === 'Property' ? propertyName(property) : null;\n if (property.type === 'Property' && name !== null && MOTION_PROPERTIES.has(name)) {\n note(property.key.loc);\n }\n }\n },\n TaggedTemplateExpression(node: ESTree.TaggedTemplateExpression) {\n if (!isCssTemplate(node)) {\n return;\n }\n if (rootIdentifier(node.tag) === 'keyframes') {\n note(node.loc);\n }\n const { sourceCode } = context;\n for (const quasi of node.quasi.quasis) {\n const [start] = quasi.range;\n for (const match of sourceText(context, quasi).matchAll(MOTION_DECLARATION)) {\n const index = start + match.index;\n note({\n start: sourceCode.getLocFromIndex(index),\n end: sourceCode.getLocFromIndex(index + match[0].length),\n });\n }\n }\n },\n after() {\n if (first !== null && !hasReducedMotion) {\n context.report({ message: MESSAGE, loc: first });\n }\n },\n };\n },\n};\n","import type { Context, ESTree, Rule } from '@oxlint/plugins';\n\nimport { docs, reportMatches, staticMemberName } from '../shared';\n\nconst HEX = /(?<![\\w&/#])#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4})\\b/g;\nconst LINK_ATTRIBUTES = new Set(['href', 'to']);\nconst MODULE_PARENTS = new Set([\n 'ImportDeclaration',\n 'ExportNamedDeclaration',\n 'ExportAllDeclaration',\n 'ImportExpression',\n]);\n\n// `chartColor(Color.X)` is a deliberate chart series override (PDS charts accept Persona tokens,\n// never hex), so a `Color.*` inside it is allowed like a `semanticColor` fallback. Hex still fails.\nconst TOKEN_CALLEES = new Set(['semanticColor', 'chartColor']);\n\nconst isSemanticColorCall = (node: ESTree.CallExpression): boolean =>\n node.callee.type === 'Identifier' && TOKEN_CALLEES.has(node.callee.name);\n\nconst isLinkAttribute = (node: ESTree.JSXAttribute): boolean =>\n node.name.type === 'JSXIdentifier' && LINK_ATTRIBUTES.has(node.name.name);\n\nexport const semanticColor: Rule = {\n meta: {\n type: 'problem',\n docs: docs(\n 'Paint with a semantic token (`semanticColor`), not a hex value or a `Color.*` outside its fallback.',\n ),\n },\n createOnce(context: Context) {\n let insideSemanticColor = 0;\n let insideLink = 0;\n const checkText = (node: ESTree.Node) => {\n if (insideLink === 0) {\n reportMatches(\n context,\n node,\n HEX,\n (match) => `Hex colour ${match[0]}: paint with a semantic token (\\`semanticColor\\`).`,\n );\n }\n };\n return {\n before() {\n insideSemanticColor = 0;\n insideLink = 0;\n },\n CallExpression(node) {\n if (isSemanticColorCall(node)) {\n insideSemanticColor++;\n }\n },\n 'CallExpression:exit'(node) {\n if (isSemanticColorCall(node)) {\n insideSemanticColor--;\n }\n },\n JSXAttribute(node) {\n if (isLinkAttribute(node)) {\n insideLink++;\n }\n },\n 'JSXAttribute:exit'(node) {\n if (isLinkAttribute(node)) {\n insideLink--;\n }\n },\n Literal(node) {\n if (typeof node.value === 'string' && !MODULE_PARENTS.has(node.parent.type)) {\n checkText(node);\n }\n },\n TemplateElement: checkText,\n MemberExpression(node) {\n const name = staticMemberName(node);\n if (\n insideSemanticColor === 0 &&\n name !== null &&\n node.object.type === 'Identifier' &&\n node.object.name === 'Color' &&\n /^[A-Z]\\w*$/.test(name)\n ) {\n context.report({\n node,\n message: `\\`Color.${name}\\` outside \\`semanticColor\\`: paint with a semantic token, with this as its fallback (or wrap a chart series override in \\`chartColor\\`).`,\n });\n }\n },\n };\n },\n};\n","import type { Plugin } from '@oxlint/plugins';\n\nimport { completeTypography } from './rules/complete-typography';\nimport { durationToken } from './rules/duration-token';\nimport { exitMotion } from './rules/exit-motion';\nimport { minCopySize } from './rules/min-copy-size';\nimport { motionOrigin } from './rules/motion-origin';\nimport { noLayoutMotion } from './rules/no-layout-motion';\nimport { noRawTable } from './rules/no-raw-table';\nimport { noTransitionAll } from './rules/no-transition-all';\nimport { overlayMotion } from './rules/overlay-motion';\nimport { reducedMotion } from './rules/reduced-motion';\nimport { semanticColor } from './rules/semantic-color';\n\n/**\n * The product UI standard's automated checks as an oxlint JS plugin. Load it with\n * `\"jsPlugins\": [\"@persona/design-system/lint\"]` and enable rules as `pds/<rule>`.\n */\nconst plugin: Plugin = {\n meta: { name: 'pds' },\n rules: {\n 'semantic-color': semanticColor,\n 'complete-typography': completeTypography,\n 'min-copy-size': minCopySize,\n 'reduced-motion': reducedMotion,\n 'no-raw-table': noRawTable,\n 'exit-motion': exitMotion,\n 'overlay-motion': overlayMotion,\n 'motion-origin': motionOrigin,\n 'no-layout-motion': noLayoutMotion,\n 'no-transition-all': noTransitionAll,\n 'duration-token': durationToken,\n },\n};\n\nexport default plugin;\n"],"mappings":"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"}
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
"pds/complete-typography": "error",
|
|
6
6
|
"pds/no-raw-table": "error",
|
|
7
7
|
"pds/min-copy-size": "warn",
|
|
8
|
-
"pds/reduced-motion": "warn"
|
|
8
|
+
"pds/reduced-motion": "warn",
|
|
9
|
+
"pds/exit-motion": "warn",
|
|
10
|
+
"pds/overlay-motion": "warn",
|
|
11
|
+
"pds/motion-origin": "warn",
|
|
12
|
+
"pds/no-layout-motion": "warn",
|
|
13
|
+
"pds/no-transition-all": "warn",
|
|
14
|
+
"pds/duration-token": "warn"
|
|
9
15
|
}
|
|
10
16
|
}
|
package/dist/mixins/focus.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as css } from "../styledComponentsInterop-Cs5CCPRy.mjs";
|
|
2
|
-
import { semanticColor } from "../lib/semanticColor.mjs";
|
|
3
2
|
import { isFocusedVisible, isNotDisabled } from "../lib/pseudoClass.mjs";
|
|
3
|
+
import { semanticColor } from "../lib/semanticColor.mjs";
|
|
4
4
|
import { Color } from "@persona/design-tokens";
|
|
5
5
|
//#region src/mixins/focus.ts
|
|
6
6
|
const focusColor = (theme) => semanticColor(theme, "BorderFocus", Color.BorderFocus);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as css } from "../styledComponentsInterop-Cs5CCPRy.mjs";
|
|
2
|
-
import "../variables/transitions.mjs";
|
|
3
2
|
import { isDisabled, isHovered, isNotDisabled } from "../lib/pseudoClass.mjs";
|
|
4
3
|
import { focusOutlineControlled } from "./focus.mjs";
|
|
5
4
|
import "../variables/effect.mjs";
|
|
5
|
+
import "../variables/transitions.mjs";
|
|
6
6
|
//#region src/mixins/hoverable.ts
|
|
7
7
|
const hoverMixin = css`
|
|
8
8
|
box-shadow:
|
|
@@ -18,7 +18,7 @@ const hoverableMixin = css`
|
|
|
18
18
|
cursor: not-allowed;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
transition: box-shadow ${"200ms"};
|
|
21
|
+
transition: box-shadow ${"200ms"} ${"cubic-bezier(0.4, 0, 0.2, 1)"};
|
|
22
22
|
|
|
23
23
|
&${isHovered}${isNotDisabled} {
|
|
24
24
|
${hoverMixin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hoverable.mjs","names":[],"sources":["../../src/mixins/hoverable.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport type { Variant } from '#src/theme';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { Elevation } from '#src/variables/effect';\nimport { TransitionDuration } from '#src/variables/transitions';\n\ninterface HoverableMixinProps extends PseudoClassProps {\n variant?: Variant;\n}\n\nexport const hoverMixin = css<HoverableMixinProps>`\n box-shadow:\n 0 0 0 3px transparent,\n ${Elevation.Mid};\n`;\n\n/**\n * Adds an outline for a11y when focused, and a shadow when hovered.\n */\nconst hoverableMixin = css<HoverableMixinProps>`\n cursor: pointer;\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n transition: box-shadow ${TransitionDuration.Fast};\n\n &${isHovered}${isNotDisabled} {\n ${hoverMixin};\n }\n\n ${focusOutlineControlled}\n`;\n\nexport default hoverableMixin;\n"],"mappings":";;;;;;AAaA,MAAa,aAAa,GAAwB;;;mFAG9B;;;;;AAMpB,MAAM,iBAAiB,GAAwB;;KAE1C,WAAW;;;;mCAImC;;
|
|
1
|
+
{"version":3,"file":"hoverable.mjs","names":[],"sources":["../../src/mixins/hoverable.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport type { Variant } from '#src/theme';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { Elevation } from '#src/variables/effect';\nimport { TransitionDuration, TransitionEasing } from '#src/variables/transitions';\n\ninterface HoverableMixinProps extends PseudoClassProps {\n variant?: Variant;\n}\n\nexport const hoverMixin = css<HoverableMixinProps>`\n box-shadow:\n 0 0 0 3px transparent,\n ${Elevation.Mid};\n`;\n\n/**\n * Adds an outline for a11y when focused, and a shadow when hovered.\n */\nconst hoverableMixin = css<HoverableMixinProps>`\n cursor: pointer;\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n transition: box-shadow ${TransitionDuration.Fast} ${TransitionEasing.Move};\n\n &${isHovered}${isNotDisabled} {\n ${hoverMixin};\n }\n\n ${focusOutlineControlled}\n`;\n\nexport default hoverableMixin;\n"],"mappings":";;;;;;AAaA,MAAa,aAAa,GAAwB;;;mFAG9B;;;;;AAMpB,MAAM,iBAAiB,GAAwB;;KAE1C,WAAW;;;;mCAImC,GAAA,+BAAyB;;KAEvE,YAAY,cAAc;MACzB,WAAW;;;IAGb,uBAAuB"}
|
package/dist/mixins/input.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as css } from "../styledComponentsInterop-Cs5CCPRy.mjs";
|
|
2
|
+
import { isDisabled, isHovered, isNotDisabled } from "../lib/pseudoClass.mjs";
|
|
2
3
|
import { semanticColor, semanticTokens } from "../lib/semanticColor.mjs";
|
|
4
|
+
import { focusOutlineControlled } from "./focus.mjs";
|
|
3
5
|
import "../variables/transitions.mjs";
|
|
4
6
|
import { withAlpha } from "../lib/color.mjs";
|
|
5
|
-
import { isDisabled, isHovered, isNotDisabled } from "../lib/pseudoClass.mjs";
|
|
6
|
-
import { focusOutlineControlled } from "./focus.mjs";
|
|
7
7
|
import { printMixins } from "./print/index.mjs";
|
|
8
8
|
import { Color, Spacing, Typography } from "@persona/design-tokens";
|
|
9
9
|
//#region src/mixins/input.ts
|
|
@@ -27,6 +27,7 @@ const inputMixin = css`
|
|
|
27
27
|
|
|
28
28
|
text-decoration: none;
|
|
29
29
|
transition-duration: ${"200ms"};
|
|
30
|
+
transition-timing-function: ${"cubic-bezier(0.4, 0, 0.2, 1)"};
|
|
30
31
|
transition-property: background-color, color, border-color, width, height;
|
|
31
32
|
|
|
32
33
|
/* Some input-likes like <select/> reduce opacity when disabled */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.mjs","names":[],"sources":["../../src/mixins/input.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nimport { withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport type ErrorProps from '#src/types/ErrorProps';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nexport type InputSizes = 'md' | 'sm';\n\nexport interface InputMixinProps extends ErrorProps, PseudoClassProps {\n $size?: InputSizes;\n}\n\n/**\n * Provides input-like hover and focus outline effects. Can also be applied to\n * non-input elements (like divs) to give input-like styles.\n */\nconst inputMixin = css<InputMixinProps>`\n background: ${({ theme }) =>\n semanticColor(theme, 'InputSurfaceDefault', theme.color.background.primary)};\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n border-width: 1px;\n border-style: solid;\n border-color: ${({ theme }) => semanticColor(theme, 'InputBorderDefault', theme.color.border.input)};\n box-sizing: border-box;\n border-radius: ${({ theme }) => theme.element.borderRadius};\n\n width: 100%;\n min-width: 0;\n\n ${focusOutlineControlled}\n\n text-decoration: none;\n transition-duration: ${TransitionDuration.Fast};\n transition-property: background-color, color, border-color, width, height;\n\n /* Some input-likes like <select/> reduce opacity when disabled */\n opacity: 1;\n\n &::placeholder {\n font-weight: ${({ theme }) => theme.text.paragraph.md.fontWeight};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.tertiary)};\n }\n\n &${isDisabled} {\n background: ${({ theme }) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? withAlpha(tokens.InputSurfaceDisabled, tokens.Opacity65)\n : theme.color.background.disabled;\n }};\n border-color: ${({ theme }) =>\n semanticColor(theme, 'InputBorderDisabled', theme.color.border.disabled)};\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n ::placeholder {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n }\n }\n\n &${isHovered}${isNotDisabled} {\n ${({ theme }) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? css`\n background: ${tokens.InputSurfaceHover};\n border-color: ${tokens.InputBorderHover};\n `\n : css`\n border-color: ${theme.color.border.inputHover};\n `;\n }}\n }\n\n ${({ $size }) => {\n switch ($size) {\n default:\n case 'md':\n return css`\n height: ${({ theme }) => theme.element.height.xs};\n padding-top: ${Spacing[2]};\n padding-right: ${Spacing[3]};\n padding-bottom: ${Spacing[2]};\n padding-left: ${Spacing[3]};\n ${Typography.TextMedium};\n `;\n case 'sm':\n return css`\n height: 24px;\n padding-top: ${Spacing[1]};\n padding-right: ${Spacing[2]};\n padding-bottom: ${Spacing[1]};\n padding-left: ${Spacing[2]};\n ${Typography.TextSmall};\n `;\n }\n }}\n\n /* Validation borders are for enabled fields only. Disabled fields keep the\n disabled border above, whose :disabled selector outranks this bare rule. */\n ${({ theme, hasError, hasWarning }) => {\n if (hasError) {\n const danger = semanticColor(theme, 'BorderDanger', theme.color.variants.danger.default);\n return css`\n border-color: ${danger};\n\n &${isHovered}${isNotDisabled} {\n border-color: ${danger};\n }\n `;\n }\n\n if (hasWarning) {\n const warning = semanticColor(theme, 'BorderWarning', Color.CoreOrange700);\n return css`\n border-color: ${warning};\n\n &${isHovered}${isNotDisabled} {\n border-color: ${warning};\n }\n `;\n }\n\n return css`\n border-color: ${semanticColor(theme, 'InputBorderDefault', theme.color.border.input)};\n `;\n }}\n\n ${printMixins.hide}\n`;\n\nexport default inputMixin;\n"],"mappings":";;;;;;;;;;;;;AAuBA,MAAM,aAAa,GAAoB;iBACtB,EAAE,YACf,cAAc,OAAO,uBAAuB,MAAM,MAAM,WAAW,QAAQ,CAAC;YACpE,EAAE,YAAY,cAAc,OAAO,aAAa,MAAM,MAAM,KAAK,QAAQ,CAAC;;;mBAGnE,EAAE,YAAY,cAAc,OAAO,sBAAsB,MAAM,MAAM,OAAO,MAAM,CAAC;;oBAElF,EAAE,YAAY,MAAM,QAAQ,aAAa;;;;;IAKzD,uBAAuB;;;iCAGsB;;;;;;;
|
|
1
|
+
{"version":3,"file":"input.mjs","names":[],"sources":["../../src/mixins/input.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { Color, Spacing, Typography } from '@persona/design-tokens';\n\nimport { withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport type ErrorProps from '#src/types/ErrorProps';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { TransitionDuration, TransitionEasing } from '#src/variables/transitions';\n\nexport type InputSizes = 'md' | 'sm';\n\nexport interface InputMixinProps extends ErrorProps, PseudoClassProps {\n $size?: InputSizes;\n}\n\n/**\n * Provides input-like hover and focus outline effects. Can also be applied to\n * non-input elements (like divs) to give input-like styles.\n */\nconst inputMixin = css<InputMixinProps>`\n background: ${({ theme }) =>\n semanticColor(theme, 'InputSurfaceDefault', theme.color.background.primary)};\n color: ${({ theme }) => semanticColor(theme, 'FgPrimary', theme.color.text.primary)};\n border-width: 1px;\n border-style: solid;\n border-color: ${({ theme }) => semanticColor(theme, 'InputBorderDefault', theme.color.border.input)};\n box-sizing: border-box;\n border-radius: ${({ theme }) => theme.element.borderRadius};\n\n width: 100%;\n min-width: 0;\n\n ${focusOutlineControlled}\n\n text-decoration: none;\n transition-duration: ${TransitionDuration.Fast};\n transition-timing-function: ${TransitionEasing.Move};\n transition-property: background-color, color, border-color, width, height;\n\n /* Some input-likes like <select/> reduce opacity when disabled */\n opacity: 1;\n\n &::placeholder {\n font-weight: ${({ theme }) => theme.text.paragraph.md.fontWeight};\n color: ${({ theme }) => semanticColor(theme, 'FgSecondary', theme.color.text.tertiary)};\n }\n\n &${isDisabled} {\n background: ${({ theme }) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? withAlpha(tokens.InputSurfaceDisabled, tokens.Opacity65)\n : theme.color.background.disabled;\n }};\n border-color: ${({ theme }) =>\n semanticColor(theme, 'InputBorderDisabled', theme.color.border.disabled)};\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n ::placeholder {\n color: ${({ theme }) => semanticColor(theme, 'FgDisabled', theme.color.text.disabled)};\n }\n }\n\n &${isHovered}${isNotDisabled} {\n ${({ theme }) => {\n const tokens = semanticTokens(theme);\n return tokens\n ? css`\n background: ${tokens.InputSurfaceHover};\n border-color: ${tokens.InputBorderHover};\n `\n : css`\n border-color: ${theme.color.border.inputHover};\n `;\n }}\n }\n\n ${({ $size }) => {\n switch ($size) {\n default:\n case 'md':\n return css`\n height: ${({ theme }) => theme.element.height.xs};\n padding-top: ${Spacing[2]};\n padding-right: ${Spacing[3]};\n padding-bottom: ${Spacing[2]};\n padding-left: ${Spacing[3]};\n ${Typography.TextMedium};\n `;\n case 'sm':\n return css`\n height: 24px;\n padding-top: ${Spacing[1]};\n padding-right: ${Spacing[2]};\n padding-bottom: ${Spacing[1]};\n padding-left: ${Spacing[2]};\n ${Typography.TextSmall};\n `;\n }\n }}\n\n /* Validation borders are for enabled fields only. Disabled fields keep the\n disabled border above, whose :disabled selector outranks this bare rule. */\n ${({ theme, hasError, hasWarning }) => {\n if (hasError) {\n const danger = semanticColor(theme, 'BorderDanger', theme.color.variants.danger.default);\n return css`\n border-color: ${danger};\n\n &${isHovered}${isNotDisabled} {\n border-color: ${danger};\n }\n `;\n }\n\n if (hasWarning) {\n const warning = semanticColor(theme, 'BorderWarning', Color.CoreOrange700);\n return css`\n border-color: ${warning};\n\n &${isHovered}${isNotDisabled} {\n border-color: ${warning};\n }\n `;\n }\n\n return css`\n border-color: ${semanticColor(theme, 'InputBorderDefault', theme.color.border.input)};\n `;\n }}\n\n ${printMixins.hide}\n`;\n\nexport default inputMixin;\n"],"mappings":";;;;;;;;;;;;;AAuBA,MAAM,aAAa,GAAoB;iBACtB,EAAE,YACf,cAAc,OAAO,uBAAuB,MAAM,MAAM,WAAW,QAAQ,CAAC;YACpE,EAAE,YAAY,cAAc,OAAO,aAAa,MAAM,MAAM,KAAK,QAAQ,CAAC;;;mBAGnE,EAAE,YAAY,cAAc,OAAO,sBAAsB,MAAM,MAAM,OAAO,MAAM,CAAC;;oBAElF,EAAE,YAAY,MAAM,QAAQ,aAAa;;;;;IAKzD,uBAAuB;;;iCAGsB;+DACK;;;;;;;oBAOlC,EAAE,YAAY,MAAM,KAAK,UAAU,GAAG,WAAW;cACvD,EAAE,YAAY,cAAc,OAAO,eAAe,MAAM,MAAM,KAAK,SAAS,CAAC;;;KAGtF,WAAW;mBACG,EAAE,YAAY;CAC3B,MAAM,SAAS,eAAe,MAAM;AACpC,QAAO,SACH,UAAU,OAAO,sBAAsB,OAAO,UAAU,GACxD,MAAM,MAAM,WAAW;EAC3B;qBACe,EAAE,YACjB,cAAc,OAAO,uBAAuB,MAAM,MAAM,OAAO,SAAS,CAAC;cACjE,EAAE,YAAY,cAAc,OAAO,cAAc,MAAM,MAAM,KAAK,SAAS,CAAC;;gBAE1E,EAAE,YAAY,cAAc,OAAO,cAAc,MAAM,MAAM,KAAK,SAAS,CAAC;;;;KAIvF,YAAY,cAAc;OACxB,EAAE,YAAY;CACf,MAAM,SAAS,eAAe,MAAM;AACpC,QAAO,SACH,GAAG;0BACa,OAAO,kBAAkB;4BACvB,OAAO,iBAAiB;cAE1C,GAAG;4BACe,MAAM,MAAM,OAAO,WAAW;;EAEpD;;;KAGD,EAAE,YAAY;AACf,SAAQ,OAAR;EACE;EACA,KAAK,KACH,QAAO,GAAG;qBACG,EAAE,YAAY,MAAM,QAAQ,OAAO,GAAG;yBAClC,QAAQ,GAAG;2BACT,QAAQ,GAAG;4BACV,QAAQ,GAAG;0BACb,QAAQ,GAAG;YACzB,WAAW,WAAW;;EAE5B,KAAK,KACH,QAAO,GAAG;;yBAEO,QAAQ,GAAG;2BACT,QAAQ,GAAG;4BACV,QAAQ,GAAG;0BACb,QAAQ,GAAG;YACzB,WAAW,UAAU;;;EAG7B;;;;KAIC,EAAE,OAAO,UAAU,iBAAiB;AACrC,KAAI,UAAU;EACZ,MAAM,SAAS,cAAc,OAAO,gBAAgB,MAAM,MAAM,SAAS,OAAO,QAAQ;AACxF,SAAO,GAAG;wBACQ,OAAO;;WAEpB,YAAY,cAAc;0BACX,OAAO;;;;AAK7B,KAAI,YAAY;EACd,MAAM,UAAU,cAAc,OAAO,iBAAiB,MAAM,cAAc;AAC1E,SAAO,GAAG;wBACQ,QAAQ;;WAErB,YAAY,cAAc;0BACX,QAAQ;;;;AAK9B,QAAO,GAAG;sBACQ,cAAc,OAAO,sBAAsB,MAAM,MAAM,OAAO,MAAM,CAAC;;EAEvF;;IAEA,YAAY,KAAK"}
|
package/dist/mixins/menuItem.mjs
CHANGED
|
@@ -78,6 +78,7 @@ const menuItemMixins = {
|
|
|
78
78
|
`,
|
|
79
79
|
hover: css`
|
|
80
80
|
transition-duration: ${"200ms"};
|
|
81
|
+
transition-timing-function: ${"cubic-bezier(0.4, 0, 0.2, 1)"};
|
|
81
82
|
color: ${({ theme, variant = "basic" }) => hoverColor(theme, variant)};
|
|
82
83
|
|
|
83
84
|
background-color: ${({ theme, variant = "basic" }) => {
|
|
@@ -96,6 +97,7 @@ const menuItemMixins = {
|
|
|
96
97
|
`,
|
|
97
98
|
active: css`
|
|
98
99
|
transition-duration: ${"200ms"};
|
|
100
|
+
transition-timing-function: ${"cubic-bezier(0.4, 0, 0.2, 1)"};
|
|
99
101
|
color: ${({ theme, variant = "basic" }) => {
|
|
100
102
|
const tokens = semanticTokens(theme);
|
|
101
103
|
if (tokens) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menuItem.mjs","names":[],"sources":["../../src/mixins/menuItem.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { Color } from '@persona/design-tokens';\n\nimport { withAlpha } from '#src/lib/color';\nimport { semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme, Variant } from '#src/theme';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { TransitionDuration } from '#src/variables/transitions';\n\ninterface MenuItemMixinProps extends PseudoClassProps {\n variant?: Variant;\n}\n\nconst iconStrokeReset = css`\n svg.pds-icon {\n * {\n stroke: unset;\n }\n /* Support icons with stroke */\n *[stroke] {\n stroke: currentColor;\n }\n }\n`;\n\nconst hoverColor = (theme: PersonaTheme, variant: Variant) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n if (variant === 'basic') {\n return theme.color.text.primary;\n }\n if (variant === 'danger') {\n return Color.CoreRed900;\n }\n return theme.color.variants[variant].default;\n};\n\n/**\n * Adds styles for hovered and selected states. For use with dropdowns, menu\n * items, etc.\n *\n * The mixins are split by interaction state for more flexibility. We need to\n * implement each state differently when used with React Router's NavLink, for\n * example.\n *\n * Note that we override the palette for 'basic' to match the neutral usecase\n * shown in the mocks. There are never menu items that match our basic palette.\n *\n * Default: standard and disabled styles\n * Hover: hover and focus styles\n * Active: active styles\n */\nconst menuItemMixins = {\n default: css<MenuItemMixinProps>`\n cursor: pointer;\n color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger' ? tokens.FgDanger1 : tokens.FgPrimary;\n }\n // default text color for these two should be neutral\n return ['basic', 'primary'].includes(variant)\n ? theme.color.text.primary\n : theme.color.variants[variant].default;\n }};\n\n ${({ theme }) => css`\n background-color: ${semanticColor(theme, 'SurfacePrimary', theme.color.background.primary)};\n border-radius: ${theme.element.borderRadius};\n `}\n\n ${({ theme, disabled, variant = 'basic' }) => {\n if (disabled) {\n const disabledColor = semanticColor(theme, 'FgDisabled', theme.color.text.disabled);\n return css`\n background-color: ${semanticColor(\n theme,\n 'SurfacePrimary',\n theme.color.background.primary,\n )};\n color: ${disabledColor};\n cursor: default;\n\n svg * {\n stroke: ${disabledColor};\n }\n\n ${iconStrokeReset}\n `;\n }\n\n const tokens = semanticTokens(theme);\n return (\n tokens &&\n variant === 'basic' &&\n css`\n svg * {\n stroke: ${tokens.FgPrimary};\n }\n\n ${iconStrokeReset}\n `\n );\n }}\n `,\n hover: css<MenuItemMixinProps>`\n transition-duration: ${TransitionDuration.Fast};\n color: ${({ theme, variant = 'basic' }) => hoverColor(theme, variant)};\n\n background-color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger'\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : tokens.SurfaceHover;\n }\n return variant === 'basic'\n ? theme.color.background.secondary\n : theme.color.variants[variant].highlightLight;\n }};\n\n ${({ theme, disabled, variant = 'basic' }) =>\n !disabled &&\n css`\n svg * {\n stroke: ${hoverColor(theme, variant)};\n }\n\n ${iconStrokeReset}\n `}\n `,\n active: css<MenuItemMixinProps>`\n transition-duration: ${TransitionDuration.Fast};\n color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return tokens.FgAccent;\n }\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n return variant === 'basic' ? theme.color.text.inverse : theme.color.variants[variant].default;\n }};\n background-color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return withAlpha(tokens.SurfaceAccent, tokens.Opacity25);\n }\n return variant === 'danger'\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : tokens.SurfaceSecondary;\n }\n return variant === 'basic'\n ? theme.color.primary.brand\n : theme.color.variants[variant].highlightLight;\n }};\n\n ${({ theme, disabled, variant = 'basic' }) =>\n !disabled &&\n css`\n svg * {\n stroke: ${(() => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return tokens.FgAccent;\n }\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n if (variant === 'basic') {\n return theme.color.text.primary;\n }\n if (variant === 'danger') {\n return Color.CoreRed900;\n }\n return theme.color.variants[variant].default;\n })()};\n }\n\n ${iconStrokeReset}\n `}\n `,\n};\n\nexport default menuItemMixins;\n"],"mappings":";;;;;;AAcA,MAAM,kBAAkB,GAAG;;;;;;;;;;;AAY3B,MAAM,cAAc,OAAqB,YAAqB;CAC5D,MAAM,SAAS,eAAe,MAAM;AACpC,KAAI,OACF,QAAO,YAAY,WAAW,OAAO,YAAY,OAAO;AAE1D,KAAI,YAAY,QACd,QAAO,MAAM,MAAM,KAAK;AAE1B,KAAI,YAAY,SACd,QAAO,MAAM;AAEf,QAAO,MAAM,MAAM,SAAS,SAAS;;;;;;;;;;;;;;;;;AAkBvC,MAAM,iBAAiB;CACrB,SAAS,GAAuB;;cAEpB,EAAE,OAAO,UAAU,cAAc;EACzC,MAAM,SAAS,eAAe,MAAM;AACpC,MAAI,OACF,QAAO,YAAY,WAAW,OAAO,YAAY,OAAO;AAG1D,SAAO,CAAC,SAAS,UAAU,CAAC,SAAS,QAAQ,GACzC,MAAM,MAAM,KAAK,UACjB,MAAM,MAAM,SAAS,SAAS;GAClC;;OAEC,EAAE,YAAY,GAAG;0BACE,cAAc,OAAO,kBAAkB,MAAM,MAAM,WAAW,QAAQ,CAAC;uBAC1E,MAAM,QAAQ,aAAa;MAC5C;;OAEC,EAAE,OAAO,UAAU,UAAU,cAAc;AAC5C,MAAI,UAAU;GACZ,MAAM,gBAAgB,cAAc,OAAO,cAAc,MAAM,MAAM,KAAK,SAAS;AACnF,UAAO,GAAG;8BACY,cAClB,OACA,kBACA,MAAM,MAAM,WAAW,QACxB,CAAC;mBACO,cAAc;;;;sBAIX,cAAc;;;YAGxB,gBAAgB;;;EAItB,MAAM,SAAS,eAAe,MAAM;AACpC,SACE,UACA,YAAY,WACZ,GAAG;;sBAEW,OAAO,UAAU;;;YAG3B,gBAAgB;;GAGtB;;CAEJ,OAAO,GAAuB;mCACmB;
|
|
1
|
+
{"version":3,"file":"menuItem.mjs","names":[],"sources":["../../src/mixins/menuItem.ts"],"sourcesContent":["import { css } from 'styled-components';\n\nimport { Color } from '@persona/design-tokens';\n\nimport { withAlpha } from '#src/lib/color';\nimport { semanticColor, semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme, Variant } from '#src/theme';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { TransitionDuration, TransitionEasing } from '#src/variables/transitions';\n\ninterface MenuItemMixinProps extends PseudoClassProps {\n variant?: Variant;\n}\n\nconst iconStrokeReset = css`\n svg.pds-icon {\n * {\n stroke: unset;\n }\n /* Support icons with stroke */\n *[stroke] {\n stroke: currentColor;\n }\n }\n`;\n\nconst hoverColor = (theme: PersonaTheme, variant: Variant) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n if (variant === 'basic') {\n return theme.color.text.primary;\n }\n if (variant === 'danger') {\n return Color.CoreRed900;\n }\n return theme.color.variants[variant].default;\n};\n\n/**\n * Adds styles for hovered and selected states. For use with dropdowns, menu\n * items, etc.\n *\n * The mixins are split by interaction state for more flexibility. We need to\n * implement each state differently when used with React Router's NavLink, for\n * example.\n *\n * Note that we override the palette for 'basic' to match the neutral usecase\n * shown in the mocks. There are never menu items that match our basic palette.\n *\n * Default: standard and disabled styles\n * Hover: hover and focus styles\n * Active: active styles\n */\nconst menuItemMixins = {\n default: css<MenuItemMixinProps>`\n cursor: pointer;\n color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger' ? tokens.FgDanger1 : tokens.FgPrimary;\n }\n // default text color for these two should be neutral\n return ['basic', 'primary'].includes(variant)\n ? theme.color.text.primary\n : theme.color.variants[variant].default;\n }};\n\n ${({ theme }) => css`\n background-color: ${semanticColor(theme, 'SurfacePrimary', theme.color.background.primary)};\n border-radius: ${theme.element.borderRadius};\n `}\n\n ${({ theme, disabled, variant = 'basic' }) => {\n if (disabled) {\n const disabledColor = semanticColor(theme, 'FgDisabled', theme.color.text.disabled);\n return css`\n background-color: ${semanticColor(\n theme,\n 'SurfacePrimary',\n theme.color.background.primary,\n )};\n color: ${disabledColor};\n cursor: default;\n\n svg * {\n stroke: ${disabledColor};\n }\n\n ${iconStrokeReset}\n `;\n }\n\n const tokens = semanticTokens(theme);\n return (\n tokens &&\n variant === 'basic' &&\n css`\n svg * {\n stroke: ${tokens.FgPrimary};\n }\n\n ${iconStrokeReset}\n `\n );\n }}\n `,\n hover: css<MenuItemMixinProps>`\n transition-duration: ${TransitionDuration.Fast};\n transition-timing-function: ${TransitionEasing.Move};\n color: ${({ theme, variant = 'basic' }) => hoverColor(theme, variant)};\n\n background-color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n return variant === 'danger'\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : tokens.SurfaceHover;\n }\n return variant === 'basic'\n ? theme.color.background.secondary\n : theme.color.variants[variant].highlightLight;\n }};\n\n ${({ theme, disabled, variant = 'basic' }) =>\n !disabled &&\n css`\n svg * {\n stroke: ${hoverColor(theme, variant)};\n }\n\n ${iconStrokeReset}\n `}\n `,\n active: css<MenuItemMixinProps>`\n transition-duration: ${TransitionDuration.Fast};\n transition-timing-function: ${TransitionEasing.Move};\n color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return tokens.FgAccent;\n }\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n return variant === 'basic' ? theme.color.text.inverse : theme.color.variants[variant].default;\n }};\n background-color: ${({ theme, variant = 'basic' }) => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return withAlpha(tokens.SurfaceAccent, tokens.Opacity25);\n }\n return variant === 'danger'\n ? withAlpha(tokens.FeedbackDanger1, tokens.Opacity25)\n : tokens.SurfaceSecondary;\n }\n return variant === 'basic'\n ? theme.color.primary.brand\n : theme.color.variants[variant].highlightLight;\n }};\n\n ${({ theme, disabled, variant = 'basic' }) =>\n !disabled &&\n css`\n svg * {\n stroke: ${(() => {\n const tokens = semanticTokens(theme);\n if (tokens) {\n if (variant === 'basic') {\n return tokens.FgAccent;\n }\n return variant === 'danger' ? tokens.FgDanger2 : tokens.FgPrimary;\n }\n if (variant === 'basic') {\n return theme.color.text.primary;\n }\n if (variant === 'danger') {\n return Color.CoreRed900;\n }\n return theme.color.variants[variant].default;\n })()};\n }\n\n ${iconStrokeReset}\n `}\n `,\n};\n\nexport default menuItemMixins;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as _$styled_components0 from "styled-components";
|
|
2
|
+
|
|
3
|
+
//#region src/mixins/motion.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The popover row of the motion scale for Radix content: fade and scale from the trigger over
|
|
6
|
+
* `Fast` on Enter, and a 150ms fade under reduced motion. There's no Exit animation: Radix would
|
|
7
|
+
* keep the content mounted until it ends, delaying `onCloseAutoFocus` focus restoration.
|
|
8
|
+
*
|
|
9
|
+
* @param originVar the Radix transform-origin custom property, e.g.
|
|
10
|
+
* `--radix-popover-content-transform-origin`
|
|
11
|
+
*/
|
|
12
|
+
declare const popoverMotion: (originVar: string) => _$styled_components0.FlattenSimpleInterpolation;
|
|
13
|
+
/**
|
|
14
|
+
* The hover-reveal row: `Faster` on Exit while hidden, `Fast` on Enter while shown. CSS runs the
|
|
15
|
+
* transition of the state being entered, so put `revealHidden` on the base rule and `revealShown`
|
|
16
|
+
* on the rule that shows the element.
|
|
17
|
+
*/
|
|
18
|
+
declare const revealHidden: _$styled_components0.FlattenSimpleInterpolation;
|
|
19
|
+
declare const revealShown: _$styled_components0.FlattenSimpleInterpolation;
|
|
20
|
+
/** `revealHidden` and `revealShown` for an element whose visibility is a prop. */
|
|
21
|
+
declare const revealTransition: (visible: boolean) => "transition: opacity 200ms cubic-bezier(0, 0, 0.2, 1);" | "transition: opacity 150ms cubic-bezier(0.4, 0, 1, 1);";
|
|
22
|
+
//#endregion
|
|
23
|
+
export { popoverMotion, revealHidden, revealShown, revealTransition };
|
|
24
|
+
//# sourceMappingURL=motion.d.mts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { i as keyframes, r as css } from "../styledComponentsInterop-Cs5CCPRy.mjs";
|
|
2
|
+
import { ReducedMotionFade } from "../variables/transitions.mjs";
|
|
3
|
+
import { fadeIn } from "../variables/keyframes.mjs";
|
|
4
|
+
//#region src/mixins/motion.ts
|
|
5
|
+
const popoverEnter = keyframes`
|
|
6
|
+
from {
|
|
7
|
+
opacity: 0;
|
|
8
|
+
transform: scale(0.96);
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
/**
|
|
12
|
+
* The popover row of the motion scale for Radix content: fade and scale from the trigger over
|
|
13
|
+
* `Fast` on Enter, and a 150ms fade under reduced motion. There's no Exit animation: Radix would
|
|
14
|
+
* keep the content mounted until it ends, delaying `onCloseAutoFocus` focus restoration.
|
|
15
|
+
*
|
|
16
|
+
* @param originVar the Radix transform-origin custom property, e.g.
|
|
17
|
+
* `--radix-popover-content-transform-origin`
|
|
18
|
+
*/
|
|
19
|
+
const popoverMotion = (originVar) => css`
|
|
20
|
+
transform-origin: var(${originVar});
|
|
21
|
+
animation: ${popoverEnter} ${"200ms"} ${"cubic-bezier(0, 0, 0.2, 1)"} both;
|
|
22
|
+
|
|
23
|
+
@media (prefers-reduced-motion: reduce) {
|
|
24
|
+
animation: ${fadeIn} ${ReducedMotionFade.duration} ${ReducedMotionFade.easing} both;
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
/**
|
|
28
|
+
* The hover-reveal row: `Faster` on Exit while hidden, `Fast` on Enter while shown. CSS runs the
|
|
29
|
+
* transition of the state being entered, so put `revealHidden` on the base rule and `revealShown`
|
|
30
|
+
* on the rule that shows the element.
|
|
31
|
+
*/
|
|
32
|
+
const revealHidden = css`
|
|
33
|
+
transition: opacity ${"150ms"} ${"cubic-bezier(0.4, 0, 1, 1)"};
|
|
34
|
+
`;
|
|
35
|
+
const revealShown = css`
|
|
36
|
+
transition-duration: ${"200ms"};
|
|
37
|
+
transition-timing-function: ${"cubic-bezier(0, 0, 0.2, 1)"};
|
|
38
|
+
`;
|
|
39
|
+
/** `revealHidden` and `revealShown` for an element whose visibility is a prop. */
|
|
40
|
+
const revealTransition = (visible) => visible ? `transition: opacity 200ms cubic-bezier(0, 0, 0.2, 1);` : `transition: opacity 150ms cubic-bezier(0.4, 0, 1, 1);`;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { popoverMotion, revealHidden, revealShown, revealTransition };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=motion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.mjs","names":[],"sources":["../../src/mixins/motion.ts"],"sourcesContent":["import { css, keyframes } from 'styled-components';\n\nimport { fadeIn } from '#src/variables/keyframes';\nimport {\n ReducedMotionFade,\n TransitionDuration,\n TransitionEasing,\n} from '#src/variables/transitions';\n\nconst popoverEnter = keyframes`\n from {\n opacity: 0;\n transform: scale(0.96);\n }\n`;\n\n/**\n * The popover row of the motion scale for Radix content: fade and scale from the trigger over\n * `Fast` on Enter, and a 150ms fade under reduced motion. There's no Exit animation: Radix would\n * keep the content mounted until it ends, delaying `onCloseAutoFocus` focus restoration.\n *\n * @param originVar the Radix transform-origin custom property, e.g.\n * `--radix-popover-content-transform-origin`\n */\nexport const popoverMotion = (originVar: string) => css`\n transform-origin: var(${originVar});\n animation: ${popoverEnter} ${TransitionDuration.Fast} ${TransitionEasing.Enter} both;\n\n @media (prefers-reduced-motion: reduce) {\n animation: ${fadeIn} ${ReducedMotionFade.duration} ${ReducedMotionFade.easing} both;\n }\n`;\n\n/**\n * The hover-reveal row: `Faster` on Exit while hidden, `Fast` on Enter while shown. CSS runs the\n * transition of the state being entered, so put `revealHidden` on the base rule and `revealShown`\n * on the rule that shows the element.\n */\nexport const revealHidden = css`\n transition: opacity ${TransitionDuration.Faster} ${TransitionEasing.Exit};\n`;\n\nexport const revealShown = css`\n transition-duration: ${TransitionDuration.Fast};\n transition-timing-function: ${TransitionEasing.Enter};\n`;\n\n/** `revealHidden` and `revealShown` for an element whose visibility is a prop. */\nexport const revealTransition = (visible: boolean) =>\n visible\n ? `transition: opacity ${TransitionDuration.Fast} ${TransitionEasing.Enter};`\n : `transition: opacity ${TransitionDuration.Faster} ${TransitionEasing.Exit};`;\n"],"mappings":";;;;AASA,MAAM,eAAe,SAAS;;;;;;;;;;;;;;AAe9B,MAAa,iBAAiB,cAAsB,GAAG;0BAC7B,UAAU;eACrB,aAAa,GAAA,QAA2B,GAAA,6BAA0B;;;iBAGhE,OAAO,GAAG,kBAAkB,SAAS,GAAG,kBAAkB,OAAO;;;;;;;;AASlF,MAAa,eAAe,GAAG;gCACmB,GAAA,6BAAyB;;AAG3E,MAAa,cAAc,GAAG;iCACmB;6DACM;;;AAIvD,MAAa,oBAAoB,YAC/B,UACI,0DACA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { a as types_d_exports, t as Context } from "./index-CLAjbq8g.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/lint/motion.d.ts
|
|
4
|
+
/** A CSS template's text with each `${…}` filled with `_` and comments blanked, so offsets match the source. */
|
|
5
|
+
interface CssText {
|
|
6
|
+
text: string;
|
|
7
|
+
start: number;
|
|
8
|
+
}
|
|
9
|
+
declare function cssText(context: Context, literal: types_d_exports.TemplateLiteral): CssText;
|
|
10
|
+
/**
|
|
11
|
+
* The element's own declarations, its states and media queries included, with the blocks for its
|
|
12
|
+
* children (`& li:hover`, `${Item}`) and `@keyframes` blanked. Offsets stay the same.
|
|
13
|
+
*/
|
|
14
|
+
declare function ownDeclarations(text: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* True when the template's own text, a nested template in it (`${(p) => p.$open && css`…`}`) or a
|
|
17
|
+
* motion-named mixin it interpolates has a transition or animation.
|
|
18
|
+
*/
|
|
19
|
+
declare function hasMotion(context: Context, css: CssTemplate): boolean;
|
|
20
|
+
/** Each CSS template in the file, with the name it is declared as (`const Name = styled…`), if any. */
|
|
21
|
+
interface CssTemplate extends CssText {
|
|
22
|
+
node: types_d_exports.TaggedTemplateExpression;
|
|
23
|
+
name: string | null;
|
|
24
|
+
nameNode: types_d_exports.Node | null;
|
|
25
|
+
}
|
|
26
|
+
declare function cssTemplate(context: Context, node: types_d_exports.TaggedTemplateExpression): CssTemplate | null;
|
|
27
|
+
declare function reportAt(context: Context, index: number, length: number, message: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Properties whose animation moves the content around them. Narrower than the source's list:
|
|
30
|
+
* `grid-template-rows` is the source's own accordion fix, and type and radius don't reflow a page.
|
|
31
|
+
*/
|
|
32
|
+
declare const LAYOUT_PROPERTIES: Set<string>;
|
|
33
|
+
/** A string value, written `'…'` or as a template literal with no `${…}`. */
|
|
34
|
+
declare function stringValue(node: types_d_exports.Node): string | null;
|
|
35
|
+
/** `fontSize` → `font-size`. */
|
|
36
|
+
declare const kebab: (name: string) => string;
|
|
37
|
+
/** The comma-separated items of a CSS value, ignoring commas inside parentheses, with their offsets. */
|
|
38
|
+
declare function splitList(value: string): {
|
|
39
|
+
item: string;
|
|
40
|
+
offset: number;
|
|
41
|
+
}[];
|
|
42
|
+
/** `transition`, `transition-property`, `animation` and friends, with the value up to `;`, `{` or `}`. */
|
|
43
|
+
declare const MOTION_DECLARATION: RegExp;
|
|
44
|
+
/**
|
|
45
|
+
* What a declared name says it is: `triggered` for a surface that opens from a trigger
|
|
46
|
+
* (`DropdownMenu`, `PopoverContent`), `overlay` for another surface that opens (`ModalOverlay`,
|
|
47
|
+
* `ToastContent`), `layer` for only a layer (`Backdrop`, `SelectionOverlay`), else null. Parts
|
|
48
|
+
* of a surface (`MenuItem`, `ModalHeader`) are null.
|
|
49
|
+
*/
|
|
50
|
+
declare function overlayKind(name: string | null): 'triggered' | 'overlay' | 'layer' | null;
|
|
51
|
+
/** Libraries and hooks that animate mounting and unmounting from outside the CSS. */
|
|
52
|
+
declare const PRESENCE_LIBRARY: RegExp;
|
|
53
|
+
declare const isMotionTag: (context: Context, node: types_d_exports.TaggedTemplateExpression) => boolean;
|
|
54
|
+
/** `styled(Popover)`: the template styles a component, which may bring its own motion. */
|
|
55
|
+
declare function wrapsComponent(node: types_d_exports.TaggedTemplateExpression): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* The animation names a template uses: each word, or `${identifier}`, in an `animation` or
|
|
58
|
+
* `animation-name` value. Other interpolations (`${ModalClose}:hover`) aren't animations.
|
|
59
|
+
*/
|
|
60
|
+
declare function animationNames(css: CssTemplate): string[];
|
|
61
|
+
//#endregion
|
|
62
|
+
export { CssTemplate, CssText, LAYOUT_PROPERTIES, MOTION_DECLARATION, PRESENCE_LIBRARY, animationNames, cssTemplate, cssText, hasMotion, isMotionTag, kebab, overlayKind, ownDeclarations, reportAt, splitList, stringValue, wrapsComponent };
|
|
63
|
+
//# sourceMappingURL=motion.d.mts.map
|