@weasel-js/ui 1.8.0 → 1.8.1
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/dist/chunks/{ActionBar-xA73vzzF.js → ActionBar-CfXS7-9f.js} +2 -2
- package/dist/chunks/{ActionBar-xA73vzzF.js.map → ActionBar-CfXS7-9f.js.map} +1 -1
- package/dist/chunks/{Badge-jYQjrTKc.js → Badge-4ShpqA0h.js} +2 -2
- package/dist/chunks/{Badge-jYQjrTKc.js.map → Badge-4ShpqA0h.js.map} +1 -1
- package/dist/chunks/{Badge-CTc9Lkwn.js → Badge-qkV9EqKs.js} +6 -2
- package/dist/chunks/Badge-qkV9EqKs.js.map +1 -0
- package/dist/chunks/{Button-XB-T75YL.js → Button-CQA-K1g9.js} +17 -17
- package/dist/chunks/Button-CQA-K1g9.js.map +1 -0
- package/dist/chunks/Button-KF-qSGtA.js +11 -0
- package/dist/chunks/Button-KF-qSGtA.js.map +1 -0
- package/dist/chunks/{ButtonBar-CIMKPPRS.js → ButtonBar-B-cYuoem.js} +10 -4
- package/dist/chunks/ButtonBar-B-cYuoem.js.map +1 -0
- package/dist/chunks/{Callout-DpTO3fkb.js → Callout-VyYDIP7w.js} +18 -18
- package/dist/chunks/Callout-VyYDIP7w.js.map +1 -0
- package/dist/chunks/{CloseButton-wb7Or5Eg.js → CloseButton-CKarkTT9.js} +3 -3
- package/dist/chunks/{CloseButton-wb7Or5Eg.js.map → CloseButton-CKarkTT9.js.map} +1 -1
- package/dist/chunks/{Code-AsKpgnv6.js → Code-ChwKP1V0.js} +8 -2
- package/dist/chunks/Code-ChwKP1V0.js.map +1 -0
- package/dist/chunks/{ColorModeControl-DET6Itwq.js → ColorModeControl-CH9PmDlT.js} +6 -6
- package/dist/chunks/{ColorModeControl-DET6Itwq.js.map → ColorModeControl-CH9PmDlT.js.map} +1 -1
- package/dist/chunks/{ComboBox-DKln_mOd.js → ComboBox-BMj_IKBj.js} +4 -4
- package/dist/chunks/ComboBox-BMj_IKBj.js.map +1 -0
- package/dist/chunks/{DataGrid-B6IS9vUk.js → DataGrid-CjiVKoaA.js} +2 -2
- package/dist/chunks/{DataGrid-B6IS9vUk.js.map → DataGrid-CjiVKoaA.js.map} +1 -1
- package/dist/chunks/{Dialog-h-5MeYpu.js → Dialog-Du4POZ52.js} +5 -5
- package/dist/chunks/Dialog-Du4POZ52.js.map +1 -0
- package/dist/chunks/{DragGhost-BeYDJyLZ.js → DragGhost-_IpuN_xM.js} +2 -2
- package/dist/chunks/{DragGhost-BeYDJyLZ.js.map → DragGhost-_IpuN_xM.js.map} +1 -1
- package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js → FallthroughDiagram-Cn6QLWKA.js} +9 -9
- package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js.map → FallthroughDiagram-Cn6QLWKA.js.map} +1 -1
- package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js → FillStrokeSwatch-BkUhlpQL.js} +2 -2
- package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js.map → FillStrokeSwatch-BkUhlpQL.js.map} +1 -1
- package/dist/chunks/{FontFamilySelect-DEvMXyZd.js → FontFamilySelect-CXN7O2-p.js} +2 -2
- package/dist/chunks/{FontFamilySelect-DEvMXyZd.js.map → FontFamilySelect-CXN7O2-p.js.map} +1 -1
- package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js → FontWeightSelect-BBuJGe_2.js} +2 -2
- package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js.map → FontWeightSelect-BBuJGe_2.js.map} +1 -1
- package/dist/chunks/{GestureRoute-BXESrHI0.js → GestureRoute-BqHUrGeQ.js} +13 -13
- package/dist/chunks/{GestureRoute-BXESrHI0.js.map → GestureRoute-BqHUrGeQ.js.map} +1 -1
- package/dist/chunks/{GradientEditor-vz771M-N.js → GradientEditor-DX4sb1Hf.js} +3 -3
- package/dist/chunks/{GradientEditor-vz771M-N.js.map → GradientEditor-DX4sb1Hf.js.map} +1 -1
- package/dist/chunks/{Icon-DPRUIo3G.js → Icon-BfqYtAX5.js} +30 -1
- package/dist/chunks/Icon-BfqYtAX5.js.map +1 -0
- package/dist/chunks/{ItemList-CRu9y7hL.js → ItemList-nbakLf3N.js} +32 -32
- package/dist/chunks/ItemList-nbakLf3N.js.map +1 -0
- package/dist/chunks/{Jog-TE6QI9i1.js → Jog-BU0xuM3G.js} +6 -6
- package/dist/chunks/{Jog-TE6QI9i1.js.map → Jog-BU0xuM3G.js.map} +1 -1
- package/dist/chunks/{Keycaps-C-FJyG8k.js → Keycaps-CM-gOj0e.js} +8 -2
- package/dist/chunks/Keycaps-CM-gOj0e.js.map +1 -0
- package/dist/chunks/LayerList-vfAoImxX.js +432 -0
- package/dist/chunks/LayerList-vfAoImxX.js.map +1 -0
- package/dist/chunks/{ListEditor-DGtwj99m.js → ListEditor-BAKs47bN.js} +3 -3
- package/dist/chunks/{ListEditor-DGtwj99m.js.map → ListEditor-BAKs47bN.js.map} +1 -1
- package/dist/chunks/{MenuButton-TAFg88Lp.js → MenuButton-CJGdhwGr.js} +5 -5
- package/dist/chunks/MenuButton-CJGdhwGr.js.map +1 -0
- package/dist/chunks/{MeshEditor-8CRsu-Td.js → MeshEditor-rhf7cXfG.js} +2 -2
- package/dist/chunks/{MeshEditor-8CRsu-Td.js.map → MeshEditor-rhf7cXfG.js.map} +1 -1
- package/dist/chunks/{OptionsBar-DeTAjVb7.js → OptionsBar-DyTXbev-.js} +9 -3
- package/dist/chunks/OptionsBar-DyTXbev-.js.map +1 -0
- package/dist/chunks/{PaintField-DX4uYlF9.js → PaintField--GbF8sL7.js} +7 -7
- package/dist/chunks/PaintField--GbF8sL7.js.map +1 -0
- package/dist/chunks/{PaintInput-CWyOJXUM.js → PaintInput-DSS5IjXn.js} +5 -5
- package/dist/chunks/{PaintInput-CWyOJXUM.js.map → PaintInput-DSS5IjXn.js.map} +1 -1
- package/dist/chunks/{PatternPicker-0j51aDJ3.js → PatternPicker-82DCUvUk.js} +2 -2
- package/dist/chunks/{PatternPicker-0j51aDJ3.js.map → PatternPicker-82DCUvUk.js.map} +1 -1
- package/dist/chunks/{Powerline-6wIFmDik.js → Powerline-CogJv9VU.js} +2 -2
- package/dist/chunks/{Powerline-6wIFmDik.js.map → Powerline-CogJv9VU.js.map} +1 -1
- package/dist/chunks/{Prefs-gbjYqvSD.js → Prefs-BSSKOvPa.js} +41 -41
- package/dist/chunks/Prefs-BSSKOvPa.js.map +1 -0
- package/dist/chunks/{Properties-BbNuMiic.js → Properties-DteSVEWs.js} +4 -4
- package/dist/chunks/{Properties-BbNuMiic.js.map → Properties-DteSVEWs.js.map} +1 -1
- package/dist/chunks/{PropertyField-CWUtNK1w.js → PropertyField-CLbUOynA.js} +67 -67
- package/dist/chunks/PropertyField-CLbUOynA.js.map +1 -0
- package/dist/chunks/{Select-ouV8O6cp.js → Select-BhHwjNsb.js} +13 -13
- package/dist/chunks/Select-BhHwjNsb.js.map +1 -0
- package/dist/chunks/{SelectionPanel-BpUqP75b.js → SelectionPanel-B6HinSdB.js} +2 -2
- package/dist/chunks/{SelectionPanel-BpUqP75b.js.map → SelectionPanel-B6HinSdB.js.map} +1 -1
- package/dist/chunks/{SidebarPanel--dJ-k9-V.js → SidebarPanel-P3a8tIIj.js} +2 -2
- package/dist/chunks/{SidebarPanel--dJ-k9-V.js.map → SidebarPanel-P3a8tIIj.js.map} +1 -1
- package/dist/chunks/{StatusBar-BEOfOX0D.js → StatusBar-DEh7J2Gj.js} +14 -9
- package/dist/chunks/StatusBar-DEh7J2Gj.js.map +1 -0
- package/dist/chunks/{SwatchStrip-BY6A511W.js → SwatchStrip-D7YNn_p0.js} +2 -2
- package/dist/chunks/{SwatchStrip-BY6A511W.js.map → SwatchStrip-D7YNn_p0.js.map} +1 -1
- package/dist/chunks/{ThemeSwitcher-tnATkIo1.js → ThemeSwitcher-BJWP1l87.js} +6 -6
- package/dist/chunks/{ThemeSwitcher-tnATkIo1.js.map → ThemeSwitcher-BJWP1l87.js.map} +1 -1
- package/dist/chunks/{Timeline-FlLUm8nd.js → Timeline-CisRg82u.js} +2 -2
- package/dist/chunks/{Timeline-FlLUm8nd.js.map → Timeline-CisRg82u.js.map} +1 -1
- package/dist/chunks/{Toast-CuHkT0x0.js → Toast-DhkU9Z0b.js} +3 -3
- package/dist/chunks/{Toast-CuHkT0x0.js.map → Toast-DhkU9Z0b.js.map} +1 -1
- package/dist/chunks/ToggleBar-CRc2k89_.js +10 -0
- package/dist/chunks/ToggleBar-CRc2k89_.js.map +1 -0
- package/dist/chunks/{ToggleBar-BZ4Gk1IU.js → ToggleBar-CfYbMK3x.js} +9 -9
- package/dist/chunks/ToggleBar-CfYbMK3x.js.map +1 -0
- package/dist/chunks/{TokenPanel-DongdiZM.js → TokenPanel-cL37E39j.js} +5 -5
- package/dist/chunks/{TokenPanel-DongdiZM.js.map → TokenPanel-cL37E39j.js.map} +1 -1
- package/dist/chunks/{ToolButton-BURp4YIO.js → ToolButton-Bo7WH1wt.js} +2 -2
- package/dist/chunks/{ToolButton-BURp4YIO.js.map → ToolButton-Bo7WH1wt.js.map} +1 -1
- package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js → ToolOptionsBar-DmhzrOmd.js} +2 -2
- package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js.map → ToolOptionsBar-DmhzrOmd.js.map} +1 -1
- package/dist/chunks/{ToolPalette-DKDFWOX-.js → ToolPalette-BTD84k9C.js} +2 -2
- package/dist/chunks/{ToolPalette-DKDFWOX-.js.map → ToolPalette-BTD84k9C.js.map} +1 -1
- package/dist/chunks/{Tooltip-C6eFCYxw.js → Tooltip-DljsPEQG.js} +4 -4
- package/dist/chunks/Tooltip-DljsPEQG.js.map +1 -0
- package/dist/chunks/Tree-B_PW6K-W.js +215 -0
- package/dist/chunks/Tree-B_PW6K-W.js.map +1 -0
- package/dist/chunks/{icons-CofIOTiI.js → icons-B_fPKEis.js} +52 -43
- package/dist/chunks/icons-B_fPKEis.js.map +1 -0
- package/dist/chunks/{model-qQj8Ny9w.js → model-Ca0f95r0.js} +5 -5
- package/dist/chunks/{model-qQj8Ny9w.js.map → model-Ca0f95r0.js.map} +1 -1
- package/dist/chunks/{portalHost-CE70wLzo.js → portalHost-RUQPxIoW.js} +3 -2
- package/dist/chunks/{portalHost-CE70wLzo.js.map → portalHost-RUQPxIoW.js.map} +1 -1
- package/dist/chunks/{prefField-CCm_nzlM.js → prefField-DPPbAmRR.js} +3 -3
- package/dist/chunks/{prefField-CCm_nzlM.js.map → prefField-DPPbAmRR.js.map} +1 -1
- package/dist/chunks/{segmentTooltip-CGxCOWNz.js → segmentTooltip-8VBPNgEc.js} +2 -2
- package/dist/chunks/{segmentTooltip-CGxCOWNz.js.map → segmentTooltip-8VBPNgEc.js.map} +1 -1
- package/dist/chunks/segmentedControl.module-62qjNWJk.js +11 -0
- package/dist/chunks/{segmentedControl.module-BzGXUL5G.js.map → segmentedControl.module-62qjNWJk.js.map} +1 -1
- package/dist/chunks/{useReorderDragList-CStYKjHl.js → useReorderDragList-DnqqvRGK.js} +38 -30
- package/dist/chunks/useReorderDragList-DnqqvRGK.js.map +1 -0
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/Badge/index.d.ts +1 -0
- package/dist/components/Badge/index.d.ts.map +1 -1
- package/dist/components/Badge/index.js +3 -3
- package/dist/components/Badge/variantIcons.d.ts +5 -0
- package/dist/components/Badge/variantIcons.d.ts.map +1 -0
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +3 -2
- package/dist/components/Button/variantIcons.d.ts +5 -0
- package/dist/components/Button/variantIcons.d.ts.map +1 -0
- package/dist/components/ButtonBar/index.d.ts +1 -0
- package/dist/components/ButtonBar/index.d.ts.map +1 -1
- package/dist/components/ButtonBar/index.js +2 -2
- package/dist/components/ButtonBar/variantIcons.d.ts +5 -0
- package/dist/components/ButtonBar/variantIcons.d.ts.map +1 -0
- package/dist/components/Callout/Callout.d.ts.map +1 -1
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/CloseButton/index.js +1 -1
- package/dist/components/Code/index.d.ts +1 -0
- package/dist/components/Code/index.d.ts.map +1 -1
- package/dist/components/Code/index.js +2 -2
- package/dist/components/Code/variantIcons.d.ts +5 -0
- package/dist/components/Code/variantIcons.d.ts.map +1 -0
- package/dist/components/ColorModeControl/index.js +1 -1
- package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
- package/dist/components/ComboBox/index.js +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/DragGhost/index.js +1 -1
- package/dist/components/FallthroughDiagram/index.js +1 -1
- package/dist/components/FillStrokeSwatch/index.js +1 -1
- package/dist/components/FontFamilySelect/index.js +1 -1
- package/dist/components/FontWeightSelect/index.js +1 -1
- package/dist/components/GestureRoute/index.js +1 -1
- package/dist/components/GradientEditor/index.js +1 -1
- package/dist/components/ItemList/index.js +1 -1
- package/dist/components/Jog/index.js +1 -1
- package/dist/components/Keycaps/index.d.ts +1 -0
- package/dist/components/Keycaps/index.d.ts.map +1 -1
- package/dist/components/Keycaps/index.js +2 -2
- package/dist/components/Keycaps/variantIcons.d.ts +5 -0
- package/dist/components/Keycaps/variantIcons.d.ts.map +1 -0
- package/dist/components/LayerList/LayerList.d.ts.map +1 -1
- package/dist/components/LayerList/index.js +1 -1
- package/dist/components/ListEditor/index.js +1 -1
- package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
- package/dist/components/MenuButton/index.js +1 -1
- package/dist/components/MeshEditor/index.js +1 -1
- package/dist/components/OptionsBar/index.d.ts +1 -0
- package/dist/components/OptionsBar/index.d.ts.map +1 -1
- package/dist/components/OptionsBar/index.js +2 -2
- package/dist/components/OptionsBar/variantIcons.d.ts +5 -0
- package/dist/components/OptionsBar/variantIcons.d.ts.map +1 -0
- package/dist/components/PaintField/PaintField.d.ts.map +1 -1
- package/dist/components/PaintField/index.js +1 -1
- package/dist/components/PaintInput/index.js +1 -1
- package/dist/components/PatternPicker/index.js +1 -1
- package/dist/components/Powerline/index.js +2 -2
- package/dist/components/Prefs/index.js +2 -2
- package/dist/components/Properties/index.js +2 -2
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectionPanel/index.js +2 -2
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/StatusBar/StatusBar.d.ts +2 -0
- package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
- package/dist/components/StatusBar/index.js +1 -1
- package/dist/components/SwatchStrip/index.js +1 -1
- package/dist/components/ThemeSwitcher/index.js +1 -1
- package/dist/components/Timeline/index.js +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/ToggleBar/index.d.ts +1 -0
- package/dist/components/ToggleBar/index.d.ts.map +1 -1
- package/dist/components/ToggleBar/index.js +3 -2
- package/dist/components/ToggleBar/variantIcons.d.ts +5 -0
- package/dist/components/ToggleBar/variantIcons.d.ts.map +1 -0
- package/dist/components/TokenPanel/index.js +1 -1
- package/dist/components/ToolButton/index.js +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/ToolPalette/index.js +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/components/Tree/Tree.d.ts +1 -1
- package/dist/components/Tree/Tree.d.ts.map +1 -1
- package/dist/components/Tree/index.js +1 -1
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/paths.d.ts +12 -0
- package/dist/icons/paths.d.ts.map +1 -1
- package/dist/index.js +100 -98
- package/dist/index.js.map +1 -1
- package/dist/overlays/portalHost.d.ts +10 -4
- package/dist/overlays/portalHost.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/dist/useReorderDragList.d.ts +3 -0
- package/dist/useReorderDragList.d.ts.map +1 -1
- package/package.json +10 -9
- package/dist/chunks/Badge-CTc9Lkwn.js.map +0 -1
- package/dist/chunks/Button-XB-T75YL.js.map +0 -1
- package/dist/chunks/ButtonBar-CIMKPPRS.js.map +0 -1
- package/dist/chunks/Callout-DpTO3fkb.js.map +0 -1
- package/dist/chunks/Code-AsKpgnv6.js.map +0 -1
- package/dist/chunks/ComboBox-DKln_mOd.js.map +0 -1
- package/dist/chunks/Dialog-h-5MeYpu.js.map +0 -1
- package/dist/chunks/Icon-DPRUIo3G.js.map +0 -1
- package/dist/chunks/ItemList-CRu9y7hL.js.map +0 -1
- package/dist/chunks/Keycaps-C-FJyG8k.js.map +0 -1
- package/dist/chunks/LayerList-BXTAjK-4.js +0 -421
- package/dist/chunks/LayerList-BXTAjK-4.js.map +0 -1
- package/dist/chunks/MenuButton-TAFg88Lp.js.map +0 -1
- package/dist/chunks/OptionsBar-DeTAjVb7.js.map +0 -1
- package/dist/chunks/PaintField-DX4uYlF9.js.map +0 -1
- package/dist/chunks/Prefs-gbjYqvSD.js.map +0 -1
- package/dist/chunks/PropertyField-CWUtNK1w.js.map +0 -1
- package/dist/chunks/Select-ouV8O6cp.js.map +0 -1
- package/dist/chunks/StatusBar-BEOfOX0D.js.map +0 -1
- package/dist/chunks/ToggleBar-BZ4Gk1IU.js.map +0 -1
- package/dist/chunks/Tooltip-C6eFCYxw.js.map +0 -1
- package/dist/chunks/Tree-hzIbj2q1.js +0 -203
- package/dist/chunks/Tree-hzIbj2q1.js.map +0 -1
- package/dist/chunks/icons-CofIOTiI.js.map +0 -1
- package/dist/chunks/interactiveTarget-BNZmTow2.js +0 -24
- package/dist/chunks/interactiveTarget-BNZmTow2.js.map +0 -1
- package/dist/chunks/segmentedControl.module-BzGXUL5G.js +0 -11
- package/dist/chunks/useReorderDragList-CStYKjHl.js.map +0 -1
- package/dist/interactiveTarget.d.ts +0 -9
- package/dist/interactiveTarget.d.ts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Select-ouV8O6cp.js","names":["Select","RACSelect","f","s","RACButton","RACPopover","RACListBox","listbox","_Fragment","RACListBoxSection","RACListBoxItem","useOverlayPortal","TriggerTooltip","segmentTooltipContent","field_module_default","listbox_module_default","Select_module_default","isGroup","entry","Select$1","variant","rest","props","portalContainer","triggerRef","useRef","pressRef","nudge","setNudge","useState","NO_NUDGE","Select","onSelectionChange","k","width","indicator","orientation","className","anchor","label","Label","Button","triggerId","SelectValue","isPlaceholder","placeholder","defaultChildren","optionLabels","options","children","l","i","description","Text","FieldError","errorMessage","Popover","popup","portalProps","AlignOverTrigger","ListBox","SelectSection","renderOption","CLICK_MS","EDGE","BELOW","markerRef","passes","useLayoutEffect","trigger","popover","value","applied","onMeasure","align","toEnd","box","seat","row","shown","over","lowest","next","useEffect","doc","onUp","press","pastDragThreshold","CheckMark","SelectItem","o","Children","isValidElement","c","withIcon","g","icon","Fragment","ListBoxSection","title","Header","textValueOf","explicit","ListBoxItem","textValue"],"sources":["../../src/components/Select/Select.module.css","../../src/components/Select/Select.tsx"],"sourcesContent":["/* `orientation='row'`: the shared layout sets the trigger beside its label; a\n fit one keeps its own width there rather than the fill width below. */\n.row.fit .trigger { width: auto; }\n\n.trigger {\n display: flex;\n width: 100%;\n align-items: center;\n gap: var(--wzl-space-3);\n /* Hooks, each defaulting to what the frame already draws: the visible box is\n this button, not the root a consumer's `className` lands on, so a surface\n that has to restyle it sets these rather than reaching in here. Together\n they draw the bare look too, for a surface that wants it from context\n rather than from `variant`: a transparent fill, no padding, the chevron\n hidden, the value underlined and an outline for focus. */\n padding: var(--wzl-select-pad, 0 var(--wzl-space-3) 0 var(--wzl-space-5));\n --_frame-h: var(--wzl-select-h);\n --_frame-bg: var(--wzl-select-bg);\n --_frame-border: var(--wzl-select-border);\n --_frame-fg: var(--wzl-select-fg, var(--wzl-fg));\n --_frame-focus-border: var(--wzl-select-focus-border);\n --_frame-focus-shadow: var(--wzl-select-focus-shadow);\n --_frame-focus-outline: var(--wzl-select-focus-outline);\n cursor: pointer;\n}\n\n.trigger[data-focus-visible] {\n outline-offset: 2px;\n}\n\n.value {\n flex: 1;\n min-width: 0;\n text-align: var(--wzl-select-align, left);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n /* The ellipsis needs `overflow: hidden`, which makes the line box a clip —\n the trigger's `line-height: 1` would cut this text's ascenders and\n descenders off. `normal` is the font's own leading, so it never can. */\n line-height: normal;\n /* The underline hook: none unless a surface or `indicator` turns it on. */\n text-decoration-line: var(--wzl-select-underline, none);\n text-decoration-style: dotted;\n text-decoration-thickness: 1px;\n text-decoration-color: var(--wzl-fg-subtle);\n text-underline-offset: 0.25em;\n transition: text-decoration-color var(--wzl-motion-fast);\n}\n\n.trigger:hover .value,\n.trigger[data-focus-visible] .value {\n text-decoration-style: solid;\n text-decoration-color: var(--wzl-fg-muted);\n}\n\n.select[data-open] .value {\n text-decoration-style: solid;\n text-decoration-color: var(--wzl-accent);\n}\n\n/* `variant='bare'`: no box. The focus ring moves to an outline, since there is no border to recolor. */\n.bare .trigger {\n padding: 0;\n background: transparent;\n border: var(--wzl-select-border, 1px solid transparent);\n}\n\n.bare .trigger[data-focus-visible] {\n border-color: transparent;\n box-shadow: none;\n outline: 1px solid var(--wzl-focus-ring);\n outline-offset: 2px;\n}\n\n.value[data-placeholder] {\n color: var(--wzl-fg-subtle);\n}\n\n.chevron {\n display: var(--wzl-select-chevron, block);\n width: 10px;\n height: 10px;\n color: var(--wzl-fg-muted);\n flex: 0 0 auto;\n}\n\n/* `indicator='underline'`: the value carries the affordance itself. A text\n decoration rather than a border, so it hugs the word and adds nothing to the\n box — the row's height and the value's width are the same either way. The\n rest of the underline's look sits on `.value`, shared with the hook. */\n.underlined .value {\n text-decoration-line: underline;\n}\n\n.value[data-placeholder] {\n text-decoration-color: var(--wzl-fg-subtle);\n}\n\n/* Nothing sits beside the value, so the row's gap and the padding kept for a\n caret are the value's to spend. */\n.underlined .trigger,\n.plain .trigger {\n gap: 0;\n}\n\n.bare.underlined .trigger,\n.bare.plain .trigger {\n padding: 0;\n}\n\n/* A list that hangs below its trigger takes the trigger's width, so the two\n read as one control. One that opens over it is already tied to the trigger\n by its selected row — widening it to match would only add blank rule beside\n the labels. `data-align` is set on exactly the ones that do. */\n.popover:not([data-align]) {\n min-width: var(--trigger-width);\n}\n\n.popover {\n max-height: inherit;\n outline: none;\n}\n\n.option {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n padding: var(--wzl-space-2) var(--wzl-space-4);\n border-radius: var(--wzl-radius-sm);\n cursor: pointer;\n color: var(--wzl-fg);\n outline: none;\n}\n\n:is(.option, .section) + .section,\n.section + .option {\n margin-top: var(--wzl-space-2);\n padding-top: var(--wzl-space-2);\n border-top: 1px solid var(--wzl-line-subtle);\n}\n\n.sectionHeader {\n padding: var(--wzl-space-2) var(--wzl-space-4);\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-medium);\n color: var(--wzl-fg-subtle);\n}\n\n.optionLabel {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.optionIcon {\n display: inline-flex;\n vertical-align: middle;\n margin-inline-end: var(--wzl-space-3);\n}\n\n.optionIcon > svg {\n display: block;\n}\n\n/* A trigger that sets its value against its end edge gets a list that does the\n same, so the row that opened over the value stays on top of it. */\n.popover[data-align='end'] .option {\n justify-content: flex-end;\n}\n\n.option[data-focused] {\n background: var(--wzl-surface-hover);\n}\n\n.option[data-selected] {\n color: var(--wzl-fg);\n font-weight: var(--wzl-font-weight-medium);\n}\n\n.option[data-disabled] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.check {\n width: 10px;\n height: 10px;\n flex: 0 0 auto;\n opacity: 0;\n}\n\n.option[data-selected] .check {\n opacity: 1;\n}\n\n.value .check {\n display: none;\n}\n\n/* `width='fit'`: a hidden stack of every option label shares the value's grid\n cell, so the trigger sizes to its widest option and never resizes on select. */\n.fit .trigger {\n display: grid;\n grid-template-columns: auto auto;\n}\n\n.fit.underlined .trigger,\n.fit.plain .trigger {\n grid-template-columns: auto;\n}\n\n.fit .value,\n.fit .sizer {\n grid-area: 1 / 1;\n}\n\n.fit .chevron {\n grid-area: 1 / 2;\n}\n\n.sizer {\n composes: sizer from '../sizer.module.css';\n}\n","import {\n Children,\n isValidElement,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport {\n Select as RACSelect,\n Label,\n Button as RACButton,\n SelectValue,\n Popover as RACPopover,\n ListBox as RACListBox,\n ListBoxItem as RACListBoxItem,\n ListBoxSection as RACListBoxSection,\n Header,\n Text,\n FieldError,\n type SelectProps as RACSelectProps,\n type ListBoxItemProps as RACListBoxItemProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { pastDragThreshold } from '@weasel-js/core';\nimport type { FieldOrientation } from '../Field/Field';\nimport { useOverlayPortal, type OverlayPortalProps } from '../../overlays/portalHost';\nimport f from '../field.module.css';\nimport listbox from '../listbox.module.css';\nimport s from './Select.module.css';\nimport { TriggerTooltip, segmentTooltipContent, type SegmentTooltipFields } from '../segmentTooltip';\n\n/** One option in a {@link Select}'s `options` list. */\nexport type SelectOption = {\n value: string;\n label: ReactNode;\n isDisabled?: boolean;\n /** A glyph drawn before `label`, in the list and in the trigger. */\n icon?: ReactNode;\n /**\n * Plain-text form of `label`, for type-to-select and screen readers.\n * Only needed when `label` isn't a bare string — a label built from\n * elements has no text React Aria can read off it. A string label\n * supplies this itself.\n */\n textValue?: string;\n};\n\n/** A titled group of options in a {@link Select}'s `options` list. */\nexport type SelectOptionGroup<T extends Key = string> = {\n title: ReactNode;\n options: ReadonlyArray<SelectOption & { value: T }>;\n};\n\ntype Key = string | number;\n\nfunction isGroup<T extends Key>(\n entry: (SelectOption & { value: T }) | SelectOptionGroup<T>,\n): entry is SelectOptionGroup<T> {\n return 'options' in entry;\n}\n\n/** How a {@link Select} trigger signals that it opens a list. */\nexport type SelectIndicator = 'chevron' | 'underline' | 'none';\n\n/** Where a {@link Select}'s list opens relative to its trigger. */\nexport type SelectPopup = 'over' | 'below';\n\n/**\n * Props for {@link Select}, on top of React Aria's `Select` props, with the\n * selection key narrowed to the option value type.\n */\nexport type SelectProps<T extends Key = string> = Omit<RACSelectProps<object>, 'children' | 'className' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> & {\n label?: ReactNode;\n /**\n * `'stacked'` (the default) puts the label above the trigger; `'row'` sets it\n * beside the trigger at its own width, with any description or error on a\n * line below. Same vocabulary as {@link Field}'s `orientation`.\n */\n orientation?: FieldOrientation;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n placeholder?: string;\n /**\n * Either pass `options` for a quick render, or `children` for full control.\n * An entry with `title` and `options` of its own is a titled section.\n */\n options?: ReadonlyArray<(SelectOption & { value: T }) | SelectOptionGroup<T>>;\n children?: ReactNode;\n selectedKey?: T | null;\n defaultSelectedKey?: T;\n onSelectionChange?: (key: T) => void;\n /**\n * `'fill'` (the default) takes the width of whatever row the select sits in.\n * `'fit'` sizes the trigger to its widest option, so it neither swallows a\n * toolbar's slack nor changes width as the selection moves.\n */\n width?: 'fill' | 'fit';\n /** `'bare'` drops the box, for a select set in a row of other chrome such as a property row. */\n variant?: 'field' | 'bare';\n /**\n * How the trigger says it opens a list. `'chevron'` draws the caret beside\n * the value; `'underline'` marks the value itself, dotted at rest and solid\n * while it is pointed at or open; `'none'` says nothing. Unset takes the\n * variant's own: a boxed select shows the caret, a bare one — set in a row\n * where 10px of caret is a tenth of the value's width — underlines.\n */\n indicator?: SelectIndicator;\n /**\n * Where the list opens. `'over'` (the default) puts the selected row on the\n * trigger, its label in the trigger's own text column, so choosing what is\n * already chosen moves nothing; `'below'` hangs it under the trigger.\n */\n popup?: SelectPopup;\n /**\n * Id for the trigger button. React Aria puts a plain `id` on the wrapper,\n * which is not labelable, so an outer `<label for>` needs this to reach a\n * control the label can actually own.\n */\n triggerId?: string;\n className?: string;\n} & SegmentTooltipFields & OverlayPortalProps;\n\n/**\n * Form select wrapping React Aria's Select. Pass either `options` for a\n * quick declarative render or `children` of `<SelectItem>` for control over\n * each row; `<SelectSection>` (or an `options` entry with a `title`) groups\n * rows under a heading.\n *\n * The selection key type is parameterized so consumers with a string-literal\n * union for `value` (e.g. `'r' | 'g' | 'b'`) get a typed `onSelectionChange`.\n *\n * `shortcut` puts a kit tooltip on the trigger reading `Name (⌘K)`, named by\n * `aria-label` or a string `label`, as `Button` does; `tooltip` replaces that\n * text.\n */\nexport function Select<T extends Key = string>(props: SelectProps<T>) {\n const {\n label,\n orientation = 'stacked',\n description,\n errorMessage,\n placeholder,\n options,\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n width = 'fill',\n variant = 'field',\n indicator = variant === 'bare' ? 'underline' : 'chevron',\n popup = 'over',\n triggerId,\n className,\n portalContainer,\n shortcut,\n tooltip,\n ...rest\n } = props;\n\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const pressRef = useRef<Press | null>(null);\n const [nudge, setNudge] = useState(NO_NUDGE);\n\n return (\n <RACSelect\n {...rest}\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange ? (k) => onSelectionChange(k as T) : undefined}\n className={[\n f.field,\n f.control,\n s.select,\n width === 'fit' && `${f.fit} ${s.fit}`,\n variant === 'bare' && s.bare,\n indicator === 'underline' && s.underlined,\n indicator === 'none' && s.plain,\n orientation === 'row' && `${f.row} ${s.row}`,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {anchor}\n {label !== undefined && <Label className={f.label}>{label}</Label>}\n <TriggerTooltip\n content={segmentTooltipContent({ tooltip, shortcut, ariaLabel: rest['aria-label'], label })}\n disabled={rest.isDisabled}\n >\n <RACButton\n id={triggerId}\n ref={triggerRef}\n className={`${f.frame} ${s.trigger}`}\n onPointerDown={(e) => {\n pressRef.current = { x: e.clientX, y: e.clientY, at: performance.now() };\n }}\n >\n <SelectValue className={s.value}>\n {({ defaultChildren, isPlaceholder }) =>\n isPlaceholder ? (placeholder ?? defaultChildren) : defaultChildren\n }\n </SelectValue>\n {width === 'fit' && (\n <span className={s.sizer} aria-hidden=\"true\">\n {placeholder !== undefined && <span>{placeholder}</span>}\n {optionLabels(options, children).map((l, i) => (\n <span key={i}>{l}</span>\n ))}\n </span>\n )}\n {indicator === 'chevron' && (\n <svg className={s.chevron} viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <path d=\"M2 4 L5 7 L8 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </RACButton>\n </TriggerTooltip>\n {description !== undefined && (\n <Text slot=\"description\" className={`${f.hint} ${f.below}`}>\n {description}\n </Text>\n )}\n <FieldError className={`${f.error} ${f.below}`}>{errorMessage}</FieldError>\n {/* `data-weasel-overlay` marks DOM that belongs to this control but\n renders in a portal, outside the subtree the trigger sits in. Any\n consumer reasoning about \"did focus leave my component?\" via\n `closest()` gets the wrong answer without it — a text editor whose\n font menu lives here would end its session the moment the menu is\n clicked. */}\n <RACPopover\n className={s.popover}\n data-weasel-overlay=\"\"\n placement=\"bottom start\"\n offset={popup === 'over' ? nudge.offset : undefined}\n crossOffset={popup === 'over' ? nudge.crossOffset : undefined}\n shouldFlip={popup !== 'over'}\n {...portalProps}\n >\n {popup === 'over' && (\n <AlignOverTrigger\n triggerRef={triggerRef}\n pressRef={pressRef}\n applied={nudge}\n onMeasure={setNudge}\n />\n )}\n <RACListBox className={`${listbox.surface} ${listbox.list}`}>\n {options !== undefined\n ? options.map((entry, i) =>\n isGroup(entry) ? (\n <SelectSection key={`section-${i}`} title={entry.title}>\n {entry.options.map(renderOption)}\n </SelectSection>\n ) : (\n renderOption(entry)\n ),\n )\n : children}\n </RACListBox>\n </RACPopover>\n </RACSelect>\n );\n}\n\ntype Nudge = { offset: number; crossOffset: number };\n\n/** Where and when the pointer went down on the trigger. */\ntype Press = { x: number; y: number; at: number };\n\n/** How long a press may last and how far it may travel and still be a click. */\nconst CLICK_MS = 500;\n\nconst NO_NUDGE: Nudge = { offset: 0, crossOffset: 0 };\n\n/** The gap kept between a list and the viewport edge — React Aria's own\n * `containerPadding` default. */\nconst EDGE = 12;\n\n/** React Aria's own resting place for a popover: hanging under its trigger. */\nconst BELOW: Nudge = { offset: 8, crossOffset: 0 };\n\n/**\n * Lands the list so its selected row covers the trigger: same text column,\n * same line. The shift is handed back as the popover's own `offset` and\n * `crossOffset` rather than a transform, so React Aria keeps owning the\n * position and still holds the list inside the viewport.\n *\n * Measuring needs the list rendered, and the correction is applied by setting\n * state from a layout effect — React finishes that pass before the browser\n * paints, so the list is never seen at the uncorrected position.\n */\nfunction AlignOverTrigger({\n triggerRef,\n pressRef,\n applied,\n onMeasure,\n}: {\n triggerRef: RefObject<HTMLButtonElement | null>;\n pressRef: RefObject<Press | null>;\n applied: Nudge;\n onMeasure: (next: Nudge) => void;\n}) {\n // React Aria positions the popover but hands out no ref to it, so the\n // element is reached from inside: this marker's own parent.\n const markerRef = useRef<HTMLSpanElement>(null);\n // A measurement that settles takes two passes — one to place the list, one\n // to confirm. A cap is what keeps a list whose own placement changes its\n // measurement from renegotiating forever.\n const passes = useRef(0);\n useLayoutEffect(() => {\n const trigger = triggerRef.current;\n const popover = markerRef.current?.closest<HTMLElement>('[data-weasel-overlay]');\n if (!trigger || !popover || passes.current > 3) return;\n const value = trigger.querySelector(`.${s.value}`);\n // Nothing chosen yet, so there is no row that belongs over the trigger —\n // and putting an arbitrary one under the pointer arms it. A select showing\n // its placeholder hangs its list below, like any other dropdown.\n const label = popover.querySelector(`[data-selected] .${s.optionLabel}`);\n if (!value || !label) {\n if (applied.offset !== BELOW.offset || applied.crossOffset !== BELOW.crossOffset)\n onMeasure(BELOW);\n return;\n }\n\n // The trigger's own text alignment decides which edge the two labels are\n // matched on, and the list follows it so the selected row reads as the\n // trigger with the others unfolded around it.\n const align = getComputedStyle(trigger).getPropertyValue('--wzl-select-align').trim();\n const toEnd = align === 'right' || align === 'end';\n popover.dataset.align = toEnd ? 'end' : 'start';\n\n // Stated against each element's own box rather than measured as a gap to\n // close: React Aria repositions after this effect, so what is on screen\n // now is a frame behind, and a correction read off it would be applied to\n // a position that has already moved — the shift compounds every pass.\n // `bottom start` puts the list's top at the trigger's bottom and their\n // left edges together, so the two insets below are the whole story.\n const box = popover.getBoundingClientRect();\n const seat = trigger.getBoundingClientRect();\n const row = label.getBoundingClientRect();\n const shown = value.getBoundingClientRect();\n // React Aria holds the list inside the viewport across the trigger but not\n // along it, and `offset` moves it along: the selected row sits on the\n // trigger only as far as the rest of the list still fits on screen.\n const over = shown.top + shown.height / 2 - seat.top - (row.top + row.height / 2 - box.top) - seat.height;\n const viewHeight = trigger.ownerDocument.documentElement.clientHeight;\n const lowest = viewHeight - EDGE - box.height - seat.bottom;\n const next = {\n offset: Math.max(EDGE - seat.bottom, Math.min(over, lowest)),\n crossOffset: toEnd\n ? shown.right - seat.left - (row.right - box.left)\n : shown.left - seat.left - (row.left - box.left),\n };\n if (Math.abs(next.offset - applied.offset) < 0.5 && Math.abs(next.crossOffset - applied.crossOffset) < 0.5)\n return;\n passes.current += 1;\n onMeasure(next);\n });\n\n // The list covers the trigger, so the release that ends the click opening it\n // lands on a row — and a row selects on release, which shuts the list again\n // before it has been seen. A click is a press and a release in the same\n // place: that one is the opening gesture and belongs to the trigger, and the\n // list keeps every release after it. Press, hold, drag and release still\n // picks a row, which is the gesture a list over its trigger is for.\n useEffect(() => {\n const doc = triggerRef.current?.ownerDocument;\n if (!doc) return;\n const onUp = (e: PointerEvent) => {\n doc.removeEventListener('pointerup', onUp, true);\n const press = pressRef.current;\n if (!press || performance.now() - press.at > CLICK_MS) return;\n if (pastDragThreshold({ clientX: press.x, clientY: press.y }, e)) return;\n e.preventDefault();\n e.stopPropagation();\n };\n doc.addEventListener('pointerup', onUp, true);\n return () => doc.removeEventListener('pointerup', onUp, true);\n }, [triggerRef, pressRef]);\n\n return <span ref={markerRef} hidden />;\n}\n\n/* `SelectValue` copies the selected row into the trigger, mark included; the\n trigger hides it, so the `width='fit'` sizer leaves it out. */\nfunction CheckMark() {\n return (\n <svg className={s.check} viewBox=\"0 0 10 10\" aria-hidden=\"true\">\n <polyline points=\"1.5,5 4,7.5 8.5,3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nfunction renderOption<T extends Key>(o: SelectOption & { value: T }) {\n return (\n <SelectItem key={String(o.value)} id={o.value} isDisabled={o.isDisabled} icon={o.icon} textValue={o.textValue}>\n {o.label}\n </SelectItem>\n );\n}\n\n/**\n * The labels a `width='fit'` trigger measures itself against. In the children\n * form the label sits one element deep, inside a `SelectItem`, or two inside a\n * `SelectSection`.\n */\nfunction optionLabels(\n options: ReadonlyArray<SelectOption | SelectOptionGroup<Key>> | undefined,\n children: ReactNode,\n): ReactNode[] {\n if (options !== undefined)\n return options.flatMap((o) =>\n 'options' in o ? o.options.map((g) => withIcon(g.icon, g.label)) : [withIcon(o.icon, o.label)],\n );\n return Children.toArray(children).flatMap((c) => {\n if (!isValidElement<{ children?: ReactNode; icon?: ReactNode }>(c)) return [c];\n return c.type === SelectSection\n ? optionLabels(undefined, c.props.children)\n : [withIcon(c.props.icon, c.props.children)];\n });\n}\n\n/** A label led by its icon, as a row draws it. */\nfunction withIcon(icon: ReactNode, label: ReactNode): ReactNode {\n if (icon === undefined || icon === null) return label;\n return (\n <>\n <span className={s.optionIcon} aria-hidden=\"true\">{icon}</span>\n {label}\n </>\n );\n}\n\n/** Props for {@link SelectSection}. */\nexport type SelectSectionProps = {\n /** Heading shown above the section's rows; it also names the group for\n * screen readers. */\n title?: ReactNode;\n children?: ReactNode;\n className?: string;\n};\n\n/** A titled group of `SelectItem` rows in a {@link Select}'s list. */\nexport function SelectSection({ title, children, className }: SelectSectionProps) {\n return (\n <RACListBoxSection className={[s.section, className].filter(Boolean).join(' ')}>\n {title !== undefined && <Header className={s.sectionHeader}>{title}</Header>}\n {children}\n </RACListBoxSection>\n );\n}\n\n/** Props for {@link SelectItem}, on top of React Aria's `ListBoxItem` props. */\nexport type SelectItemProps = Omit<RACListBoxItemProps, 'className' | 'children'> & {\n children?: ReactNode;\n /** A glyph drawn before the label, in the list and in the trigger. */\n icon?: ReactNode;\n className?: string;\n};\n\n/**\n * Every row renders a check mark beside its label, so from React Aria's\n * side the children are never plain text and it can't derive the string\n * type-to-select and screen readers need — it warns once per row. A string\n * label already *is* that string, so derive it rather than making every\n * call site restate it; anything richer has to say what it reads as.\n */\nfunction textValueOf(children: ReactNode, explicit: string | undefined): string | undefined {\n if (explicit !== undefined) return explicit;\n return typeof children === 'string' || typeof children === 'number'\n ? String(children)\n : undefined;\n}\n\n/**\n * One row in a {@link Select}'s list, with a leading check mark when\n * selected. A string child supplies its own `textValue`; anything richer must\n * pass one so type-to-select and screen readers have something to read.\n */\nexport function SelectItem({ children, icon, className, textValue, ...rest }: SelectItemProps) {\n return (\n <RACListBoxItem\n {...rest}\n textValue={textValueOf(children, textValue)}\n className={[s.option, className].filter(Boolean).join(' ')}\n >\n <CheckMark />\n {/* A box around the label, not just text: landing the list over its\n trigger means measuring where this row's label sits. */}\n <span className={s.optionLabel}>{withIcon(icon, children)}</span>\n </RACListBoxItem>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBar-BEOfOX0D.js","names":["s","StatusBar_module_default","StatusBar","props","className","ariaLabel","StatusBarItem","cls","muted","title","StatusBarSpacer"],"sources":["../../src/components/StatusBar/StatusBar.module.css","../../src/components/StatusBar/StatusBar.tsx"],"sourcesContent":[".bar {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n display: flex;\n align-items: center;\n gap: var(--wzl-space-8);\n flex-shrink: 0;\n padding: var(--wzl-space-2) var(--wzl-space-6);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n background: var(--wzl-surface);\n border-top: 1px solid var(--wzl-border);\n}\n\n.item {\n white-space: nowrap;\n}\n\n.muted {\n opacity: 0.6;\n}\n\n.hasTitle {\n cursor: help;\n}\n\n.spacer {\n margin-left: auto;\n}\n","import type { ReactNode } from 'react';\nimport s from './StatusBar.module.css';\n\n/** Props for {@link StatusBar}. */\nexport interface StatusBarProps {\n /**\n * Accessible label for the bar. Deliberately not a live region — a status\n * bar's readouts change on every pointer move (zoom, cursor position,\n * selection count), and announcing each one would make a screen reader\n * unusable. Screen-reader users reach the same facts through the controls\n * that own them.\n */\n ariaLabel?: string;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * The thin readout strip along the bottom of an editor window: monospace,\n * one row, items separated by a fixed gap, with an optional spacer that\n * pushes everything after it to the trailing edge.\n *\n * Pure presentation — it holds whatever the app puts in it. Compose with\n * `<StatusBarItem>` and `<StatusBarSpacer>`.\n */\nexport function StatusBar(props: StatusBarProps) {\n const { ariaLabel, children, className } = props;\n return (\n <footer className={[s.bar, className].filter(Boolean).join(' ')} aria-label={ariaLabel}>\n {children}\n </footer>\n );\n}\n\n/** Props for {@link StatusBarItem}. */\nexport interface StatusBarItemProps {\n /**\n * Hover text. Items that carry one also get a `help` cursor, so the\n * affordance is discoverable rather than hidden behind a hover delay.\n */\n title?: string;\n /**\n * Dim the item. For reference material that\n * shouldn't compete with live readouts — build stamps, hints, units.\n */\n muted?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/** One readout in a `<StatusBar>`. */\nexport function StatusBarItem(props: StatusBarItemProps) {\n const { title, muted, children, className } = props;\n const cls = [s.item, muted && s.muted, title !== undefined && s.hasTitle, className]\n .filter(Boolean).join(' ');\n return <span className={cls} title={title}>{children}</span>;\n}\n\n/**\n * Splits a status bar into leading and trailing runs — everything after the\n * spacer is pushed to the trailing edge. Decorative, so it's hidden from the\n * accessibility tree.\n */\nexport function StatusBarSpacer() {\n return <span className={s.spacer} aria-hidden=\"true\" />;\n}\n"],"mappings":";;;;;;;;;;ACyBA,SAAgBE,EAAU,GAAuB;CAC/C,IAAM,EAAE,cAAW,aAAU,iBAAcC;CAC3C,OACE,kBAAC,UAAD;EAAQ,WAAW,CAACH,EAAE,KAAKI,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAAG,cAAYC;EAC1E;CACK,CAAA;AAEZ;AAmBA,SAAgBC,EAAc,GAA2B;CACvD,IAAM,EAAE,UAAO,UAAO,aAAU,iBAAcH,GACxCI,IAAM;EAACP,EAAE;EAAMQ,KAASR,EAAE;EAAOS,MAAU,KAAA,KAAaT,EAAE;EAAUI;CAAS,CAAC,CACjF,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAC3B,OAAO,kBAAC,QAAD;EAAM,WAAWG;EAAY;EAAQ;CAAe,CAAA;AAC7D;AAOA,SAAgBG,IAAkB;CAChC,OAAO,kBAAC,QAAD;EAAM,WAAWV,EAAE;EAAQ,eAAY;CAAQ,CAAA;AACxD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleBar-BZ4Gk1IU.js","names":["s","segmentTooltipContent","useRovingTabIndex","useFitScope","FitScope","ToggleBar_module_default","ToggleBar","props","mode","isSelected","value","isMixed","mixed","handleClick","item","items","index","current","next","v","selectedIndex","it","roving","fit","style","height","rootCls","size","variant","className","ariaLabel","selected","cls","SegmentTooltip","i"],"sources":["../../src/components/ToggleBar/ToggleBar.module.css","../../src/components/ToggleBar/ToggleBar.tsx"],"sourcesContent":["/* Aqua-glass segmented control. The track is a pill-shaped well; the\n selected segment becomes a tinted glass cylinder that reads as the same\n \"lozenge\" family as the standalone Button. Visual params come from the\n `--btn-*` custom properties (see Button.module.css) so the Button Lab\n can tune both surfaces with one set of sliders. */\n.root {\n display: inline-flex;\n height: var(--tb-h, var(--wzl-control-h));\n padding: var(--wzl-space-1);\n background: linear-gradient(\n 180deg,\n rgba(0, 0, 0, 0.18) 0%,\n rgba(0, 0, 0, 0.05) 100%\n );\n border-radius: var(--wzl-radius-pill);\n /* Clip segments to the track outline so interior corners read crisp and\n the selected segment's glass treatment doesn't paint over the rounded\n outer pixels. */\n overflow: hidden;\n box-shadow:\n inset 0 1px 2px rgba(0, 0, 0, 0.4),\n 0 1px 0 rgba(255, 255, 255, 0.06);\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n /* The track clips, so without this a squeezing row shrinks it to nothing. */\n min-width: max-content;\n}\n\n.segment {\n position: relative;\n flex: 1 1 0;\n /* Equal widths when there is room, never narrower than the label. The\n segment clips its gloss, which otherwise drops its flex minimum to 0. */\n min-width: max-content;\n padding: 0 var(--wzl-space-6);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n margin: 0;\n font-family: var(--wzl-font-ui);\n font-weight: var(--wzl-font-weight-normal);\n font-size: var(--btn-fontsize, var(--wzl-font-size));\n line-height: 1;\n color: var(--wzl-fg-muted);\n cursor: pointer;\n /* Only round the outer corners of the bar — middle segments stay square\n so the seams between them don't render as facing parentheses. */\n border-radius: 0;\n isolation: isolate;\n overflow: hidden;\n transition: color var(--wzl-motion-fast);\n}\n\n/* 8px around a 14px glyph is most of a segment. */\n.segment:has(> svg) {\n padding: 0 5px;\n}\n\n.segment:first-of-type {\n border-radius: var(--wzl-radius-pill) 0 0 var(--wzl-radius-pill);\n}\n\n.segment:last-of-type {\n border-radius: 0 var(--wzl-radius-pill) var(--wzl-radius-pill) 0;\n}\n\n.segment:only-of-type {\n border-radius: var(--wzl-radius-pill);\n}\n\n.segment:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n\n.segment:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.segment:hover:not(:disabled):not(.segmentSelected) {\n color: var(--wzl-fg);\n}\n\n/* Selected segment — full Aqua glass cylinder. Mirrors Button.variant_primary. */\n.segmentSelected {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--wzl-accent) var(--btn-top-alpha, 45%), transparent) 0%,\n color-mix(in srgb, var(--wzl-accent) var(--btn-upper-alpha, 70%), transparent) calc(var(--btn-equator, 52%) - var(--btn-equator-spread, 12%)),\n color-mix(in srgb, var(--wzl-accent) var(--btn-equator-tint, 95%), white) var(--btn-equator, 52%),\n var(--wzl-accent) calc(var(--btn-equator, 52%) + var(--btn-equator-spread, 12%) * 1.6),\n color-mix(in srgb, var(--wzl-accent) var(--btn-base-tint, 70%), black) 100%\n );\n backdrop-filter: blur(var(--btn-blur, 6px)) saturate(var(--btn-saturate, 1.3));\n -webkit-backdrop-filter: blur(var(--btn-blur, 6px)) saturate(var(--btn-saturate, 1.3));\n color: var(--wzl-fg-on-accent);\n text-shadow:\n 0 1px 0 rgba(0, 0, 0, var(--btn-text-shadow, 0.35)),\n var(--btn-text-inset-x, 0px) var(--btn-text-inset-y, 1px) 0 rgba(0, 0, 0, var(--btn-text-inset, 0.55)),\n 0 0 6px rgba(0, 0, 0, calc(var(--btn-text-shadow, 0.35) * 0.5));\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, var(--btn-inset-hi, 0.42)),\n inset 0 -1px 2px rgba(0, 0, 0, var(--btn-inset-lo, 0.3)),\n 0 0 0 1px rgba(0, 0, 0, var(--btn-rim, 0.22)),\n 0 1px 2px rgba(0, 0, 0, var(--btn-drop-near, 0.3)),\n 0 2px 4px rgba(0, 0, 0, calc(var(--btn-drop-far, 0.18) * 0.8));\n}\n\n/* Specular gloss on the selected segment. Top corners inherit the\n segment's radius so they hug the upper edge cleanly; bottom corners\n are flattened so the gloss ends in a straight line at the equator\n instead of two little curves that read as `)(` brackets. */\n.segmentSelected::before {\n content: '';\n position: absolute;\n inset: 1px 1px var(--btn-gloss-bottom, 50%) 1px;\n border-radius: inherit;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, var(--btn-gloss-top, 0.42)) 0%,\n rgba(255, 255, 255, var(--btn-gloss-mid, 0.12)) 60%,\n rgba(255, 255, 255, 0) 100%\n );\n pointer-events: none;\n z-index: 1;\n}\n\n.segmentSelected > * {\n position: relative;\n z-index: 2;\n}\n\n/* Mixed segment (`aria-pressed=\"mixed\"`) — the sources disagree. Reads as a\n deliberate third state rather than a dimmed \"on\": a flat accent wash with\n none of the selected segment's gloss/cylinder treatment, so it can't be\n mistaken for the glass lozenge at a glance. */\n.segmentMixed {\n background: color-mix(in srgb, var(--wzl-accent) 22%, transparent);\n color: var(--wzl-fg);\n box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--wzl-accent) 45%, transparent);\n}\n\n.segmentMixed:hover:not(:disabled) {\n background: color-mix(in srgb, var(--wzl-accent) 32%, transparent);\n}\n\n.variant_minimal .segmentMixed {\n background: color-mix(in srgb, var(--wzl-accent) 18%, transparent);\n box-shadow: none;\n color: var(--wzl-fg);\n}\n\n/* Small variant — ~60% of the default height, with proportionally reduced\n padding and font. Sized for dense surfaces (lab control panels, inline\n filters, etc.). */\n.size_sm {\n height: 17px;\n padding: 1px;\n}\n\n.size_sm .segment {\n padding: 0 var(--wzl-space-4);\n font-size: var(--wzl-font-size-sm);\n}\n\n/* `.size_sm .segment` outranks the glyph rule above on specificity, so a\n small bar's glyph segments need the tight padding restated to stay\n near-square rather than reading as wide plates. */\n.size_sm .segment:has(> svg) {\n padding: 0 3px;\n}\n\n/* Minimal variant — strips the pill track, glass selected state, inset\n shadows, and outer padding. Used in dense diagnostic surfaces (dispatch\n trace, lab inspectors) where the bar must read as plain text controls. */\n.variant_minimal {\n height: auto;\n padding: 0;\n background: none;\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n box-shadow: none;\n gap: 0;\n}\n\n.variant_minimal .segment {\n padding: 0 var(--wzl-space-3);\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-medium);\n line-height: 1.4;\n border-radius: 0;\n color: var(--wzl-fg-muted);\n transition: none;\n}\n\n/* Dividers between segments make the mutual-exclusion grouping visible\n without a heavy track. Only the inner edges get a rule — the outer\n border on `.variant_minimal` handles the perimeter. */\n.variant_minimal .segment ~ .segment {\n border-left: 1px solid var(--wzl-border);\n}\n\n.variant_minimal .segment:first-of-type,\n.variant_minimal .segment:last-of-type,\n.variant_minimal .segment:only-of-type {\n border-radius: 0;\n}\n\n.variant_minimal .segment:hover:not(:disabled):not(.segmentSelected) {\n color: var(--wzl-fg);\n background: var(--wzl-surface-hover);\n}\n\n.variant_minimal .segmentSelected {\n background: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n color: var(--wzl-accent-fg);\n text-shadow: none;\n box-shadow: none;\n font-weight: var(--wzl-font-weight-medium);\n}\n\n.variant_minimal .segmentSelected::before {\n content: none;\n}\n\n/* Flat variant — no track, no glass, no pill: each segment is its own\n outlined cell. For property panels, where a bar sits in a row beside\n inputs and the glass cylinder makes it the loudest thing on the surface. */\n.variant_flat {\n padding: 0;\n background: none;\n border-radius: var(--wzl-radius-sm);\n box-shadow: none;\n overflow: visible;\n}\n\n.variant_flat .segment {\n border: 1px solid var(--wzl-border-strong);\n border-radius: 0;\n /* Sunken, so an unselected cell sits below the panel and the selected one\n reads as raised without needing the glass treatment back. */\n background: var(--wzl-surface-sunken);\n color: var(--wzl-fg-muted);\n}\n\n/* Adjacent cells share one rule rather than stacking two. */\n.variant_flat .segment ~ .segment {\n margin-inline-start: -1px;\n}\n\n.variant_flat .segment:first-of-type {\n border-start-start-radius: var(--wzl-radius-sm);\n border-end-start-radius: var(--wzl-radius-sm);\n}\n\n.variant_flat .segment:last-of-type {\n border-start-end-radius: var(--wzl-radius-sm);\n border-end-end-radius: var(--wzl-radius-sm);\n}\n\n.variant_flat .segment:hover:not(:disabled):not(.segmentSelected) {\n background: var(--wzl-surface-hover);\n color: var(--wzl-fg);\n}\n\n.variant_flat .segmentSelected {\n /* Above its neighbors, or the next cell's left border covers its right one. */\n z-index: 1;\n background: var(--wzl-accent);\n color: var(--wzl-fg-on-accent);\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n text-shadow: none;\n box-shadow: none;\n}\n\n.variant_flat .segmentSelected::before {\n content: none;\n}\n","import { type CSSProperties, type ReactElement, type ReactNode } from 'react';\nimport s from './ToggleBar.module.css';\nimport { useRovingTabIndex } from '../../useRovingTabIndex';\nimport { FitScope, useFitScope } from '../FitLabel/FitLabel';\nimport { SegmentTooltip, segmentTooltipContent, type SegmentTooltipFields } from '../segmentTooltip';\n\n/** One segment of a {@link ToggleBar}, identified by its `value`. */\nexport type ToggleBarItem<V extends string | number = string> = {\n value: V;\n label?: ReactNode;\n ariaLabel?: string;\n disabled?: boolean;\n} & SegmentTooltipFields;\n\n/** Segment height and type scale for a {@link ToggleBar}. */\nexport type ToggleBarSize = 'sm' | 'md';\n/** Visual treatment of a {@link ToggleBar}. */\nexport type ToggleBarVariant = 'default' | 'minimal' | 'flat';\n\ntype CommonProps = {\n ariaLabel?: string;\n className?: string;\n height?: number;\n /** Size variant. `sm` is ~60% of the default height with reduced padding\n * and font size — sized for dense surfaces like lab control panels. */\n size?: ToggleBarSize;\n /** Visual variant. `minimal` strips the pill track and glass treatment;\n * selection becomes a flat accent. For dense diagnostic surfaces. */\n variant?: ToggleBarVariant;\n};\n\n/**\n * Props for {@link ToggleBar}, discriminated on `mode`. Single mode is\n * controlled by one value or `null`; multiple mode by an array, and only it\n * accepts `mixedValues`.\n */\nexport type ToggleBarProps<V extends string | number = string> =\n | (CommonProps & {\n mode?: 'single';\n items: readonly ToggleBarItem<V>[];\n value: V | null;\n onChange: (next: V | null) => void;\n allowDeselect?: boolean;\n })\n | (CommonProps & {\n mode: 'multiple';\n items: readonly ToggleBarItem<V>[];\n value: readonly V[];\n /**\n * Values that are neither on nor off — the sources this bar\n * aggregates disagree (a text range that is bold in part of it, a\n * multi-selection whose nodes differ). Rendered `aria-pressed=\"mixed\"`,\n * the ARIA tri-state a toggle button actually has, rather than\n * `SelectionPanel`'s reduced-opacity-plus-`title` workaround for\n * `Switch`, which has no indeterminate state to render.\n *\n * `value` wins where the two lists overlap, so a caller that can't\n * cheaply keep them disjoint doesn't get an ambiguous segment.\n *\n * Clicking a mixed segment turns it fully **on**, matching the\n * everywhere-else convention (and `toggleFlagInRange`'s rule for a\n * partially-styled text range) that a mixed toggle resolves toward\n * the affirmative rather than clearing.\n */\n mixedValues?: readonly V[];\n onChange: (next: V[]) => void;\n });\n\n/**\n * Segmented control for choosing among a fixed set of values — one of them\n * (`mode: 'single'`, the default) or any number (`mode: 'multiple'`).\n *\n * Single mode ignores a click on the already-selected segment unless\n * `allowDeselect` is set. Arrow keys move focus without changing the value;\n * Space and Enter commit.\n */\nexport function ToggleBar<V extends string | number = string>(props: ToggleBarProps<V>): ReactElement {\n const { items, ariaLabel, className, height, size, variant } = props;\n const mode = props.mode ?? 'single';\n\n const isSelected = (value: V): boolean => {\n if (mode === 'multiple') return (props.value as readonly V[]).includes(value);\n return (props.value as V | null) === value;\n };\n\n /** Mixed only in multiple mode, and only where `value` doesn't already\n * claim the segment. Single mode has nothing to be mixed about — its\n * aggregate is one value or none. */\n const isMixed = (value: V): boolean => {\n if (mode !== 'multiple') return false;\n const mixed = (props as { mixedValues?: readonly V[] }).mixedValues;\n return mixed !== undefined && mixed.includes(value) && !isSelected(value);\n };\n\n const handleClick = (index: number) => () => {\n const item = items[index];\n if (item.disabled) return;\n if (mode === 'multiple') {\n const current = props.value as readonly V[];\n const next = current.includes(item.value)\n ? current.filter(v => v !== item.value)\n : [...current, item.value];\n (props.onChange as (n: V[]) => void)(next);\n } else {\n const current = props.value as V | null;\n if (current === item.value) {\n if ((props as { allowDeselect?: boolean }).allowDeselect) {\n (props.onChange as (n: V | null) => void)(null);\n }\n return;\n }\n (props.onChange as (n: V | null) => void)(item.value);\n }\n };\n\n const selectedIndex = mode === 'single'\n ? items.findIndex(it => it.value === (props.value as V | null))\n : -1;\n\n const roving = useRovingTabIndex({\n itemSelector: `.${s.segment}`,\n // Single mode is a radiogroup: the tab stop is the current value, and\n // arrow keys move the selection with the focus. Multiple mode is a set of\n // independent toggles — focus alone moves, and Space/Enter flips.\n tabStopIndex: selectedIndex >= 0 ? selectedIndex : undefined,\n onNavigate: mode === 'single'\n ? (index) => (props.onChange as (n: V | null) => void)(items[index].value)\n : undefined,\n onActivate: mode === 'multiple' ? (index) => handleClick(index)() : undefined,\n });\n\n // Segment labels drawn as `FitLabel`s shorten together when the bar is\n // squeezed or will not fit where it sits.\n const fit = useFitScope(roving.rootRef);\n\n const style: CSSProperties | undefined = height !== undefined\n ? ({ ['--tb-h' as string]: `${height}px` } as CSSProperties)\n : undefined;\n\n const rootCls = [\n s.root,\n size && s[`size_${size}`],\n variant && s[`variant_${variant}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div\n ref={roving.rootRef}\n onKeyDown={roving.onKeyDown}\n className={rootCls}\n role={mode === 'multiple' ? 'group' : 'radiogroup'}\n aria-label={ariaLabel}\n style={style}\n >\n <FitScope value={fit}>\n {items.map((item, i) => {\n const selected = isSelected(item.value);\n const mixed = isMixed(item.value);\n const cls = [s.segment, selected && s.segmentSelected, mixed && s.segmentMixed]\n .filter(Boolean)\n .join(' ');\n return (\n <SegmentTooltip key={item.value} content={segmentTooltipContent(item)} disabled={item.disabled}>\n <button\n type=\"button\"\n role={mode === 'multiple' ? undefined : 'radio'}\n aria-checked={mode === 'multiple' ? undefined : selected}\n aria-pressed={mode === 'multiple' ? (mixed ? 'mixed' : selected) : undefined}\n aria-label={item.ariaLabel}\n disabled={item.disabled}\n className={cls}\n onClick={handleClick(i)}\n >\n {item.label}\n </button>\n </SegmentTooltip>\n );\n })}\n </FitScope>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AC4EA,SAAgBM,EAA8C,GAAwC;CACpG,IAAM,EAAE,UAAO,cAAW,cAAW,WAAQ,SAAM,eAAYC,GACzDC,IAAOD,EAAM,QAAQ,UAErBE,KAAc,MACdD,MAAS,aAAoBD,EAAM,MAAuB,SAASG,CAAK,IACpEH,EAAM,UAAuBG,GAMjCC,KAAW,MAAsB;EACrC,IAAIH,MAAS,YAAY,OAAO;EAChC,IAAMI,IAASL,EAAyC;EACxD,OAAOK,MAAU,KAAA,KAAaA,EAAM,SAASF,CAAK,KAAK,CAACD,EAAWC,CAAK;CAC1E,GAEMG,KAAe,YAAwB;EAC3C,IAAMC,IAAOC,EAAMC;EACnB,IAAI,GAAK,UACT;OAAIR,MAAS,YAAY;IACvB,IAAMS,IAAUV,EAAM,OAChBW,IAAOD,EAAQ,SAASH,EAAK,KAAK,IACpCG,EAAQ,QAAO,MAAKE,MAAML,EAAK,KAAK,IACpC,CAAC,GAAGG,GAASH,EAAK,KAAK;IAC3B,EAAO,SAA8BI,CAAI;GAC3C,OAAO;IAEL,IADgBX,EAAM,UACNO,EAAK,OAAO;KAC1B,AAAKP,EAAsC,iBACzCA,EAAO,SAAmC,IAAI;KAEhD;IACF;IACA,EAAO,SAAmCO,EAAK,KAAK;GACtD;;CACF,GAEMM,IAAgBZ,MAAS,WAC3BO,EAAM,WAAU,MAAMM,EAAG,UAAWd,EAAM,KAAkB,IAC5D,IAEEe,IAASpB,EAAkB;EAC/B,cAAc,IAAIF,EAAE;EAIpB,cAAcoB,KAAiB,IAAIA,IAAgB,KAAA;EACnD,YAAYZ,MAAS,YAChB,MAAWD,EAAM,SAAmCQ,EAAMC,EAAM,CAAC,KAAK,IACvE,KAAA;EACJ,YAAYR,MAAS,cAAc,MAAUK,EAAYG,CAAK,CAAC,CAAC,IAAI,KAAA;CACtE,CAAC,GAIKO,IAAMpB,EAAYmB,EAAO,OAAO,GAEhCE,IAAmCC,MAAW,KAAA,IAEhD,KAAA,IADC,EAAG,UAAqB,GAAGA,EAAO,IAAI,GAGrCC,IAAU;EACd1B,EAAE;EACF2B,KAAQ3B,EAAE,QAAQ2B;EAClBC,KAAW5B,EAAE,WAAW4B;EACxBC;CACF,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAE1B,OACE,kBAAC,OAAD;EACE,KAAKP,EAAO;EACZ,WAAWA,EAAO;EAClB,WAAWI;EACX,MAAMlB,MAAS,aAAa,UAAU;EACtC,cAAYsB;EACL;EAEP,UAAA,kBAAC1B,GAAD;GAAU,OAAOmB;GACd,UAAAR,EAAM,KAAK,GAAM,MAAM;IACtB,IAAMgB,IAAWtB,EAAWK,EAAK,KAAK,GAChCF,IAAQD,EAAQG,EAAK,KAAK,GAC1BkB,IAAM;KAAChC,EAAE;KAAS+B,KAAY/B,EAAE;KAAiBY,KAASZ,EAAE;IAAY,CAAC,CAC5E,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;IACX,OACE,kBAACiC,GAAD;KAAiC,SAAShC,EAAsBa,CAAI;KAAG,UAAUA,EAAK;KACpF,UAAA,kBAAC,UAAD;MACE,MAAK;MACL,MAAMN,MAAS,aAAa,KAAA,IAAY;MACxC,gBAAcA,MAAS,aAAa,KAAA,IAAYuB;MAChD,gBAAcvB,MAAS,aAAcI,IAAQ,UAAUmB,IAAY,KAAA;MACnE,cAAYjB,EAAK;MACjB,UAAUA,EAAK;MACf,WAAWkB;MACX,SAASnB,EAAYqB,CAAC;MAErB,UAAApB,EAAK;KACA,CAAA;IACM,GAbKA,EAAK,KAaV;GAEpB,CAAC;EACO,CAAA;CACP,CAAA;AAET"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip-C6eFCYxw.js","names":["TooltipTrigger","RACTooltipTrigger","Tooltip","_Fragment","RACTooltip","s","useOverlayPortal","Focusable$1","Tooltip_module_default","TooltipTrigger$1","rest","props","TooltipTrigger","Tooltip$1","portalContainer","Fragment","anchor","Tooltip","className","portalProps","OverlayArrow","children"],"sources":["../../src/components/Tooltip/Tooltip.module.css","../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":[".tooltip {\n /* Above Dialog overlay (1000) and ToastRegion (1100) — RAC sets no z-index. */\n z-index: 1200;\n background: var(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n line-height: 1.3;\n padding: var(--wzl-space-2) var(--wzl-space-4);\n max-width: 260px;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.tooltip[data-entering],\n.tooltip[data-exiting] {\n opacity: 0;\n}\n\n.arrow svg {\n display: block;\n fill: var(--wzl-surface);\n stroke: var(--wzl-border);\n stroke-width: 1;\n}\n\n.arrow[data-placement='bottom'] svg {\n transform: rotate(180deg);\n}\n\n.arrow[data-placement='left'] svg {\n transform: rotate(-90deg);\n}\n\n.arrow[data-placement='right'] svg {\n transform: rotate(90deg);\n}\n","import type { ReactNode } from 'react';\nimport {\n TooltipTrigger as RACTooltipTrigger,\n Tooltip as RACTooltip,\n OverlayArrow,\n type TooltipProps as RACTooltipProps,\n type TooltipTriggerComponentProps,\n} from 'react-aria-components';\nimport { useOverlayPortal, type OverlayPortalProps, type WithoutPortalTarget } from '../../overlays/portalHost';\nimport s from './Tooltip.module.css';\n\n/** Makes a non-RAC element a {@link TooltipTrigger} trigger: supplies\n * `tabIndex`, the hover/focus handlers and `aria-describedby`. The child must\n * forward its ref and DOM props, and carry an interactive role (or `img`). */\nexport { Focusable } from 'react-aria-components';\n\n/**\n * Props for {@link TooltipTrigger} — React Aria's `TooltipTrigger` props\n * unchanged.\n */\nexport type TooltipTriggerProps = TooltipTriggerComponentProps;\n\n/**\n * TooltipTrigger with kit defaults: ~600 ms open delay, instant close.\n * Wrap a focusable trigger plus a `<Tooltip>`. Non-RAC triggers (plain\n * `<button>`, a `Badge` etc.) must be wrapped in {@link Focusable} so\n * hover/focus props reach the DOM node.\n *\n * Caveat: while a tooltip is open, react-aria captures the first Escape\n * keydown (document-level, capture phase) to dismiss it — app-level\n * Escape handlers (deselect, cancel gesture) see only the second press.\n */\nexport function TooltipTrigger(props: TooltipTriggerProps) {\n const { delay = 600, closeDelay = 0, ...rest } = props;\n return <RACTooltipTrigger delay={delay} closeDelay={closeDelay} {...rest} />;\n}\n\n/** Props for {@link Tooltip}, on top of React Aria's `Tooltip` props. */\nexport type TooltipProps = Omit<WithoutPortalTarget<RACTooltipProps>, 'children' | 'className'> &\n OverlayPortalProps & {\n children?: ReactNode;\n className?: string;\n };\n\n/**\n * Tooltip bubble with an arrow pointing at the trigger. Non-interactive\n * content only (ARIA tooltip semantics). Use inside `<TooltipTrigger>`.\n */\nexport function Tooltip(props: TooltipProps) {\n const { children, className, placement = 'top', offset = 8, portalContainer, ...rest } = props;\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n return (\n <>\n {anchor}\n <RACTooltip\n {...rest}\n placement={placement}\n offset={offset}\n className={[s.tooltip, className].filter(Boolean).join(' ')}\n data-weasel-overlay=\"\"\n {...portalProps}\n >\n <OverlayArrow className={s.arrow}>\n <svg width={8} height={8} viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M0 0 L4 4 L8 0\" />\n </svg>\n </OverlayArrow>\n {children}\n </RACTooltip>\n </>\n );\n}\n"],"mappings":";;;;;;;;;ACgCA,SAAgBA,EAAe,GAA4B;CACzD,IAAM,EAAE,WAAQ,KAAK,gBAAa,GAAG,GAAGU,MAASC;CACjD,OAAO,kBAACV,GAAD;EAA0B;EAAmB;EAAY,GAAIS;CAAO,CAAA;AAC7E;AAaA,SAAgBR,EAAQ,GAAqB;CAC3C,IAAM,EAAE,aAAU,cAAW,eAAY,OAAO,YAAS,GAAG,oBAAiB,GAAGQ,MAASC,GACnF,EAAE,WAAQ,mBAAgBL,EAAiBQ,CAAe;CAChE,OACE,kBAAAX,GAAA,EAAA,UAAA,CACGa,GACD,kBAACZ,GAAD;EACE,GAAIM;EACO;EACH;EACR,WAAW,CAACL,EAAE,SAASa,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAC1D,uBAAoB;EACpB,GAAIC;EANN,UAAA,CAQE,kBAACC,GAAD;GAAc,WAAWf,EAAE;GACzB,UAAA,kBAAC,OAAD;IAAK,OAAO;IAAG,QAAQ;IAAG,SAAQ;IAAU,eAAY;IACtD,UAAA,kBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;GACvB,CAAA;EACO,CAAA,GACbgB,CACS;CACZ,CAAA,CAAA,EAAA,CAAA;AAEN"}
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./Disclosure-CpWt87nO.js";
|
|
2
|
-
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
-
import { forwardRef as r, useId as i, useMemo as a, useRef as o, useState as s } from "react";
|
|
4
|
-
var c = {
|
|
5
|
-
tree: "_tree_10k4o_1",
|
|
6
|
-
group: "_group_10k4o_2",
|
|
7
|
-
item: "_item_10k4o_19",
|
|
8
|
-
row: "_row_10k4o_23",
|
|
9
|
-
twisty: "_twisty_10k4o_61",
|
|
10
|
-
leading: "_leading_10k4o_75",
|
|
11
|
-
label: "_label_10k4o_81",
|
|
12
|
-
trailing: "_trailing_10k4o_88",
|
|
13
|
-
empty: "_empty_10k4o_95"
|
|
14
|
-
}, l = 500, u = r(function({ nodes: r, empty: u, className: d, "aria-label": f, "aria-labelledby": g, expandedIds: _, defaultExpandedIds: v, onExpandedChange: y, selectionMode: b = "none", selectedIds: x, defaultSelectedIds: S, onSelectionChange: C, onAction: w }, T) {
|
|
15
|
-
let [E, D] = h(_, v, y), [O, k] = h(x, S, C), A = b !== "none", j = i(), M = a(() => {
|
|
16
|
-
let e = [], t = (n, r, i) => {
|
|
17
|
-
for (let a of n) e.push({
|
|
18
|
-
node: a,
|
|
19
|
-
parentId: r,
|
|
20
|
-
level: i
|
|
21
|
-
}), a.children && E.has(a.id) && t(a.children, a.id, i + 1);
|
|
22
|
-
};
|
|
23
|
-
return t(r, null, 1), e;
|
|
24
|
-
}, [r, E]), N = a(() => new Map(M.map((e, t) => [e.node.id, t])), [M]), P = o(/* @__PURE__ */ new Map()), [F, I] = s(null), L = o(null), R = o({
|
|
25
|
-
text: "",
|
|
26
|
-
at: 0
|
|
27
|
-
}), z = F != null && N.has(F) ? F : (M.find((e) => A && O.has(e.node.id)) ?? M[0])?.node.id;
|
|
28
|
-
if (r.length === 0) return /* @__PURE__ */ t("div", {
|
|
29
|
-
className: [c.empty, d].filter(Boolean).join(" "),
|
|
30
|
-
children: u ?? "—"
|
|
31
|
-
});
|
|
32
|
-
let B = (e) => {
|
|
33
|
-
e != null && P.current.get(e)?.focus();
|
|
34
|
-
}, V = (e) => {
|
|
35
|
-
if (!e.children || e.disabled) return;
|
|
36
|
-
let t = new Set(E);
|
|
37
|
-
t.has(e.id) ? t.delete(e.id) : t.add(e.id), D(t);
|
|
38
|
-
}, H = (e, t) => {
|
|
39
|
-
let n;
|
|
40
|
-
if (b === "multiple" && t.shiftKey && L.current != null && N.has(L.current)) {
|
|
41
|
-
let t = N.get(L.current), r = N.get(e);
|
|
42
|
-
n = new Set(M.slice(Math.min(t, r), Math.max(t, r) + 1).filter((e) => !e.node.disabled).map((e) => e.node.id));
|
|
43
|
-
} else b === "multiple" && (t.metaKey || t.ctrlKey) ? (n = new Set(O), n.has(e) ? n.delete(e) : n.add(e), L.current = e) : (n = /* @__PURE__ */ new Set([e]), L.current = e);
|
|
44
|
-
(n.size !== O.size || [...n].some((e) => !O.has(e))) && k(n);
|
|
45
|
-
}, U = (e, t) => {
|
|
46
|
-
e.disabled || (V(e), A && H(e.id, t), w?.(e.id, t));
|
|
47
|
-
}, W = (e) => (t) => {
|
|
48
|
-
if (t.target !== t.currentTarget) return;
|
|
49
|
-
let n = N.get(e.node.id), { node: r } = e, i = !!r.children && E.has(r.id);
|
|
50
|
-
switch (t.key) {
|
|
51
|
-
case "ArrowDown":
|
|
52
|
-
t.preventDefault(), B(M[Math.min(n + 1, M.length - 1)].node.id);
|
|
53
|
-
return;
|
|
54
|
-
case "ArrowUp":
|
|
55
|
-
t.preventDefault(), B(M[Math.max(n - 1, 0)].node.id);
|
|
56
|
-
return;
|
|
57
|
-
case "Home":
|
|
58
|
-
t.preventDefault(), B(M[0].node.id);
|
|
59
|
-
return;
|
|
60
|
-
case "End":
|
|
61
|
-
t.preventDefault(), B(M[M.length - 1].node.id);
|
|
62
|
-
return;
|
|
63
|
-
case "ArrowRight":
|
|
64
|
-
if (!r.children) return;
|
|
65
|
-
t.preventDefault(), i ? B(r.children[0]?.id) : V(r);
|
|
66
|
-
return;
|
|
67
|
-
case "ArrowLeft":
|
|
68
|
-
t.preventDefault(), i ? V(r) : B(e.parentId ?? void 0);
|
|
69
|
-
return;
|
|
70
|
-
case "Enter":
|
|
71
|
-
case " ":
|
|
72
|
-
t.preventDefault(), U(r, m(t));
|
|
73
|
-
return;
|
|
74
|
-
default:
|
|
75
|
-
if (t.key.length !== 1 || t.ctrlKey || t.metaKey || t.altKey) return;
|
|
76
|
-
G(t, n);
|
|
77
|
-
}
|
|
78
|
-
}, G = (e, t) => {
|
|
79
|
-
let n = Date.now(), r = R.current;
|
|
80
|
-
r.text = n - r.at > l ? e.key : r.text + e.key, r.at = n;
|
|
81
|
-
let i = r.text.toLowerCase(), a = r.text.length === 1 ? t + 1 : t;
|
|
82
|
-
for (let t = 0; t < M.length; t++) {
|
|
83
|
-
let n = M[(a + t) % M.length];
|
|
84
|
-
if (p(n.node).toLowerCase().startsWith(i)) {
|
|
85
|
-
e.preventDefault(), B(n.node.id);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}, K = (e) => (t) => U(e, m(t)), q = (e) => (t) => {
|
|
90
|
-
t.stopPropagation(), V(e);
|
|
91
|
-
}, J = (e) => (t) => {
|
|
92
|
-
t ? P.current.set(e, t) : P.current.delete(e);
|
|
93
|
-
}, Y = 0, X = (r, i, a) => r.map((o, s) => {
|
|
94
|
-
let l = Y++, u = !!o.children, d = u && E.has(o.id), f = `${j}-${l}`, p = o.trailing == null ? void 0 : `${j}-${l}-t`;
|
|
95
|
-
return /* @__PURE__ */ n("li", {
|
|
96
|
-
ref: J(o.id),
|
|
97
|
-
role: "treeitem",
|
|
98
|
-
className: [c.item, o.className].filter(Boolean).join(" "),
|
|
99
|
-
"aria-level": a,
|
|
100
|
-
"aria-setsize": r.length,
|
|
101
|
-
"aria-posinset": s + 1,
|
|
102
|
-
"aria-expanded": u ? d : void 0,
|
|
103
|
-
"aria-selected": A ? O.has(o.id) : void 0,
|
|
104
|
-
"aria-disabled": o.disabled || void 0,
|
|
105
|
-
"aria-labelledby": p ? `${f} ${p}` : f,
|
|
106
|
-
"data-muted": o.muted ? "true" : void 0,
|
|
107
|
-
tabIndex: o.id === z ? 0 : -1,
|
|
108
|
-
onKeyDown: W({
|
|
109
|
-
node: o,
|
|
110
|
-
parentId: i,
|
|
111
|
-
level: a
|
|
112
|
-
}),
|
|
113
|
-
onFocus: (e) => {
|
|
114
|
-
e.target === e.currentTarget && I(o.id);
|
|
115
|
-
},
|
|
116
|
-
children: [/* @__PURE__ */ n("div", {
|
|
117
|
-
className: c.row,
|
|
118
|
-
onClick: K(o),
|
|
119
|
-
children: [
|
|
120
|
-
/* @__PURE__ */ t("span", {
|
|
121
|
-
className: c.twisty,
|
|
122
|
-
"aria-hidden": "true",
|
|
123
|
-
onClick: u ? q(o) : void 0,
|
|
124
|
-
children: u && /* @__PURE__ */ t(e, { open: d })
|
|
125
|
-
}),
|
|
126
|
-
o.leading != null && /* @__PURE__ */ t("span", {
|
|
127
|
-
className: c.leading,
|
|
128
|
-
children: o.leading
|
|
129
|
-
}),
|
|
130
|
-
/* @__PURE__ */ t("span", {
|
|
131
|
-
id: f,
|
|
132
|
-
className: c.label,
|
|
133
|
-
children: o.label
|
|
134
|
-
}),
|
|
135
|
-
p && /* @__PURE__ */ t("span", {
|
|
136
|
-
id: p,
|
|
137
|
-
className: c.trailing,
|
|
138
|
-
children: o.trailing
|
|
139
|
-
})
|
|
140
|
-
]
|
|
141
|
-
}), d && o.children.length > 0 && /* @__PURE__ */ t("ul", {
|
|
142
|
-
role: "group",
|
|
143
|
-
className: c.group,
|
|
144
|
-
children: X(o.children, o.id, a + 1)
|
|
145
|
-
})]
|
|
146
|
-
}, o.id);
|
|
147
|
-
});
|
|
148
|
-
return /* @__PURE__ */ t("ul", {
|
|
149
|
-
ref: T,
|
|
150
|
-
role: "tree",
|
|
151
|
-
className: [c.tree, d].filter(Boolean).join(" "),
|
|
152
|
-
"aria-label": f,
|
|
153
|
-
"aria-labelledby": g,
|
|
154
|
-
"aria-multiselectable": b === "multiple" || void 0,
|
|
155
|
-
children: X(r, null, 1)
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
function d(e, t) {
|
|
159
|
-
let n = !1, r = [];
|
|
160
|
-
for (let i of e) {
|
|
161
|
-
if (t(i)) {
|
|
162
|
-
r.push(i);
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
let e = i.children ? d(i.children, t) : [];
|
|
166
|
-
if (e.length === 0) {
|
|
167
|
-
n = !0;
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
e !== i.children && (n = !0), r.push(e === i.children ? i : {
|
|
171
|
-
...i,
|
|
172
|
-
children: e
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
return n ? r : e;
|
|
176
|
-
}
|
|
177
|
-
function f(e) {
|
|
178
|
-
let t = [], n = (e) => {
|
|
179
|
-
for (let r of e) r.children && (t.push(r.id), n(r.children));
|
|
180
|
-
};
|
|
181
|
-
return n(e), t;
|
|
182
|
-
}
|
|
183
|
-
function p(e) {
|
|
184
|
-
return e.textValue ?? (typeof e.label == "string" ? e.label : "");
|
|
185
|
-
}
|
|
186
|
-
function m(e) {
|
|
187
|
-
return {
|
|
188
|
-
shiftKey: e.shiftKey,
|
|
189
|
-
ctrlKey: e.ctrlKey,
|
|
190
|
-
metaKey: e.metaKey,
|
|
191
|
-
altKey: e.altKey
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
function h(e, t, n) {
|
|
195
|
-
let [r, i] = s(() => new Set(t));
|
|
196
|
-
return [a(() => e === void 0 ? void 0 : new Set(e), [e]) ?? r, (t) => {
|
|
197
|
-
e === void 0 && i(t), n?.(t);
|
|
198
|
-
}];
|
|
199
|
-
}
|
|
200
|
-
//#endregion
|
|
201
|
-
export { d as n, f as r, u as t };
|
|
202
|
-
|
|
203
|
-
//# sourceMappingURL=Tree-hzIbj2q1.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tree-hzIbj2q1.js","names":["s","DisclosureMark","Tree_module_default","TYPEAHEAD_MS","Tree","forwardRef","ariaLabel","ariaLabelledBy","expanded","setExpanded","useControlledSet","expandedIds","defaultExpandedIds","onExpandedChange","selected","setSelected","selectedIds","defaultSelectedIds","onSelectionChange","selectable","selectionMode","baseId","useId","visible","useMemo","out","walk","node","list","level","nodes","indexOf","v","i","items","useRef","focusId","setFocusId","useState","anchor","typed","stopId","className","empty","focus","id","toggle","next","select","mods","a","b","x","activate","onAction","onKeyDown","e","open","modsOf","typeAhead","now","t","want","start","from","k","textOf","onRowClick","onTwistyClick","itemRef","el","seq","renderLevel","n","branch","labelId","trailingId","pos","filterTree","changed","match","kids","treeBranchIds","own","setOwn","initial","value","onChange"],"sources":["../../src/components/Tree/Tree.module.css","../../src/components/Tree/Tree.tsx"],"sourcesContent":[".tree,\n.group {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.tree {\n user-select: none;\n -webkit-user-select: none;\n width: 100%;\n}\n\n/* One twisty and one gap, so a child's twisty sits under its parent's label. */\n.group {\n padding-inline-start: var(--wzl-tree-indent, calc(var(--wzl-control-h-xs) + var(--wzl-space-2)));\n}\n\n.item {\n outline: none;\n}\n\n.row {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n padding: 0 var(--wzl-space-2) 0 0;\n height: var(--wzl-control-h);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg);\n border-radius: var(--wzl-radius-sm);\n cursor: default;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.row:hover {\n background: var(--wzl-surface);\n}\n\n.item:focus-visible > .row {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n.item[aria-selected='true'] > .row {\n background: var(--wzl-border);\n}\n\n.item[data-muted] > .row {\n color: var(--wzl-fg-subtle);\n}\n\n.item[aria-disabled='true'] > .row {\n color: var(--wzl-fg-subtle);\n cursor: not-allowed;\n}\n\n/* A leaf keeps the empty box, so labels at one level line up whether or not\n their rows are branches. */\n.twisty {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wzl-control-h-xs);\n align-self: stretch;\n color: var(--wzl-fg-muted);\n}\n\n.row:hover > .twisty {\n color: var(--wzl-fg);\n}\n\n.leading {\n flex: none;\n display: inline-flex;\n align-items: center;\n}\n\n.label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.trailing {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n}\n\n.empty {\n padding: var(--wzl-space-6) var(--wzl-space-4);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n font-style: italic;\n}\n","import {\n forwardRef,\n useId,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport type { PressModifiers } from '../../useReorderDragList';\nimport { DisclosureMark } from '../Disclosure';\nimport s from './Tree.module.css';\n\n/** One node. A node with `children` is a branch, even when the array is empty. */\nexport interface TreeNode {\n /** Unique across the whole tree. */\n id: string;\n label: ReactNode;\n /** What type-ahead matches against. Defaults to `label` when that is a string. */\n textValue?: string;\n /** Decoration before the label — an icon. Not a control. */\n leading?: ReactNode;\n /** Decoration after the label — a count badge. Not a control. Read as part\n * of the row's accessible name. */\n trailing?: ReactNode;\n children?: readonly TreeNode[];\n /** Present but not in effect. */\n muted?: boolean;\n /** Focusable and announced, but cannot be activated, expanded or selected. */\n disabled?: boolean;\n className?: string;\n}\n\n/** Whether and how rows are selectable. */\nexport type TreeSelectionMode = 'none' | 'single' | 'multiple';\n\n/** Props for {@link Tree}. */\nexport interface TreeProps {\n nodes: readonly TreeNode[];\n /** Shown in place of the tree when `nodes` is empty. */\n empty?: ReactNode;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n\n /** Open branches, controlled. */\n expandedIds?: Iterable<string>;\n /** Open branches on first render, when uncontrolled. */\n defaultExpandedIds?: Iterable<string>;\n /** The whole set a toggle would produce. Called whether or not controlled. */\n onExpandedChange?(ids: Set<string>): void;\n\n /** Default `'none'`. `'multiple'` adds to the selection with Cmd/Ctrl and\n * extends it over visible rows with Shift. */\n selectionMode?: TreeSelectionMode;\n /** Selected rows, controlled. */\n selectedIds?: Iterable<string>;\n /** Selected rows on first render, when uncontrolled. */\n defaultSelectedIds?: Iterable<string>;\n /** The whole set an activation would produce, when it differs. */\n onSelectionChange?(ids: Set<string>): void;\n\n /** A row was activated — click, Enter or Space — with the modifiers held. */\n onAction?(id: string, mods: PressModifiers): void;\n}\n\ninterface Visible {\n node: TreeNode;\n parentId: string | null;\n level: number;\n}\n\nconst TYPEAHEAD_MS = 500;\n\n/**\n * A hierarchy of rows that expand and collapse: a file tree, a registry\n * browser, an outline.\n *\n * **Semantics.** WAI-ARIA `tree`: each node is a `treeitem` carrying\n * `aria-level`, `aria-setsize` and `aria-posinset`; a branch carries\n * `aria-expanded` and nests its children in a `group`, which is rendered only\n * while the branch is open. `aria-selected` appears only when `selectionMode`\n * is set. A treeitem may not contain interactive content, so `leading` and\n * `trailing` are decoration — an icon, a count — and the twisty is a drawn\n * `DisclosureMark`, not a button.\n *\n * **Keyboard.** One treeitem is in the tab order: the one last focused, else\n * the first selected, else the first. Up/Down move between visible rows,\n * Home/End go to the first and last. Right opens a closed branch, then moves\n * into it; Left closes an open branch, else moves to the parent. Enter and\n * Space activate, as a click does. Typing moves to the next row whose text\n * starts with what was typed.\n *\n * **Activating** a row — click, Enter, Space — toggles it if it is a branch,\n * selects it under `selectionMode`, and calls `onAction`. Clicking the twisty\n * only toggles.\n *\n * **Filtering** is the consumer's: narrow `nodes` with `filterTree`, and pass\n * `treeBranchIds` of the result as `expandedIds` so every match shows.\n */\nexport const Tree = forwardRef(function Tree(\n {\n nodes, empty, className,\n 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy,\n expandedIds, defaultExpandedIds, onExpandedChange,\n selectionMode = 'none', selectedIds, defaultSelectedIds, onSelectionChange,\n onAction,\n }: TreeProps,\n ref: Ref<HTMLUListElement>,\n) {\n const [expanded, setExpanded] = useControlledSet(expandedIds, defaultExpandedIds, onExpandedChange);\n const [selected, setSelected] = useControlledSet(selectedIds, defaultSelectedIds, onSelectionChange);\n const selectable = selectionMode !== 'none';\n const baseId = useId();\n\n const visible = useMemo(() => {\n const out: Visible[] = [];\n const walk = (list: readonly TreeNode[], parentId: string | null, level: number) => {\n for (const node of list) {\n out.push({ node, parentId, level });\n if (node.children && expanded.has(node.id)) walk(node.children, node.id, level + 1);\n }\n };\n walk(nodes, null, 1);\n return out;\n }, [nodes, expanded]);\n const indexOf = useMemo(() => new Map(visible.map((v, i) => [v.node.id, i])), [visible]);\n\n const items = useRef(new Map<string, HTMLLIElement>());\n const [focusId, setFocusId] = useState<string | null>(null);\n const anchor = useRef<string | null>(null);\n const typed = useRef({ text: '', at: 0 });\n\n const stopId = focusId != null && indexOf.has(focusId)\n ? focusId\n : (visible.find((v) => selectable && selected.has(v.node.id)) ?? visible[0])?.node.id;\n\n if (nodes.length === 0) {\n return <div className={[s.empty, className].filter(Boolean).join(' ')}>{empty ?? '—'}</div>;\n }\n\n const focus = (id: string | undefined) => { if (id != null) items.current.get(id)?.focus(); };\n\n const toggle = (node: TreeNode) => {\n if (!node.children || node.disabled) return;\n const next = new Set(expanded);\n if (next.has(node.id)) next.delete(node.id);\n else next.add(node.id);\n setExpanded(next);\n };\n\n const select = (id: string, mods: PressModifiers) => {\n let next: Set<string>;\n if (selectionMode === 'multiple' && mods.shiftKey && anchor.current != null && indexOf.has(anchor.current)) {\n const a = indexOf.get(anchor.current)!;\n const b = indexOf.get(id)!;\n next = new Set(visible.slice(Math.min(a, b), Math.max(a, b) + 1)\n .filter((v) => !v.node.disabled).map((v) => v.node.id));\n } else if (selectionMode === 'multiple' && (mods.metaKey || mods.ctrlKey)) {\n next = new Set(selected);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n anchor.current = id;\n } else {\n next = new Set([id]);\n anchor.current = id;\n }\n if (next.size !== selected.size || [...next].some((x) => !selected.has(x))) setSelected(next);\n };\n\n const activate = (node: TreeNode, mods: PressModifiers) => {\n if (node.disabled) return;\n toggle(node);\n if (selectable) select(node.id, mods);\n onAction?.(node.id, mods);\n };\n\n const onKeyDown = (v: Visible) => (e: KeyboardEvent<HTMLLIElement>) => {\n if (e.target !== e.currentTarget) return;\n const i = indexOf.get(v.node.id)!;\n const { node } = v;\n const open = !!node.children && expanded.has(node.id);\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n focus(visible[Math.min(i + 1, visible.length - 1)].node.id);\n return;\n case 'ArrowUp':\n e.preventDefault();\n focus(visible[Math.max(i - 1, 0)].node.id);\n return;\n case 'Home':\n e.preventDefault();\n focus(visible[0].node.id);\n return;\n case 'End':\n e.preventDefault();\n focus(visible[visible.length - 1].node.id);\n return;\n case 'ArrowRight':\n if (!node.children) return;\n e.preventDefault();\n if (!open) toggle(node);\n else focus(node.children[0]?.id);\n return;\n case 'ArrowLeft':\n e.preventDefault();\n if (open) toggle(node);\n else focus(v.parentId ?? undefined);\n return;\n case 'Enter':\n case ' ':\n e.preventDefault();\n activate(node, modsOf(e));\n return;\n default:\n if (e.key.length !== 1 || e.ctrlKey || e.metaKey || e.altKey) return;\n typeAhead(e, i);\n }\n };\n\n const typeAhead = (e: KeyboardEvent, from: number) => {\n const now = Date.now();\n const t = typed.current;\n t.text = now - t.at > TYPEAHEAD_MS ? e.key : t.text + e.key;\n t.at = now;\n const want = t.text.toLowerCase();\n // A fresh first letter looks past the current row; a longer prefix may still match it.\n const start = t.text.length === 1 ? from + 1 : from;\n for (let k = 0; k < visible.length; k++) {\n const v = visible[(start + k) % visible.length];\n if (textOf(v.node).toLowerCase().startsWith(want)) {\n e.preventDefault();\n focus(v.node.id);\n return;\n }\n }\n };\n\n const onRowClick = (node: TreeNode) => (e: MouseEvent<HTMLDivElement>) => activate(node, modsOf(e));\n\n const onTwistyClick = (node: TreeNode) => (e: MouseEvent<HTMLSpanElement>) => {\n e.stopPropagation();\n toggle(node);\n };\n\n const itemRef = (id: string) => (el: HTMLLIElement | null) => {\n if (el) items.current.set(id, el);\n else items.current.delete(id);\n };\n\n let seq = 0;\n const renderLevel = (list: readonly TreeNode[], parentId: string | null, level: number): ReactNode =>\n list.map((node, pos) => {\n const n = seq++;\n const branch = !!node.children;\n const open = branch && expanded.has(node.id);\n const labelId = `${baseId}-${n}`;\n const trailingId = node.trailing != null ? `${baseId}-${n}-t` : undefined;\n return (\n <li\n key={node.id}\n ref={itemRef(node.id)}\n role=\"treeitem\"\n className={[s.item, node.className].filter(Boolean).join(' ')}\n aria-level={level}\n aria-setsize={list.length}\n aria-posinset={pos + 1}\n aria-expanded={branch ? open : undefined}\n aria-selected={selectable ? selected.has(node.id) : undefined}\n aria-disabled={node.disabled || undefined}\n aria-labelledby={trailingId ? `${labelId} ${trailingId}` : labelId}\n data-muted={node.muted ? 'true' : undefined}\n tabIndex={node.id === stopId ? 0 : -1}\n onKeyDown={onKeyDown({ node, parentId, level })}\n onFocus={(e) => { if (e.target === e.currentTarget) setFocusId(node.id); }}\n >\n <div className={s.row} onClick={onRowClick(node)}>\n <span className={s.twisty} aria-hidden=\"true\" onClick={branch ? onTwistyClick(node) : undefined}>\n {branch && <DisclosureMark open={open} />}\n </span>\n {node.leading != null && <span className={s.leading}>{node.leading}</span>}\n <span id={labelId} className={s.label}>{node.label}</span>\n {trailingId && <span id={trailingId} className={s.trailing}>{node.trailing}</span>}\n </div>\n {open && node.children!.length > 0 && (\n <ul role=\"group\" className={s.group}>\n {renderLevel(node.children!, node.id, level + 1)}\n </ul>\n )}\n </li>\n );\n });\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n className={[s.tree, className].filter(Boolean).join(' ')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-multiselectable={selectionMode === 'multiple' || undefined}\n >\n {renderLevel(nodes, null, 1)}\n </ul>\n );\n});\n\n/**\n * `nodes` narrowed to those `match` accepts, plus their ancestors. A matching\n * node keeps its whole subtree; a branch with no match inside it is dropped.\n * Returns `nodes` itself when nothing is dropped.\n */\nexport function filterTree(\n nodes: readonly TreeNode[],\n match: (node: TreeNode) => boolean,\n): readonly TreeNode[] {\n let changed = false;\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (match(node)) {\n out.push(node);\n continue;\n }\n const kids = node.children ? filterTree(node.children, match) : [];\n if (kids.length === 0) {\n changed = true;\n continue;\n }\n if (kids !== node.children) changed = true;\n out.push(kids === node.children ? node : { ...node, children: kids });\n }\n return changed ? out : nodes;\n}\n\n/** Every branch id in `nodes`, depth first — `expandedIds` for a tree with everything open. */\nexport function treeBranchIds(nodes: readonly TreeNode[]): string[] {\n const out: string[] = [];\n const walk = (list: readonly TreeNode[]) => {\n for (const node of list) {\n if (!node.children) continue;\n out.push(node.id);\n walk(node.children);\n }\n };\n walk(nodes);\n return out;\n}\n\nfunction textOf(node: TreeNode): string {\n return node.textValue ?? (typeof node.label === 'string' ? node.label : '');\n}\n\nfunction modsOf(e: { shiftKey: boolean; ctrlKey: boolean; metaKey: boolean; altKey: boolean }): PressModifiers {\n return { shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey };\n}\n\nfunction useControlledSet(\n value: Iterable<string> | undefined,\n initial: Iterable<string> | undefined,\n onChange: ((ids: Set<string>) => void) | undefined,\n): [ReadonlySet<string>, (next: Set<string>) => void] {\n const [own, setOwn] = useState<ReadonlySet<string>>(() => new Set(initial));\n const controlled = useMemo(() => (value === undefined ? undefined : new Set(value)), [value]);\n const set = (next: Set<string>) => {\n if (value === undefined) setOwn(next);\n onChange?.(next);\n };\n return [controlled ?? own, set];\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icons-CofIOTiI.js","names":["Icon","UnknownIcon$1","CloneIcon","p","ResetIcon","CloseIcon","ExportIcon","ZoomInIcon","PanIcon","AddIcon","ModeLightIcon","ModeDarkIcon","ModeAutoIcon","RemoveIcon","SortIcon","ZoomOutIcon","FitIcon","SnapshotIcon","PlayIcon","PauseIcon","StopIcon","StepBackIcon","StepForwardIcon","StepIcon","CrosshairIcon","FullscreenIcon","CompareIcon","FilterIcon","SearchIcon","LoupeIcon","LayersIcon","PageIcon","LockIcon","UnlockIcon","VisibleIcon","HiddenIcon","PinIcon","LinkIcon","CollapseIcon","ExpandIcon","ChevronIcon","TuneIcon","GridIcon","SnapIcon","MeasureIcon","RandomizeIcon","RefreshIcon","InfoIcon","WarningIcon","ErrorIcon","BusyIcon","CheckIcon","LayoutRowsIcon","LayoutColumnsIcon","LayoutGridIcon","UngroupIcon","DistributeVerticalIcon","TextIcon","GroupIcon","LineIcon","HandIcon","FlipXIcon","FlipYIcon","DistributeHorizontalIcon","StarIcon","EllipseIcon","LassoIcon","SendBackwardIcon","AlignLeftIcon","PencilIcon","CutIcon","ArrowIcon","PolygonIcon","RedoIcon","SelectIcon","AlignCenterYIcon","PenIcon","EyedropperIcon","UndoIcon","BringForwardIcon","AlignBottomIcon","PasteIcon","AlignRightIcon","AlignCenterXIcon","AlignTopIcon","BringToFrontIcon","RectIcon","CopyIcon","SendToBackIcon","DuplicateIcon","DeleteIcon","ImageIcon"],"sources":["../../src/icons/index.tsx"],"sourcesContent":["import { Icon, type IconProps } from './Icon';\n\nexport { Icon, isFillable } from './Icon';\nexport type { IconProps } from './Icon';\nexport { ICON_FILLS, ICON_GROUPS, ICON_PATHS } from './paths';\nexport type { FillableIconName, IconName } from './paths';\n\n// Tool glyphs live in @weasel-js/core because core needs them for\n// `Tool.presentation.icon` defaults and cannot depend on this package.\n// Re-exported here so consumers have one import site for the whole set.\nexport {\n SelectIcon, LassoIcon, RectIcon, EllipseIcon, ImageIcon, EyedropperIcon,\n LineIcon, ArrowIcon, PolygonIcon, StarIcon, PencilIcon, TextIcon, PenIcon, HandIcon,\n UnknownIcon,\n} from '@weasel-js/core';\n// The standard edit actions' glyphs live beside those actions in core, for the\n// same reason.\nexport {\n CutIcon, CopyIcon, PasteIcon, DuplicateIcon, GroupIcon, UngroupIcon,\n BringForwardIcon, BringToFrontIcon, SendBackwardIcon, SendToBackIcon, FlipXIcon, FlipYIcon,\n UndoIcon, RedoIcon, DeleteIcon,\n AlignLeftIcon, AlignCenterXIcon, AlignRightIcon, AlignTopIcon, AlignCenterYIcon, AlignBottomIcon,\n DistributeHorizontalIcon, DistributeVerticalIcon,\n} from '@weasel-js/core';\n\n/** Clone: a ruled card with a second one tucked behind it. */\nexport const CloneIcon = (p: IconProps) => <Icon name=\"clone\" {...p} />;\n/** Reset: a near-full counterclockwise arc, arrowhead at the top. */\nexport const ResetIcon = (p: IconProps) => <Icon name=\"reset\" {...p} />;\n/** Close: an X. */\nexport const CloseIcon = (p: IconProps) => <Icon name=\"close\" {...p} />;\n/** Export: an arrow pointing down into an open tray. */\nexport const ExportIcon = (p: IconProps) => <Icon name=\"export\" {...p} />;\n/** Zoom in: a magnifier with a plus. */\nexport const ZoomInIcon = (p: IconProps) => <Icon name=\"zoomIn\" {...p} />;\n/** Pan: four arrows out from a hub. */\nexport const PanIcon = (p: IconProps) => <Icon name=\"pan\" {...p} />;\n/** Add: a plus. */\nexport const AddIcon = (p: IconProps) => <Icon name=\"add\" {...p} />;\n/** Light color mode: a sun. */\nexport const ModeLightIcon = (p: IconProps) => <Icon name=\"modeLight\" {...p} />;\n/** Dark color mode: a crescent moon. */\nexport const ModeDarkIcon = (p: IconProps) => <Icon name=\"modeDark\" {...p} />;\n/** Automatic color mode: a four-pointed sparkle. */\nexport const ModeAutoIcon = (p: IconProps) => <Icon name=\"modeAuto\" {...p} />;\n/** Remove: a minus. */\nexport const RemoveIcon = (p: IconProps) => <Icon name=\"remove\" {...p} />;\n/** Sort: three ruled lines beside a downward arrow. */\nexport const SortIcon = (p: IconProps) => <Icon name=\"sort\" {...p} />;\n/** Zoom out: a magnifier with a minus. */\nexport const ZoomOutIcon = (p: IconProps) => <Icon name=\"zoomOut\" {...p} />;\n/** Fit: four corner brackets around a small rect. */\nexport const FitIcon = (p: IconProps) => <Icon name=\"fit\" {...p} />;\n/** Snapshot: a camera. */\nexport const SnapshotIcon = (p: IconProps) => <Icon name=\"snapshot\" {...p} />;\n/** Play: a right-pointing triangle. */\nexport const PlayIcon = (p: IconProps) => <Icon name=\"play\" {...p} />;\n/** Pause: two vertical bars. */\nexport const PauseIcon = (p: IconProps) => <Icon name=\"pause\" {...p} />;\n/** Stop: a rounded square. */\nexport const StopIcon = (p: IconProps) => <Icon name=\"stop\" {...p} />;\n/** Step back: a left-pointing triangle against a bar. */\nexport const StepBackIcon = (p: IconProps) => <Icon name=\"stepBack\" {...p} />;\n/** Step forward: a right-pointing triangle against a bar. */\nexport const StepForwardIcon = (p: IconProps) => <Icon name=\"stepForward\" {...p} />;\n/** @deprecated Use {@link StepForwardIcon}; `step` alone stopped naming a direction. */\nexport const StepIcon = StepForwardIcon;\n/** Crosshair: a ring with four ticks on the axes. */\nexport const CrosshairIcon = (p: IconProps) => <Icon name=\"crosshair\" {...p} />;\n/** Fullscreen: two corner arrows pointing out diagonally. */\nexport const FullscreenIcon = (p: IconProps) => <Icon name=\"fullscreen\" {...p} />;\n/** Compare: a frame split into two columns of lines. */\nexport const CompareIcon = (p: IconProps) => <Icon name=\"compare\" {...p} />;\n/** Filter: a funnel. */\nexport const FilterIcon = (p: IconProps) => <Icon name=\"filter\" {...p} />;\n/** Search: an empty magnifier. */\nexport const SearchIcon = (p: IconProps) => <Icon name=\"search\" {...p} />;\n/** Loupe: a magnifier over a grid of pixels. */\nexport const LoupeIcon = (p: IconProps) => <Icon name=\"loupe\" {...p} />;\n/** Layers: a stack of three sheets. */\nexport const LayersIcon = (p: IconProps) => <Icon name=\"layers\" {...p} />;\n/** Page: a document with a folded corner. */\nexport const PageIcon = (p: IconProps) => <Icon name=\"page\" {...p} />;\n/** Lock: a closed padlock. */\nexport const LockIcon = (p: IconProps) => <Icon name=\"lock\" {...p} />;\n/** Unlock: an open padlock. */\nexport const UnlockIcon = (p: IconProps) => <Icon name=\"unlock\" {...p} />;\n/** Visible: an eye. */\nexport const VisibleIcon = (p: IconProps) => <Icon name=\"visible\" {...p} />;\n/** Hidden: an eye struck through. */\nexport const HiddenIcon = (p: IconProps) => <Icon name=\"hidden\" {...p} />;\n/** Pin: a push pin. */\nexport const PinIcon = (p: IconProps) => <Icon name=\"pin\" {...p} />;\n/** Link: two chain links. */\nexport const LinkIcon = (p: IconProps) => <Icon name=\"link\" {...p} />;\n/** Collapse: two chevrons pointing inward. */\nexport const CollapseIcon = (p: IconProps) => <Icon name=\"collapse\" {...p} />;\n/** Expand: two chevrons pointing outward. */\nexport const ExpandIcon = (p: IconProps) => <Icon name=\"expand\" {...p} />;\n/** Chevron: a downward disclosure mark, centered to spin in place under `rotate()`. */\nexport const ChevronIcon = (p: IconProps) => <Icon name=\"chevron\" {...p} />;\n/** Tune: three slider tracks with their knobs. */\nexport const TuneIcon = (p: IconProps) => <Icon name=\"tune\" {...p} />;\n/** Grid: an outlined 3x3 grid — the grid to snap to. */\nexport const GridIcon = (p: IconProps) => <Icon name=\"grid\" {...p} />;\n/** Snap: a horseshoe magnet. */\nexport const SnapIcon = (p: IconProps) => <Icon name=\"snap\" {...p} />;\n/** Measure: a ruler. */\nexport const MeasureIcon = (p: IconProps) => <Icon name=\"measure\" {...p} />;\n/** Randomize: a die showing three. */\nexport const RandomizeIcon = (p: IconProps) => <Icon name=\"randomize\" {...p} />;\n/** Refresh: two arcs chasing each other around a circle. */\nexport const RefreshIcon = (p: IconProps) => <Icon name=\"refresh\" {...p} />;\n/** Info: an i in a ring. */\nexport const InfoIcon = (p: IconProps) => <Icon name=\"info\" {...p} />;\n/** Warning: an exclamation mark in a triangle. */\nexport const WarningIcon = (p: IconProps) => <Icon name=\"warning\" {...p} />;\n/** Error: an X in a ring. */\nexport const ErrorIcon = (p: IconProps) => <Icon name=\"error\" {...p} />;\n/** Busy: a three-quarter arc, for a spinner. */\nexport const BusyIcon = (p: IconProps) => <Icon name=\"busy\" {...p} />;\n/** Check: a check mark. */\nexport const CheckIcon = (p: IconProps) => <Icon name=\"check\" {...p} />;\n/** Row layout: three filled horizontal bars. */\nexport const LayoutRowsIcon = (p: IconProps) => <Icon name=\"layoutRows\" {...p} />;\n/** Column layout: three filled vertical bars. */\nexport const LayoutColumnsIcon = (p: IconProps) => <Icon name=\"layoutColumns\" {...p} />;\n/** Grid layout: a filled 3x3 of cells. */\nexport const LayoutGridIcon = (p: IconProps) => <Icon name=\"layoutGrid\" {...p} />;\n"],"mappings":"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"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//#region src/interactiveTarget.ts
|
|
2
|
-
var e = [
|
|
3
|
-
"button",
|
|
4
|
-
"input",
|
|
5
|
-
"select",
|
|
6
|
-
"textarea",
|
|
7
|
-
"a[href]",
|
|
8
|
-
"[contenteditable=\"\"]",
|
|
9
|
-
"[contenteditable=\"true\"]",
|
|
10
|
-
"[role=\"button\"]",
|
|
11
|
-
"[role=\"checkbox\"]",
|
|
12
|
-
"[role=\"switch\"]",
|
|
13
|
-
"[role=\"menuitem\"]",
|
|
14
|
-
"[role=\"link\"]"
|
|
15
|
-
].join(",");
|
|
16
|
-
function t(t, n) {
|
|
17
|
-
if (!(t instanceof Element)) return !1;
|
|
18
|
-
let r = t.closest(e);
|
|
19
|
-
return r !== null && r !== n && n.contains(r);
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
|
-
export { t as n, e as t };
|
|
23
|
-
|
|
24
|
-
//# sourceMappingURL=interactiveTarget-BNZmTow2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveTarget-BNZmTow2.js","names":["CONTROL_SELECTOR","isInControlWithin","target","control","host"],"sources":["../../src/interactiveTarget.ts"],"sourcesContent":["/** Elements that handle their own press and keys. */\nexport const CONTROL_SELECTOR = [\n 'button', 'input', 'select', 'textarea', 'a[href]', '[contenteditable=\"\"]', '[contenteditable=\"true\"]',\n '[role=\"button\"]', '[role=\"checkbox\"]', '[role=\"switch\"]', '[role=\"menuitem\"]', '[role=\"link\"]',\n].join(',');\n\n/**\n * Whether `target` sits in a control of its own somewhere inside `host` — a\n * toggle in a list row. The host's handlers leave such an event to the\n * control, so a row's press, click and keys never swallow its controls'.\n */\nexport function isInControlWithin(target: EventTarget | null, host: Element): boolean {\n if (!(target instanceof Element)) return false;\n const control = target.closest(CONTROL_SELECTOR);\n return control !== null && control !== host && host.contains(control);\n}\n"],"mappings":";AACA,IAAaA,IAAmB;CAC9B;CAAU;CAAS;CAAU;CAAY;CAAW;CAAwB;CAC5E;CAAmB;CAAqB;CAAmB;CAAqB;AAClF,CAAC,CAAC,KAAK,GAAG;AAOV,SAAgBC,EAAkB,GAA4B,GAAwB;CACpF,IAAI,EAAEC,aAAkB,UAAU,OAAO;CACzC,IAAMC,IAAUD,EAAO,QAAQF,CAAgB;CAC/C,OAAOG,MAAY,QAAQA,MAAYC,KAAQA,EAAK,SAASD,CAAO;AACtE"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
var e = {
|
|
2
|
-
root: "_root_16n8h_10",
|
|
3
|
-
segment: "_segment_16n8h_34",
|
|
4
|
-
segmentSelected: "_segmentSelected_16n8h_88",
|
|
5
|
-
size_sm: "_size_sm_16n8h_146",
|
|
6
|
-
variant_minimal: "_variant_minimal_16n8h_164"
|
|
7
|
-
};
|
|
8
|
-
//#endregion
|
|
9
|
-
export { e as t };
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=segmentedControl.module-BzGXUL5G.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useReorderDragList-CStYKjHl.js","names":["isInControlWithin","IDLE","unlockedSegment","lo","i","sourceIndex","items","hi","draggedIdsFor","index","selectedIds","id","it","x","isNoopDrop","indices","draggedIds","a","b","contiguous","prev","v","first","last","targetIndex","useReorderDragList","optsRef","useLatest","opts","containerRef","useRef","dragRef","state","setState","useState","computeTargetIndex","useCallback","c","sel","rows","el","raw","row","clientY","refCb","reset","onPointerDownRow","container","e","mods","pressed","child","grab","ghostAt","ev","startThresholdDrag","drop","onPress","swallowNextClick","ids","at","target","delta","onReorder","swallow"],"sources":["../../src/useReorderDragList.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { ReactNode, PointerEvent as ReactPointerEvent, RefCallback } from 'react';\nimport { startThresholdDrag, useLatest, type ThresholdDragHandle } from '@weasel-js/core';\nimport { isInControlWithin } from './interactiveTarget';\n\n/** One row in a reorderable list. */\nexport interface ReorderItem {\n id: string;\n label: ReactNode;\n /** Locked rows cannot be dragged, cannot be crossed by drops, and\n * never combine with other rows in a multi-selection. */\n locked?: boolean;\n}\n\n/**\n * Options for {@link useReorderDragList}. `onReorder` receives the dragged ids\n * and the index they were dropped at, measured against the pre-drag `items`.\n */\nexport interface UseReorderDragListOptions {\n items: ReorderItem[];\n selectedIds: string[];\n onReorder(ids: string[], targetIndex: number): void;\n /** A press that was released without ever engaging a drag — the click a\n * list row means by it. Fires for locked rows too, which can be selected\n * but not dragged. Modifiers are read at press, not at release. When this\n * is given, the DOM click that follows the press is dropped, so a row that\n * also handles `click` sees one press, not two. A press that starts on a\n * control inside the row (a toggle) is left to the control. */\n onPress?(id: string, mods: PressModifiers): void;\n /** Pointer-move distance (px) before pending drag engages. Default `DRAG_THRESHOLD_PX`. */\n threshold?: number;\n /** Selector matching the container's children that are rows, for a list\n * that interleaves other elements (a table's detail rows). Default: every\n * child is a row. */\n rowSelector?: string;\n}\n\n/** Modifier keys held when a press began. */\nexport interface PressModifiers {\n shiftKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n altKey: boolean;\n}\n\n/**\n * Where a drag's ghost goes: the dragged rows, drawn again with their top-left\n * at a client-space point, so the row that was grabbed stays under the pointer\n * where it was picked up. `width` is the grabbed row's.\n */\nexport interface ReorderGhost {\n ids: readonly string[];\n left: number;\n top: number;\n width: number;\n}\n\n/**\n * Live drag state for rendering feedback: which ids are being dragged, the\n * insertion index the drop would use, and where their ghost goes. All `null`\n * when no drag is engaged.\n */\nexport interface ReorderDragState {\n draggedIds: string[] | null;\n targetIndex: number | null;\n ghost: ReorderGhost | null;\n}\n\nconst IDLE: ReorderDragState = { draggedIds: null, targetIndex: null, ghost: null };\n\n/**\n * A `ref` for the list container, an `onPointerDown` for each row, and the\n * live {@link ReorderDragState}. The container ref is required, not optional\n * decoration: it is what the drop index is measured against and what the\n * pointer session is opened on.\n */\nexport interface ReorderDragHandlers {\n rowProps(id: string, index: number): { onPointerDown(e: ReactPointerEvent): void };\n containerProps: {\n ref: RefCallback<HTMLElement>;\n };\n state: ReorderDragState;\n /**\n * Move the row at `index` one place up (`-1`) or down (`1`) — the keyboard\n * reorder. It moves what a drag of that row would: the whole selection if\n * the row is in it, else the row alone, never across a locked row. Calls\n * `onReorder` and returns `true`, or returns `false` when nothing can move.\n */\n nudge(id: string, index: number, delta: -1 | 1): boolean;\n}\n\n/**\n * The half-open run of indices a row at `sourceIndex` may be dropped into:\n * bounded by the nearest locked row above and below it, so a locked row is a\n * wall in both directions rather than a global ceiling.\n */\nfunction unlockedSegment(items: readonly ReorderItem[], sourceIndex: number): [number, number] {\n let lo = 0;\n for (let i = sourceIndex - 1; i >= 0; i--) {\n if (items[i]?.locked) { lo = i + 1; break; }\n }\n let hi = items.length;\n for (let i = sourceIndex + 1; i < items.length; i++) {\n if (items[i]?.locked) { hi = i; break; }\n }\n return [lo, hi];\n}\n\n/** What a drag of the row at `index` carries: the selection within its segment if the row is selected, else the row. */\nfunction draggedIdsFor(\n items: readonly ReorderItem[],\n selectedIds: readonly string[],\n id: string,\n index: number,\n): string[] {\n const [lo, hi] = unlockedSegment(items, index);\n return (selectedIds.includes(id) ? [...selectedIds] : [id]).filter((x) => {\n const i = items.findIndex((it) => it.id === x);\n return i >= lo && i < hi;\n });\n}\n\n/** Would dropping `draggedIds` at `targetIndex` leave a contiguous block where it already is? */\nfunction isNoopDrop(items: readonly ReorderItem[], draggedIds: readonly string[], targetIndex: number): boolean {\n const indices = draggedIds\n .map((id) => items.findIndex((it) => it.id === id))\n .filter((i) => i >= 0)\n .sort((a, b) => a - b);\n const contiguous =\n indices.length > 0 &&\n indices.every((v, i) => {\n if (i === 0) return true;\n const prev = indices[i - 1];\n return prev !== undefined && v === prev + 1;\n });\n const first = indices[0];\n const last = indices[indices.length - 1];\n return contiguous\n && first !== undefined\n && last !== undefined\n && targetIndex >= first\n && targetIndex <= last + 1;\n}\n\n/**\n * Drag-to-reorder for a vertical list of rows. Dragging a row that is part of\n * the current selection drags the whole selection; dragging any other row\n * drags just that row. Locked rows can neither be dragged nor crossed by a\n * drop. A drop that would leave a contiguous block where it already is does\n * not call `onReorder`.\n *\n * The rows are the container's children, whatever they are: `ItemList` rows,\n * or the `PropertyGroup`s of a `PropertyList`. A row's `onPointerDown` can go\n * on the whole row or on a handle inside it.\n *\n * A press opens a `startThresholdDrag` on the *container*, which owns the\n * rest of the gesture: a drag that leaves the list still tracks, a release\n * anywhere still drops, and a release the window never delivered still ends\n * the drag. The container is the origin rather than the row because rows come\n * and go as the list re-renders, and a drag must outlive the row it grabbed.\n */\nexport function useReorderDragList(opts: UseReorderDragListOptions): ReorderDragHandlers {\n const optsRef = useLatest(opts);\n const containerRef = useRef<HTMLElement | null>(null);\n const dragRef = useRef<ThresholdDragHandle | null>(null);\n const [state, setState] = useState<ReorderDragState>(IDLE);\n\n useEffect(() => () => { dragRef.current?.cancel(); }, []);\n\n const computeTargetIndex = useCallback((clientY: number, sourceIndex: number): number => {\n const [lo, hi] = unlockedSegment(optsRef.current.items, sourceIndex);\n const c = containerRef.current;\n if (!c) return lo;\n const sel = optsRef.current.rowSelector;\n const rows = (sel ? Array.from(c.children).filter((el) => el.matches(sel)) : Array.from(c.children)) as HTMLElement[];\n let raw = rows.length;\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n if (!row) continue;\n const r = row.getBoundingClientRect();\n if (clientY < r.bottom) { raw = i; break; }\n }\n return Math.max(lo, Math.min(raw, hi));\n }, [optsRef]);\n\n const refCb = useCallback<RefCallback<HTMLElement>>((el) => {\n containerRef.current = el;\n }, []);\n\n const reset = useCallback(() => {\n dragRef.current = null;\n setState(IDLE);\n }, []);\n\n const onPointerDownRow = useCallback((id: string, index: number, e: ReactPointerEvent) => {\n const container = containerRef.current;\n if (!container || dragRef.current) return;\n if (isInControlWithin(e.target, e.currentTarget as Element)) return;\n\n const mods: PressModifiers = {\n shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey,\n };\n let draggedIds: string[] = [];\n let targetIndex = 0;\n // Where in the grabbed row the pointer went down, so the ghost keeps that point under it. The handler may sit on\n // a handle inside the row rather than the row itself, so the row is the container's child holding it.\n const pressed = e.currentTarget as Element;\n const rowEl = Array.from(container.children).find((child) => child.contains(pressed)) ?? pressed;\n const row = rowEl.getBoundingClientRect();\n const grab = { x: e.clientX - row.left, y: e.clientY - row.top };\n const ghostAt = (ev: { clientX: number; clientY: number }): ReorderGhost => ({\n ids: draggedIds,\n left: ev.clientX - grab.x,\n top: ev.clientY - grab.y,\n width: row.width,\n });\n\n dragRef.current = startThresholdDrag(e, {\n origin: container,\n // A locked row still opens a drag so its release reaches `onPress`, and\n // a threshold nothing can cross is what keeps it from ever engaging.\n threshold: optsRef.current.items[index]?.locked\n ? Number.POSITIVE_INFINITY\n : optsRef.current.threshold,\n onActivate: (ev) => {\n draggedIds = draggedIdsFor(optsRef.current.items, optsRef.current.selectedIds, id, index);\n targetIndex = computeTargetIndex(ev.clientY, index);\n setState({ draggedIds, targetIndex, ghost: ghostAt(ev) });\n },\n onMove: (ev) => {\n targetIndex = computeTargetIndex(ev.clientY, index);\n setState({ draggedIds, targetIndex, ghost: ghostAt(ev) });\n },\n onCommit: (ev) => {\n const drop = computeTargetIndex(ev.clientY, index);\n if (!isNoopDrop(optsRef.current.items, draggedIds, drop)) {\n optsRef.current.onReorder(draggedIds, drop);\n }\n reset();\n },\n onClick: () => {\n const { onPress } = optsRef.current;\n if (onPress) {\n onPress(id, mods);\n swallowNextClick(container);\n }\n reset();\n },\n // Every cancel reason — the browser's, a lost capture, an unmount —\n // says the gesture was interrupted rather than aimed, so the rows stay\n // where they were.\n onCancel: reset,\n });\n }, [computeTargetIndex, reset, optsRef]);\n\n const nudge = useCallback((id: string, index: number, delta: -1 | 1): boolean => {\n const { items, selectedIds, onReorder } = optsRef.current;\n if (items[index]?.locked) return false;\n const ids = draggedIdsFor(items, selectedIds, id, index);\n const at = ids.map((x) => items.findIndex((it) => it.id === x)).sort((a, b) => a - b);\n const first = at[0];\n const last = at[at.length - 1];\n if (first === undefined || last === undefined) return false;\n const [lo, hi] = unlockedSegment(items, index);\n const target = delta < 0 ? first - 1 : last + 2;\n if (target < lo || target > hi || isNoopDrop(items, ids, target)) return false;\n onReorder(ids, target);\n return true;\n }, [optsRef]);\n\n return {\n nudge,\n rowProps: (id, index) => ({\n onPointerDown: (e) => onPointerDownRow(id, index, e),\n }),\n containerProps: {\n ref: refCb,\n },\n state,\n };\n}\n\n/**\n * The session captured the pointer on the container, so browsers disagree on\n * where the release's click lands; it may still reach the row. `onPress` has\n * already reported this press, so that click is dropped rather than read as a\n * second one. It is dispatched in the same task as the release.\n */\nfunction swallowNextClick(container: HTMLElement): void {\n const swallow = (e: Event) => { e.stopPropagation(); };\n container.addEventListener('click', swallow, true);\n setTimeout(() => { container.removeEventListener('click', swallow, true); }, 0);\n}\n"],"mappings":";;;;AAoEA,IAAMC,IAAyB;CAAE,YAAY;CAAM,aAAa;CAAM,OAAO;AAAK;AA4BlF,SAASC,EAAgB,GAA+B,GAAuC;CAC7F,IAAIC,IAAK;CACT,KAAK,IAAIC,IAAIC,IAAc,GAAGD,KAAK,GAAG,KACpC,IAAIE,EAAMF,EAAE,EAAE,QAAQ;EAAE,IAAKA,IAAI;EAAG;CAAO;CAE7C,IAAIG,IAAKD,EAAM;CACf,KAAK,IAAIF,IAAIC,IAAc,GAAGD,IAAIE,EAAM,QAAQ,KAC9C,IAAIA,EAAMF,EAAE,EAAE,QAAQ;EAAE,IAAKA;EAAG;CAAO;CAEzC,OAAO,CAACD,GAAII,CAAE;AAChB;AAGA,SAASC,EACP,GACA,GACA,GACA,GACU;CACV,IAAM,CAACL,GAAII,KAAML,EAAgBI,GAAOG,CAAK;CAC7C,QAAQC,EAAY,SAASC,CAAE,IAAI,CAAC,GAAGD,CAAW,IAAI,CAACC,CAAE,EAAA,CAAG,QAAQ,MAAM;EACxE,IAAMP,IAAIE,EAAM,WAAW,MAAOM,EAAG,OAAOC,CAAC;EAC7C,OAAOT,KAAKD,KAAMC,IAAIG;CACxB,CAAC;AACH;AAGA,SAASO,EAAW,GAA+B,GAA+B,GAA8B;CAC9G,IAAMC,IAAUC,EACb,KAAK,MAAOV,EAAM,WAAW,MAAOM,EAAG,OAAOD,CAAE,CAAC,CAAC,CAClD,QAAQ,MAAMP,KAAK,CAAC,CAAC,CACrB,MAAM,GAAG,MAAMa,IAAIC,CAAC,GACjBC,IACJJ,EAAQ,SAAS,KACjBA,EAAQ,OAAO,GAAG,MAAM;EACtB,IAAIX,MAAM,GAAG,OAAO;EACpB,IAAMgB,IAAOL,EAAQX,IAAI;EACzB,OAAOgB,MAAS,KAAA,KAAaC,MAAMD,IAAO;CAC5C,CAAC,GACGE,IAAQP,EAAQ,IAChBQ,IAAOR,EAAQA,EAAQ,SAAS;CACtC,OAAOI,KACFG,MAAU,KAAA,KACVC,MAAS,KAAA,KACTC,KAAeF,KACfE,KAAeD,IAAO;AAC7B;AAmBA,SAAgBE,EAAmB,GAAsD;CACvF,IAAMC,IAAUC,EAAUC,CAAI,GACxBC,IAAeC,EAA2B,IAAI,GAC9CC,IAAUD,EAAmC,IAAI,GACjD,CAACE,GAAOC,KAAYC,EAA2BjC,CAAI;CAEzD,cAAsB;EAAE,EAAQ,SAAS,OAAO;CAAG,GAAG,CAAC,CAAC;CAExD,IAAMkC,IAAqBC,GAAa,GAAiB,MAAgC;EACvF,IAAM,CAACjC,GAAII,KAAML,EAAgBwB,EAAQ,QAAQ,OAAOrB,CAAW,GAC7DgC,IAAIR,EAAa;EACvB,IAAI,CAACQ,GAAG,OAAOlC;EACf,IAAMmC,IAAMZ,EAAQ,QAAQ,aACtBa,IAAQD,IAAM,MAAM,KAAKD,EAAE,QAAQ,CAAC,CAAC,QAAQ,MAAOG,EAAG,QAAQF,CAAG,CAAC,IAAI,MAAM,KAAKD,EAAE,QAAQ,GAC9FI,IAAMF,EAAK;EACf,KAAK,IAAInC,IAAI,GAAGA,IAAImC,EAAK,QAAQ,KAAK;GACpC,IAAMG,IAAMH,EAAKnC;GACjB,IAAKsC,KAEDC,IADMD,EAAI,sBACA,CAAA,CAAE,QAAQ;IAAE,IAAMtC;IAAG;GAAO;EAC5C;EACA,OAAO,KAAK,IAAID,GAAI,KAAK,IAAIsC,GAAKlC,CAAE,CAAC;CACvC,GAAG,CAACmB,CAAO,CAAC,GAENkB,IAAQR,GAAuC,MAAO;EAC1D,EAAa,UAAUI;CACzB,GAAG,CAAC,CAAC,GAECK,IAAQT,QAAkB;EAE9B,AADA,EAAQ,UAAU,MAClBH,EAAShC,CAAI;CACf,GAAG,CAAC,CAAC,GAEC6C,IAAmBV,GAAa,GAAY,GAAe,MAAyB;EACxF,IAAMW,IAAYlB,EAAa;EAE/B,IADI,CAACkB,KAAahB,EAAQ,WACtB/B,EAAkBgD,EAAE,QAAQA,EAAE,aAAwB,GAAG;EAE7D,IAAMC,IAAuB;GAC3B,UAAUD,EAAE;GAAU,SAASA,EAAE;GAAS,SAASA,EAAE;GAAS,QAAQA,EAAE;EAC1E,GACIhC,IAAuB,CAAC,GACxBQ,IAAc,GAGZ0B,IAAUF,EAAE,eAEZN,KADQ,MAAM,KAAKK,EAAU,QAAQ,CAAC,CAAC,MAAM,MAAUI,EAAM,SAASD,CAAO,CAAC,KAAKA,EAAA,CACvE,sBAAsB,GAClCE,IAAO;GAAE,GAAGJ,EAAE,UAAUN,EAAI;GAAM,GAAGM,EAAE,UAAUN,EAAI;EAAI,GACzDW,KAAW,OAA4D;GAC3E,KAAKrC;GACL,MAAMsC,EAAG,UAAUF,EAAK;GACxB,KAAKE,EAAG,UAAUF,EAAK;GACvB,OAAOV,EAAI;EACb;EAEA,EAAQ,UAAUa,EAAmBP,GAAG;GACtC,QAAQD;GAGR,WAAWrB,EAAQ,QAAQ,MAAMjB,EAAM,EAAE,SACrC,WACAiB,EAAQ,QAAQ;GACpB,aAAa,MAAO;IAGlB,AAFA,IAAalB,EAAckB,EAAQ,QAAQ,OAAOA,EAAQ,QAAQ,aAAaf,GAAIF,CAAK,GACxF,IAAc0B,EAAmBmB,EAAG,SAAS7C,CAAK,GAClDwB,EAAS;KAAE;KAAY;KAAa,OAAOoB,EAAQC,CAAE;IAAE,CAAC;GAC1D;GACA,SAAS,MAAO;IAEd,AADA,IAAcnB,EAAmBmB,EAAG,SAAS7C,CAAK,GAClDwB,EAAS;KAAE;KAAY;KAAa,OAAOoB,EAAQC,CAAE;IAAE,CAAC;GAC1D;GACA,WAAW,MAAO;IAChB,IAAME,IAAOrB,EAAmBmB,EAAG,SAAS7C,CAAK;IAIjD,AAHKK,EAAWY,EAAQ,QAAQ,OAAOV,GAAYwC,CAAI,KACrD9B,EAAQ,QAAQ,UAAUV,GAAYwC,CAAI,GAE5CX,EAAM;GACR;GACA,eAAe;IACb,IAAM,EAAE,eAAYnB,EAAQ;IAK5B,AAJI+B,MACFA,EAAQ9C,GAAIsC,CAAI,GAChBS,EAAiBX,CAAS,IAE5BF,EAAM;GACR;GAIA,UAAUA;EACZ,CAAC;CACH,GAAG;EAACV;EAAoBU;EAAOnB;CAAO,CAAC;CAiBvC,OAAO;EACL,OAhBYU,GAAa,GAAY,GAAe,MAA2B;GAC/E,IAAM,EAAE,UAAO,gBAAa,iBAAcV,EAAQ;GAClD,IAAIpB,EAAMG,EAAM,EAAE,QAAQ,OAAO;GACjC,IAAMkD,IAAMnD,EAAcF,GAAOI,GAAaC,GAAIF,CAAK,GACjDmD,IAAKD,EAAI,KAAK,MAAMrD,EAAM,WAAW,MAAOM,EAAG,OAAOC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAMI,IAAIC,CAAC,GAC9EI,IAAQsC,EAAG,IACXrC,IAAOqC,EAAGA,EAAG,SAAS;GAC5B,IAAItC,MAAU,KAAA,KAAaC,MAAS,KAAA,GAAW,OAAO;GACtD,IAAM,CAACpB,GAAII,KAAML,EAAgBI,GAAOG,CAAK,GACvCoD,IAASC,IAAQ,IAAIxC,IAAQ,IAAIC,IAAO;GAG9C,OAFIsC,IAAS1D,KAAM0D,IAAStD,KAAMO,EAAWR,GAAOqD,GAAKE,CAAM,IAAU,MACzEE,EAAUJ,GAAKE,CAAM,GACd;EACT,GAAG,CAACnC,CAAO,CAGT;EACA,WAAW,GAAI,OAAW,EACxB,gBAAgB,MAAMoB,EAAiBnC,GAAIF,GAAOuC,CAAC,EACrD;EACA,gBAAgB,EACd,KAAKJ,EACP;EACA;CACF;AACF;AAQA,SAASc,EAAiB,GAA8B;CACtD,IAAMM,KAAW,MAAa;EAAE,EAAE,gBAAgB;CAAG;CAErD,AADAjB,EAAU,iBAAiB,SAASiB,GAAS,EAAI,GACjD,iBAAiB;EAAE,EAAU,oBAAoB,SAASA,GAAS,EAAI;CAAG,GAAG,CAAC;AAChF"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/** Elements that handle their own press and keys. */
|
|
2
|
-
export declare const CONTROL_SELECTOR: string;
|
|
3
|
-
/**
|
|
4
|
-
* Whether `target` sits in a control of its own somewhere inside `host` — a
|
|
5
|
-
* toggle in a list row. The host's handlers leave such an event to the
|
|
6
|
-
* control, so a row's press, click and keys never swallow its controls'.
|
|
7
|
-
*/
|
|
8
|
-
export declare function isInControlWithin(target: EventTarget | null, host: Element): boolean;
|
|
9
|
-
//# sourceMappingURL=interactiveTarget.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveTarget.d.ts","sourceRoot":"","sources":["../src/interactiveTarget.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,eAAO,MAAM,gBAAgB,QAGlB,CAAC;AAEZ;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAIpF"}
|