@weasel-js/ui 1.1.0 → 1.3.0-pre.0
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-BvPEd_GW.js → ActionBar-BTev_ZZl.js} +21 -21
- package/dist/chunks/ActionBar-BTev_ZZl.js.map +1 -0
- package/dist/chunks/{ActionsBar-9aR5N3lU.js → ActionsBar-gTuCtkv8.js} +4 -4
- package/dist/chunks/{ActionsBar-9aR5N3lU.js.map → ActionsBar-gTuCtkv8.js.map} +1 -1
- package/dist/chunks/{Badge-DZQqAV4d.js → Badge-9dPfvYOk.js} +715 -707
- package/dist/chunks/Badge-9dPfvYOk.js.map +1 -0
- package/dist/chunks/{BandEditor-D3i6l299.js → BandEditor-DKbcHG2_.js} +46 -46
- package/dist/chunks/BandEditor-DKbcHG2_.js.map +1 -0
- package/dist/chunks/{Button-9QNIYugK.js → Button-CIu40Epu.js} +28 -28
- package/dist/chunks/Button-CIu40Epu.js.map +1 -0
- package/dist/chunks/{Callout-NSOjza6G.js → Callout-CHs98djt.js} +40 -39
- package/dist/chunks/Callout-CHs98djt.js.map +1 -0
- package/dist/chunks/Checkbox-BLEw-wEb.js +47 -0
- package/dist/chunks/Checkbox-BLEw-wEb.js.map +1 -0
- package/dist/chunks/ColorField-D1t-BdSa.js +60 -0
- package/dist/chunks/ColorField-D1t-BdSa.js.map +1 -0
- package/dist/chunks/{ComboBox-ONQISwtI.js → ComboBox-cvdKolWv.js} +28 -28
- package/dist/chunks/ComboBox-cvdKolWv.js.map +1 -0
- package/dist/chunks/{CurveEditor-SmwwvrsA.js → CurveEditor-BaA-PabB.js} +116 -116
- package/dist/chunks/CurveEditor-BaA-PabB.js.map +1 -0
- package/dist/chunks/DataGrid-D15I779H.js +210 -0
- package/dist/chunks/DataGrid-D15I779H.js.map +1 -0
- package/dist/chunks/Dialog-DC1x46Sq.js +59 -0
- package/dist/chunks/Dialog-DC1x46Sq.js.map +1 -0
- package/dist/chunks/{Field-VQwmrIna.js → Field-BjFl_yng.js} +6 -6
- package/dist/chunks/Field-BjFl_yng.js.map +1 -0
- package/dist/chunks/GradientEditor-BJRD0n1g.js +308 -0
- package/dist/chunks/GradientEditor-BJRD0n1g.js.map +1 -0
- package/dist/chunks/InlineRange-C6UYKxLD.js +24 -0
- package/dist/chunks/InlineRange-C6UYKxLD.js.map +1 -0
- package/dist/chunks/Input-DhWBgpRx.js +55 -0
- package/dist/chunks/Input-DhWBgpRx.js.map +1 -0
- package/dist/chunks/{Keycaps-CFX7UAj8.js → Keycaps-BhCKdyws.js} +15 -15
- package/dist/chunks/Keycaps-BhCKdyws.js.map +1 -0
- package/dist/chunks/NumberField-ZdVa4bpJ.js +59 -0
- package/dist/chunks/NumberField-ZdVa4bpJ.js.map +1 -0
- package/dist/chunks/{OptionsBar-CHvH4n4u.js → OptionsBar-DahCI4Aq.js} +4 -4
- package/dist/chunks/{OptionsBar-CHvH4n4u.js.map → OptionsBar-DahCI4Aq.js.map} +1 -1
- package/dist/chunks/PaintInput-Cggm9OIl.js +205 -0
- package/dist/chunks/PaintInput-Cggm9OIl.js.map +1 -0
- package/dist/chunks/PatternPicker-B63SlDoF.js +93 -0
- package/dist/chunks/PatternPicker-B63SlDoF.js.map +1 -0
- package/dist/chunks/{Plot2D-CEnhzodm.js → Plot2D-sPXTw_-l.js} +27 -27
- package/dist/chunks/{Plot2D-CEnhzodm.js.map → Plot2D-sPXTw_-l.js.map} +1 -1
- package/dist/chunks/{PointPlotter-BUIse9c4.js → PointPlotter-CLd9u5Bq.js} +2 -2
- package/dist/chunks/{PointPlotter-BUIse9c4.js.map → PointPlotter-CLd9u5Bq.js.map} +1 -1
- package/dist/chunks/{Powerline-Dd9Ukhcl.js → Powerline-DhQJYaUg.js} +2 -2
- package/dist/chunks/{Powerline-Dd9Ukhcl.js.map → Powerline-DhQJYaUg.js.map} +1 -1
- package/dist/chunks/Prefs-BSJ0lMmJ.js +300 -0
- package/dist/chunks/Prefs-BSJ0lMmJ.js.map +1 -0
- package/dist/chunks/RadioGroup-vtwjRiUm.js +49 -0
- package/dist/chunks/RadioGroup-vtwjRiUm.js.map +1 -0
- package/dist/chunks/RangeSlider-B-n_7AgJ.js +52 -0
- package/dist/chunks/RangeSlider-B-n_7AgJ.js.map +1 -0
- package/dist/chunks/{ResizeHandle-BOpmtOOj.js → ResizeHandle--ZExnMfa.js} +8 -8
- package/dist/chunks/{ResizeHandle-BOpmtOOj.js.map → ResizeHandle--ZExnMfa.js.map} +1 -1
- package/dist/chunks/{Select-CHsuQCp0.js → Select--BVTi-j0.js} +32 -32
- package/dist/chunks/Select--BVTi-j0.js.map +1 -0
- package/dist/chunks/SelectionPanel-C7kygTFE.js +446 -0
- package/dist/chunks/SelectionPanel-C7kygTFE.js.map +1 -0
- package/dist/chunks/{Sidebar-DP_nyJze.js → Sidebar-CtwBdr4n.js} +1 -1
- package/dist/chunks/{Sidebar-DP_nyJze.js.map → Sidebar-CtwBdr4n.js.map} +1 -1
- package/dist/chunks/SidebarPanel-AeSc7wNR.js +59 -0
- package/dist/chunks/SidebarPanel-AeSc7wNR.js.map +1 -0
- package/dist/chunks/{Slider-tGbqoAZH.js → Slider-cxWR47gi.js} +39 -39
- package/dist/chunks/Slider-cxWR47gi.js.map +1 -0
- package/dist/chunks/{StatusBar-DBO0E0Yd.js → StatusBar-D_wu-SZh.js} +6 -6
- package/dist/chunks/StatusBar-D_wu-SZh.js.map +1 -0
- package/dist/chunks/Switch-CtZwp5zm.js +27 -0
- package/dist/chunks/Switch-CtZwp5zm.js.map +1 -0
- package/dist/chunks/Tabs-lB0IB4TX.js +41 -0
- package/dist/chunks/Tabs-lB0IB4TX.js.map +1 -0
- package/dist/chunks/{Toast-DFw4IrD_.js → Toast-hr9BYsho.js} +31 -31
- package/dist/chunks/{Toast-DFw4IrD_.js.map → Toast-hr9BYsho.js.map} +1 -1
- package/dist/chunks/{ToggleBar-BP1zFcvg.js → ToggleBar-BxgWq-wO.js} +11 -10
- package/dist/chunks/ToggleBar-BxgWq-wO.js.map +1 -0
- package/dist/chunks/{ToolButton-ClPz5L6j.js → ToolButton-CJrPjbsj.js} +16 -16
- package/dist/chunks/ToolButton-CJrPjbsj.js.map +1 -0
- package/dist/chunks/{ToolGroup-BTIwd4U4.js → ToolGroup-D_lDzkvU.js} +1 -1
- package/dist/chunks/{ToolGroup-BTIwd4U4.js.map → ToolGroup-D_lDzkvU.js.map} +1 -1
- package/dist/chunks/{ToolOptionsBar-JvmY7iNe.js → ToolOptionsBar-BA6Sb3U2.js} +4 -4
- package/dist/chunks/ToolOptionsBar-BA6Sb3U2.js.map +1 -0
- package/dist/chunks/{ToolPalette-DAiVhdtV.js → ToolPalette-TMvkaJwr.js} +24 -24
- package/dist/chunks/ToolPalette-TMvkaJwr.js.map +1 -0
- package/dist/chunks/Tooltip-Di7vxbFa.js +40 -0
- package/dist/chunks/Tooltip-Di7vxbFa.js.map +1 -0
- package/dist/chunks/{keyGlyph-BDH5fqkO.js → keyGlyph-DNpLxF8u.js} +1 -1
- package/dist/chunks/{keyGlyph-BDH5fqkO.js.map → keyGlyph-DNpLxF8u.js.map} +1 -1
- package/dist/chunks/segmentedControl.module-D4b7x19O.js +11 -0
- package/dist/chunks/segmentedControl.module-D4b7x19O.js.map +1 -0
- package/dist/chunks/{useRovingTabIndex-DBZtq4IH.js → useRovingTabIndex-CQz8EiKh.js} +1 -1
- package/dist/chunks/{useRovingTabIndex-DBZtq4IH.js.map → useRovingTabIndex-CQz8EiKh.js.map} +1 -1
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/ActionsBar/index.js +1 -1
- package/dist/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/bases/index.d.ts.map +1 -1
- package/dist/components/Badge/effects/index.d.ts.map +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/Badge/shapes/index.d.ts.map +1 -1
- package/dist/components/BandEditor/index.js +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Callout/Callout.d.ts.map +1 -1
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/components/Checkbox/index.js +1 -1
- package/dist/components/ColorField/ColorField.d.ts.map +1 -1
- package/dist/components/ColorField/index.js +1 -1
- package/dist/components/ComboBox/index.js +1 -1
- package/dist/components/CurveEditor/LayeredCurveEditor.d.ts +1 -1
- package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
- package/dist/components/CurveEditor/createFunctionLayer.d.ts +1 -2
- package/dist/components/CurveEditor/createFunctionLayer.d.ts.map +1 -1
- package/dist/components/CurveEditor/index.js +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/Field/index.js +1 -1
- package/dist/components/GradientEditor/SceneGradientHandles.d.ts +41 -0
- package/dist/components/GradientEditor/SceneGradientHandles.d.ts.map +1 -0
- package/dist/components/GradientEditor/index.d.ts +1 -0
- package/dist/components/GradientEditor/index.d.ts.map +1 -1
- package/dist/components/GradientEditor/index.js +2 -2
- package/dist/components/InlineRange/InlineRange.d.ts +17 -0
- package/dist/components/InlineRange/InlineRange.d.ts.map +1 -0
- package/dist/components/InlineRange/index.d.ts +2 -0
- package/dist/components/InlineRange/index.d.ts.map +1 -0
- package/dist/components/InlineRange/index.js +2 -0
- package/dist/components/Input/Input.d.ts +1 -1
- package/dist/components/Input/index.js +1 -1
- package/dist/components/Keycaps/index.js +2 -2
- package/dist/components/NumberField/NumberField.d.ts +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/OptionsBar/index.js +1 -1
- package/dist/components/PaintInput/PaintInput.d.ts +40 -0
- package/dist/components/PaintInput/PaintInput.d.ts.map +1 -0
- package/dist/components/PaintInput/index.d.ts +2 -0
- package/dist/components/PaintInput/index.d.ts.map +1 -0
- package/dist/components/PaintInput/index.js +2 -0
- package/dist/components/PatternPicker/PatternPicker.d.ts +31 -0
- package/dist/components/PatternPicker/PatternPicker.d.ts.map +1 -0
- package/dist/components/PatternPicker/index.d.ts +2 -0
- package/dist/components/PatternPicker/index.d.ts.map +1 -0
- package/dist/components/PatternPicker/index.js +2 -0
- package/dist/components/Plot2D/Plot2D.d.ts.map +1 -1
- package/dist/components/Plot2D/index.js +1 -1
- package/dist/components/PointPlotter/index.js +1 -1
- package/dist/components/Powerline/index.js +2 -2
- package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
- package/dist/components/Prefs/index.d.ts +1 -1
- package/dist/components/Prefs/index.d.ts.map +1 -1
- package/dist/components/Prefs/index.js +1 -1
- package/dist/components/Prefs/schema.d.ts +4 -93
- package/dist/components/Prefs/schema.d.ts.map +1 -1
- package/dist/components/RadioGroup/index.js +1 -1
- package/dist/components/RangeSlider/index.js +1 -1
- package/dist/components/ResizeHandle/index.js +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectionPanel/SelectionPanel.d.ts +32 -1
- package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
- package/dist/components/SelectionPanel/index.js +1 -1
- package/dist/components/Sidebar/index.js +1 -1
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/StatusBar/index.js +1 -1
- package/dist/components/Switch/Switch.d.ts +1 -1
- package/dist/components/Switch/index.js +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/ToggleBar/ToggleBar.d.ts +1 -1
- package/dist/components/ToggleBar/ToggleBar.d.ts.map +1 -1
- package/dist/components/ToggleBar/index.js +1 -1
- package/dist/components/ToolButton/index.js +1 -1
- package/dist/components/ToolGroup/index.js +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/ToolPalette/index.js +1 -1
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/components/paintValue.d.ts +8 -0
- package/dist/components/paintValue.d.ts.map +1 -0
- package/dist/icons/Icon.d.ts +17 -0
- package/dist/icons/Icon.d.ts.map +1 -0
- package/dist/icons/index.d.ts +50 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/paths.d.ts +71 -0
- package/dist/icons/paths.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +184 -48
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +4 -3
- package/dist/chunks/ActionBar-BvPEd_GW.js.map +0 -1
- package/dist/chunks/Badge-DZQqAV4d.js.map +0 -1
- package/dist/chunks/BandEditor-D3i6l299.js.map +0 -1
- package/dist/chunks/Button-9QNIYugK.js.map +0 -1
- package/dist/chunks/Callout-NSOjza6G.js.map +0 -1
- package/dist/chunks/Checkbox-KQ5L8APP.js +0 -47
- package/dist/chunks/Checkbox-KQ5L8APP.js.map +0 -1
- package/dist/chunks/ColorField-ykpiD3XU.js +0 -60
- package/dist/chunks/ColorField-ykpiD3XU.js.map +0 -1
- package/dist/chunks/ComboBox-ONQISwtI.js.map +0 -1
- package/dist/chunks/CurveEditor-SmwwvrsA.js.map +0 -1
- package/dist/chunks/DataGrid-DZQ4Chbd.js +0 -210
- package/dist/chunks/DataGrid-DZQ4Chbd.js.map +0 -1
- package/dist/chunks/Dialog-CqwdJv_t.js +0 -59
- package/dist/chunks/Dialog-CqwdJv_t.js.map +0 -1
- package/dist/chunks/Field-VQwmrIna.js.map +0 -1
- package/dist/chunks/GradientEditor-Bg6SX64V.js +0 -280
- package/dist/chunks/GradientEditor-Bg6SX64V.js.map +0 -1
- package/dist/chunks/Input-DpkwYtUY.js +0 -55
- package/dist/chunks/Input-DpkwYtUY.js.map +0 -1
- package/dist/chunks/Keycaps-CFX7UAj8.js.map +0 -1
- package/dist/chunks/NumberField-BbzI0GtU.js +0 -59
- package/dist/chunks/NumberField-BbzI0GtU.js.map +0 -1
- package/dist/chunks/Prefs-BMR9wMiZ.js +0 -238
- package/dist/chunks/Prefs-BMR9wMiZ.js.map +0 -1
- package/dist/chunks/RadioGroup-CIpHr3g6.js +0 -49
- package/dist/chunks/RadioGroup-CIpHr3g6.js.map +0 -1
- package/dist/chunks/RangeSlider-CaDogGTj.js +0 -52
- package/dist/chunks/RangeSlider-CaDogGTj.js.map +0 -1
- package/dist/chunks/Select-CHsuQCp0.js.map +0 -1
- package/dist/chunks/SelectionPanel-D_wk_8ZN.js +0 -303
- package/dist/chunks/SelectionPanel-D_wk_8ZN.js.map +0 -1
- package/dist/chunks/SidebarPanel-BVTQ1ZyM.js +0 -59
- package/dist/chunks/SidebarPanel-BVTQ1ZyM.js.map +0 -1
- package/dist/chunks/Slider-tGbqoAZH.js.map +0 -1
- package/dist/chunks/StatusBar-DBO0E0Yd.js.map +0 -1
- package/dist/chunks/Switch-JyVSSAzC.js +0 -27
- package/dist/chunks/Switch-JyVSSAzC.js.map +0 -1
- package/dist/chunks/Tabs-Df0sDomx.js +0 -41
- package/dist/chunks/Tabs-Df0sDomx.js.map +0 -1
- package/dist/chunks/ToggleBar-BP1zFcvg.js.map +0 -1
- package/dist/chunks/ToolButton-ClPz5L6j.js.map +0 -1
- package/dist/chunks/ToolOptionsBar-JvmY7iNe.js.map +0 -1
- package/dist/chunks/ToolPalette-DAiVhdtV.js.map +0 -1
- package/dist/chunks/Tooltip-DXJbdR5B.js +0 -40
- package/dist/chunks/Tooltip-DXJbdR5B.js.map +0 -1
- package/dist/chunks/segmentedControl.module-DCyuDbj1.js +0 -11
- package/dist/chunks/segmentedControl.module-DCyuDbj1.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GradientEditor-Bg6SX64V.js","names":[],"sources":["../../src/paintGradientTrack.tsx","../../src/components/GradientEditor/GradientEditor.module.css","../../src/components/GradientEditor/GradientEditor.tsx","../../src/components/GradientEditor/GradientHandles.module.css","../../src/components/GradientEditor/GradientHandles.tsx"],"sourcesContent":["import type { ReactNode, CSSProperties } from 'react';\nimport type { TrackCtx } from './components/Slider';\n\n/**\n * Options for {@link paintGradientTrack}.\n *\n * `gradient` maps a normalized position along the track (0 to 1) to a CSS\n * color; `samples` is how many stops the resulting linear-gradient uses.\n * `activeRange`, given in the slider's own value units, keeps that span at\n * full strength and dims + hatches the rest.\n */\nexport type GradientTrackOpts = {\n gradient: (t: number) => string;\n samples?: number;\n activeRange?: [number, number];\n hatch?: {\n angleDeg?: number;\n stripe?: number;\n gap?: number;\n dim?: number;\n };\n};\n\nconst DEFAULT_HATCH = { angleDeg: 135, stripe: 2, gap: 4, dim: 75 };\n\n/**\n * Builds a `Slider` `renderTrack` function that paints the track as a\n * sampled color gradient, optionally dimming and hatching the portions\n * outside an active range.\n */\nexport function paintGradientTrack(opts: GradientTrackOpts): (ctx: TrackCtx) => ReactNode {\n const { gradient, samples = 16, activeRange, hatch } = opts;\n\n return (ctx: TrackCtx) => {\n const stops: string[] = [];\n for (let i = 0; i <= samples; i++) {\n const t = i / samples;\n stops.push(`${gradient(t)} ${(t * 100).toFixed(1)}%`);\n }\n const baseGradient = `linear-gradient(to right, ${stops.join(', ')})`;\n\n const layers: string[] = [];\n if (activeRange) {\n const lowPct = ctx.valueToFraction(activeRange[0]) * 100;\n const highPct = ctx.valueToFraction(activeRange[1]) * 100;\n const h = { ...DEFAULT_HATCH, ...hatch };\n const stripe = `repeating-linear-gradient(${h.angleDeg}deg, transparent 0 ${h.stripe}px, var(--wzl-surface) ${h.stripe}px ${h.stripe + h.gap}px)`;\n const dimColor = `color-mix(in srgb, var(--wzl-surface) ${h.dim}%, transparent)`;\n const dimOverlay = `linear-gradient(${dimColor}, ${dimColor})`;\n\n if (lowPct > 0) {\n layers.push(`${dimOverlay} left 0 / ${lowPct.toFixed(2)}% 100% no-repeat`);\n layers.push(`${stripe} left 0 / ${lowPct.toFixed(2)}% 100% no-repeat`);\n }\n if (highPct < 100) {\n const wR = (100 - highPct).toFixed(2);\n layers.push(`${dimOverlay} right 0 / ${wR}% 100% no-repeat`);\n layers.push(`${stripe} right 0 / ${wR}% 100% no-repeat`);\n }\n }\n layers.push(baseGradient);\n\n const style: CSSProperties = {\n position: 'absolute',\n inset: 0,\n background: layers.join(', '),\n };\n return <div style={style} />;\n };\n}\n",".root {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-inline-size: 0;\n}\n\n.swatches {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* Each stop's opacity slider would otherwise stretch the row to a width no\n * properties panel has; the chip stays legible, the slider yields. */\n.swatch {\n flex: 0 1 auto;\n min-inline-size: 0;\n}\n","import { useCallback, type ReactElement } from 'react';\nimport {\n sampleGradientStops,\n withGradientKind,\n type GradStop,\n type GradientFill,\n type GradientKind,\n} from '@weasel-js/core';\nimport { Slider, type Thumb } from '../Slider';\nimport { ColorField } from '../ColorField';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport { paintGradientTrack } from '../../paintGradientTrack';\nimport s from './GradientEditor.module.css';\n\nconst KINDS: readonly ToggleBarItem<GradientKind>[] = [\n { value: 'linear-gradient', label: 'Linear' },\n { value: 'radial-gradient', label: 'Radial' },\n { value: 'conic-gradient', label: 'Conic' },\n];\n\n/** Fewer than two stops is not a gradient any renderer can ramp between. */\nconst MIN_STOPS = 2;\n\n/**\n * Props for {@link GradientEditor}. `onInput` fires throughout a gesture and\n * `onChange` once at its end.\n */\nexport interface GradientEditorProps {\n /** The gradient being edited. */\n value: GradientFill;\n /**\n * Live value during a gesture — a stop drag, a color-picker scrub. Wire\n * it for preview; it fires many times per gesture and must not be\n * written to history.\n */\n onInput?: (next: GradientFill) => void;\n /** Committed value: one call per completed gesture. Pair with an\n * undoable write. */\n onChange: (next: GradientFill) => void;\n /** Show the linear / radial / conic switch. Default true; turn it off\n * when the surrounding UI already owns the kind. */\n kindSwitch?: boolean;\n className?: string;\n}\n\ntype StopThumb = Thumb & { color: string };\n\n/**\n * Editor for a gradient's kind and stop list.\n *\n * Geometry (`from`/`to`, `center`, `radius`, `angle`) is deliberately not\n * edited here — on a canvas that belongs on the artwork, via\n * `<GradientHandles>`. This component owns the parts with no spatial\n * meaning, so it composes into a properties panel at any width.\n *\n * Stops are addressed by their position in `value.stops`, which is never\n * reordered — dragging one stop past another leaves both indices alone, so\n * a drag can cross a neighbour without the two swapping under the pointer.\n * Rendering sorts a copy.\n */\nexport function GradientEditor(props: GradientEditorProps): ReactElement {\n const { value, onInput, onChange, kindSwitch = true, className } = props;\n const stops = value.stops;\n\n const withStops = useCallback(\n (next: GradStop[]): GradientFill => ({ ...value, stops: next }),\n [value],\n );\n\n const thumbs: StopThumb[] = stops.map((stop) => ({ value: stop.offset, color: stop.color }));\n\n const applyThumbs = (next: StopThumb[]): GradStop[] =>\n next.map((t) => ({ offset: t.value, color: t.color }));\n\n const setStopColor = (index: number, color: string): GradStop[] =>\n stops.map((stop, i) => (i === index ? { ...stop, color } : stop));\n\n // Sorted view for the swatch row, carrying each stop's real index so a\n // recolor writes back to the right entry.\n const ordered = stops\n .map((stop, index) => ({ stop, index }))\n .sort((a, b) => a.stop.offset - b.stop.offset);\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n {kindSwitch && (\n <ToggleBar<GradientKind>\n items={KINDS}\n value={value.fill}\n size=\"sm\"\n ariaLabel=\"Gradient kind\"\n onChange={(kind) => kind && onChange(withGradientKind(value, kind))}\n />\n )}\n\n <Slider<StopThumb>\n min={0}\n max={1}\n step={0.005}\n constraint=\"free\"\n thumbs={thumbs}\n ariaLabel=\"Gradient stops\"\n readoutPlacement=\"none\"\n onInput={(next) => onInput?.(withStops(applyThumbs(next)))}\n onChange={(next) => onChange(withStops(applyThumbs(next)))}\n onAddThumb={(at) => ({ value: at, color: sampleGradientStops(stops, at) })}\n onRemoveThumb={() => stops.length > MIN_STOPS}\n renderTrack={paintGradientTrack({\n gradient: (t) => sampleGradientStops(stops, t),\n samples: 32,\n })}\n />\n\n <div className={s.swatches}>\n {ordered.map(({ stop, index }) => (\n <ColorField\n key={index}\n value={stop.color}\n alpha\n aria-label={`Stop ${index + 1} at ${Math.round(stop.offset * 100)}%`}\n className={s.swatch}\n onInput={(hex) => onInput?.(withStops(setStopColor(index, hex)))}\n onChange={(hex) => onChange(withStops(setStopColor(index, hex)))}\n />\n ))}\n </div>\n </div>\n );\n}\n","/* The overlay covers the canvas but must not intercept tool input; only the\n * handles opt back into hit-testing. */\n.overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n/* These sit over artwork of unknown color, not over the app's own surface,\n * so they are deliberately not themed: a themed handle disappears against\n * whatever the user painted underneath. White-on-dark reads on anything,\n * which is why every editor draws handles this way. */\n.guide {\n fill: none;\n stroke: #ffffff;\n stroke-opacity: 0.7;\n stroke-dasharray: 4 4;\n paint-order: stroke;\n}\n\n.handle {\n fill: #ffffff;\n stroke: #222222;\n stroke-width: 2;\n cursor: grab;\n pointer-events: auto;\n}\n\n.handle:active {\n cursor: grabbing;\n}\n\n.handle:focus-visible {\n outline: 2px solid var(--wzl-accent, #4a9eff);\n outline-offset: 2px;\n}\n","import { useRef, type KeyboardEvent as ReactKeyboardEvent, type ReactElement, type ReactNode } from 'react';\nimport { useHandleDrag, gradientGeometry, type GradientFill } from '@weasel-js/core';\nimport s from './GradientHandles.module.css';\n\n/** Structural, and deliberately not exported — `Plot2D` and `CurveEditor`\n * each publish their own `Point`, and a third would only be ambiguous at\n * the package barrel. Consumers pass any `{ x, y }`. */\ninterface Point {\n x: number;\n y: number;\n}\n\n/**\n * Props for {@link GradientHandles}. `onInput` fires throughout a drag and\n * `onChange` once at its end.\n */\nexport interface GradientHandlesProps {\n /**\n * The gradient whose geometry these handles move, in a **resolved,\n * isotropic** frame — one where `radius` is a length in the same units as\n * `center.x` and a right angle is a right angle.\n *\n * A `units: 'bounds'` gradient is not such a frame: `x` and `y` are\n * fractions of two different lengths, so a circle there is an ellipse on\n * screen and polar math silently mixes scales. Resolve it first with\n * `fillInPoseFrame(fill, box)` and convert edits back with\n * `fillToBoundsFrame(next, box)`.\n */\n value: GradientFill;\n /**\n * Gradient space → overlay pixels. For a `units: 'local'` gradient this\n * is the node's local-to-screen transform; for `'world'`, the view.\n */\n toScreen: (p: Point) => Point;\n /** Overlay pixels → gradient space. Must invert `toScreen`. */\n toLocal: (p: Point) => Point;\n /** Live during a drag — wire for preview, do not write to history. */\n onInput?: (next: GradientFill) => void;\n /** Committed at drag end: one call per gesture. */\n onChange: (next: GradientFill) => void;\n /** Overlay size in CSS pixels. */\n width: number;\n height: number;\n className?: string;\n}\n\n/**\n * Direct-manipulation handles for a gradient's geometry, drawn as an SVG\n * overlay above a canvas: endpoints for linear, center and radius for\n * radial, center and angle arm for conic.\n *\n * Positioning is entirely the consumer's `toScreen` / `toLocal` — this\n * component never sees a view or a scene node, so the same handles serve a\n * node-local gradient, a world-space one, and a plain unzoomed preview.\n *\n * The overlay ignores pointer events except on the handles themselves, so\n * it can sit over live canvas content without swallowing tool input.\n */\nexport function GradientHandles(props: GradientHandlesProps): ReactElement {\n const { value, toScreen, toLocal, onInput, onChange, width, height, className } = props;\n\n return (\n <svg\n className={[s.overlay, className].filter(Boolean).join(' ')}\n width={width}\n height={height}\n >\n {renderForKind(value, toScreen, toLocal, onInput, onChange)}\n </svg>\n );\n}\n\nfunction renderForKind(\n value: GradientFill,\n toScreen: (p: Point) => Point,\n toLocal: (p: Point) => Point,\n onInput: ((next: GradientFill) => void) | undefined,\n onChange: (next: GradientFill) => void,\n): ReactNode {\n const emit = (next: GradientFill, phase: 'input' | 'commit'): void => {\n if (phase === 'input') onInput?.(next);\n else onChange(next);\n };\n\n if (value.fill === 'linear-gradient') {\n const from = toScreen(value.from);\n const to = toScreen(value.to);\n return (\n <>\n <Guide x1={from.x} y1={from.y} x2={to.x} y2={to.y} />\n <DragPoint\n at={from}\n label=\"Gradient start\"\n onDrag={(p, phase) => emit({ ...value, from: toLocal(p) }, phase)}\n />\n <DragPoint\n at={to}\n label=\"Gradient end\"\n onDrag={(p, phase) => emit({ ...value, to: toLocal(p) }, phase)}\n />\n </>\n );\n }\n\n if (value.fill === 'radial-gradient') {\n const center = toScreen(value.center);\n // The radius handle rides the +x axis of gradient space, so it stays on\n // the drawn circle under a rotated or anisotropic transform.\n const edge = toScreen({ x: value.center.x + value.radius, y: value.center.y });\n const screenRadius = Math.hypot(edge.x - center.x, edge.y - center.y);\n return (\n <>\n <circle className={s.guide} cx={center.x} cy={center.y} r={screenRadius} />\n <DragPoint\n at={center}\n label=\"Gradient center\"\n onDrag={(p, phase) => emit({ ...value, center: toLocal(p) }, phase)}\n />\n <DragPoint\n at={edge}\n label=\"Gradient radius\"\n onDrag={(p, phase) => {\n const local = toLocal(p);\n const radius = Math.hypot(local.x - value.center.x, local.y - value.center.y);\n emit({ ...value, radius: Math.max(MIN_RADIUS, radius) }, phase);\n }}\n />\n </>\n );\n }\n\n const center = toScreen(value.center);\n const { radius } = gradientGeometry(value);\n const tip = toScreen({\n x: value.center.x + Math.cos(value.angle) * radius,\n y: value.center.y + Math.sin(value.angle) * radius,\n });\n return (\n <>\n <Guide x1={center.x} y1={center.y} x2={tip.x} y2={tip.y} />\n <DragPoint\n at={center}\n label=\"Gradient center\"\n onDrag={(p, phase) => emit({ ...value, center: toLocal(p) }, phase)}\n />\n <DragPoint\n at={tip}\n label=\"Gradient angle\"\n onDrag={(p, phase) => {\n const local = toLocal(p);\n const angle = Math.atan2(local.y - value.center.y, local.x - value.center.x);\n emit({ ...value, angle }, phase);\n }}\n />\n </>\n );\n}\n\n/** A radius of zero divides by zero in the shader's `t`; keep it off the floor. */\nconst MIN_RADIUS = 1;\n\nfunction Guide(props: { x1: number; y1: number; x2: number; y2: number }): ReactElement {\n return <line className={s.guide} {...props} />;\n}\n\nfunction DragPoint({\n at,\n label,\n onDrag,\n}: {\n at: Point;\n label: string;\n onDrag: (p: Point, phase: 'input' | 'commit') => void;\n}): ReactElement {\n // `useHandleDrag` reports the pointer on move but not on end, so the last\n // position is held here to commit with. It stays null until the pointer\n // actually moves: a press that never moves must not write anything.\n const last = useRef<Point | null>(null);\n const start = useRef<Point>(at);\n const drag = useHandleDrag<SVGCircleElement>({\n onStart: () => {\n start.current = at;\n last.current = null;\n },\n onMove: (p) => {\n last.current = p;\n onDrag(p, 'input');\n },\n onEnd: (e) => {\n const moved = last.current;\n last.current = null;\n if (moved === null) return;\n // A canceled pointer is not an edit — put the live preview back where\n // the gesture started rather than committing where it was abandoned.\n if (e.type === 'pointercancel') onDrag(start.current, 'input');\n else onDrag(moved, 'commit');\n },\n });\n const onKeyDown = (e: ReactKeyboardEvent<SVGCircleElement>): void => {\n const amount = e.shiftKey ? KEY_STEP * 10 : KEY_STEP;\n let dx = 0;\n let dy = 0;\n if (e.key === 'ArrowLeft') dx = -amount;\n else if (e.key === 'ArrowRight') dx = amount;\n else if (e.key === 'ArrowUp') dy = -amount;\n else if (e.key === 'ArrowDown') dy = amount;\n else return;\n e.preventDefault();\n const next = { x: at.x + dx, y: at.y + dy };\n onDrag(next, 'input');\n onDrag(next, 'commit');\n };\n return (\n <circle\n className={s.handle}\n cx={at.x}\n cy={at.y}\n r={HANDLE_RADIUS}\n // Not `slider`: the handle carries a 2-D position, not one value, so\n // it has no `aria-valuenow` to honor the role's contract with.\n role=\"button\"\n aria-label={label}\n tabIndex={0}\n onKeyDown={onKeyDown}\n {...drag}\n />\n );\n}\n\nconst HANDLE_RADIUS = 7;\n\n/** One arrow-key step, in overlay pixels. */\nconst KEY_STEP = 1;\n"],"mappings":"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"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./Field-VQwmrIna.js";
|
|
2
|
-
import { forwardRef as t } from "react";
|
|
3
|
-
import { FieldError as n, Input as r, Label as i, Text as a, TextField as o } from "react-aria-components";
|
|
4
|
-
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
5
|
-
var l = {
|
|
6
|
-
field: "_field_cahom_1",
|
|
7
|
-
frame: "_frame_cahom_9",
|
|
8
|
-
adornment: "_adornment_cahom_54"
|
|
9
|
-
}, u = t(function(t, u) {
|
|
10
|
-
let { label: d, description: f, errorMessage: p, placeholder: m, leadingAdornment: h, trailingAdornment: g, className: _, ...v } = t;
|
|
11
|
-
return /* @__PURE__ */ c(o, {
|
|
12
|
-
...v,
|
|
13
|
-
className: [
|
|
14
|
-
l.field,
|
|
15
|
-
e.root,
|
|
16
|
-
_
|
|
17
|
-
].filter(Boolean).join(" "),
|
|
18
|
-
children: [
|
|
19
|
-
d !== void 0 && /* @__PURE__ */ s(i, {
|
|
20
|
-
className: e.label,
|
|
21
|
-
children: d
|
|
22
|
-
}),
|
|
23
|
-
/* @__PURE__ */ c("div", {
|
|
24
|
-
className: l.frame,
|
|
25
|
-
children: [
|
|
26
|
-
h !== void 0 && /* @__PURE__ */ s("span", {
|
|
27
|
-
className: l.adornment,
|
|
28
|
-
children: h
|
|
29
|
-
}),
|
|
30
|
-
/* @__PURE__ */ s(r, {
|
|
31
|
-
ref: u,
|
|
32
|
-
placeholder: m
|
|
33
|
-
}),
|
|
34
|
-
g !== void 0 && /* @__PURE__ */ s("span", {
|
|
35
|
-
className: l.adornment,
|
|
36
|
-
children: g
|
|
37
|
-
})
|
|
38
|
-
]
|
|
39
|
-
}),
|
|
40
|
-
f !== void 0 && /* @__PURE__ */ s(a, {
|
|
41
|
-
slot: "description",
|
|
42
|
-
className: e.hint,
|
|
43
|
-
children: f
|
|
44
|
-
}),
|
|
45
|
-
/* @__PURE__ */ s(n, {
|
|
46
|
-
className: e.error,
|
|
47
|
-
children: p
|
|
48
|
-
})
|
|
49
|
-
]
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
//#endregion
|
|
53
|
-
export { u as t };
|
|
54
|
-
|
|
55
|
-
//# sourceMappingURL=Input-DpkwYtUY.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Input-DpkwYtUY.js","names":[],"sources":["../../src/components/Input/Input.module.css","../../src/components/Input/Input.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: 4px;\n}\n\n.frame {\n display: flex;\n align-items: center;\n gap: 6px;\n height: 24px;\n padding: 0 8px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: 13px;\n line-height: 1;\n transition: border-color var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast);\n}\n\n.frame:focus-within {\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n.field[data-invalid] .frame {\n border-color: var(--wzl-danger, #ff5b5b);\n}\n\n.field[data-disabled] .frame {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.frame input {\n flex: 1;\n min-width: 0;\n background: transparent;\n border: none;\n outline: none;\n color: inherit;\n font: inherit;\n padding: 0;\n}\n\n.frame input::placeholder {\n color: var(--wzl-fg-subtle);\n}\n\n.adornment {\n display: inline-flex;\n align-items: center;\n color: var(--wzl-fg-subtle);\n font-size: 12px;\n pointer-events: none;\n}\n","import { forwardRef, type ReactNode, type Ref } from 'react';\nimport {\n TextField,\n Label,\n Input as RACInput,\n Text,\n FieldError,\n type TextFieldProps as RACTextFieldProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { fieldClasses } from '../Field/Field';\nimport s from './Input.module.css';\n\n/** Props for {@link Input}, on top of React Aria's `TextField` props. */\nexport type InputProps = Omit<RACTextFieldProps, 'children' | 'className'> & {\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n placeholder?: string;\n leadingAdornment?: ReactNode;\n trailingAdornment?: ReactNode;\n className?: string;\n};\n\n/**\n * Single-line text input wrapping React Aria's TextField. Supplies a\n * default skin against the `--wzl-*` token system, and exposes the\n * familiar label / description / errorMessage / adornment slot shape.\n *\n * `ref` forwards to the underlying `<input>`.\n */\nexport const Input = forwardRef(function Input(\n props: InputProps,\n ref: Ref<HTMLInputElement>,\n) {\n const {\n label,\n description,\n errorMessage,\n placeholder,\n leadingAdornment,\n trailingAdornment,\n className,\n ...textFieldProps\n } = props;\n\n return (\n <TextField {...textFieldProps} className={[s.field, fieldClasses.root, className].filter(Boolean).join(' ')}>\n {label !== undefined && <Label className={fieldClasses.label}>{label}</Label>}\n <div className={s.frame}>\n {leadingAdornment !== undefined && <span className={s.adornment}>{leadingAdornment}</span>}\n <RACInput ref={ref} placeholder={placeholder} />\n {trailingAdornment !== undefined && <span className={s.adornment}>{trailingAdornment}</span>}\n </div>\n {description !== undefined && (\n <Text slot=\"description\" className={fieldClasses.hint}>\n {description}\n </Text>\n )}\n <FieldError className={fieldClasses.error}>{errorMessage}</FieldError>\n </TextField>\n );\n});\n"],"mappings":";;;;;;;;GC+Ba,IAAQ,EAAW,SAC9B,GACA,GACA;CACA,IAAM,EACJ,UACA,gBACA,iBACA,gBACA,qBACA,sBACA,cACA,GAAG,MACD;AAEJ,QACE,kBAAC,GAAD;EAAW,GAAI;EAAgB,WAAW;GAAC,EAAE;GAAO,EAAa;GAAM;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAA3G;GACG,MAAU,KAAA,KAAa,kBAAC,GAAD;IAAO,WAAW,EAAa;cAAQ;IAAc,CAAA;GAC7E,kBAAC,OAAD;IAAK,WAAW,EAAE;cAAlB;KACG,MAAqB,KAAA,KAAa,kBAAC,QAAD;MAAM,WAAW,EAAE;gBAAY;MAAwB,CAAA;KAC1F,kBAAC,GAAD;MAAe;MAAkB;MAAe,CAAA;KAC/C,MAAsB,KAAA,KAAa,kBAAC,QAAD;MAAM,WAAW,EAAE;gBAAY;MAAyB,CAAA;KACxF;;GACL,MAAgB,KAAA,KACf,kBAAC,GAAD;IAAM,MAAK;IAAc,WAAW,EAAa;cAC9C;IACI,CAAA;GAET,kBAAC,GAAD;IAAY,WAAW,EAAa;cAAQ;IAA0B,CAAA;GAC5D;;EAEd"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Keycaps-CFX7UAj8.js","names":[],"sources":["../../src/components/Keycaps/Keycaps.module.css","../../src/components/Keycaps/Keycap.tsx","../../src/components/Keycaps/Keycaps.tsx","../../src/components/Keycaps/keySpecsFromMods.ts"],"sourcesContent":["/* Keystroke \"key cap\" styling — each modifier and key in its own bordered chip. */\n.keys {\n display: inline-flex;\n gap: 3px;\n /* Bottom-align so chips with text labels and chips with icon glyphs\n (arrows, modifier symbols) line up at the same bottom edge. Baseline\n drifts because text baselines sit above icon centers. */\n align-items: flex-end;\n /* When this whole sequence sits inline in surrounding text (e.g.\n \"Press <KeySequence> to confirm.\"), the row anchors to the\n surrounding line's bottom edge, not its baseline. */\n vertical-align: bottom;\n flex-wrap: wrap;\n}\n\n.keysEmpty {\n color: var(--wzl-fg-muted);\n}\n\n.sep {\n color: var(--wzl-fg-muted);\n font-size: 11px;\n line-height: 1;\n}\n\n.key {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n height: 18px;\n padding: 0 4px;\n /* Light face, slightly-darker-than-face border, dark glyph — reads as\n a real keycap rather than a recessed slot in the panel. */\n background: var(--wzl-fg, #e6e7e9);\n border: 1px solid #25272c;\n border-bottom-width: 2px;\n border-radius: 3px;\n color: var(--wzl-surface);\n /* Keycaps are a deliberate exception to the site theme — the design-\n system UI font (often a display face like Oswald) is wrong for\n keyboard chips. Use a neutral sans stack so labels read like real\n key legends. Consumers wanting a specific face per chip pass the\n `font` prop on KeyCap. */\n font-family: ui-sans-serif, system-ui, sans-serif;\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n}\n\n/* Default chip is square — letters, digits, and single glyphs (⎋ ⌫ ↑ etc.)\n sit in a uniform key-cap box. */\n.key[data-kind='square'] {\n width: 18px;\n padding: 0;\n}\n\n/* Modifiers (⌘ ⇪ ⌥ ⌃) are wider to match the visual weight of how they\n appear on a real keyboard — and to differentiate them from the keys\n they modify in a stack. */\n.key[data-kind='modifier'] {\n min-width: 26px;\n padding: 0 6px;\n}\n\n/* Tab / Enter / Space — actual wide keys on a real keyboard. */\n.key[data-kind='wide'] {\n min-width: 32px;\n padding: 0 8px;\n}\n\n/* Optional/inverted (default variant): face flips to dark; legend drops\n to 60% opacity; dotted border drops to 40% opacity. Three soft cues\n stacked for \"may be held but isn't required.\" */\n.key[data-inverted] {\n background: var(--wzl-surface);\n color: color-mix(in srgb, var(--wzl-fg, #e6e7e9) 60%, transparent);\n border-style: dotted;\n border-color: color-mix(in srgb, var(--wzl-fg, #e6e7e9) 40%, transparent);\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n\n/* Minimal variant — no fill, borders and legend follow currentColor.\n Useful inline in colored prose / next to colored badges where the\n chip should take the surrounding text color. */\n.key[data-variant='minimal'] {\n background: transparent;\n border-color: currentColor;\n color: currentColor;\n}\n\n/* Optional + minimal: dotted border at full currentColor, legend at full\n currentColor. The dotted pattern alone carries the \"optional\" cue here\n — minimal's whole point is to defer color to the surrounding context,\n so dimming would fight that. (Default variant uses graded opacity as a\n stacked cue; minimal keeps it crisp.) */\n.key[data-variant='minimal'][data-inverted] {\n border-style: dotted;\n border-color: currentColor;\n color: currentColor;\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n","import type { CSSProperties } from 'react';\nimport s from './Keycaps.module.css';\n\nconst MODIFIER_GLYPHS = new Set(['⌘', '⇪', '⌥', '⌃', '⇧']);\nconst WIDE_GLYPHS = new Set(['⇥', '↵', '␣']);\n\n/**\n * Width class of a keycap: a modifier glyph, a multi-character legend that\n * needs a wider chip, or a single character in a square one.\n */\nexport type KeycapKind = 'modifier' | 'wide' | 'square';\n\n/**\n * Picks the chip width for a legend — modifier glyphs and anything longer\n * than one character get the wider forms.\n */\nexport function inferKeycapKind(label: string): KeycapKind {\n if (MODIFIER_GLYPHS.has(label)) return 'modifier';\n if (WIDE_GLYPHS.has(label)) return 'wide';\n if (label.length > 1) return 'wide';\n return 'square';\n}\n\n/** Visual style of a keycap chip. */\nexport type KeyCapVariant = 'default' | 'minimal';\n\n/** Props for {@link KeyCap}. */\nexport interface KeyCapProps {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** Marks the chip as not required to trigger the action. In the default\n * variant the chip face inverts (dark face / light glyph) for\n * emphasis. In the `'minimal'` variant the chip's border becomes\n * dotted to read as \"may be held, but isn't required.\" */\n inverted?: boolean;\n /** Visual style. `'default'` (default) renders a filled chip; `'minimal'`\n * renders an unfilled chip whose border and legend are `currentColor`\n * — useful inline in colored prose / next to colored badges where the\n * chip should take the surrounding text color. */\n variant?: KeyCapVariant;\n className?: string;\n /** Optional inline style. Useful for one-off width overrides (e.g.\n * building a keyboard-layout where the space bar spans several\n * standard-key widths). The component sets no inline styles of its\n * own — everything else comes from the CSS module. */\n style?: CSSProperties;\n /** Override the chip's font-family. Accepts any CSS font-family\n * string. When omitted, the chip inherits from the design-system\n * UI font token (`--wzl-font-ui`). Useful for one-off cases where\n * a different face is desired — though the canonical move is to\n * override the CSS variable at the consumer's scope, not the prop. */\n font?: string;\n}\n\n/** Single bordered keycap chip for one glyph (modifier or key). Use\n * `KeySequence` to render a full shortcut. */\nexport function KeyCap({ label, inverted = false, variant = 'default', className, style, font }: KeyCapProps) {\n const resolvedStyle = font ? { ...style, fontFamily: font } : style;\n return (\n <kbd\n className={[s.key, className].filter(Boolean).join(' ')}\n data-kind={inferKeycapKind(label)}\n data-variant={variant === 'default' ? undefined : variant}\n data-inverted={inverted || undefined}\n style={resolvedStyle}\n >\n {label}\n </kbd>\n );\n}\n","import { Fragment } from 'react';\nimport s from './Keycaps.module.css';\nimport { KeyCap, inferKeycapKind, type KeyCapVariant } from './Keycap';\n\n/** One key in a shortcut. */\nexport interface KeySpec {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** When true, the chip renders inverted to mark it as not required to\n * trigger the action (e.g. an optional modifier). Defaults to false. */\n optional?: boolean;\n}\n\n/** Props for {@link KeySequence}. */\nexport interface KeySequenceProps {\n /** Keys to render. `undefined` or empty renders a muted em-dash.\n * Modifiers are always rendered first regardless of input order; relative\n * order within each group is preserved. */\n keys: readonly KeySpec[] | undefined;\n /** Character inserted between the trailing modifier chip and the first\n * non-modifier chip (e.g. `'+'` renders `⌘ + K`). `null` or `''`\n * suppresses it. Defaults to `'+'`. */\n separator?: string | null;\n /** Forwarded to every `KeyCap` in the sequence. `'minimal'` renders\n * unfilled chips whose border + legend are `currentColor`. */\n variant?: KeyCapVariant;\n /** Forwarded to every `KeyCap` in the sequence. Overrides the design-\n * system UI font for that chip only. */\n font?: string;\n className?: string;\n}\n\n/** Renders a shortcut as a row of `KeyCap` chips, one per key. Optional\n * keys render inverted to distinguish them from required ones. */\nexport function KeySequence({ keys, separator = '+', variant = 'default', font, className }: KeySequenceProps) {\n if (!keys || keys.length === 0) {\n return <span className={[s.keysEmpty, className].filter(Boolean).join(' ')}>—</span>;\n }\n const ordered = keys\n .map((k, i) => ({ k, i }))\n .sort((a, b) => {\n const am = inferKeycapKind(a.k.label) === 'modifier' ? 0 : 1;\n const bm = inferKeycapKind(b.k.label) === 'modifier' ? 0 : 1;\n return am - bm || a.i - b.i;\n })\n .map(({ k }) => k);\n const sepIdx = ordered.findIndex((k) => inferKeycapKind(k.label) !== 'modifier');\n const showSep = !!separator && sepIdx > 0 && sepIdx < ordered.length;\n return (\n <span className={[s.keys, className].filter(Boolean).join(' ')}>\n {ordered.map((k, i) => (\n <Fragment key={i}>\n {showSep && i === sepIdx ? <span className={s.sep}>{separator}</span> : null}\n <KeyCap label={k.label} inverted={k.optional ?? false} variant={variant} font={font} />\n </Fragment>\n ))}\n </span>\n );\n}\n","import type { KeySpec } from './Keycaps';\n\n/** Logical modifier name. Matches the kit's `ModifierKey` in shape — kept as a\n * local type so `weasel-ui` stays independent of `@weasel-js/core`. */\nexport type LogicalMod = 'mod' | 'shift' | 'alt' | 'ctrl' | 'meta';\n\n/** Detected (or overridden) platform. `'mod'` resolves to ⌘ on macOS,\n * Ctrl on Windows / Linux. */\nexport type Platform = 'macos' | 'windows' | 'linux';\n\n/** Visual form of a modifier or named-key label.\n *\n * - `'auto'` (default): the per-entry, per-platform default — whatever\n * label is actually printed on the physical key. macOS keys show the\n * Apple glyphs (⌘ ⌥ ⌃ ⇧ ⎋ ↵ ⇥). Windows keys mostly show text\n * (Ctrl, Alt, Shift) BUT the Win key shows its logo (⊞) and the\n * context-menu key shows ▤. Linux mirrors Windows with Super (⊞).\n * - `'symbol'` forces the Apple-style glyph everywhere a symbolic form\n * exists. Entries without a widely-recognized symbol still fall\n * back to text.\n * - `'text'` always spells the label out (Cmd / Option / Esc / Enter). */\nexport type LegendStyle = 'auto' | 'symbol' | 'text';\n\n/** A modifier to render, named platform-independently. */\nexport interface LogicalModSpec {\n name: LogicalMod;\n /** Marks this modifier as optional (may be held but isn't required).\n * Forwarded as the resulting `KeySpec.optional`. */\n optional?: boolean;\n}\n\n/** Options for {@link keySpecsFromMods}. */\nexport interface KeySpecsFromModsOptions {\n /** Override OS detection. Defaults to the detected platform, or\n * `'macos'` when detection is unavailable (e.g. in tests, or when\n * `navigator` is missing). */\n platform?: Platform;\n /** Defaults to `'auto'` (symbol on macOS, text everywhere else). Pass\n * `'symbol'` or `'text'` to force a specific style regardless of\n * platform. */\n legend?: LegendStyle;\n}\n\nconst MOD_BY_PLATFORM: Record<LogicalMod, Record<Platform, Record<LegendStyle, string>>> = {\n mod: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n shift: {\n macos: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n windows: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n linux: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n },\n alt: {\n macos: { auto: '⌥', symbol: '⌥', text: 'Option' },\n windows: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n linux: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n },\n ctrl: {\n macos: { auto: '⌃', symbol: '⌃', text: 'Control' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n // Windows/Linux Meta has a recognized symbol on the physical key (⊞ Win\n // logo / Super logo), so `auto` shows it. Use `text` for Win / Super.\n meta: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: '⊞', symbol: '⊞', text: 'Win' },\n linux: { auto: '⊞', symbol: '⊞', text: 'Super' },\n },\n};\n\n/** Detect the user's OS from the browser environment. UA sniffing — not\n * 100% reliable, but adequate for picking a modifier-glyph convention.\n * Falls back to `'macos'` (matches the kit's docs convention) when\n * `navigator` is unavailable. */\nexport function detectPlatform(): Platform {\n if (typeof navigator === 'undefined') return 'macos';\n // Prefer the modern userAgentData when available (Chromium-only today).\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n const raw = (uaData?.platform ?? navigator.userAgent ?? '').toLowerCase();\n if (raw.includes('mac') || raw.includes('darwin') || raw.includes('iphone') || raw.includes('ipad')) return 'macos';\n if (raw.includes('win')) return 'windows';\n if (raw.includes('linux') || raw.includes('x11')) return 'linux';\n return 'macos';\n}\n\n/**\n * Map a list of **logical** modifiers (`'mod'`, `'shift'`, …) to **visual**\n * `KeySpec`s appropriate for the current platform.\n *\n * The kit-side gesture grammar uses logical names so the same route reads\n * correctly on every OS — `'mod'` means \"Cmd on Mac, Ctrl on Win/Linux\".\n * `KeySequence` is purely visual and renders the labels you give it; this\n * helper is the bridge.\n *\n * ```ts\n * <KeySequence\n * keys={keySpecsFromMods([{ name: 'mod' }, { name: 'shift', optional: true }])}\n * />\n * ```\n *\n * On a Mac: renders `⌘ ⇧`. On Windows: renders `Ctrl Shift`. Pass an\n * explicit `platform` to override detection (e.g. for docs that always\n * show the macOS form). Pass `legend: 'text'` to force \"Cmd\" over \"⌘\"\n * even on macOS.\n */\nexport function keySpecsFromMods(\n mods: readonly LogicalModSpec[],\n opts: KeySpecsFromModsOptions = {},\n): readonly KeySpec[] {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n return mods.map((m) => {\n const label = MOD_BY_PLATFORM[m.name][platform][legend];\n return m.optional ? { label, optional: true } : { label };\n });\n}\n\n/** Per-platform × per-legend table for named, non-modifier keys. `auto`\n * is whatever's printed on the physical key for that platform. Arrows\n * are universal symbols on every platform. */\nconst NAMED_KEY: Record<string, Record<Platform, Record<LegendStyle, string>>> = {\n Escape: { macos: { auto: '⎋', symbol: '⎋', text: 'Esc' }, windows: { auto: 'Esc', symbol: 'Esc', text: 'Esc' }, linux: { auto: 'Esc', symbol: 'Esc', text: 'Esc' } },\n Enter: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Return: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Tab: { macos: { auto: '⇥', symbol: '⇥', text: 'Tab' }, windows: { auto: 'Tab', symbol: 'Tab', text: 'Tab' }, linux: { auto: 'Tab', symbol: 'Tab', text: 'Tab' } },\n Space: { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n ' ': { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n Backspace: { macos: { auto: '⌫', symbol: '⌫', text: 'Backspace' }, windows: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' }, linux: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' } },\n Delete: { macos: { auto: '⌦', symbol: '⌦', text: 'Delete' }, windows: { auto: 'Delete', symbol: 'Delete', text: 'Delete' }, linux: { auto: 'Delete', symbol: 'Delete', text: 'Delete' } },\n // Context-menu key (the right-Ctrl-area key on Windows / Linux keyboards\n // with a ▤ icon). Mac has no equivalent; falls back to text 'Menu'.\n ContextMenu: { macos: { auto: 'Menu', symbol: 'Menu', text: 'Menu' }, windows: { auto: '▤', symbol: '▤', text: 'Menu' }, linux: { auto: '▤', symbol: '▤', text: 'Menu' } },\n ArrowUp: { macos: { auto: '↑', symbol: '↑', text: '↑' }, windows: { auto: '↑', symbol: '↑', text: '↑' }, linux: { auto: '↑', symbol: '↑', text: '↑' } },\n ArrowDown: { macos: { auto: '↓', symbol: '↓', text: '↓' }, windows: { auto: '↓', symbol: '↓', text: '↓' }, linux: { auto: '↓', symbol: '↓', text: '↓' } },\n ArrowLeft: { macos: { auto: '←', symbol: '←', text: '←' }, windows: { auto: '←', symbol: '←', text: '←' }, linux: { auto: '←', symbol: '←', text: '←' } },\n ArrowRight: { macos: { auto: '→', symbol: '→', text: '→' }, windows: { auto: '→', symbol: '→', text: '→' }, linux: { auto: '→', symbol: '→', text: '→' } },\n};\n\n/**\n * Render a raw `KeyboardEvent.key` value as a platform-appropriate\n * `KeySpec`. Named non-modifier keys (Esc, Enter, Tab, Space, Backspace,\n * Delete, arrows) get the platform's conventional form. Letter / digit /\n * other keys pass through upper-cased.\n *\n * ```ts\n * keySpecFromKey('Escape', { platform: 'macos' }) // { label: '⎋' }\n * keySpecFromKey('Escape', { platform: 'windows' }) // { label: 'Esc' }\n * keySpecFromKey('p') // { label: 'P' }\n * ```\n *\n * Symbol mode is only meaningful on macOS — Windows / Linux keyboards\n * print the text form on the physical key, so symbol mode there falls\n * back to text.\n */\nexport function keySpecFromKey(\n raw: string,\n opts: KeySpecsFromModsOptions & { optional?: boolean } = {},\n): KeySpec {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n const entry = NAMED_KEY[raw];\n const label = entry ? entry[platform][legend] : raw.length === 1 ? raw.toUpperCase() : raw;\n return opts.optional ? { label, optional: true } : { label };\n}\n"],"mappings":"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"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./Field-VQwmrIna.js";
|
|
2
|
-
import { forwardRef as t } from "react";
|
|
3
|
-
import { Button as n, FieldError as r, Group as i, Input as a, Label as o, NumberField as s, Text as c } from "react-aria-components";
|
|
4
|
-
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
|
-
var d = {
|
|
6
|
-
field: "_field_e75yx_1",
|
|
7
|
-
frame: "_frame_e75yx_9",
|
|
8
|
-
steppers: "_steppers_e75yx_57",
|
|
9
|
-
stepper: "_stepper_e75yx_57"
|
|
10
|
-
}, f = t(function(t, f) {
|
|
11
|
-
let { label: p, description: m, errorMessage: h, hideSteppers: g, placeholder: _, className: v, ...y } = t;
|
|
12
|
-
return /* @__PURE__ */ u(s, {
|
|
13
|
-
...y,
|
|
14
|
-
className: [
|
|
15
|
-
d.field,
|
|
16
|
-
e.root,
|
|
17
|
-
v
|
|
18
|
-
].filter(Boolean).join(" "),
|
|
19
|
-
children: [
|
|
20
|
-
p !== void 0 && /* @__PURE__ */ l(o, {
|
|
21
|
-
className: e.label,
|
|
22
|
-
children: p
|
|
23
|
-
}),
|
|
24
|
-
/* @__PURE__ */ u(i, {
|
|
25
|
-
className: d.frame,
|
|
26
|
-
children: [/* @__PURE__ */ l(a, {
|
|
27
|
-
ref: f,
|
|
28
|
-
placeholder: _
|
|
29
|
-
}), !g && /* @__PURE__ */ u("div", {
|
|
30
|
-
className: d.steppers,
|
|
31
|
-
children: [/* @__PURE__ */ l(n, {
|
|
32
|
-
slot: "increment",
|
|
33
|
-
className: d.stepper,
|
|
34
|
-
"aria-label": "Increment",
|
|
35
|
-
children: "▲"
|
|
36
|
-
}), /* @__PURE__ */ l(n, {
|
|
37
|
-
slot: "decrement",
|
|
38
|
-
className: d.stepper,
|
|
39
|
-
"aria-label": "Decrement",
|
|
40
|
-
children: "▼"
|
|
41
|
-
})]
|
|
42
|
-
})]
|
|
43
|
-
}),
|
|
44
|
-
m !== void 0 && /* @__PURE__ */ l(c, {
|
|
45
|
-
slot: "description",
|
|
46
|
-
className: e.hint,
|
|
47
|
-
children: m
|
|
48
|
-
}),
|
|
49
|
-
/* @__PURE__ */ l(r, {
|
|
50
|
-
className: e.error,
|
|
51
|
-
children: h
|
|
52
|
-
})
|
|
53
|
-
]
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
//#endregion
|
|
57
|
-
export { f as t };
|
|
58
|
-
|
|
59
|
-
//# sourceMappingURL=NumberField-BbzI0GtU.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NumberField-BbzI0GtU.js","names":[],"sources":["../../src/components/NumberField/NumberField.module.css","../../src/components/NumberField/NumberField.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n width: 100%;\n min-width: 0;\n gap: 4px;\n}\n\n.frame {\n display: flex;\n align-items: stretch;\n height: 24px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: 13px;\n line-height: 1;\n overflow: hidden;\n transition: border-color var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast);\n}\n\n.frame:focus-within {\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n.field[data-invalid] .frame {\n border-color: var(--wzl-danger, #ff5b5b);\n}\n\n.field[data-disabled] .frame {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.frame input {\n flex: 1;\n min-width: 0;\n background: transparent;\n border: none;\n outline: none;\n color: inherit;\n font: inherit;\n padding: 0 8px;\n text-align: right;\n -moz-appearance: textfield;\n}\n\n.frame input::-webkit-outer-spin-button,\n.frame input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.steppers {\n display: flex;\n flex-direction: column;\n border-left: 1px solid var(--wzl-border);\n}\n\n.stepper {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n flex: 1;\n background: transparent;\n border: none;\n color: var(--wzl-fg-muted);\n cursor: pointer;\n padding: 0;\n font-size: 9px;\n line-height: 1;\n}\n\n.stepper:not(:last-child) {\n border-bottom: 1px solid var(--wzl-border);\n}\n\n.stepper[data-hovered]:not([data-disabled]) {\n background: color-mix(in srgb, var(--wzl-fg) 10%, transparent);\n color: var(--wzl-fg);\n}\n\n.stepper[data-pressed]:not([data-disabled]) {\n background: color-mix(in srgb, var(--wzl-fg) 18%, transparent);\n}\n\n.stepper[data-disabled] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n","import { forwardRef, type ReactNode, type Ref } from 'react';\nimport {\n NumberField as RACNumberField,\n Label,\n Input as RACInput,\n Group,\n Button as RACButton,\n Text,\n FieldError,\n type NumberFieldProps as RACNumberFieldProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { fieldClasses } from '../Field/Field';\nimport s from './NumberField.module.css';\n\n/** Props for {@link NumberField}, on top of React Aria's `NumberField` props. */\nexport type NumberFieldProps = Omit<RACNumberFieldProps, 'children' | 'className'> & {\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n /** Hide the up/down stepper buttons. Defaults to false. */\n hideSteppers?: boolean;\n /** Native input placeholder — e.g. `'Mixed'` for a multi-selection\n * editor with no shared value. */\n placeholder?: string;\n className?: string;\n};\n\n/**\n * Numeric input with stepper buttons, wrapping React Aria's NumberField and\n * supplying the same label / description / errorMessage slots as `Input`.\n * Arrow keys and scroll step the value; parsing and formatting are React\n * Aria's.\n *\n * `ref` forwards to the underlying `<input>`.\n */\nexport const NumberField = forwardRef(function NumberField(\n props: NumberFieldProps,\n ref: Ref<HTMLInputElement>,\n) {\n const { label, description, errorMessage, hideSteppers, placeholder, className, ...rest } = props;\n return (\n <RACNumberField\n {...rest}\n className={[s.field, fieldClasses.root, className].filter(Boolean).join(' ')}\n >\n {label !== undefined && <Label className={fieldClasses.label}>{label}</Label>}\n <Group className={s.frame}>\n <RACInput ref={ref} placeholder={placeholder} />\n {!hideSteppers && (\n <div className={s.steppers}>\n <RACButton slot=\"increment\" className={s.stepper} aria-label=\"Increment\">▲</RACButton>\n <RACButton slot=\"decrement\" className={s.stepper} aria-label=\"Decrement\">▼</RACButton>\n </div>\n )}\n </Group>\n {description !== undefined && (\n <Text slot=\"description\" className={fieldClasses.hint}>\n {description}\n </Text>\n )}\n <FieldError className={fieldClasses.error}>{errorMessage}</FieldError>\n </RACNumberField>\n );\n});\n"],"mappings":";;;;;;;;;GCoCa,IAAc,EAAW,SACpC,GACA,GACA;CACA,IAAM,EAAE,UAAO,gBAAa,iBAAc,iBAAc,gBAAa,cAAW,GAAG,MAAS;AAC5F,QACE,kBAAC,GAAD;EACE,GAAI;EACJ,WAAW;GAAC,EAAE;GAAO,EAAa;GAAM;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAF9E;GAIG,MAAU,KAAA,KAAa,kBAAC,GAAD;IAAO,WAAW,EAAa;cAAQ;IAAc,CAAA;GAC7E,kBAAC,GAAD;IAAO,WAAW,EAAE;cAApB,CACE,kBAAC,GAAD;KAAe;KAAkB;KAAe,CAAA,EAC/C,CAAC,KACA,kBAAC,OAAD;KAAK,WAAW,EAAE;eAAlB,CACE,kBAAC,GAAD;MAAW,MAAK;MAAY,WAAW,EAAE;MAAS,cAAW;gBAAY;MAAa,CAAA,EACtF,kBAAC,GAAD;MAAW,MAAK;MAAY,WAAW,EAAE;MAAS,cAAW;gBAAY;MAAa,CAAA,CAClF;OAEF;;GACP,MAAgB,KAAA,KACf,kBAAC,GAAD;IAAM,MAAK;IAAc,WAAW,EAAa;cAC9C;IACI,CAAA;GAET,kBAAC,GAAD;IAAY,WAAW,EAAa;cAAQ;IAA0B,CAAA;GACvD;;EAEnB"}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { n as e, t } from "./Tooltip-DXJbdR5B.js";
|
|
2
|
-
import { t as n } from "./Checkbox-KQ5L8APP.js";
|
|
3
|
-
import { t as r } from "./ColorField-ykpiD3XU.js";
|
|
4
|
-
import { t as i } from "./Input-DpkwYtUY.js";
|
|
5
|
-
import { t as a } from "./NumberField-BbzI0GtU.js";
|
|
6
|
-
import { n as o, t as s } from "./RadioGroup-CIpHr3g6.js";
|
|
7
|
-
import { t as c } from "./RangeSlider-CaDogGTj.js";
|
|
8
|
-
import { t as l } from "./Select-CHsuQCp0.js";
|
|
9
|
-
import { t as u } from "./Switch-JyVSSAzC.js";
|
|
10
|
-
import { t as d } from "./Dialog-CqwdJv_t.js";
|
|
11
|
-
import { useMemo as f } from "react";
|
|
12
|
-
import { Focusable as p } from "react-aria-components";
|
|
13
|
-
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
14
|
-
//#region src/components/Prefs/schema.ts
|
|
15
|
-
function _(e) {
|
|
16
|
-
return "kind" in e;
|
|
17
|
-
}
|
|
18
|
-
function v(e, t) {
|
|
19
|
-
let n = e;
|
|
20
|
-
for (let e of t.split(".")) {
|
|
21
|
-
if (typeof n != "object" || !n) return;
|
|
22
|
-
n = n[e];
|
|
23
|
-
}
|
|
24
|
-
return n;
|
|
25
|
-
}
|
|
26
|
-
function y(e, t) {
|
|
27
|
-
if (_(e)) return e.hidden && !t ? null : e;
|
|
28
|
-
let n = e, r = {};
|
|
29
|
-
for (let [e, i] of Object.entries(n.children)) {
|
|
30
|
-
let n = y(i, t);
|
|
31
|
-
n && (r[e] = n);
|
|
32
|
-
}
|
|
33
|
-
return Object.keys(r).length === 0 ? null : {
|
|
34
|
-
...e,
|
|
35
|
-
children: r
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
var b = {
|
|
39
|
-
columns: "_columns_y5ks5_5",
|
|
40
|
-
column: "_column_y5ks5_5",
|
|
41
|
-
panel: "_panel_y5ks5_23",
|
|
42
|
-
subpanel: "_subpanel_y5ks5_33",
|
|
43
|
-
groupHeader: "_groupHeader_y5ks5_44",
|
|
44
|
-
groupTitle: "_groupTitle_y5ks5_57",
|
|
45
|
-
groupDesc: "_groupDesc_y5ks5_72",
|
|
46
|
-
rows: "_rows_y5ks5_79",
|
|
47
|
-
row: "_row_y5ks5_79",
|
|
48
|
-
rowLabel: "_rowLabel_y5ks5_95",
|
|
49
|
-
help: "_help_y5ks5_104",
|
|
50
|
-
rowControl: "_rowControl_y5ks5_128",
|
|
51
|
-
textarea: "_textarea_y5ks5_135",
|
|
52
|
-
unrenderable: "_unrenderable_y5ks5_147",
|
|
53
|
-
titleRow: "_titleRow_y5ks5_154"
|
|
54
|
-
};
|
|
55
|
-
//#endregion
|
|
56
|
-
//#region src/components/Prefs/PrefsForm.tsx
|
|
57
|
-
function x(e) {
|
|
58
|
-
let { schema: t, values: n, onChange: r, renderers: i, showHidden: a = !1, className: o } = e, s = f(() => y(t, a), [t, a]), c = {
|
|
59
|
-
values: n,
|
|
60
|
-
onChange: r,
|
|
61
|
-
renderers: i
|
|
62
|
-
};
|
|
63
|
-
return /* @__PURE__ */ h("div", {
|
|
64
|
-
className: [b.columns, o].filter(Boolean).join(" "),
|
|
65
|
-
children: Object.entries(s?.children ?? {}).map(([e, t]) => /* @__PURE__ */ h("div", {
|
|
66
|
-
className: b.column,
|
|
67
|
-
children: _(t) ? /* @__PURE__ */ h(C, {
|
|
68
|
-
ctx: c,
|
|
69
|
-
path: e,
|
|
70
|
-
pref: t
|
|
71
|
-
}) : /* @__PURE__ */ h(S, {
|
|
72
|
-
ctx: c,
|
|
73
|
-
group: t,
|
|
74
|
-
path: e,
|
|
75
|
-
depth: 0
|
|
76
|
-
})
|
|
77
|
-
}, e))
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
function S({ ctx: e, group: t, path: n, depth: r }) {
|
|
81
|
-
return /* @__PURE__ */ g("div", {
|
|
82
|
-
className: r === 0 ? b.panel : b.subpanel,
|
|
83
|
-
children: [/* @__PURE__ */ g("div", {
|
|
84
|
-
className: b.groupHeader,
|
|
85
|
-
children: [/* @__PURE__ */ h("h3", {
|
|
86
|
-
className: b.groupTitle,
|
|
87
|
-
children: t.name
|
|
88
|
-
}), t.description !== void 0 && /* @__PURE__ */ h("p", {
|
|
89
|
-
className: b.groupDesc,
|
|
90
|
-
children: t.description
|
|
91
|
-
})]
|
|
92
|
-
}), /* @__PURE__ */ h("div", {
|
|
93
|
-
className: b.rows,
|
|
94
|
-
children: Object.entries(t.children).map(([t, i]) => {
|
|
95
|
-
let a = `${n}.${t}`;
|
|
96
|
-
return _(i) ? /* @__PURE__ */ h(C, {
|
|
97
|
-
ctx: e,
|
|
98
|
-
path: a,
|
|
99
|
-
pref: i
|
|
100
|
-
}, t) : /* @__PURE__ */ h(S, {
|
|
101
|
-
ctx: e,
|
|
102
|
-
group: i,
|
|
103
|
-
path: a,
|
|
104
|
-
depth: r + 1
|
|
105
|
-
}, t);
|
|
106
|
-
})
|
|
107
|
-
})]
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function C({ ctx: n, path: r, pref: i }) {
|
|
111
|
-
let a = v(n.values, r), o = {
|
|
112
|
-
path: r,
|
|
113
|
-
pref: i,
|
|
114
|
-
value: a === void 0 ? i.default : a,
|
|
115
|
-
setValue: (e) => n.onChange(r, e)
|
|
116
|
-
}, s = n.renderers?.[i.kind], c = s ? s(o) : w(o);
|
|
117
|
-
return s && c === null ? null : i.block ? /* @__PURE__ */ h(m, { children: c }) : /* @__PURE__ */ g("label", {
|
|
118
|
-
className: b.row,
|
|
119
|
-
children: [/* @__PURE__ */ g("span", {
|
|
120
|
-
className: b.rowLabel,
|
|
121
|
-
children: [i.name, i.description ? /* @__PURE__ */ g(e, { children: [/* @__PURE__ */ h(p, { children: /* @__PURE__ */ h("button", {
|
|
122
|
-
type: "button",
|
|
123
|
-
className: b.help,
|
|
124
|
-
"aria-label": `About ${i.name}`,
|
|
125
|
-
children: "ⓘ"
|
|
126
|
-
}) }), /* @__PURE__ */ h(t, { children: i.description })] }) : null]
|
|
127
|
-
}), /* @__PURE__ */ h("span", {
|
|
128
|
-
className: b.rowControl,
|
|
129
|
-
children: c
|
|
130
|
-
})]
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function w(e) {
|
|
134
|
-
let { pref: t, value: d, setValue: f } = e;
|
|
135
|
-
switch (t.kind) {
|
|
136
|
-
case "boolean": {
|
|
137
|
-
let e = t, r = !!d;
|
|
138
|
-
return e.control === "switch" ? /* @__PURE__ */ h(u, {
|
|
139
|
-
isSelected: r,
|
|
140
|
-
onChange: f,
|
|
141
|
-
"aria-label": e.name
|
|
142
|
-
}) : /* @__PURE__ */ h(n, {
|
|
143
|
-
isSelected: r,
|
|
144
|
-
onChange: f,
|
|
145
|
-
"aria-label": e.name
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
case "number": {
|
|
149
|
-
let e = t, n = typeof d == "number" && Number.isFinite(d) ? d : 0;
|
|
150
|
-
return e.control === "slider" ? /* @__PURE__ */ h(c, {
|
|
151
|
-
value: n,
|
|
152
|
-
onChange: (e) => f(typeof e == "number" ? e : e[0]),
|
|
153
|
-
minValue: e.min,
|
|
154
|
-
maxValue: e.max,
|
|
155
|
-
step: e.step ?? 1,
|
|
156
|
-
"aria-label": e.name
|
|
157
|
-
}) : /* @__PURE__ */ h(a, {
|
|
158
|
-
value: n,
|
|
159
|
-
onChange: f,
|
|
160
|
-
minValue: e.min,
|
|
161
|
-
maxValue: e.max,
|
|
162
|
-
step: e.step ?? 1,
|
|
163
|
-
"aria-label": e.name
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
case "string": {
|
|
167
|
-
let e = t, n = typeof d == "string" ? d : "";
|
|
168
|
-
return e.control === "textarea" ? /* @__PURE__ */ h("textarea", {
|
|
169
|
-
className: b.textarea,
|
|
170
|
-
value: n,
|
|
171
|
-
onChange: (e) => f(e.target.value),
|
|
172
|
-
"aria-label": e.name,
|
|
173
|
-
rows: 3
|
|
174
|
-
}) : /* @__PURE__ */ h(i, {
|
|
175
|
-
value: n,
|
|
176
|
-
onChange: f,
|
|
177
|
-
"aria-label": e.name
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
case "enum": {
|
|
181
|
-
let e = t, n = typeof d == "string" ? d : e.default;
|
|
182
|
-
return e.control === "radio" ? /* @__PURE__ */ h(o, {
|
|
183
|
-
value: n,
|
|
184
|
-
onChange: (e) => f(e),
|
|
185
|
-
"aria-label": e.name,
|
|
186
|
-
children: e.options.map((e) => /* @__PURE__ */ h(s, {
|
|
187
|
-
value: e.value,
|
|
188
|
-
children: e.label
|
|
189
|
-
}, e.value))
|
|
190
|
-
}) : /* @__PURE__ */ h(l, {
|
|
191
|
-
options: e.options.map((e) => ({
|
|
192
|
-
value: e.value,
|
|
193
|
-
label: e.label
|
|
194
|
-
})),
|
|
195
|
-
selectedKey: n,
|
|
196
|
-
onSelectionChange: (e) => f(e),
|
|
197
|
-
"aria-label": e.name
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
case "color": {
|
|
201
|
-
let e = t;
|
|
202
|
-
return /* @__PURE__ */ h(r, {
|
|
203
|
-
value: typeof d == "string" ? d : e.default,
|
|
204
|
-
alpha: e.alpha,
|
|
205
|
-
onChange: f,
|
|
206
|
-
"aria-label": e.name
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
default: return /* @__PURE__ */ g("span", {
|
|
210
|
-
className: b.unrenderable,
|
|
211
|
-
children: [
|
|
212
|
-
"(",
|
|
213
|
-
t.kind,
|
|
214
|
-
": no renderer)"
|
|
215
|
-
]
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
//#endregion
|
|
220
|
-
//#region src/components/Prefs/PrefsDialog.tsx
|
|
221
|
-
function T(e) {
|
|
222
|
-
let { isOpen: t, onOpenChange: n, title: r, headerExtra: i, dialogClassName: a, ...o } = e;
|
|
223
|
-
return /* @__PURE__ */ h(d, {
|
|
224
|
-
isOpen: t,
|
|
225
|
-
onOpenChange: n,
|
|
226
|
-
"aria-label": typeof r == "string" ? r : o.schema.name,
|
|
227
|
-
className: a,
|
|
228
|
-
title: i === void 0 ? r ?? o.schema.name : /* @__PURE__ */ g("span", {
|
|
229
|
-
className: b.titleRow,
|
|
230
|
-
children: [/* @__PURE__ */ h("span", { children: r ?? o.schema.name }), i]
|
|
231
|
-
}),
|
|
232
|
-
children: /* @__PURE__ */ h(x, { ...o })
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
//#endregion
|
|
236
|
-
export { y as a, v as i, x as n, _ as r, T as t };
|
|
237
|
-
|
|
238
|
-
//# sourceMappingURL=Prefs-BMR9wMiZ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Prefs-BMR9wMiZ.js","names":[],"sources":["../../src/components/Prefs/schema.ts","../../src/components/Prefs/Prefs.module.css","../../src/components/Prefs/PrefsForm.tsx","../../src/components/Prefs/PrefsDialog.tsx"],"sourcesContent":["// Preference-schema vocabulary for PrefsForm / PrefsDialog.\n//\n// Deliberately field-compatible with core's `ToolPref*` family\n// (src/tools/prefs.ts): this schema module deliberately avoids importing\n// @weasel-js/core, so the contract is structural — a `ToolPrefGroup` (and\n// any host-app superset, like WeaselDraw's registry) assigns into\n// `PrefGroup` with no import and no cast. Keep the two in sync\n// field-for-field.\n\n/** Control-presentation hints per kind — visually-equivalent renderings\n * of the same value type. The persisted value is unchanged either way. */\nexport type PrefNumberControl = 'input' | 'slider';\n/** Which control renders a {@link PrefBoolean}. */\nexport type PrefBooleanControl = 'checkbox' | 'switch';\n/** Which control renders a {@link PrefString}. */\nexport type PrefStringControl = 'input' | 'textarea';\n/** Which control renders a {@link PrefEnum}. */\nexport type PrefEnumControl = 'select' | 'radio';\n\ninterface PrefBase<K extends string, Value> {\n kind: K;\n /** Human-readable label, e.g. \"Show grid\". */\n name: string;\n /** Longer help text — surfaces as a tooltip on the row label. */\n description: string;\n /** Fallback when `values` holds nothing at this leaf's path. */\n default: Value;\n /** Omitted from the form unless `showHidden` is set. */\n hidden?: boolean;\n /** Render the control full-width with no label/tooltip row — for\n * controls that supply their own chrome (embedded sub-panel editors).\n * The `description` still applies wherever the renderer surfaces it. */\n block?: boolean;\n /** Row-pairing hint for compact property UIs (`SelectionPanel`):\n * leaves sharing a `pair` id render side-by-side on one row labeled\n * with the `pair` string. Purely presentational. */\n pair?: string;\n}\n\n/** Display-unit conversion for number leaves whose stored value uses a\n * canonical unit the user shouldn't see (radians → degrees). Mirrors\n * core's `ToolPrefNumberUnit`. */\nexport interface PrefNumberUnit {\n toDisplay: (stored: number) => number;\n fromDisplay: (display: number) => number;\n suffix?: string;\n}\n\n/**\n * A numeric preference. `unit` lets the stored value stay in a canonical unit\n * while the user edits a converted one.\n */\nexport interface PrefNumber extends PrefBase<'number', number> {\n min?: number;\n max?: number;\n step?: number;\n control?: PrefNumberControl;\n unit?: PrefNumberUnit;\n}\n/** A boolean preference. */\nexport interface PrefBoolean extends PrefBase<'boolean', boolean> {\n control?: PrefBooleanControl;\n}\n/** A free-text preference. */\nexport interface PrefString extends PrefBase<'string', string> {\n control?: PrefStringControl;\n}\n/** A preference chosen from a fixed set of options. */\nexport interface PrefEnum<T extends string = string> extends PrefBase<'enum', T> {\n options: readonly { value: T; label: string }[];\n control?: PrefEnumControl;\n}\n\n/** A color preference, stored as a hex string. */\nexport interface PrefColor extends PrefBase<'color', string> {\n /** Value is `#rrggbb`, or `#rrggbbaa` when `alpha` is set. */\n alpha?: boolean;\n}\n\n/** The leaf kinds `PrefsForm` renders without a custom renderer. */\nexport type BuiltinPref = PrefNumber | PrefBoolean | PrefString | PrefEnum | PrefColor;\n\n/**\n * Open leaf: any node with a `kind` the form doesn't know renders via the\n * `renderers` map (`renderers[kind]`). App schemas keep their extra fields\n * (e.g. a registry-enum's `source`/`filter`) — renderers receive the node\n * and narrow it themselves. Deliberately NOT index-signatured so concrete\n * app interfaces stay assignable.\n */\nexport interface PrefCustom extends PrefBase<string, unknown> {}\n\n/**\n * Any leaf in a preference schema — a built-in kind, or an app-defined one\n * rendered through `PrefsFormProps.renderers`.\n */\nexport type PrefLeaf = BuiltinPref | PrefCustom;\n\n/** Nestable group: branch nodes in the schema tree. */\nexport interface PrefGroup {\n name: string;\n description?: string;\n children: Record<string, PrefLeaf | PrefGroup>;\n}\n\n/** Distinguishes a leaf from a group while walking a schema tree. */\nexport function isPrefLeaf(node: PrefLeaf | PrefGroup): node is PrefLeaf {\n return 'kind' in node;\n}\n\n/** Get the value at a dotted path inside a nested value tree. Returns\n * `undefined` when a segment is missing or hits a non-object. */\nexport function prefValueAtPath(values: unknown, path: string): unknown {\n let cur: unknown = values;\n for (const seg of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return cur;\n}\n\n/**\n * Recursively drop `hidden` leaves (unless `showHidden`), pruning groups\n * that end up empty. Returns null when the entire subtree is hidden.\n */\nexport function visiblePrefSubtree<T extends PrefLeaf | PrefGroup>(\n node: T,\n showHidden: boolean,\n): T | null {\n if (isPrefLeaf(node)) return node.hidden && !showHidden ? null : node;\n const group = node as PrefGroup;\n const children: Record<string, PrefLeaf | PrefGroup> = {};\n for (const [key, child] of Object.entries(group.children)) {\n const kept = visiblePrefSubtree(child, showHidden);\n if (kept) children[key] = kept;\n }\n if (Object.keys(children).length === 0) return null;\n return { ...node, children };\n}\n","/* Ported from WeaselDraw's wd-prefs-* rules (apps/draw/src/app.css),\n * generalized onto theme tokens. Column width is overridable via\n * --wzl-prefs-column-width at any ancestor scope. */\n\n.columns {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: 12px;\n overflow-y: auto;\n padding-right: 4px;\n}\n\n.column {\n flex: 0 0 var(--wzl-prefs-column-width, 300px);\n width: var(--wzl-prefs-column-width, 300px);\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.panel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n\n.subpanel {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n padding: 8px 8px 8px 10px;\n background: var(--wzl-surface-sunken);\n border-left: 2px solid var(--wzl-border);\n border-radius: 2px;\n}\n\n.groupHeader {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding-bottom: 4px;\n border-bottom: 1px solid var(--wzl-border);\n}\n\n.subpanel .groupHeader {\n border-bottom: none;\n padding-bottom: 2px;\n}\n\n.groupTitle {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--wzl-fg);\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.subpanel .groupTitle {\n font-size: 11px;\n text-transform: none;\n letter-spacing: 0;\n}\n\n.groupDesc {\n margin: 0;\n font-size: 11px;\n color: var(--wzl-fg-subtle);\n line-height: 1.35;\n}\n\n.rows {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n font-size: 12px;\n color: var(--wzl-fg);\n cursor: default;\n}\n\n.rowLabel {\n flex: 1 1 auto;\n min-width: 0;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n/* Description affordance — quiet until hovered/focused. */\n.help {\n flex: 0 0 auto;\n padding: 0;\n border: none;\n background: none;\n color: var(--wzl-fg-subtle);\n font-size: 11px;\n line-height: 1;\n cursor: help;\n border-radius: var(--wzl-radius-sm);\n}\n\n.help:hover {\n color: var(--wzl-fg);\n}\n\n.help:focus-visible {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: 1px;\n color: var(--wzl-fg);\n}\n\n/* Control slot — fixed width so the label can take the rest of the row.\n * Kit form controls render as block-level flex columns that fill it. */\n.rowControl {\n flex: 0 0 110px;\n min-width: 0;\n display: flex;\n align-items: center;\n}\n\n.textarea {\n width: 100%;\n padding: 4px 8px;\n background: var(--wzl-surface-sunken);\n color: var(--wzl-fg);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n font: inherit;\n font-size: 12px;\n resize: vertical;\n}\n\n.unrenderable {\n font-family: var(--wzl-font-mono);\n font-size: 11px;\n color: var(--wzl-fg-subtle);\n}\n\n/* PrefsDialog header row: title text + optional headerExtra chrome. */\n.titleRow {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.titleRow > span:first-child {\n flex: 1;\n min-width: 0;\n}\n","import { useMemo, type ReactNode } from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { Checkbox } from '../Checkbox';\nimport { ColorField } from '../ColorField';\nimport { Input } from '../Input';\nimport { NumberField } from '../NumberField';\nimport { RadioGroup, Radio } from '../RadioGroup';\nimport { RangeSlider } from '../RangeSlider';\nimport { Select } from '../Select';\nimport { Switch } from '../Switch';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport {\n isPrefLeaf,\n prefValueAtPath,\n visiblePrefSubtree,\n type PrefBoolean,\n type PrefColor,\n type PrefEnum,\n type PrefGroup,\n type PrefLeaf,\n type PrefNumber,\n type PrefString,\n} from './schema';\nimport s from './Prefs.module.css';\n\n/** What a {@link PrefRenderer} is given for the leaf it is rendering. */\nexport interface PrefRenderContext {\n /** Dotted path of the leaf within the schema root. */\n path: string;\n /** The schema node. App renderers narrow this to their own kind shape. */\n pref: PrefLeaf;\n /** Current value — `values` at `path`, falling back to `pref.default`. */\n value: unknown;\n setValue: (value: unknown) => void;\n}\n\n/**\n * Renders the control cell for one preference leaf. Returning `null`\n * collapses the row.\n */\nexport type PrefRenderer = (ctx: PrefRenderContext) => ReactNode;\n\n/** Props for {@link PrefsForm}. */\nexport interface PrefsFormProps {\n /** Root of the schema tree. Core `ToolPrefGroup`s assign structurally. */\n schema: PrefGroup;\n /** Nested value tree (shape mirrors the schema). Sparse is fine —\n * missing leaves fall back to their schema `default`. */\n values?: unknown;\n /** Change callback with the leaf's dotted path. Values apply live;\n * there is no dirty/commit state. */\n onChange: (path: string, value: unknown) => void;\n /**\n * Per-kind renderers for app-defined kinds. Entries also override the\n * built-in kinds when keys collide. A renderer owns the control cell\n * (the label/tooltip row chrome stays with the form, unless the leaf\n * sets `block`); returning `null` collapses the row entirely. Unknown\n * kinds with no renderer show a labeled placeholder instead of\n * crashing.\n */\n renderers?: Record<string, PrefRenderer>;\n /** Reveal `hidden` leaves (dev tooling). Default false. */\n showHidden?: boolean;\n className?: string;\n}\n\n/**\n * Schema-driven preferences form. Top-level groups render as columns,\n * nested groups as indented sub-panels, leaves as label + control rows.\n * Storage-agnostic: pair with `PrefsDialog` for the modal composition,\n * and persist however the app likes via `onChange`.\n */\nexport function PrefsForm(props: PrefsFormProps) {\n const { schema, values, onChange, renderers, showHidden = false, className } = props;\n const visibleRoot = useMemo(\n () => visiblePrefSubtree(schema, showHidden),\n [schema, showHidden],\n );\n const ctx: WalkCtx = { values, onChange, renderers };\n return (\n <div className={[s.columns, className].filter(Boolean).join(' ')}>\n {Object.entries(visibleRoot?.children ?? {}).map(([key, child]) => (\n <div key={key} className={s.column}>\n {isPrefLeaf(child) ? (\n // Top-level leaves are unusual but legal — give each its own\n // column for symmetry with grouped siblings.\n <PrefRow ctx={ctx} path={key} pref={child} />\n ) : (\n <GroupBody ctx={ctx} group={child} path={key} depth={0} />\n )}\n </div>\n ))}\n </div>\n );\n}\n\ninterface WalkCtx {\n values: unknown;\n onChange: (path: string, value: unknown) => void;\n renderers?: Record<string, PrefRenderer>;\n}\n\nfunction GroupBody({ ctx, group, path, depth }: {\n ctx: WalkCtx;\n group: PrefGroup;\n path: string;\n depth: number;\n}) {\n return (\n <div className={depth === 0 ? s.panel : s.subpanel}>\n <div className={s.groupHeader}>\n <h3 className={s.groupTitle}>{group.name}</h3>\n {group.description !== undefined && (\n <p className={s.groupDesc}>{group.description}</p>\n )}\n </div>\n <div className={s.rows}>\n {Object.entries(group.children).map(([key, child]) => {\n const childPath = `${path}.${key}`;\n return isPrefLeaf(child) ? (\n <PrefRow key={key} ctx={ctx} path={childPath} pref={child} />\n ) : (\n <GroupBody key={key} ctx={ctx} group={child} path={childPath} depth={depth + 1} />\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction PrefRow({ ctx, path, pref }: { ctx: WalkCtx; path: string; pref: PrefLeaf }) {\n const stored = prefValueAtPath(ctx.values, path);\n const renderCtx: PrefRenderContext = {\n path,\n pref,\n value: stored !== undefined ? stored : pref.default,\n setValue: (v) => ctx.onChange(path, v),\n };\n\n const custom = ctx.renderers?.[pref.kind];\n const control = custom ? custom(renderCtx) : renderBuiltin(renderCtx);\n if (custom && control === null) return null;\n\n // `block` leaves own their chrome (embedded editors with their own\n // header) — no label/tooltip row.\n if (pref.block) return <>{control}</>;\n\n return (\n <label className={s.row}>\n <span className={s.rowLabel}>\n {pref.name}\n {pref.description ? (\n // Help affordance carries the description tooltip. A tooltip\n // trigger must be interactive (keyboard-reachable), so this is\n // a real button — a bare label span would be neither focusable\n // nor announced.\n <TooltipTrigger>\n <Focusable>\n <button type=\"button\" className={s.help} aria-label={`About ${pref.name}`}>\n ⓘ\n </button>\n </Focusable>\n <Tooltip>{pref.description}</Tooltip>\n </TooltipTrigger>\n ) : null}\n </span>\n <span className={s.rowControl}>{control}</span>\n </label>\n );\n}\n\nfunction renderBuiltin(ctx: PrefRenderContext): ReactNode {\n const { pref, value, setValue } = ctx;\n switch (pref.kind) {\n case 'boolean': {\n const p = pref as PrefBoolean;\n const checked = Boolean(value);\n return p.control === 'switch' ? (\n <Switch isSelected={checked} onChange={setValue} aria-label={p.name} />\n ) : (\n <Checkbox isSelected={checked} onChange={setValue} aria-label={p.name} />\n );\n }\n case 'number': {\n const p = pref as PrefNumber;\n const n = typeof value === 'number' && Number.isFinite(value) ? value : 0;\n if (p.control === 'slider') {\n return (\n <RangeSlider\n value={n}\n onChange={(v) => setValue(typeof v === 'number' ? v : v[0])}\n minValue={p.min}\n maxValue={p.max}\n step={p.step ?? 1}\n aria-label={p.name}\n />\n );\n }\n return (\n <NumberField\n value={n}\n onChange={setValue}\n minValue={p.min}\n maxValue={p.max}\n step={p.step ?? 1}\n aria-label={p.name}\n />\n );\n }\n case 'string': {\n const p = pref as PrefString;\n const text = typeof value === 'string' ? value : '';\n if (p.control === 'textarea') {\n return (\n <textarea\n className={s.textarea}\n value={text}\n onChange={(e) => setValue(e.target.value)}\n aria-label={p.name}\n rows={3}\n />\n );\n }\n return <Input value={text} onChange={setValue} aria-label={p.name} />;\n }\n case 'enum': {\n const p = pref as PrefEnum;\n const selected = typeof value === 'string' ? value : p.default;\n if (p.control === 'radio') {\n return (\n <RadioGroup\n value={selected}\n onChange={(v) => setValue(v)}\n aria-label={p.name}\n >\n {p.options.map((o) => (\n <Radio key={o.value} value={o.value}>{o.label}</Radio>\n ))}\n </RadioGroup>\n );\n }\n return (\n <Select<string>\n options={p.options.map((o) => ({ value: o.value, label: o.label }))}\n selectedKey={selected}\n onSelectionChange={(v) => setValue(v)}\n aria-label={p.name}\n />\n );\n }\n case 'color': {\n const p = pref as PrefColor;\n const hex = typeof value === 'string' ? value : p.default;\n return (\n <ColorField\n value={hex}\n alpha={p.alpha}\n onChange={setValue}\n aria-label={p.name}\n />\n );\n }\n default:\n // Unknown kind with no renderer entry: labeled placeholder, not a\n // crash — a missing wiring should be visible and recoverable.\n return <span className={s.unrenderable}>({pref.kind}: no renderer)</span>;\n }\n}\n","import type { ReactNode } from 'react';\nimport { Dialog } from '../Dialog';\nimport { PrefsForm, type PrefsFormProps } from './PrefsForm';\nimport s from './Prefs.module.css';\n\n/**\n * Props for {@link PrefsDialog} — everything {@link PrefsForm} takes, plus\n * the dialog's own open state and chrome.\n */\nexport interface PrefsDialogProps extends PrefsFormProps {\n isOpen: boolean;\n onOpenChange: (open: boolean) => void;\n /** Dialog heading. Defaults to the schema root's `name`. */\n title?: ReactNode;\n /** Extra chrome rendered inline with the title (e.g. a dev-mode\n * \"Show hidden\" switch). */\n headerExtra?: ReactNode;\n /** Class applied to the dialog's modal box. */\n dialogClassName?: string;\n}\n\n/**\n * The kit's preferences dialog: `Dialog` + `PrefsForm`. Changes apply\n * live through `onChange` — there is no OK/Cancel staging. For custom\n * placement (sidebar, popover, inline page), compose `PrefsForm`\n * directly; this wrapper is intentionally thin.\n */\nexport function PrefsDialog(props: PrefsDialogProps) {\n const { isOpen, onOpenChange, title, headerExtra, dialogClassName, ...form } = props;\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n aria-label={typeof title === 'string' ? title : form.schema.name}\n className={dialogClassName}\n title={\n headerExtra !== undefined ? (\n <span className={s.titleRow}>\n <span>{title ?? form.schema.name}</span>\n {headerExtra}\n </span>\n ) : (\n title ?? form.schema.name\n )\n }\n >\n <PrefsForm {...form} />\n </Dialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./Field-VQwmrIna.js";
|
|
2
|
-
import { FieldError as t, Label as n, Radio as r, RadioGroup as i, Text as a } from "react-aria-components";
|
|
3
|
-
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
4
|
-
var c = {
|
|
5
|
-
group: "_group_kaubu_1",
|
|
6
|
-
legend: "_legend_kaubu_14",
|
|
7
|
-
radio: "_radio_kaubu_20",
|
|
8
|
-
dot: "_dot_kaubu_36"
|
|
9
|
-
};
|
|
10
|
-
//#endregion
|
|
11
|
-
//#region src/components/RadioGroup/RadioGroup.tsx
|
|
12
|
-
function l(r) {
|
|
13
|
-
let { label: l, description: u, errorMessage: d, children: f, className: p, ...m } = r;
|
|
14
|
-
return /* @__PURE__ */ s(i, {
|
|
15
|
-
...m,
|
|
16
|
-
className: [
|
|
17
|
-
c.group,
|
|
18
|
-
e.root,
|
|
19
|
-
p
|
|
20
|
-
].filter(Boolean).join(" "),
|
|
21
|
-
children: [
|
|
22
|
-
l !== void 0 && /* @__PURE__ */ o(n, {
|
|
23
|
-
className: c.legend,
|
|
24
|
-
children: l
|
|
25
|
-
}),
|
|
26
|
-
f,
|
|
27
|
-
u !== void 0 && /* @__PURE__ */ o(a, {
|
|
28
|
-
slot: "description",
|
|
29
|
-
className: e.hint,
|
|
30
|
-
children: u
|
|
31
|
-
}),
|
|
32
|
-
/* @__PURE__ */ o(t, {
|
|
33
|
-
className: e.error,
|
|
34
|
-
children: d
|
|
35
|
-
})
|
|
36
|
-
]
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
function u({ children: e, className: t, ...n }) {
|
|
40
|
-
return /* @__PURE__ */ s(r, {
|
|
41
|
-
...n,
|
|
42
|
-
className: [c.radio, t].filter(Boolean).join(" "),
|
|
43
|
-
children: [/* @__PURE__ */ o("span", { className: c.dot }), e !== void 0 && /* @__PURE__ */ o("span", { children: e })]
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
//#endregion
|
|
47
|
-
export { l as n, u as t };
|
|
48
|
-
|
|
49
|
-
//# sourceMappingURL=RadioGroup-CIpHr3g6.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup-CIpHr3g6.js","names":[],"sources":["../../src/components/RadioGroup/RadioGroup.module.css","../../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":[".group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-family: var(--wzl-font-ui);\n color: var(--wzl-fg);\n}\n\n.group[data-orientation=\"horizontal\"] {\n flex-direction: row;\n gap: 16px;\n}\n\n.legend {\n font-size: 12px;\n font-weight: 500;\n color: var(--wzl-fg);\n}\n\n.radio {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n font-size: 13px;\n color: var(--wzl-fg);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.radio[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.dot {\n position: relative;\n flex: 0 0 auto;\n width: 14px;\n height: 14px;\n background: var(--wzl-surface-sunken);\n border: 1px solid var(--wzl-border-strong);\n border-radius: 50%;\n transition: border-color var(--wzl-motion-fast), box-shadow var(--wzl-motion-fast);\n}\n\n.radio[data-focus-visible] .dot {\n box-shadow: 0 0 0 2px var(--wzl-focus-ring);\n}\n\n.radio[data-hovered]:not([data-disabled]) .dot {\n border-color: var(--wzl-fg-muted);\n}\n\n.radio[data-selected] .dot {\n border-color: var(--wzl-accent-strong);\n}\n\n.dot::after {\n content: '';\n position: absolute;\n inset: 3px;\n border-radius: 50%;\n background: var(--wzl-accent-strong);\n transform: scale(0);\n transition: transform var(--wzl-motion-fast);\n}\n\n.radio[data-selected] .dot::after {\n transform: scale(1);\n}\n","import type { ReactNode } from 'react';\nimport {\n RadioGroup as RACRadioGroup,\n Radio as RACRadio,\n Label,\n Text,\n FieldError,\n type RadioGroupProps as RACRadioGroupProps,\n type RadioProps as RACRadioProps,\n type ValidationResult,\n} from 'react-aria-components';\nimport { fieldClasses } from '../Field/Field';\nimport s from './RadioGroup.module.css';\n\n/** Props for {@link RadioGroup}, on top of React Aria's `RadioGroup` props. */\nexport type RadioGroupProps = Omit<RACRadioGroupProps, 'children' | 'className'> & {\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);\n children?: ReactNode;\n className?: string;\n};\n\n/**\n * A set of mutually exclusive choices, wrapping React Aria's RadioGroup and\n * supplying the same label / description / errorMessage slots as `Input`.\n * Holds {@link Radio} children.\n */\nexport function RadioGroup(props: RadioGroupProps) {\n const { label, description, errorMessage, children, className, ...rest } = props;\n return (\n <RACRadioGroup\n {...rest}\n className={[s.group, fieldClasses.root, className].filter(Boolean).join(' ')}\n >\n {label !== undefined && <Label className={s.legend}>{label}</Label>}\n {children}\n {description !== undefined && (\n <Text slot=\"description\" className={fieldClasses.hint}>\n {description}\n </Text>\n )}\n <FieldError className={fieldClasses.error}>{errorMessage}</FieldError>\n </RACRadioGroup>\n );\n}\n\n/** Props for {@link Radio}, on top of React Aria's `Radio` props. */\nexport type RadioProps = Omit<RACRadioProps, 'className' | 'children'> & {\n children?: ReactNode;\n className?: string;\n};\n\n/** One choice in a {@link RadioGroup}. The label is passed as children. */\nexport function Radio({ children, className, ...rest }: RadioProps) {\n return (\n <RACRadio {...rest} className={[s.radio, className].filter(Boolean).join(' ')}>\n <span className={s.dot} />\n {children !== undefined && <span>{children}</span>}\n </RACRadio>\n );\n}\n"],"mappings":";;;;;;;;;;;AC4BA,SAAgB,EAAW,GAAwB;CACjD,IAAM,EAAE,UAAO,gBAAa,iBAAc,aAAU,cAAW,GAAG,MAAS;AAC3E,QACE,kBAAC,GAAD;EACE,GAAI;EACJ,WAAW;GAAC,EAAE;GAAO,EAAa;GAAM;GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAF9E;GAIG,MAAU,KAAA,KAAa,kBAAC,GAAD;IAAO,WAAW,EAAE;cAAS;IAAc,CAAA;GAClE;GACA,MAAgB,KAAA,KACf,kBAAC,GAAD;IAAM,MAAK;IAAc,WAAW,EAAa;cAC9C;IACI,CAAA;GAET,kBAAC,GAAD;IAAY,WAAW,EAAa;cAAQ;IAA0B,CAAA;GACxD;;;AAWpB,SAAgB,EAAM,EAAE,aAAU,cAAW,GAAG,KAAoB;AAClE,QACE,kBAAC,GAAD;EAAU,GAAI;EAAM,WAAW,CAAC,EAAE,OAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAA7E,CACE,kBAAC,QAAD,EAAM,WAAW,EAAE,KAAO,CAAA,EACzB,MAAa,KAAA,KAAa,kBAAC,QAAD,EAAO,aAAgB,CAAA,CACzC"}
|