@weasel-js/labkit 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/README.md +3 -3
  2. package/dist/_dts/{CanvasStackContext-Wo6OwIVM.d.ts → CanvasStackContext-Cjy6I-Iv.d.ts} +4 -1
  3. package/dist/_dts/{Stage-DWBBi8IU.d.ts → Stage-D6t7o0pF.d.ts} +59 -18
  4. package/dist/_dts/{index-CKyX0ME_.d.ts → index-BTmaRy6a.d.ts} +10 -6
  5. package/dist/_dts/{types-B7yBTTF9.d.ts → index-DCMA4Fy1.d.ts} +59 -113
  6. package/dist/_dts/{types-DTuViBvc.d.ts → types-BUBSIZuV.d.ts} +18 -8
  7. package/dist/_dts/{useTrialState-CMaV6UD4.d.ts → useTrialState-Bh8bzFgE.d.ts} +1 -1
  8. package/dist/canvas/index.d.ts +8 -6
  9. package/dist/canvas/index.js +6 -6
  10. package/dist/chrome/index.d.ts +6 -4
  11. package/dist/chrome/index.js +11 -10
  12. package/dist/chunk-2ES4W47N.js +8 -0
  13. package/dist/chunk-2ES4W47N.js.map +1 -0
  14. package/dist/{chunk-WPLAANH4.js → chunk-2N7UBSS2.js} +12 -12
  15. package/dist/chunk-2N7UBSS2.js.map +1 -0
  16. package/dist/chunk-4KSC7NXL.js +15491 -0
  17. package/dist/chunk-4KSC7NXL.js.map +1 -0
  18. package/dist/{chunk-SLAQPUI4.js → chunk-CEGFXTBD.js} +10 -63
  19. package/dist/chunk-CEGFXTBD.js.map +1 -0
  20. package/dist/chunk-CZZPXUOU.js +3 -0
  21. package/dist/{chunk-SBXNQW4G.js.map → chunk-CZZPXUOU.js.map} +1 -1
  22. package/dist/{chunk-QGMOA2YE.js → chunk-E23Q6A3Y.js} +296 -104
  23. package/dist/chunk-E23Q6A3Y.js.map +1 -0
  24. package/dist/{chunk-GHGO52SO.js → chunk-E6NARGU7.js} +5 -5
  25. package/dist/{chunk-GHGO52SO.js.map → chunk-E6NARGU7.js.map} +1 -1
  26. package/dist/{chunk-IJJUK4FU.js → chunk-EESJUSYR.js} +5 -6
  27. package/dist/chunk-EESJUSYR.js.map +1 -0
  28. package/dist/{chunk-HXXTULDN.js → chunk-EFXRM6XQ.js} +8 -11
  29. package/dist/chunk-EFXRM6XQ.js.map +1 -0
  30. package/dist/chunk-F4ACIK7Z.js +210 -0
  31. package/dist/chunk-F4ACIK7Z.js.map +1 -0
  32. package/dist/{chunk-6FLXL3I7.js → chunk-FB4MIZOO.js} +77 -45
  33. package/dist/chunk-FB4MIZOO.js.map +1 -0
  34. package/dist/{chunk-AWQG7FCC.js → chunk-FG3EXZDV.js} +3 -3
  35. package/dist/{chunk-AWQG7FCC.js.map → chunk-FG3EXZDV.js.map} +1 -1
  36. package/dist/{chunk-4TT3PNPR.js → chunk-GAHELLJT.js} +95 -95
  37. package/dist/chunk-GAHELLJT.js.map +1 -0
  38. package/dist/{chunk-HKV7LRHY.js → chunk-IBVRMHW5.js} +5 -5
  39. package/dist/{chunk-HKV7LRHY.js.map → chunk-IBVRMHW5.js.map} +1 -1
  40. package/dist/{chunk-ASOK76ZH.js → chunk-JFOJESJF.js} +72 -29
  41. package/dist/chunk-JFOJESJF.js.map +1 -0
  42. package/dist/{chunk-RWNDDKOH.js → chunk-PMLZP7RT.js} +18 -15
  43. package/dist/chunk-PMLZP7RT.js.map +1 -0
  44. package/dist/{chunk-TJ77A4A3.js → chunk-READTDQX.js} +5 -9
  45. package/dist/chunk-READTDQX.js.map +1 -0
  46. package/dist/{chunk-JVBYV6TL.js → chunk-ROGJWDQA.js} +3 -3
  47. package/dist/{chunk-JVBYV6TL.js.map → chunk-ROGJWDQA.js.map} +1 -1
  48. package/dist/{chunk-CGHF6RZV.js → chunk-T6DLGEJB.js} +18 -18
  49. package/dist/chunk-T6DLGEJB.js.map +1 -0
  50. package/dist/{chunk-24W5VEJW.js → chunk-ULYYNWGP.js} +2 -2
  51. package/dist/{chunk-24W5VEJW.js.map → chunk-ULYYNWGP.js.map} +1 -1
  52. package/dist/{chunk-DWMSB4CA.js → chunk-VYVGVBGY.js} +95 -32
  53. package/dist/chunk-VYVGVBGY.js.map +1 -0
  54. package/dist/{chunk-IRTGUQ5O.js → chunk-WLMDTI2Q.js} +16 -6
  55. package/dist/chunk-WLMDTI2Q.js.map +1 -0
  56. package/dist/{chunk-NEXR37YJ.js → chunk-XE5HJOPL.js} +6 -8
  57. package/dist/chunk-XE5HJOPL.js.map +1 -0
  58. package/dist/chunk-XVUKDSYV.js +38 -0
  59. package/dist/chunk-XVUKDSYV.js.map +1 -0
  60. package/dist/{chunk-O6FFFOHS.js → chunk-YCFKW5RX.js} +16 -8
  61. package/dist/chunk-YCFKW5RX.js.map +1 -0
  62. package/dist/{chunk-CQLQPQ4P.js → chunk-ZQIHJXP4.js} +2 -2
  63. package/dist/chunk-ZQIHJXP4.js.map +1 -0
  64. package/dist/config/index.d.ts +28 -13
  65. package/dist/config/index.js +4 -4
  66. package/dist/controls/index.d.ts +4 -7
  67. package/dist/controls/index.js +6 -5
  68. package/dist/dragdrop/index.d.ts +23 -3
  69. package/dist/dragdrop/index.js +4 -3
  70. package/dist/fonts/oswald-tabular-digits.woff2 +0 -0
  71. package/dist/index.d.ts +72 -487
  72. package/dist/index.js +603 -441
  73. package/dist/index.js.map +1 -1
  74. package/dist/job/index.d.ts +8 -0
  75. package/dist/job/index.js +1 -1
  76. package/dist/layers/index.d.ts +6 -5
  77. package/dist/layers/index.js +3 -2
  78. package/dist/loupe/index.d.ts +100 -30
  79. package/dist/loupe/index.js +585 -6
  80. package/dist/loupe/index.js.map +1 -1
  81. package/dist/overview/index.d.ts +4 -2
  82. package/dist/overview/index.js +20 -18
  83. package/dist/overview/index.js.map +1 -1
  84. package/dist/passthrough/weasel-canvas.d.ts +2 -0
  85. package/dist/passthrough/weasel-ui.d.ts +2 -2701
  86. package/dist/passthrough/weasel-ui.js +4 -3
  87. package/dist/primitives/index.d.ts +37 -2
  88. package/dist/primitives/index.js +9 -8
  89. package/dist/state/index.d.ts +7 -5
  90. package/dist/state/index.js +6 -6
  91. package/dist/styles.css +150 -126
  92. package/dist/surface/index.d.ts +10 -2
  93. package/dist/surface/index.js +1 -1
  94. package/dist/undo/index.d.ts +5 -3
  95. package/package.json +14 -13
  96. package/src/annotations/AnnotationOverlay.abandon.test.tsx +143 -0
  97. package/src/annotations/AnnotationOverlay.tsx +52 -33
  98. package/src/annotations/Annotations.less +0 -10
  99. package/src/annotations/Annotations.overlay.test.tsx +31 -0
  100. package/src/annotations/MarkList.tsx +4 -8
  101. package/src/annotations/capture.browser.test.ts +41 -0
  102. package/src/annotations/capture.ts +14 -7
  103. package/src/annotations/drawOne.ts +2 -2
  104. package/src/annotations/frac.test.ts +44 -1
  105. package/src/annotations/frac.ts +46 -18
  106. package/src/annotations/index.ts +1 -0
  107. package/src/annotations/paint.test.ts +76 -46
  108. package/src/annotations/paint.ts +65 -43
  109. package/src/annotations/store.test.ts +212 -2
  110. package/src/annotations/store.ts +130 -27
  111. package/src/annotations/svgNodes.test.ts +28 -19
  112. package/src/annotations/svgNodes.ts +6 -6
  113. package/src/annotations/types.ts +29 -10
  114. package/src/canvas/AGENTS.md +1 -0
  115. package/src/canvas/CameraInput.test.tsx +30 -0
  116. package/src/canvas/CameraInput.tsx +60 -48
  117. package/src/canvas/CanvasStack.tsx +11 -6
  118. package/src/canvas/CanvasStackContext.ts +4 -1
  119. package/src/canvas/LinkedCursor.less +1 -1
  120. package/src/canvas/Stage.test.tsx +33 -4
  121. package/src/canvas/Stage.tsx +9 -4
  122. package/src/canvas/cameraRegistry.test.ts +55 -0
  123. package/src/canvas/cameraRegistry.ts +87 -0
  124. package/src/canvas/cameraZoom.test.ts +46 -0
  125. package/src/canvas/cameraZoom.ts +24 -0
  126. package/src/canvas/index.ts +14 -2
  127. package/src/canvas/sharedScope.test.tsx +94 -0
  128. package/src/canvas/worldSpec.ts +3 -1
  129. package/src/chrome/ChromeRegions.stories.tsx +1 -0
  130. package/src/chrome/builtins.test.ts +7 -6
  131. package/src/chrome/builtins.tsx +5 -1
  132. package/src/chrome/index.ts +1 -1
  133. package/src/chrome/merge.test.ts +5 -0
  134. package/src/chrome/merge.ts +4 -2
  135. package/src/chrome/regions/PaletteRegion.less +0 -7
  136. package/src/chrome/regions/PaletteRegion.test.tsx +2 -3
  137. package/src/chrome/regions/PaletteRegion.tsx +3 -4
  138. package/src/chrome/regions/SidebarRegion.less +12 -2
  139. package/src/chrome/regions/ViewportRegion.browser.test.less +6 -0
  140. package/src/chrome/regions/ViewportRegion.browser.test.tsx +38 -0
  141. package/src/chrome/regions/ViewportRegion.less +6 -0
  142. package/src/chrome/regions/ViewportRegion.tsx +10 -4
  143. package/src/chrome/types.ts +4 -2
  144. package/src/config/auto.ts +1 -0
  145. package/src/config/builder.test.ts +2 -1
  146. package/src/config/builder.ts +18 -5
  147. package/src/config/fromConfigField.test.ts +14 -0
  148. package/src/config/fromConfigField.ts +18 -4
  149. package/src/config/path.ts +2 -5
  150. package/src/config/resolve.ts +4 -0
  151. package/src/config/types.ts +14 -9
  152. package/src/controls/ControlPanel.less +1 -1
  153. package/src/controls/ControlPanel.stories.tsx +3 -2
  154. package/src/controls/ControlPanel.test.tsx +98 -11
  155. package/src/controls/ControlPanel.tsx +61 -2
  156. package/src/dragdrop/DragDropRuntime.tsx +22 -13
  157. package/src/dragdrop/DragGhost.tsx +3 -0
  158. package/src/dragdrop/Palette.tsx +2 -0
  159. package/src/index.test.ts +5 -0
  160. package/src/index.ts +16 -2
  161. package/src/instrument/types.ts +0 -6
  162. package/src/job/useJob.ts +14 -9
  163. package/src/lab/Lab.tsx +88 -73
  164. package/src/lab/{LabFit.stories.less → LabFit.browser.test.less} +1 -1
  165. package/src/lab/{LabFit.stories.tsx → LabFit.browser.test.tsx} +41 -63
  166. package/src/lab/LabFullChrome.stories.tsx +1 -0
  167. package/src/lab/LabHeader.test.tsx +24 -14
  168. package/src/lab/LabHeader.tsx +11 -12
  169. package/src/lab/LabShell.less +9 -17
  170. package/src/lab/LabSwitcher.browser.test.tsx +27 -0
  171. package/src/lab/LabSwitcher.less +8 -6
  172. package/src/lab/LabZoom.test.tsx +223 -0
  173. package/src/lab/LabZoom.tsx +170 -0
  174. package/src/lab/Workspace.tsx +48 -52
  175. package/src/lab/index.ts +1 -0
  176. package/src/loupe/AGENTS.md +28 -15
  177. package/src/loupe/CanvasLoupe.tsx +2 -3
  178. package/src/loupe/DomLoupe.tsx +1 -7
  179. package/src/loupe/Loupe.less +16 -0
  180. package/src/loupe/LoupeGestures.tsx +1 -1
  181. package/src/loupe/TrialLoupe.tsx +120 -57
  182. package/src/loupe/index.ts +1 -6
  183. package/src/loupe/types.test.ts +3 -3
  184. package/src/loupe/types.ts +24 -27
  185. package/src/loupe/useLoupe.test.tsx +29 -4
  186. package/src/loupe/useLoupe.ts +20 -17
  187. package/src/overview/OverviewMarks.tsx +12 -4
  188. package/src/overview/TrialOverview.tsx +10 -8
  189. package/src/passthrough/weasel-ui.test.ts +2 -0
  190. package/src/passthrough/weasel-ui.ts +17 -5
  191. package/src/primitives/FloatingPanel.test.tsx +11 -0
  192. package/src/primitives/FloatingPanel.tsx +8 -7
  193. package/src/primitives/JobProgress.less +2 -1
  194. package/src/primitives/Legend.stories.tsx +1 -0
  195. package/src/primitives/Readout.browser.test.tsx +137 -0
  196. package/src/primitives/Readout.less +12 -0
  197. package/src/primitives/Readout.stories.tsx +58 -0
  198. package/src/primitives/Readout.test.tsx +93 -0
  199. package/src/primitives/Readout.tsx +56 -0
  200. package/src/primitives/Split.tsx +69 -41
  201. package/src/primitives/Toolbar.tsx +3 -3
  202. package/src/primitives/ZoomControl.less +1 -2
  203. package/src/primitives/index.ts +2 -0
  204. package/src/specimen/Specimen.stories.tsx +1 -0
  205. package/src/specimen/Specimen.tsx +2 -3
  206. package/src/state/Persistence.browser.test.tsx +47 -0
  207. package/src/state/store.test.ts +5 -1
  208. package/src/state/undock.ts +3 -0
  209. package/src/state/useOpenOnce.ts +20 -16
  210. package/src/state/usePersistedState.test.tsx +1 -1
  211. package/src/state/view.ts +1 -0
  212. package/src/styles.less +1 -0
  213. package/src/surface/index.ts +1 -1
  214. package/src/surface/useTiledSurface.test.tsx +14 -0
  215. package/src/surface/useTiledSurface.ts +11 -3
  216. package/src/theme/Interstellar.stories.tsx +3 -1
  217. package/src/theme/base.less +21 -47
  218. package/src/theme/interstellar.test.ts +1 -1
  219. package/src/theme/interstellar.theme.json +10 -3
  220. package/src/trial/Trial.annotations.test.tsx +73 -0
  221. package/src/trial/Trial.less +0 -29
  222. package/src/trial/Trial.loupe.test.tsx +28 -11
  223. package/src/trial/Trial.tsx +85 -67
  224. package/src/trial/TrialChrome.tsx +27 -6
  225. package/src/trial/index.ts +2 -0
  226. package/src/trial/loupeSwitch.ts +15 -0
  227. package/dist/_dts/LayerList.d-BoELAMsM.d.ts +0 -83
  228. package/dist/_dts/PrefsRow.d-DFpPIeIC.d.ts +0 -39
  229. package/dist/_dts/PropertyField.d-D0ndfIIt.d.ts +0 -404
  230. package/dist/_dts/Select.d-Cr8-zoup.d.ts +0 -569
  231. package/dist/chunk-4TT3PNPR.js.map +0 -1
  232. package/dist/chunk-6FLXL3I7.js.map +0 -1
  233. package/dist/chunk-ASOK76ZH.js.map +0 -1
  234. package/dist/chunk-CGHF6RZV.js.map +0 -1
  235. package/dist/chunk-CQLQPQ4P.js.map +0 -1
  236. package/dist/chunk-DWMSB4CA.js.map +0 -1
  237. package/dist/chunk-HXXTULDN.js.map +0 -1
  238. package/dist/chunk-IJJUK4FU.js.map +0 -1
  239. package/dist/chunk-IRTGUQ5O.js.map +0 -1
  240. package/dist/chunk-KHK5FGER.js +0 -145
  241. package/dist/chunk-KHK5FGER.js.map +0 -1
  242. package/dist/chunk-NEXR37YJ.js.map +0 -1
  243. package/dist/chunk-O6FFFOHS.js.map +0 -1
  244. package/dist/chunk-QGMOA2YE.js.map +0 -1
  245. package/dist/chunk-RWNDDKOH.js.map +0 -1
  246. package/dist/chunk-S4NCI32V.js +0 -549
  247. package/dist/chunk-S4NCI32V.js.map +0 -1
  248. package/dist/chunk-SBXNQW4G.js +0 -3
  249. package/dist/chunk-SLAQPUI4.js.map +0 -1
  250. package/dist/chunk-TJ77A4A3.js.map +0 -1
  251. package/dist/chunk-TYN6MLXX.js +0 -13864
  252. package/dist/chunk-TYN6MLXX.js.map +0 -1
  253. package/dist/chunk-WPLAANH4.js.map +0 -1
  254. package/src/primitives/useRovingTabIndex.test.ts +0 -48
  255. package/src/primitives/useRovingTabIndex.ts +0 -88
  256. package/src/state/Persistence.stories.tsx +0 -75
@@ -1,2701 +1,2 @@
1
- import { j as ToggleBarSize, k as ToggleBarVariant, l as SegmentTooltipFields, F as FieldOrientation, O as OverlayPortalProps, W as WithoutPortalTarget } from '../_dts/Select.d-Cr8-zoup.js';
2
- export { B as Button, a as ButtonProps, b as ButtonSize, c as ButtonVariant, m as Field, n as FieldProps, o as ICON_PATHS, d as Icon, p as IconName, I as IconProps, e as Input, f as InputProps, S as Select, q as SelectItem, r as SelectItemProps, s as SelectOption, g as SelectProps, T as ToggleBar, h as ToggleBarItem, i as ToggleBarProps, t as fieldClasses } from '../_dts/Select.d-Cr8-zoup.js';
3
- import { ToolPrefLeaf, ToolPrefGroup, ToolsApi, oklchDegToHex } from '@weasel-js/core';
4
- export { ToolPref as BuiltinPref, ToolPrefBoolean as PrefBoolean, ToolPrefBooleanControl as PrefBooleanControl, ToolPrefColor as PrefColor, ToolPrefCustom as PrefCustom, ToolPrefEnum as PrefEnum, ToolPrefEnumControl as PrefEnumControl, ToolPrefEnumEncoding as PrefEnumEncoding, ToolPrefGroup as PrefGroup, ToolPrefKind as PrefKind, ToolPrefLeaf as PrefLeaf, ToolPrefNumber as PrefNumber, ToolPrefNumberControl as PrefNumberControl, ToolPrefNumberUnit as PrefNumberUnit, ToolPrefObject as PrefObject, ToolPrefPaint as PrefPaint, ToolPrefString as PrefString, ToolPrefStringControl as PrefStringControl } from '@weasel-js/core';
5
- import * as react from 'react';
6
- import { ReactNode, CSSProperties, HTMLAttributes, ReactElement, PointerEvent, RefCallback, KeyboardEvent, RefObject } from 'react';
7
- import { S as StanceProps, P as PrefRenderer } from '../_dts/PrefsRow.d-DFpPIeIC.js';
8
- export { a as PrefRenderContext } from '../_dts/PrefsRow.d-DFpPIeIC.js';
9
- export { L as LayerList, a as LayerListItem, b as LayerListProps, c as LayerMove, m as moveLayers } from '../_dts/LayerList.d-BoELAMsM.js';
10
- import { ColorModePreference } from '@weasel-js/theme';
11
- export { M as MINUS_SIGN, q as PropertyAlign, r as PropertyDensity, P as PropertyMetricProps, s as formatNumber } from '../_dts/PropertyField.d-D0ndfIIt.js';
12
- import { CheckboxProps as CheckboxProps$1, SwitchProps as SwitchProps$1, TabProps as TabProps$1, TabListProps as TabListProps$1, TabPanelProps as TabPanelProps$1, TabsProps as TabsProps$1, RadioProps as RadioProps$1, RadioGroupProps as RadioGroupProps$1, ValidationResult, NumberFieldProps as NumberFieldProps$1, ComboBoxProps as ComboBoxProps$1, ListBoxItemProps, SliderProps as SliderProps$1, ModalOverlayProps, DialogProps as DialogProps$1, PopoverProps } from 'react-aria-components';
13
- export { DialogTrigger as CalloutTrigger } from 'react-aria-components';
14
-
15
- /**
16
- * Namespaced, opt-in console tracing. Off by default; production builds
17
- * may strip the calls entirely depending on the bundler.
18
- *
19
- * Enable in the browser:
20
- *
21
- * localStorage.setItem('weasel.debug', '*') // all namespaces
22
- * localStorage.setItem('weasel.debug', 'curve-editor') // just curve editor
23
- * localStorage.setItem('weasel.debug', 'curve-editor,layer-stack')
24
- *
25
- * Each component picks a stable namespace and calls `dlog(namespace, ...)`.
26
- * Useful for tracing pointer/event flows that are hard to capture
27
- * post-hoc (drag handlers, gesture sequences, selection mutations).
28
- *
29
- * The flag is read once and cached for the page session — reload to
30
- * pick up changes. Cheap hot-path checks (one nullish-coalesce + Set
31
- * lookup) so leaving calls in place is fine.
32
- *
33
- * Mirrors `src/debug/flag.ts` in the kit. Two impls live here because
34
- * weasel-ui doesn't depend on the kit, but both read the same
35
- * localStorage keys so behavior is uniform. See the kit copy for the
36
- * canonical list of kit-level namespaces.
37
- *
38
- * Known weasel-ui namespaces:
39
- * - plot2d — Plot2D mount / unmount
40
- * - curve-editor — CurveEditor pointer flow
41
- */
42
- /** True when `namespace` (or `*`) is enabled. */
43
- declare function isDebugEnabled(namespace: string): boolean;
44
- /** Conditional `console.debug` — no-op unless `namespace` (or `*`) is enabled.
45
- * Each call is prefixed with `[namespace]` so the source is searchable. */
46
- declare function dlog(namespace: string, ...args: unknown[]): void;
47
-
48
- /** Props for {@link ActionBar}. */
49
- interface ActionBarProps {
50
- /** Group key — only actions with `action.group === group` are rendered. */
51
- group: string;
52
- /** Layout direction. Defaults to `'horizontal'`. */
53
- orientation?: 'horizontal' | 'vertical';
54
- /**
55
- * Per-entry icon overrides, keyed by `ActionItem.key` — the action id, or
56
- * `id:variant` for one variant of a parametric action. When an entry is provided
57
- * it replaces the action's own `icon` for this bar only. Mirrors
58
- * `PathfinderPanelProps.icons` so call sites that ship custom glyph sets
59
- * can swap them in without re-registering actions.
60
- */
61
- icons?: Record<string, ReactNode>;
62
- /**
63
- * Per-entry label overrides, keyed like `icons`. Drives both `aria-label`
64
- * and `title`. When omitted, the entry's own `label` is used.
65
- */
66
- labels?: Record<string, string>;
67
- /** Additional class for the toolbar root. */
68
- className?: string;
69
- }
70
- /**
71
- * Generic group-keyed action toolbar. Reads the parent `ActionsRegistry`,
72
- * filters to actions whose `group` matches `props.group`, and renders one
73
- * icon button per match — or per variant, for an action that declares
74
- * `variants`. Disabled state is derived from each action's
75
- * `enabled` predicate via `evaluateEnabled` (so the button greys out and
76
- * swallows clicks while the keybinding — if any — still fires through the
77
- * registry's keydown listener; that's the registry's contract, not ours).
78
- *
79
- * Visual parity with the WeaselDraw `<PathfinderPanel>` is intentional;
80
- * this is the generic, registry-driven version. No keyboard navigation
81
- * (roving tabindex) yet — bar consumers today are short flat strips. Add
82
- * if/when a long bar lands.
83
- */
84
- declare function ActionBar(props: ActionBarProps): react.JSX.Element;
85
-
86
- /**
87
- * Built-in badge silhouettes. `pill`, `plain` and `square` are drawn in CSS;
88
- * the rest are SVG outlines, several of which route through the compose
89
- * pipeline (a base shape plus perimeter effects).
90
- */
91
- type BadgeShape = 'pill' | 'plain' | 'square' | 'notched' | 'perforated' | 'hexagon' | 'starburst' | 'scalloped' | 'shield' | 'ribbon' | 'beavis' | 'sparkler' | 'postage' | 'cloud' | 'house' | 'plaque' | 'crest' | 'urn' | 'coffin' | 'receipt' | 'wood' | 'quatrefoil';
92
- /**
93
- * Status color of a badge. `custom` paints from the `--badge-edge` custom
94
- * property instead of a theme token, so a call site can supply its own color.
95
- */
96
- type BadgeStatus = 'accent' | 'info' | 'success' | 'warn' | 'danger' | 'muted' | 'neutral' | 'custom';
97
- /** How a badge's color is applied: outline only, filled, or a soft tinted fill. */
98
- type BadgeVariant = 'outline' | 'solid' | 'subtle';
99
- /** Badge type scale and padding step. `xs` is for counts and markers set
100
- * inside a dense row, on the 2xs type step. */
101
- type BadgeSize = 'xs' | 'sm' | 'md';
102
-
103
- interface SquareParams {
104
- /** 0..1 fraction of the maximum corner rounding (1 = full pill). */
105
- erosion?: number;
106
- }
107
-
108
- interface NotchedParams {
109
- /** 0..1 fraction of max corner radius. */
110
- erosion?: number;
111
- /** rx/ry eccentricity of the corner arcs. */
112
- eccentricity?: number;
113
- }
114
-
115
- interface PerforatedParams {
116
- holeRadius?: number;
117
- holePitch?: number;
118
- }
119
-
120
- interface HexagonParams {
121
- tipHeight?: number;
122
- /** Truncate the top and bottom tips, leaving a horizontal flat edge.
123
- * Measured as a distance from each tip vertically (0 = sharp point, tipHeight = fully flat). */
124
- tipTruncation?: number;
125
- }
126
-
127
- interface StarburstParams {
128
- points?: number;
129
- outerR?: number;
130
- innerR?: number;
131
- rotation?: number;
132
- erosion?: number;
133
- }
134
-
135
- interface ScallopedParams {
136
- scallopRadius?: number;
137
- scallopSpacing?: number;
138
- irregularity?: number;
139
- }
140
-
141
- interface ShieldParams {
142
- pointDepth?: number;
143
- shoulderY?: number;
144
- curveTightness?: number;
145
- /** 0..1 fraction of max top-corner rounding. */
146
- erosion?: number;
147
- }
148
-
149
- type RibbonEnd$1 = 'inward' | 'outward' | 'flat';
150
- interface RibbonParams$1 {
151
- left?: RibbonEnd$1;
152
- right?: RibbonEnd$1;
153
- /** Taper depth in CSS px. The actual pointer width stays fixed regardless
154
- * of badge width — the underlying base recomputes viewBox vertices at
155
- * build time using the rendered box dimensions. */
156
- taperWidth?: number;
157
- }
158
-
159
- interface BeavisParams {
160
- points?: number;
161
- cornerRadius?: number;
162
- spikeLen?: number;
163
- spikeBaseWidth?: number;
164
- irregularity?: number;
165
- }
166
-
167
- interface SparklerParams {
168
- points?: number;
169
- outerR?: number;
170
- innerR?: number;
171
- rotation?: number;
172
- }
173
-
174
- interface PostageParams {
175
- biteRadius?: number;
176
- biteSpacing?: number;
177
- irregularity?: number;
178
- }
179
-
180
- interface CloudParams {
181
- bumpWidth?: number;
182
- puffiness?: number;
183
- /** 0..1 fraction of max body roundness. */
184
- erosion?: number;
185
- irregularity?: number;
186
- }
187
-
188
- interface HouseParams {
189
- eaveY?: number;
190
- peakHeight?: number;
191
- roofOverhang?: number;
192
- }
193
-
194
- type PlaqueCorner = 'tl' | 'tr' | 'bl' | 'br';
195
- interface PlaqueParams {
196
- bevelWidth?: number;
197
- lightFrom?: PlaqueCorner;
198
- rivetRadius?: number;
199
- rivetInset?: number;
200
- sheenIntensity?: number;
201
- }
202
-
203
- interface CrestParams {
204
- topInset?: number;
205
- pointDepth?: number;
206
- }
207
-
208
- interface CoffinParams {
209
- headX?: number;
210
- headHalfHeight?: number;
211
- shoulderX?: number;
212
- shoulderHalfHeight?: number;
213
- footX?: number;
214
- footHalfHeight?: number;
215
- }
216
-
217
- interface ReceiptParams {
218
- teeth?: number;
219
- tearDepth?: number;
220
- sideToTopRatio?: number;
221
- }
222
-
223
- interface QuatrefoilParams$1 {
224
- spikeR?: number;
225
- lobeR?: number;
226
- valleyR?: number;
227
- valleyAt?: number;
228
- spikeCurvature?: number;
229
- spikeBend?: number;
230
- spikeTipErosion?: number;
231
- lobeCurvature?: number;
232
- lobeBend?: number;
233
- lobeTipErosion?: number;
234
- valleySmooth?: number;
235
- rotation?: number;
236
- samples?: number;
237
- }
238
-
239
- interface BadgeShapeParams {
240
- pill: Record<string, never>;
241
- plain: Record<string, never>;
242
- square: SquareParams;
243
- notched: NotchedParams;
244
- perforated: PerforatedParams;
245
- hexagon: HexagonParams;
246
- starburst: StarburstParams;
247
- scalloped: ScallopedParams;
248
- shield: ShieldParams;
249
- ribbon: RibbonParams$1;
250
- beavis: BeavisParams;
251
- sparkler: SparklerParams;
252
- postage: PostageParams;
253
- cloud: CloudParams;
254
- house: HouseParams;
255
- plaque: PlaqueParams;
256
- crest: CrestParams;
257
- urn: Record<string, never>;
258
- coffin: CoffinParams;
259
- receipt: ReceiptParams;
260
- wood: Record<string, never>;
261
- quatrefoil: QuatrefoilParams$1;
262
- }
263
-
264
- interface ChamferedRectParams {
265
- /** CSS px length of each 45° corner chamfer. */
266
- chamfer?: number;
267
- }
268
-
269
- interface RoundedRectParams {
270
- /** 0..1 fraction of the maximum corner rounding (1 = full pill / ellipse). */
271
- erosion?: number;
272
- /** Stretch the corner arcs horizontally vs vertically. 1 = circular at the badge's
273
- * native aspect; >1 wider corner arcs; <1 taller corner arcs. */
274
- eccentricity?: number;
275
- /** 0..1 vertical squeeze applied to the left and right ends, linearly tapering toward
276
- * the middle. 1 = ends fully collapsed to the centerline (lemon/lens silhouette). */
277
- pinch?: number;
278
- }
279
-
280
- interface PolygonParams {
281
- /** Vertices in viewBox 0..100 coordinates, traced clockwise. */
282
- vertices?: [number, number][];
283
- }
284
-
285
- type PuzzleEdge = 'flat' | 'out' | 'in';
286
- interface PuzzleParams {
287
- top?: PuzzleEdge;
288
- right?: PuzzleEdge;
289
- bottom?: PuzzleEdge;
290
- left?: PuzzleEdge;
291
- /** Tab radius in viewBox units (0..50). */
292
- tabSize?: number;
293
- /** Sample density per tab arc. */
294
- arcSamples?: number;
295
- }
296
-
297
- /**
298
- * 8-fold-symmetric polar shape. The whole silhouette is defined by a single curve r(s)
299
- * over s ∈ [0, 1], where s=0 is the cardinal direction and s=1 is the diagonal. The full
300
- * shape comes from reflecting that octant curve eight times around the center. The curve
301
- * itself is two superellipse segments meeting at a valley:
302
- *
303
- * s ∈ [0, valleyAt] → spike segment, from `spikeR` down to `valleyR`
304
- * s ∈ [valleyAt, 1] → lobe segment, from `valleyR` up to `lobeR`
305
- *
306
- * Each segment has its own curvature, bend bias, and tip-erosion controls.
307
- */
308
- interface QuatrefoilParams {
309
- /** Radius at s=0 (cardinal direction). */
310
- spikeR?: number;
311
- /** Radius at s=1 (diagonal direction). */
312
- lobeR?: number;
313
- /** Radius at the junction between spike and lobe segments. */
314
- valleyR?: number;
315
- /** Position of the junction in [0, 1]. 0.5 = symmetric octant; <0.5 narrows the spike side. */
316
- valleyAt?: number;
317
- /** Spike-segment curvature (superellipse exponent). 1 = flat diagonal sides; <1 caves
318
- * inward (concave/star); >1 bulges outward (convex/square-shouldered). */
319
- spikeCurvature?: number;
320
- /** Spike-segment bend bias. Positive shifts the curve's bend toward the tip; negative
321
- * toward the base. */
322
- spikeBend?: number;
323
- /** Flat-top truncation of the cardinal tip (0..1). */
324
- spikeTipErosion?: number;
325
- /** Lobe-segment curvature, same semantics as spike. */
326
- lobeCurvature?: number;
327
- /** Lobe-segment bend bias. */
328
- lobeBend?: number;
329
- /** Flat-top truncation of the diagonal lobe peak (0..1). */
330
- lobeTipErosion?: number;
331
- /** Smooth the corner at the valley junction. 0 = sharp, higher = puffier crossover. */
332
- valleySmooth?: number;
333
- /** Rotate the pattern in degrees. */
334
- rotation?: number;
335
- /** Polygon sample count. */
336
- samples?: number;
337
- }
338
-
339
- /**
340
- * Symmetric polar-spline base. The silhouette comes from a single curve r(s) over
341
- * s ∈ [0, 1] that gets reflected/rotated to fill the full circle:
342
- *
343
- * - `mode: 'octant'`: 1/8 of the perimeter (cardinal → diagonal), mirrored within each
344
- * quadrant and rotated to fill the rest. 8-fold symmetric.
345
- * - `mode: 'quadrant'`: 1/4 of the perimeter (cardinal → next cardinal), rotated 4 times
346
- * with no internal mirror. 4-fold rotational symmetry; endpoints share radius.
347
- *
348
- * The interpolant is a **clamped natural cubic spline** with zero slope at both endpoints
349
- * (so the reflected/rotated full curve has no kink crossing the symmetry axes). C² across
350
- * the whole octant — continuous curvature, not just slope — which removes the "lumpy" feel
351
- * that local Hermite splines have when anchors are uneven.
352
- */
353
- interface OctantSplineParams {
354
- mode?: 'octant' | 'quadrant';
355
- /** Number of active anchors (3..12). */
356
- count?: number;
357
- s0?: number;
358
- s1?: number;
359
- s2?: number;
360
- s3?: number;
361
- s4?: number;
362
- s5?: number;
363
- s6?: number;
364
- s7?: number;
365
- s8?: number;
366
- s9?: number;
367
- s10?: number;
368
- s11?: number;
369
- r0?: number;
370
- r1?: number;
371
- r2?: number;
372
- r3?: number;
373
- r4?: number;
374
- r5?: number;
375
- r6?: number;
376
- r7?: number;
377
- r8?: number;
378
- r9?: number;
379
- r10?: number;
380
- r11?: number;
381
- /** Per-anchor weight (0..3). The spline is constructed to pass through every anchor exactly;
382
- * the weight biases how strongly that anchor influences the rest of the curve. Implementation
383
- * detail: blends the C² interpolant with a polynomial fit weighted by w. Default 1 = pure
384
- * C² interpolation; <1 lets the curve sweep past the anchor (anchor still passed through);
385
- * >1 makes the curve hug the anchor more tightly (sharper local bend). */
386
- w0?: number;
387
- w1?: number;
388
- w2?: number;
389
- w3?: number;
390
- w4?: number;
391
- w5?: number;
392
- w6?: number;
393
- w7?: number;
394
- w8?: number;
395
- w9?: number;
396
- w10?: number;
397
- w11?: number;
398
- rotation?: number;
399
- samples?: number;
400
- }
401
-
402
- /**
403
- * Symmetric polar NURBS base. Same anchor concept as `octant-spline` but the curve is an
404
- * **approximating** cubic NURBS — the control points pull the curve without sitting on it.
405
- * Each anchor's weight increases the local pull toward that control point.
406
- *
407
- * Endpoint behaviour: the curve uses mirror-phantom control points just outside [0, 1]
408
- * derived from the second-from-end anchors, which enforces zero slope at s=0 and s=1 so
409
- * the reflected/rotated full silhouette closes cleanly across the symmetry axes.
410
- */
411
- interface OctantBSplineParams {
412
- mode?: 'octant' | 'quadrant';
413
- count?: number;
414
- s0?: number;
415
- s1?: number;
416
- s2?: number;
417
- s3?: number;
418
- s4?: number;
419
- s5?: number;
420
- s6?: number;
421
- s7?: number;
422
- s8?: number;
423
- s9?: number;
424
- s10?: number;
425
- s11?: number;
426
- r0?: number;
427
- r1?: number;
428
- r2?: number;
429
- r3?: number;
430
- r4?: number;
431
- r5?: number;
432
- r6?: number;
433
- r7?: number;
434
- r8?: number;
435
- r9?: number;
436
- r10?: number;
437
- r11?: number;
438
- w0?: number;
439
- w1?: number;
440
- w2?: number;
441
- w3?: number;
442
- w4?: number;
443
- w5?: number;
444
- w6?: number;
445
- w7?: number;
446
- w8?: number;
447
- w9?: number;
448
- w10?: number;
449
- w11?: number;
450
- rotation?: number;
451
- samples?: number;
452
- }
453
-
454
- type RibbonEnd = 'inward' | 'outward' | 'flat';
455
- interface RibbonParams {
456
- left?: RibbonEnd;
457
- right?: RibbonEnd;
458
- /** Taper depth in CSS px. Stays fixed regardless of badge width — viewBox
459
- * vertices are computed at build time using `boxW`. */
460
- taperWidth?: number;
461
- }
462
-
463
- /**
464
- * Shapes one vertical edge of a badge base. Given a position down the edge
465
- * (`t`, 0 at the top to 1 at the bottom) and the configured depth in CSS px,
466
- * returns the horizontal displacement of that point, positive to the right.
467
- */
468
- type EdgeProfile = (t: number, depth: number) => number;
469
- /** The named edge profiles in {@link EDGE_PROFILES}. */
470
- type BuiltInEdgeName = 'flat' | 'chevron' | 'slant' | 'slant-up' | 'round' | 'scallop' | 'concave-chevron';
471
- /** An edge profile, either by name or as a function. */
472
- type EdgeCap = BuiltInEdgeName | EdgeProfile;
473
- /** The built-in {@link EdgeProfile} implementations, by name. */
474
- declare const EDGE_PROFILES: Record<BuiltInEdgeName, EdgeProfile>;
475
-
476
- interface PowerlineParams {
477
- /** Profile for the left edge (the cap segment N inherits from segment N-1). */
478
- leftEdge?: EdgeCap;
479
- /** Profile for the right edge (this segment's own end cap). */
480
- rightEdge?: EdgeCap;
481
- /** Protrusion depth in CSS px (positive values stick out beyond the rect). */
482
- depth?: number;
483
- }
484
-
485
- type BadgeBase = 'chamfered-rect' | 'rounded-rect' | 'polygon' | 'puzzle' | 'quatrefoil' | 'octant-spline' | 'octant-bspline' | 'ribbon' | 'powerline';
486
- interface BadgeBaseParams {
487
- 'chamfered-rect': ChamferedRectParams;
488
- 'rounded-rect': RoundedRectParams;
489
- 'polygon': PolygonParams;
490
- 'puzzle': PuzzleParams;
491
- 'quatrefoil': QuatrefoilParams;
492
- 'octant-spline': OctantSplineParams;
493
- 'octant-bspline': OctantBSplineParams;
494
- 'ribbon': RibbonParams;
495
- 'powerline': PowerlineParams;
496
- }
497
-
498
- interface RangeMaskParams {
499
- /** Optional `[start, end]` as fractions of totalCss (0..1). Restricts the effect to a
500
- * contiguous slice of the perimeter; `end < start` wraps around. */
501
- range?: [number, number];
502
- }
503
-
504
- interface SpikesEffectParams extends RangeMaskParams {
505
- count?: number;
506
- length?: number;
507
- baseWidth?: number;
508
- vertScale?: number;
509
- horzScale?: number;
510
- diagonalScale?: number;
511
- irregularity?: number;
512
- /**
513
- * 0..1 strength of curvature-based shortening on corners. At 1 we fully cancel the tip-arc
514
- * expansion `(1 + κL)` so neighbouring spike tips stay roughly evenly spaced even on tight
515
- * corner arcs; at 0 spikes are constant length and visibly fan outward around corners.
516
- */
517
- cornerCompensation?: number;
518
- }
519
-
520
- interface PuffsEffectParams extends RangeMaskParams {
521
- bumpWidth?: number;
522
- puffiness?: number;
523
- irregularity?: number;
524
- }
525
-
526
- interface BitesEffectParams extends RangeMaskParams {
527
- biteRadius?: number;
528
- biteSpacing?: number;
529
- irregularity?: number;
530
- }
531
-
532
- interface ScallopsEffectParams extends RangeMaskParams {
533
- scallopRadius?: number;
534
- scallopSpacing?: number;
535
- irregularity?: number;
536
- }
537
-
538
- type Corner$2 = 'tl' | 'tr' | 'bl' | 'br';
539
- interface BevelEffectParams {
540
- /** Bevel band width in CSS px. */
541
- bevelWidth?: number;
542
- /** Which corner the light originates from (drives the highlight/shadow distribution across edges). */
543
- lightFrom?: Corner$2;
544
- }
545
-
546
- type Corner$1 = 'tl' | 'tr' | 'bl' | 'br';
547
- interface SheenEffectParams {
548
- lightFrom?: Corner$1;
549
- /** Peak gradient opacity (0..1). */
550
- intensity?: number;
551
- }
552
-
553
- type Corner = 'tl' | 'tr' | 'bl' | 'br';
554
- interface RivetsEffectParams {
555
- /** Rivet radius in CSS px. */
556
- radius?: number;
557
- /** Inset from each corner in CSS px. */
558
- inset?: number;
559
- /** Light origin (drives which side of each rivet gets the highlight). */
560
- lightFrom?: Corner;
561
- }
562
-
563
- interface ShadowEffectParams {
564
- /** Offset in CSS px. */
565
- dx?: number;
566
- dy?: number;
567
- /** Alpha 0..1. */
568
- opacity?: number;
569
- }
570
-
571
- interface WoodgrainEffectParams {
572
- /** Number of grain curves. */
573
- lines?: number;
574
- /** Number of knot circles. */
575
- knots?: number;
576
- /** Overall grain opacity (0..1). */
577
- intensity?: number;
578
- }
579
-
580
- interface PerforationsEffectParams extends RangeMaskParams {
581
- /** Hole radius in CSS px. */
582
- holeRadius?: number;
583
- /** Spacing between hole centers along the perimeter, in CSS px. */
584
- holeSpacing?: number;
585
- }
586
-
587
- interface Bevel2EffectParams {
588
- /** Bevel band width in CSS px. */
589
- bevelWidth?: number;
590
- /** Compass angle the light originates from, in degrees. 0° = top, 90° =
591
- * right, 180° = bottom, 270° = left (CSS `linear-gradient` convention). */
592
- lightFrom?: number;
593
- }
594
-
595
- interface OutlineEffectParams {
596
- /** Stroke width in CSS px. */
597
- width?: number;
598
- /** Stroke color. */
599
- color?: string;
600
- /** Optional SVG dasharray (e.g. "4 2"). */
601
- dash?: string;
602
- /** CSS mix-blend-mode: 'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten',
603
- * 'difference', etc. Useful when the outline color should react to whatever's behind it. */
604
- blendMode?: string;
605
- /** 0..1 stroke opacity. */
606
- opacity?: number;
607
- }
608
-
609
- interface SunbeamsEffectParams {
610
- /** Number of beams (parallelograms) cast across the body. */
611
- count?: number;
612
- /** Beam width in CSS px (measured horizontally before the skew). */
613
- width?: number;
614
- /** Gap between adjacent beams in CSS px. */
615
- gap?: number;
616
- /** Skew angle in degrees. 0 = vertical bars; positive = leaning right. */
617
- angle?: number;
618
- /** 0..1 lightness opacity. */
619
- opacity?: number;
620
- /** Beam color. Defaults to white. */
621
- color?: string;
622
- /** Drift the beam pattern left/right by N CSS px (lets you slide the "window" over the body). */
623
- offset?: number;
624
- /** 0..1 perturbs each beam's width, opacity, and angle slightly with a deterministic
625
- * per-beam noise; 0 = perfectly regular. */
626
- irregularity?: number;
627
- /** Gradient mask angle in degrees. 0 = left→right, 90 = top→bottom. */
628
- gradientAngle?: number;
629
- /** Position along the gradient axis (0..1) where the mask is fully opaque (beams visible). */
630
- gradientStart?: number;
631
- /** Position along the gradient axis (0..1) where the mask is fully transparent (beams faded out). */
632
- gradientEnd?: number;
633
- }
634
-
635
- /**
636
- * Aqua-glass treatment — composes onto any badge silhouette by walking the
637
- * sampler's perimeter and painting four layered sub-effects in one pass:
638
- *
639
- * 1. Body gradient — vertical tint that runs translucent-top through a
640
- * bright equator band into a dark base.
641
- * 2. Specular gloss — upper-hemisphere white-fade clipped to the body.
642
- * 3. Bezel highlight — bright stroke along perimeter segments whose
643
- * outward normal points up (`ny < 0`). On a pill that's
644
- * the upper half; on a hex it's the three top edges;
645
- * on a starburst it's the upward tips. Normal-aware,
646
- * not bbox-aligned, which is what makes it work on
647
- * arbitrary silhouettes.
648
- * 4. Rim outline — faint dark stroke along the full perimeter.
649
- *
650
- * For the *truly* translucent look (with backdrop-filter blur reading the
651
- * surface behind the badge), use this with `variant="outline"` so the badge's
652
- * own flat fill doesn't paint behind the gradient, and set
653
- * `backdrop-filter: blur(...)` on the host element via CSS.
654
- */
655
- interface AquaEffectParams {
656
- /** Body tint. Defaults to `var(--badge-edge)` so the badge's color drives it. */
657
- accent?: string;
658
- /** Stop opacities along the body gradient (0..1). */
659
- topAlpha?: number;
660
- upperAlpha?: number;
661
- /** Equator Y position in viewBox units (0..100). */
662
- equator?: number;
663
- /** Half-width of the transition band around the equator (viewBox units). */
664
- equatorSpread?: number;
665
- /** Mix ratios for the bright equator and dark base stops (0..100, % accent). */
666
- equatorTint?: number;
667
- baseTint?: number;
668
- /** Specular gloss params. */
669
- glossTopAlpha?: number;
670
- glossMidAlpha?: number;
671
- /** Y extent the gloss covers, in viewBox units. 50 = upper hemisphere. */
672
- glossExtent?: number;
673
- /** Normal-aware bezel highlight. */
674
- bezelAlpha?: number;
675
- bezelWidth?: number;
676
- /** Full-perimeter rim. */
677
- rimAlpha?: number;
678
- rimWidth?: number;
679
- }
680
-
681
- /**
682
- * Metal — opaque cousin of the Aqua treatment. Same four sub-passes (body
683
- * gradient, specular gloss, normal-aware bezel, perimeter rim), but tuned
684
- * for an opaque metallic surface with a single tunable `specularity`
685
- * parameter that drives how sharp / contrasty the highlights read.
686
- *
687
- * Low specularity → matte aluminum / brushed pewter feel: muted contrast,
688
- * soft gloss, faint bezel.
689
- * High specularity → chrome / polished steel: sharp specular peak at the
690
- * equator, bright bezel and rim, hard transitions in the body gradient.
691
- *
692
- * The same `specularity` knob multiplies the equator brightness, gloss
693
- * alpha, bezel alpha, and rim alpha — so one slider moves the whole
694
- * surface along a coherent matte-to-mirror axis.
695
- */
696
- interface MetalEffectParams {
697
- /** Base metal color. Defaults to a neutral steel; pass e.g. `'#c8a657'` for brass. */
698
- accent?: string;
699
- /** 0 = matte, 1 = mirror. Multiplies the brightness of the equator, gloss,
700
- * bezel, and rim simultaneously. */
701
- specularity?: number;
702
- /** Equator Y position (viewBox units, 0..100). */
703
- equator?: number;
704
- /** Half-width of the bright equator band. Smaller = sharper specular. */
705
- equatorSpread?: number;
706
- /** How dark the upper and lower extremes are (% accent vs black, 0..100). */
707
- topDarkness?: number;
708
- baseDarkness?: number;
709
- /** Gloss params. */
710
- glossExtent?: number;
711
- /** Per-zone alpha *baselines* — scaled by `specularity`. */
712
- glossAlphaTop?: number;
713
- bezelAlpha?: number;
714
- bezelWidth?: number;
715
- rimAlpha?: number;
716
- rimWidth?: number;
717
- }
718
-
719
- type BadgeEffect = 'spikes' | 'puffs' | 'bites' | 'scallops' | 'bevel' | 'bevel2' | 'sheen' | 'sunbeams' | 'rivets' | 'shadow' | 'woodgrain' | 'perforations' | 'outline' | 'aqua' | 'metal';
720
- interface BadgeEffectParams {
721
- spikes: SpikesEffectParams;
722
- puffs: PuffsEffectParams;
723
- bites: BitesEffectParams;
724
- scallops: ScallopsEffectParams;
725
- bevel: BevelEffectParams;
726
- bevel2: Bevel2EffectParams;
727
- sheen: SheenEffectParams;
728
- rivets: RivetsEffectParams;
729
- shadow: ShadowEffectParams;
730
- woodgrain: WoodgrainEffectParams;
731
- perforations: PerforationsEffectParams;
732
- outline: OutlineEffectParams;
733
- sunbeams: SunbeamsEffectParams;
734
- aqua: AquaEffectParams;
735
- metal: MetalEffectParams;
736
- }
737
- interface EffectSpec<E extends BadgeEffect = BadgeEffect> {
738
- type: E;
739
- params?: BadgeEffectParams[E];
740
- }
741
-
742
- interface BadgeBaseProps extends StanceProps {
743
- /** The status the badge reports. A peer `tone`, or a stance's accent, paints over it. */
744
- status?: BadgeStatus;
745
- variant?: BadgeVariant;
746
- size?: BadgeSize;
747
- /** "Edge bloat": offset every base perimeter sample outward by N CSS px along the normal
748
- * before any compose effects run. Negative values shrink the silhouette. Photoshop-style
749
- * expand-selection on the body. */
750
- bloat?: number;
751
- padding?: number | string;
752
- /**
753
- * For CSS-rendered shapes (pill, plain) that fragment across line wraps, controls how the
754
- * background/border behaves at each break.
755
- * - `'slice'` (default): decoration is severed at the break (looks like one continuous badge cut by the line).
756
- * - `'clone'`: each fragment paints its own complete decoration (looks like two separate badges).
757
- */
758
- breakStyle?: 'slice' | 'clone';
759
- /** When set, perimeter-pattern shapes (beavis, cloud, postage, scalloped) continuously shift their pattern. */
760
- crawl?: boolean | number;
761
- /** Compose-mode: base shape underneath the badge content. When set, overrides the `shape` prop. */
762
- base?: BadgeBase;
763
- baseParams?: BadgeBaseParams[BadgeBase];
764
- /** Compose-mode: layered effects applied around / over the base. */
765
- effects?: EffectSpec[];
766
- onClick?: () => void;
767
- onRemove?: () => void;
768
- removeLabel?: string;
769
- href?: string;
770
- as?: 'span' | 'button' | 'a';
771
- children: ReactNode;
772
- className?: string;
773
- /** Optional style overrides merged with the badge's own style. Useful for setting CSS
774
- * custom properties (e.g. `--badge-edge` to inject a `custom` status color). */
775
- style?: CSSProperties;
776
- 'aria-label'?: string;
777
- /**
778
- * Tooltip content. Wraps the badge in a kit tooltip trigger. A tooltip
779
- * trigger must be focusable and carry a role that announces its
780
- * description, so a badge that is neither a button nor a link joins the tab
781
- * order as `role="img"`, named by `aria-label` or else by string content.
782
- */
783
- tooltip?: ReactNode;
784
- }
785
- /** DOM attributes a badge passes through to its root element, e.g. the ones
786
- * `Focusable` supplies when a badge sits under a `TooltipTrigger`. */
787
- type BadgeDomProps = Omit<HTMLAttributes<HTMLElement>, keyof BadgeBaseProps | 'onClick' | 'children' | 'className' | 'style'>;
788
- type BadgePropsByShape = {
789
- [S in BadgeShape]: BadgeBaseProps & BadgeDomProps & {
790
- shape?: S;
791
- shapeParams?: BadgeShapeParams[S];
792
- };
793
- }[BadgeShape];
794
- /**
795
- * Props for {@link Badge}. Discriminated on `shape` so `shapeParams` is typed
796
- * to the chosen shape's own parameters.
797
- */
798
- type BadgeProps = BadgePropsByShape;
799
- /**
800
- * A small labelled chip. Renders as a `<span>`, or as a `<button>`/`<a>` when
801
- * given `onClick`/`href` — override with `as`.
802
- *
803
- * Beyond the built-in {@link BadgeShape} silhouettes, a badge can be composed:
804
- * `base` picks the underlying outline and `effects` layer perimeter treatments
805
- * over it, which stack additively. `bloat` pushes the whole silhouette outward
806
- * along its normals before effects run, and `crawl` animates perimeter
807
- * patterns.
808
- *
809
- * `ref` and any other DOM attributes forward to the root element.
810
- */
811
- declare const Badge: react.ForwardRefExoticComponent<BadgePropsByShape & react.RefAttributes<HTMLElement>>;
812
-
813
- /**
814
- * One column of a {@link DataGrid}. `id` doubles as the default property name
815
- * read off each row when no `accessor` is given.
816
- */
817
- interface DataGridColumn<Row> {
818
- id: string;
819
- header: ReactNode;
820
- /** Pull a sortable value from the row. Defaults to `(row as any)[column.id]`. */
821
- accessor?: (row: Row) => string | number | null | undefined;
822
- /** Render the cell. Defaults to `String(accessor(row) ?? '')`. */
823
- render?: (row: Row) => ReactNode;
824
- /** Default true. Set false to suppress the sort affordance on this column. */
825
- sortable?: boolean;
826
- /** Optional CSS class on every <td> in this column. */
827
- className?: string;
828
- }
829
- /** Props for {@link DataGrid}. */
830
- interface DataGridProps<Row extends {
831
- id: string;
832
- }> {
833
- rows: readonly Row[];
834
- columns: readonly DataGridColumn<Row>[];
835
- /** Initial sort. Omit for unsorted (rows render in input order). */
836
- defaultSort?: {
837
- columnId: string;
838
- direction: 'asc' | 'desc';
839
- };
840
- /** Enable drag handles in a leading column. Receives the reorder spec
841
- * (the existing `useReorderDragList` semantics — see weasel-ui). */
842
- onReorder?: (ids: string[], targetIndex: number) => void;
843
- /** Empty-state row text. Default `'—'`. */
844
- empty?: ReactNode;
845
- className?: string;
846
- /** Extra class on a row's `<tr>`, for row-level state such as a verdict. */
847
- rowClassName?: (row: Row) => string | undefined;
848
- /**
849
- * Activate a row. Makes each row focusable: a click anywhere in it, or
850
- * Enter/Space while it has focus, calls this. Clicks and keys landing on a
851
- * control inside a cell (button, link, input, …) are left to that control.
852
- */
853
- onRowClick?: (row: Row) => void;
854
- /**
855
- * Content for a full-width detail row under `row`, shown while the row is
856
- * expanded. Setting it adds a leading disclosure column. Return `null` for
857
- * no detail row.
858
- */
859
- renderDetail?: (row: Row) => ReactNode;
860
- /** Which rows offer the disclosure. Default: every row. */
861
- rowExpandable?: (row: Row) => boolean;
862
- /** Expanded row ids, controlled. Pair with `onExpandedChange`. */
863
- expandedIds?: ReadonlySet<string>;
864
- /** Initially expanded row ids when uncontrolled. */
865
- defaultExpandedIds?: Iterable<string>;
866
- /** Called with the next expanded set when a disclosure toggles. */
867
- onExpandedChange?: (ids: ReadonlySet<string>) => void;
868
- }
869
- /**
870
- * Sortable table for inspector-style data. Rows are keyed by `id`. Clicking a
871
- * sortable header cycles ascending, descending, unsorted; nullish values sort
872
- * last regardless of direction. Passing `onReorder` adds a leading drag-handle
873
- * column — note that the drag indices it reports are into the *sorted* row
874
- * order, not the input order.
875
- */
876
- declare function DataGrid<Row extends {
877
- id: string;
878
- }>(props: DataGridProps<Row>): react.JSX.Element;
879
-
880
- /** Props for `<DisclosureMark>`. */
881
- interface DisclosureMarkProps {
882
- /** Whether the section it stands for is open: `−` when open, `+` when shut. */
883
- open: boolean;
884
- /** Mark size in px, square. Default 13. */
885
- size?: number;
886
- className?: string;
887
- }
888
- /**
889
- * The fold mark alone: a dark violet rounded square holding a `+` while its section is
890
- * shut and a `−` while it is open. Decorative — it carries no role or label —
891
- * for a row that is itself the control, such as a tree item or a header
892
- * button. Anywhere the mark has to be the control, use `<Disclosure>`.
893
- *
894
- * Deliberately not part of the icon register, on the same grounds as
895
- * `DragHandleGlyph`: that register is outline strokes at a fixed weight, and
896
- * this mark is filled.
897
- */
898
- declare function DisclosureMark({ open, size, className }: DisclosureMarkProps): react.JSX.Element;
899
- /** Props for `<Disclosure>`. */
900
- interface DisclosureProps {
901
- /** Whether the section it controls is open. The consumer owns this. */
902
- open: boolean;
903
- onToggle: () => void;
904
- /**
905
- * Names the section, for a screen reader. The control has no text of its
906
- * own, so without this it announces as an unlabeled button.
907
- */
908
- label: string;
909
- /**
910
- * `id` of the element this expands. Sets `aria-controls`, which lets a
911
- * screen reader move to the revealed content.
912
- */
913
- controls?: string;
914
- /** Mark size in px. The hit target is at least 20px and grows with it.
915
- * Default 13. */
916
- size?: number;
917
- disabled?: boolean;
918
- className?: string;
919
- }
920
- /**
921
- * The twisty on a collapsible section: a `<DisclosureMark>` in a button.
922
- *
923
- * Presentational — it holds no open/closed state and renders no children.
924
- * The consumer owns the state and the panel; this is the control that toggles
925
- * it, and `aria-expanded` is what ties the two together.
926
- *
927
- * Three things it settles that a hand-rolled twisty keeps getting wrong. The
928
- * mark is drawn rather than typed, because `--wzl-font-ui` carries no ▸/▾ and
929
- * a text glyph falls back to whatever the system offers at whatever size that
930
- * font renders it. The hit target is larger than the mark. And it is a sibling
931
- * of the row's label rather than a child, so clicking to expand does not
932
- * actuate the label's own control.
933
- */
934
- declare function Disclosure({ open, onToggle, label, controls, size, disabled, className }: DisclosureProps): react.JSX.Element;
935
- /** Props for `<DisclosureRow>`. */
936
- interface DisclosureRowProps extends Omit<DisclosureProps, 'className'> {
937
- /** The row's own content — a label, a checkbox, a count. */
938
- children: ReactNode;
939
- className?: string;
940
- }
941
- /**
942
- * A `<Disclosure>` and a row of content beside it, laid out so the twisty
943
- * leads and the content takes the rest.
944
- *
945
- * The layout is the point: the twisty sits *outside* whatever the row puts in
946
- * it, so a row whose content is a `<label>` wrapping a checkbox stays
947
- * clickable as a label without the twisty actuating it.
948
- */
949
- declare function DisclosureRow({ children, className, ...twisty }: DisclosureRowProps): react.JSX.Element;
950
-
951
- /** Props for `<DragGhost>`. */
952
- interface DragGhostProps {
953
- /** The ghost's top-left in client space, and its width — `useReorderDragList`'s `state.ghost` is one. */
954
- at: {
955
- left: number;
956
- top: number;
957
- width: number;
958
- };
959
- /** An element inside the list being dragged from. The ghost portals to its nearest themed ancestor, so it resolves
960
- * the list's tokens without being clipped by the list's panel. */
961
- from: Element;
962
- /** What to draw: copies of the dragged items, or any stand-in for them. */
963
- children: ReactNode;
964
- }
965
- /**
966
- * What follows the pointer during a drag while the dragged items hold their place: `children` on a raised surface at
967
- * a client-space point. Hidden from assistive tech and from the pointer, so it never becomes the drop target.
968
- */
969
- declare function DragGhost({ at, from, children }: DragGhostProps): react.ReactPortal;
970
-
971
- /** Props for `<DragHandleGlyph>`. */
972
- interface DragHandleGlyphProps {
973
- /** Height in px; width scales with it. Default 16. */
974
- size?: number;
975
- }
976
- /** The two-column dot grip used on anything draggable by a handle.
977
- *
978
- * Deliberately not part of the icon register: that register is outline strokes
979
- * at a fixed weight, and a grip is filled dots. Forcing it in would either
980
- * break the register's rule or produce a worse glyph. */
981
- declare function DragHandleGlyph({ size }: DragHandleGlyphProps): react.JSX.Element;
982
-
983
- /**
984
- * Width class of a keycap: a modifier glyph, a multi-character legend that
985
- * needs a wider chip, or a single character in a square one.
986
- */
987
- type KeycapKind = 'modifier' | 'wide' | 'square';
988
- /**
989
- * Picks the chip width for a legend — modifier glyphs and anything longer
990
- * than one character get the wider forms.
991
- */
992
- declare function inferKeycapKind(label: string): KeycapKind;
993
- /** Visual style of a keycap chip. */
994
- type KeyCapVariant = 'default' | 'minimal';
995
- /** Props for {@link KeyCap}. */
996
- interface KeyCapProps {
997
- /** Glyph rendered in the chip (modifier or key). */
998
- label: string;
999
- /** Marks the chip as not required to trigger the action. In the default
1000
- * variant the chip face inverts (dark face / light glyph) for
1001
- * emphasis. In the `'minimal'` variant the chip's border becomes
1002
- * dotted to read as "may be held, but isn't required." */
1003
- inverted?: boolean;
1004
- /** Visual style. `'default'` (default) renders a filled chip; `'minimal'`
1005
- * renders an unfilled chip whose border and legend are `currentColor`
1006
- * — useful inline in colored prose / next to colored badges where the
1007
- * chip should take the surrounding text color. */
1008
- variant?: KeyCapVariant;
1009
- className?: string;
1010
- /** Optional inline style. Useful for one-off width overrides (e.g.
1011
- * building a keyboard-layout where the space bar spans several
1012
- * standard-key widths). The component sets no inline styles of its
1013
- * own — everything else comes from the CSS module. */
1014
- style?: CSSProperties;
1015
- /** Override the chip's font-family. Accepts any CSS font-family
1016
- * string. When omitted, the chip inherits from the design-system
1017
- * UI font token (`--wzl-font-ui`). Useful for one-off cases where
1018
- * a different face is desired — though the canonical move is to
1019
- * override the CSS variable at the consumer's scope, not the prop. */
1020
- font?: string;
1021
- }
1022
- /** Single bordered keycap chip for one glyph (modifier or key). Use
1023
- * `KeySequence` to render a full shortcut. */
1024
- declare function KeyCap({ label, inverted, variant, className, style, font }: KeyCapProps): react.JSX.Element;
1025
-
1026
- /** One key in a shortcut. */
1027
- interface KeySpec {
1028
- /** Glyph rendered in the chip (modifier or key). */
1029
- label: string;
1030
- /** When true, the chip renders inverted to mark it as not required to
1031
- * trigger the action (e.g. an optional modifier). Defaults to false. */
1032
- optional?: boolean;
1033
- }
1034
- /** Props for {@link KeySequence}. */
1035
- interface KeySequenceProps {
1036
- /** Keys to render. `undefined` or empty renders a muted em-dash.
1037
- * Modifiers are always rendered first regardless of input order; relative
1038
- * order within each group is preserved. */
1039
- keys: readonly KeySpec[] | undefined;
1040
- /** Character inserted between the trailing modifier chip and the first
1041
- * non-modifier chip (e.g. `'+'` renders `⌘ + K`). `null` or `''`
1042
- * suppresses it. Defaults to `'+'`. */
1043
- separator?: string | null;
1044
- /** Forwarded to every `KeyCap` in the sequence. `'minimal'` renders
1045
- * unfilled chips whose border + legend are `currentColor`. */
1046
- variant?: KeyCapVariant;
1047
- /** Forwarded to every `KeyCap` in the sequence. Overrides the design-
1048
- * system UI font for that chip only. */
1049
- font?: string;
1050
- className?: string;
1051
- }
1052
- /** Renders a shortcut as a row of `KeyCap` chips, one per key. Optional
1053
- * keys render inverted to distinguish them from required ones. */
1054
- declare function KeySequence({ keys, separator, variant, font, className }: KeySequenceProps): react.JSX.Element;
1055
-
1056
- /** Apple-style glyph for a DOM `KeyboardEvent.key` value. Covers escape,
1057
- * delete/backspace, arrows, enter/return, tab, space. Unknown keys are
1058
- * upper-cased (so `'a'` reads as `A` on a keycap) and returned unchanged
1059
- * otherwise — making this safe to apply uniformly without a `has-glyph`
1060
- * check at the call site. */
1061
- declare function keyGlyph(rawKey: string): string;
1062
-
1063
- /** Logical modifier name. Matches the kit's `ModifierKey` in shape — kept as a
1064
- * local type so `weasel-ui` stays independent of `@weasel-js/core`. */
1065
- type LogicalMod = 'mod' | 'shift' | 'alt' | 'ctrl' | 'meta';
1066
- /** Detected (or overridden) platform. `'mod'` resolves to ⌘ on macOS,
1067
- * Ctrl on Windows / Linux. */
1068
- type Platform = 'macos' | 'windows' | 'linux';
1069
- /** Visual form of a modifier or named-key label.
1070
- *
1071
- * - `'auto'` (default): the per-entry, per-platform default — whatever
1072
- * label is actually printed on the physical key. macOS keys show the
1073
- * Apple glyphs (⌘ ⌥ ⌃ ⇧ ⎋ ↵ ⇥). Windows keys mostly show text
1074
- * (Ctrl, Alt, Shift) BUT the Win key shows its logo (⊞) and the
1075
- * context-menu key shows ▤. Linux mirrors Windows with Super (⊞).
1076
- * - `'symbol'` forces the Apple-style glyph everywhere a symbolic form
1077
- * exists. Entries without a widely-recognized symbol still fall
1078
- * back to text.
1079
- * - `'text'` always spells the label out (Cmd / Option / Esc / Enter). */
1080
- type LegendStyle = 'auto' | 'symbol' | 'text';
1081
- /** A modifier to render, named platform-independently. */
1082
- interface LogicalModSpec {
1083
- name: LogicalMod;
1084
- /** Marks this modifier as optional (may be held but isn't required).
1085
- * Forwarded as the resulting `KeySpec.optional`. */
1086
- optional?: boolean;
1087
- }
1088
- /** Options for {@link keySpecsFromMods}. */
1089
- interface KeySpecsFromModsOptions {
1090
- /** Override OS detection. Defaults to the detected platform, or
1091
- * `'macos'` when detection is unavailable (e.g. in tests, or when
1092
- * `navigator` is missing). */
1093
- platform?: Platform;
1094
- /** Defaults to `'auto'` (symbol on macOS, text everywhere else). Pass
1095
- * `'symbol'` or `'text'` to force a specific style regardless of
1096
- * platform. */
1097
- legend?: LegendStyle;
1098
- }
1099
- /** Detect the user's OS from the browser environment. UA sniffing — not
1100
- * 100% reliable, but adequate for picking a modifier-glyph convention.
1101
- * Falls back to `'macos'` (matches the kit's docs convention) when
1102
- * `navigator` is unavailable. */
1103
- declare function detectPlatform(): Platform;
1104
- /**
1105
- * Map a list of **logical** modifiers (`'mod'`, `'shift'`, …) to **visual**
1106
- * `KeySpec`s appropriate for the current platform.
1107
- *
1108
- * The kit-side gesture grammar uses logical names so the same route reads
1109
- * correctly on every OS — `'mod'` means "Cmd on Mac, Ctrl on Win/Linux".
1110
- * `KeySequence` is purely visual and renders the labels you give it; this
1111
- * helper is the bridge.
1112
- *
1113
- * ```ts
1114
- * <KeySequence
1115
- * keys={keySpecsFromMods([{ name: 'mod' }, { name: 'shift', optional: true }])}
1116
- * />
1117
- * ```
1118
- *
1119
- * On a Mac: renders `⌘ ⇧`. On Windows: renders `Ctrl Shift`. Pass an
1120
- * explicit `platform` to override detection (e.g. for docs that always
1121
- * show the macOS form). Pass `legend: 'text'` to force "Cmd" over "⌘"
1122
- * even on macOS.
1123
- */
1124
- declare function keySpecsFromMods(mods: readonly LogicalModSpec[], opts?: KeySpecsFromModsOptions): readonly KeySpec[];
1125
- /**
1126
- * Render a raw `KeyboardEvent.key` value as a platform-appropriate
1127
- * `KeySpec`. Named non-modifier keys (Esc, Enter, Tab, Space, Backspace,
1128
- * Delete, arrows) get the platform's conventional form. Letter / digit /
1129
- * other keys pass through upper-cased.
1130
- *
1131
- * ```ts
1132
- * keySpecFromKey('Escape', { platform: 'macos' }) // { label: '⎋' }
1133
- * keySpecFromKey('Escape', { platform: 'windows' }) // { label: 'Esc' }
1134
- * keySpecFromKey('p') // { label: 'P' }
1135
- * ```
1136
- *
1137
- * Symbol mode is only meaningful on macOS — Windows / Linux keyboards
1138
- * print the text form on the physical key, so symbol mode there falls
1139
- * back to text.
1140
- */
1141
- declare function keySpecFromKey(raw: string, opts?: KeySpecsFromModsOptions & {
1142
- optional?: boolean;
1143
- }): KeySpec;
1144
-
1145
- interface ShortcutInput {
1146
- key: string | readonly string[];
1147
- mod?: boolean;
1148
- alt?: boolean;
1149
- shift?: boolean | 'optional';
1150
- }
1151
- /** Format a shortcut as an array of display chips, one per key — modifier
1152
- * icons (⌘, ↑, ⌥) followed by the key glyph. UIs that want a boxed
1153
- * per-key look render each chip in its own element. `shift: 'optional'` is
1154
- * treated as falsy. */
1155
- declare function formatShortcutParts(b: ShortcutInput | undefined): readonly string[] | undefined;
1156
- /** Format a shortcut as a single display string. Order: mod, shift, alt,
1157
- * key. Returns `undefined` for `undefined` input so callers can `??` a
1158
- * fallback. When `key` is an array, the first element is used. `shift: 'optional'`
1159
- * is treated as falsy. */
1160
- declare function formatShortcut(b: ShortcutInput | undefined): string | undefined;
1161
-
1162
- /**
1163
- * A shortcut as `KeySequence` keys, one per key: mod, shift, alt, then the
1164
- * key, each in the platform's own legend (`⌘` on macOS, `Ctrl` elsewhere).
1165
- * The `KeySpec` counterpart of `formatShortcutParts`, which always prints
1166
- * macOS glyphs. `shift: 'optional'` becomes an optional key; a key list
1167
- * renders its first key. Returns `undefined` for no shortcut.
1168
- *
1169
- * ```tsx
1170
- * <KeySequence keys={keySpecsFromShortcut({ key: 'z', mod: true, shift: true })} />
1171
- * ```
1172
- */
1173
- declare function keySpecsFromShortcut(shortcut: ShortcutInput | undefined, opts?: KeySpecsFromModsOptions): readonly KeySpec[] | undefined;
1174
-
1175
- /**
1176
- * Passed to a custom thumb renderer: the thumb box in CSS px, and whether
1177
- * this thumb is the one being dragged.
1178
- */
1179
- type ThumbRenderCtx = {
1180
- width: number;
1181
- height: number;
1182
- isActive: boolean;
1183
- };
1184
- /**
1185
- * A thumb's appearance — one of the two built-in shapes, or a custom
1186
- * renderer.
1187
- */
1188
- type ThumbShape = 'round' | 'notched' | {
1189
- render: (ctx: ThumbRenderCtx) => ReactNode;
1190
- };
1191
- /**
1192
- * One handle on a {@link Slider}. `bounds` narrows the range this particular
1193
- * thumb may move within, either fixed or computed from the current thumb
1194
- * list.
1195
- */
1196
- type Thumb = {
1197
- value: number;
1198
- label?: string;
1199
- shape?: ThumbShape;
1200
- bounds?: [number, number] | ((ctx: BoundsCtx) => [number, number]);
1201
- /**
1202
- * Spoken form of `value`, published as `aria-valuetext`. Required by ARIA
1203
- * whenever `value` is not the quantity the user is choosing — an index into
1204
- * a value list, a log-scaled position — since `aria-valuenow` alone then
1205
- * announces a number that means nothing.
1206
- */
1207
- valueText?: string;
1208
- };
1209
- /**
1210
- * Passed to a thumb's `bounds` function: the full thumb list and this thumb's
1211
- * index in it, so a bound can be expressed relative to its neighbors.
1212
- */
1213
- type BoundsCtx = {
1214
- thumbs: readonly Thumb[];
1215
- index: number;
1216
- };
1217
- /**
1218
- * Passed to `renderTrack`: the track's width in CSS px and a mapping from a
1219
- * slider value to its 0..1 position along the track.
1220
- */
1221
- type TrackCtx = {
1222
- trackWidth: number;
1223
- valueToFraction: (v: number) => number;
1224
- };
1225
- /** A {@link Slider} stop that carries a label, drawn under the track at the stop. */
1226
- type SliderStop = {
1227
- value: number;
1228
- label?: ReactNode;
1229
- };
1230
- /**
1231
- * Props for {@link Slider}.
1232
- *
1233
- * `onInput` fires continuously through a drag; `onChange` fires once when it
1234
- * ends and is the one to write to history.
1235
- *
1236
- * `stops` are attractors: a drag that passes within a few pixels of one lands
1237
- * on it, and the arrow keys move stop to stop. `step` still quantizes the
1238
- * values between them. Each one is drawn on the track as a mark; pass
1239
- * `showStops: false` for a track whose own paint already reads as the stops.
1240
- * A stop given as a {@link SliderStop} with a `label` gets that label drawn
1241
- * under it; `stopLabels` narrows the row to the two ends or turns it off.
1242
- *
1243
- * `snap: 'strict'` makes every stop a detent the thumb must rest on: drags and
1244
- * track presses land on the nearest one, and `step` no longer applies.
1245
- * `spacing: 'even'` places the stops at equal intervals, runs the track from
1246
- * the first stop to the last, and maps values linearly within each gap — so a
1247
- * geometric list (0.25/0.5/1/2/4) gets usable room for every stop instead of
1248
- * four crowded into the first fifth. Both need stops; with fewer than two,
1249
- * `'even'` falls back to linear.
1250
- *
1251
- * `trackClick: 'move-nearest'` makes a press on bare track send the closest
1252
- * thumb there, focus it, and continue as a drag. It is the default for a
1253
- * single thumb. With several it defaults to `'none'`, because on a
1254
- * multi-thumb editor a stray click would yank a stop the user was not aiming
1255
- * at; `onAddThumb`, where it is set, keeps the track press.
1256
- *
1257
- * `constraint: 'ordered'` keeps thumbs from crossing each other. Supplying
1258
- * `onAddThumb` makes a click on empty track create a thumb, and supplying
1259
- * `onRemoveThumb` lets a right-click or a drag off the track remove one —
1260
- * both callbacks can decline by returning `null`/`false`. `allowShiftAll`
1261
- * makes shift-drag translate every thumb together.
1262
- */
1263
- type SliderProps<T extends Thumb = Thumb> = {
1264
- thumbs: readonly T[];
1265
- onInput: (next: T[]) => void;
1266
- onChange?: (next: T[]) => void;
1267
- min: number;
1268
- max: number;
1269
- step?: number;
1270
- stops?: readonly (number | SliderStop)[];
1271
- showStops?: boolean;
1272
- stopLabels?: 'all' | 'ends' | 'none';
1273
- snap?: 'magnetic' | 'strict';
1274
- spacing?: 'linear' | 'even';
1275
- trackClick?: 'none' | 'move-nearest';
1276
- constraint?: 'free' | 'ordered';
1277
- onAddThumb?: (atValue: number) => T | null;
1278
- onRemoveThumb?: (index: number) => boolean;
1279
- allowShiftAll?: boolean;
1280
- renderTrack?: (ctx: TrackCtx) => ReactNode;
1281
- trackHeight?: number;
1282
- /** `'slim'` drives the track and thumb from the kit's slider tokens, so a
1283
- * Slider matches the property rows. `trackHeight` still wins if given. */
1284
- density?: 'default' | 'slim';
1285
- renderReadout?: (thumb: T, index: number) => ReactNode;
1286
- readoutPlacement?: 'none' | 'inline-after' | 'below-thumb';
1287
- ariaLabel?: string;
1288
- className?: string;
1289
- };
1290
- /**
1291
- * Multi-thumb slider over a shared track. The thumb list is fully controlled:
1292
- * every change, live or committed, arrives as a whole new array.
1293
- *
1294
- * Thumbs are draggable, and arrow/Home/End move the focused thumb — those
1295
- * keystrokes fire `onInput` and `onChange` together, since there is no
1296
- * in-flight state to buffer.
1297
- */
1298
- declare function Slider<T extends Thumb = Thumb>(props: SliderProps<T>): ReactElement;
1299
-
1300
- /** One row in a reorderable list. */
1301
- interface ReorderItem {
1302
- id: string;
1303
- label: ReactNode;
1304
- /** Locked rows cannot be dragged, cannot be crossed by drops, and
1305
- * never combine with other rows in a multi-selection. */
1306
- locked?: boolean;
1307
- }
1308
- /**
1309
- * Options for {@link useReorderDragList}. `onReorder` receives the dragged ids
1310
- * and the index they were dropped at, measured against the pre-drag `items`.
1311
- */
1312
- interface UseReorderDragListOptions {
1313
- items: ReorderItem[];
1314
- selectedIds: string[];
1315
- onReorder(ids: string[], targetIndex: number): void;
1316
- /** A press that was released without ever engaging a drag — the click a
1317
- * list row means by it. Fires for locked rows too, which can be selected
1318
- * but not dragged. Modifiers are read at press, not at release. When this
1319
- * is given, the DOM click that follows the press is dropped, so a row that
1320
- * also handles `click` sees one press, not two. A press that starts on a
1321
- * control inside the row (a toggle) is left to the control. */
1322
- onPress?(id: string, mods: PressModifiers): void;
1323
- /** Pointer-move distance (px) before pending drag engages. Default 4. */
1324
- threshold?: number;
1325
- /** Selector matching the container's children that are rows, for a list
1326
- * that interleaves other elements (a table's detail rows). Default: every
1327
- * child is a row. */
1328
- rowSelector?: string;
1329
- }
1330
- /** Modifier keys held when a press began. */
1331
- interface PressModifiers {
1332
- shiftKey: boolean;
1333
- ctrlKey: boolean;
1334
- metaKey: boolean;
1335
- altKey: boolean;
1336
- }
1337
- /**
1338
- * Where a drag's ghost goes: the dragged rows, drawn again with their top-left
1339
- * at a client-space point, so the row that was grabbed stays under the pointer
1340
- * where it was picked up. `width` is the grabbed row's.
1341
- */
1342
- interface ReorderGhost {
1343
- ids: readonly string[];
1344
- left: number;
1345
- top: number;
1346
- width: number;
1347
- }
1348
- /**
1349
- * Live drag state for rendering feedback: which ids are being dragged, the
1350
- * insertion index the drop would use, and where their ghost goes. All `null`
1351
- * when no drag is engaged.
1352
- */
1353
- interface ReorderDragState {
1354
- draggedIds: string[] | null;
1355
- targetIndex: number | null;
1356
- ghost: ReorderGhost | null;
1357
- }
1358
- /**
1359
- * A `ref` for the list container, an `onPointerDown` for each row, and the
1360
- * live {@link ReorderDragState}. The container ref is required, not optional
1361
- * decoration: it is what the drop index is measured against and what the
1362
- * pointer session is opened on.
1363
- */
1364
- interface ReorderDragHandlers {
1365
- rowProps(id: string, index: number): {
1366
- onPointerDown(e: PointerEvent): void;
1367
- };
1368
- containerProps: {
1369
- ref: RefCallback<HTMLElement>;
1370
- };
1371
- state: ReorderDragState;
1372
- /**
1373
- * Move the row at `index` one place up (`-1`) or down (`1`) — the keyboard
1374
- * reorder. It moves what a drag of that row would: the whole selection if
1375
- * the row is in it, else the row alone, never across a locked row. Calls
1376
- * `onReorder` and returns `true`, or returns `false` when nothing can move.
1377
- */
1378
- nudge(id: string, index: number, delta: -1 | 1): boolean;
1379
- }
1380
- /**
1381
- * Drag-to-reorder for a vertical list of rows. Dragging a row that is part of
1382
- * the current selection drags the whole selection; dragging any other row
1383
- * drags just that row. Locked rows can neither be dragged nor crossed by a
1384
- * drop. A drop that would leave a contiguous block where it already is does
1385
- * not call `onReorder`.
1386
- *
1387
- * The rows are the container's children, whatever they are: `ItemList` rows,
1388
- * or the `PropertyGroup`s of a `PropertyList`. A row's `onPointerDown` can go
1389
- * on the whole row or on a handle inside it.
1390
- *
1391
- * A press opens a `startThresholdDrag` on the *container*, which owns the
1392
- * rest of the gesture: a drag that leaves the list still tracks, a release
1393
- * anywhere still drops, and a release the window never delivered still ends
1394
- * the drag. The container is the origin rather than the row because rows come
1395
- * and go as the list re-renders, and a drag must outlive the row it grabbed.
1396
- */
1397
- declare function useReorderDragList(opts: UseReorderDragListOptions): ReorderDragHandlers;
1398
-
1399
- /** Props for {@link ListEditor}. */
1400
- interface ListEditorProps {
1401
- value: readonly string[];
1402
- /** Every edit, add and removal, with the whole list. Entries are written as
1403
- * typed — an empty one stays until it is removed. */
1404
- onChange: (next: string[]) => void;
1405
- /** Shown in an empty entry. */
1406
- placeholder?: string;
1407
- /** Shown in place of the entries when there are none. */
1408
- empty?: string;
1409
- /** Text of the add button. */
1410
- addLabel?: string;
1411
- /** Names the list for assistive tech; each entry is named from it. */
1412
- 'aria-label'?: string;
1413
- className?: string;
1414
- }
1415
- /**
1416
- * An editable list of strings: one field per entry, a remove button beside
1417
- * each, and an add button under them. Enter in an entry adds one after it;
1418
- * Backspace in an empty one removes it.
1419
- */
1420
- declare function ListEditor({ value, onChange, placeholder, empty, addLabel, 'aria-label': ariaLabel, className, }: ListEditorProps): react.JSX.Element;
1421
-
1422
- /** Props for {@link ColorModeControl}. */
1423
- interface ColorModeControlProps {
1424
- value: ColorModePreference;
1425
- onChange: (next: ColorModePreference) => void;
1426
- /** Accessible name of the group. Defaults to `'Color mode'`. */
1427
- ariaLabel?: string;
1428
- size?: ToggleBarSize;
1429
- variant?: ToggleBarVariant;
1430
- className?: string;
1431
- }
1432
- /**
1433
- * The Auto / Light / Dark choice, as a three-way radiogroup of mode glyphs.
1434
- * Controlled: pair it with `useColorModePreference` from
1435
- * `@weasel-js/theme/react` and put the hook's resolved `mode` in the
1436
- * `ThemeProvider` selection.
1437
- */
1438
- declare function ColorModeControl({ value, onChange, ariaLabel, size, variant, className, }: ColorModeControlProps): ReactElement;
1439
-
1440
- /**
1441
- * One segment of an {@link OptionsBar}. Unlike `ToggleBar`, each item carries
1442
- * its own selected state and its own `onChange`.
1443
- */
1444
- type OptionsBarItem<V extends string | number = string> = {
1445
- value: V;
1446
- label?: ReactNode;
1447
- ariaLabel?: string;
1448
- disabled?: boolean;
1449
- selected: boolean;
1450
- onChange: (next: boolean) => void;
1451
- };
1452
- /** Segment height and type scale for an {@link OptionsBar}. */
1453
- type OptionsBarSize = 'sm' | 'md';
1454
- /** Visual treatment of an {@link OptionsBar}. */
1455
- type OptionsBarVariant = 'default' | 'minimal';
1456
- /** Props for {@link OptionsBar}. */
1457
- type OptionsBarProps<V extends string | number = string> = {
1458
- items: readonly OptionsBarItem<V>[];
1459
- ariaLabel?: string;
1460
- className?: string;
1461
- height?: number;
1462
- /** Size variant. `sm` is ~60% of the default height with reduced padding
1463
- * and font size — sized for dense surfaces like lab control panels. */
1464
- size?: OptionsBarSize;
1465
- /** Visual variant. `minimal` strips the pill track and glass treatment;
1466
- * selection becomes a flat accent. For dense diagnostic surfaces. */
1467
- variant?: OptionsBarVariant;
1468
- };
1469
- /**
1470
- * Segmented strip of independent on/off options, each owning its own state.
1471
- * Use it when the segments are unrelated booleans; use `ToggleBar` when they
1472
- * are values of one setting.
1473
- */
1474
- declare function OptionsBar<V extends string | number = string>(props: OptionsBarProps<V>): ReactElement;
1475
-
1476
- /**
1477
- * One button in an {@link ButtonBar}. `value` is only a React key; the item
1478
- * carries no selected state.
1479
- */
1480
- type ButtonBarItem<V extends string | number = string> = {
1481
- value: V;
1482
- label?: ReactNode;
1483
- ariaLabel?: string;
1484
- disabled?: boolean;
1485
- onAction: () => void;
1486
- } & SegmentTooltipFields;
1487
- /** Segment height and type scale for an {@link ButtonBar}. */
1488
- type ButtonBarSize = 'sm' | 'md';
1489
- /** Visual treatment of an {@link ButtonBar}. */
1490
- type ButtonBarVariant = 'default' | 'minimal';
1491
- /** Props for {@link ButtonBar}. */
1492
- type ButtonBarProps<V extends string | number = string> = {
1493
- items: readonly ButtonBarItem<V>[];
1494
- ariaLabel?: string;
1495
- className?: string;
1496
- height?: number;
1497
- size?: ButtonBarSize;
1498
- variant?: ButtonBarVariant;
1499
- };
1500
- /**
1501
- * Segmented strip of momentary buttons — each press fires and nothing stays
1502
- * selected. Shares the look and the arrow-key navigation of `ToggleBar` and
1503
- * `OptionsBar`.
1504
- *
1505
- * This is a plain callback bar. For buttons driven by the kit's actions
1506
- * registry, use `ActionBar` instead.
1507
- */
1508
- declare function ButtonBar<V extends string | number = string>(props: ButtonBarProps<V>): ReactElement;
1509
-
1510
- /**
1511
- * One segment of a {@link Powerline}. Giving it `onClick` or `href` makes it
1512
- * interactive, the same way it does on a `Badge`.
1513
- */
1514
- interface PowerlineSegment extends StanceProps {
1515
- text: ReactNode;
1516
- /** Cap on this segment's right edge. Next segment's left edge adopts the same profile. */
1517
- endCap?: EdgeCap;
1518
- status?: BadgeStatus;
1519
- variant?: BadgeVariant;
1520
- size?: BadgeSize;
1521
- onClick?: () => void;
1522
- href?: string;
1523
- 'aria-label'?: string;
1524
- }
1525
- /** Props for {@link Powerline}. */
1526
- interface PowerlineProps {
1527
- segments: PowerlineSegment[];
1528
- /** Left edge of the first segment. Defaults to 'flat'. */
1529
- startCap?: EdgeCap;
1530
- /** Default size for every segment (per-segment `size` wins). */
1531
- size?: BadgeSize;
1532
- /** Default variant for every segment (per-segment `variant` wins). */
1533
- variant?: BadgeVariant;
1534
- /** Protrusion depth in CSS px, passed through to every segment's base. */
1535
- depth?: number;
1536
- /** Visible gap between adjacent segments. Number → px; string → literal CSS length.
1537
- * Default: `0.2em` (scales with the row's font size). Pass `0` for flush. */
1538
- gap?: number | string;
1539
- className?: string;
1540
- 'aria-label'?: string;
1541
- }
1542
- /**
1543
- * A row of chevron-linked badge segments, in the style of a shell powerline
1544
- * prompt. Each segment's `endCap` shapes both its own right edge and the next
1545
- * segment's left edge, so the run reads as one continuous chain.
1546
- *
1547
- * Built for showing a path through a sequence of steps — the inspector uses
1548
- * it to display how input routes from tool to gesture to action to target.
1549
- */
1550
- declare function Powerline({ segments, startCap, size, variant, depth, gap, className, ...rest }: PowerlineProps): react.JSX.Element;
1551
-
1552
- /** Distinguishes a leaf from a group while walking a schema tree. */
1553
- declare function isPrefLeaf(node: ToolPrefLeaf | ToolPrefGroup): node is ToolPrefLeaf;
1554
- /** Get the value at a dotted path inside a nested value tree. Returns
1555
- * `undefined` when a segment is missing or hits a non-object. */
1556
- declare function prefValueAtPath(values: unknown, path: string): unknown;
1557
- /**
1558
- * Recursively drop `hidden` leaves (unless `showHidden`), pruning groups
1559
- * that end up empty. Returns null when the entire subtree is hidden.
1560
- */
1561
- declare function visiblePrefSubtree<T extends ToolPrefLeaf | ToolPrefGroup>(node: T, showHidden: boolean): T | null;
1562
-
1563
- /** How a {@link PrefsForm} lays its groups out. */
1564
- type PrefsLayout = 'columns' | 'rail';
1565
- /** Props for {@link PrefsForm}. */
1566
- interface PrefsFormProps {
1567
- /** Root of the schema tree. Core `ToolPrefGroup`s assign structurally. */
1568
- schema: ToolPrefGroup;
1569
- /** Nested value tree (shape mirrors the schema). Sparse is fine —
1570
- * missing leaves fall back to their schema `default`. */
1571
- values?: unknown;
1572
- /** Change callback with the leaf's dotted path. Values apply live;
1573
- * there is no dirty/commit state. */
1574
- onChange: (path: string, value: unknown) => void;
1575
- /**
1576
- * Per-kind renderers for app-defined kinds. Entries also override the
1577
- * built-in kinds when keys collide. A renderer owns the control cell
1578
- * (the label/tooltip row chrome stays with the form, unless the leaf
1579
- * sets `block`); returning `null` collapses the row entirely. Unknown
1580
- * kinds with no renderer show a labeled placeholder instead of
1581
- * crashing.
1582
- */
1583
- renderers?: Record<string, PrefRenderer>;
1584
- /** Reveal `hidden` leaves (dev tooling). Default false. */
1585
- showHidden?: boolean;
1586
- /**
1587
- * `'columns'` (the default) wraps each top-level group into its own panel
1588
- * column. `'rail'` puts a two-level navigation rail beside one group's
1589
- * settings at a time — what a dialog-sized surface wants, since columns
1590
- * overflow sideways once there are more than two.
1591
- */
1592
- layout?: PrefsLayout;
1593
- /** Show a filter field that narrows the form to matching leaves. */
1594
- filterable?: boolean;
1595
- /** Rail layout: path of the open top-level group. Controlled. */
1596
- section?: string;
1597
- /** Rail layout: path of the group open before the reader picks one.
1598
- * Defaults to the first in the schema. */
1599
- defaultSection?: string;
1600
- onSectionChange?: (path: string) => void;
1601
- className?: string;
1602
- }
1603
- /**
1604
- * Schema-driven preferences form. Leaves render as label + control rows;
1605
- * how the groups around them are arranged is `layout`'s to say — columns of
1606
- * panels, or a navigation rail beside one group at a time.
1607
- *
1608
- * Storage-agnostic: pair with `PrefsDialog` for the modal composition, and
1609
- * persist however the app likes via `onChange`.
1610
- */
1611
- declare function PrefsForm(props: PrefsFormProps): react.JSX.Element;
1612
-
1613
- /**
1614
- * Props for {@link PrefsDialog} — everything {@link PrefsForm} takes, plus
1615
- * the dialog's own open state and chrome.
1616
- */
1617
- interface PrefsDialogProps extends PrefsFormProps {
1618
- isOpen: boolean;
1619
- onOpenChange: (open: boolean) => void;
1620
- /** Dialog heading. Defaults to the schema root's `name`. */
1621
- title?: ReactNode;
1622
- /** Extra chrome rendered at the end of the title row (e.g. a dev-mode
1623
- * "Show hidden" switch). An action the reader acts on when they are done
1624
- * — resetting, importing — belongs in `footer` instead, where a dialog's
1625
- * actions live. */
1626
- headerExtra?: ReactNode;
1627
- /** Footer slot, passed through to `Dialog` — typically a reset or done
1628
- * action. */
1629
- footer?: ReactNode;
1630
- /** Class applied to the dialog's modal box. */
1631
- dialogClassName?: string;
1632
- }
1633
- /**
1634
- * The kit's preferences dialog: `Dialog` + `PrefsForm`. Changes apply
1635
- * live through `onChange` — there is no OK/Cancel staging. For custom
1636
- * placement (sidebar, popover, inline page), compose `PrefsForm`
1637
- * directly; this wrapper is intentionally thin.
1638
- *
1639
- * `layout="rail"` is what a dialog usually wants: the default columns wrap
1640
- * sideways past two groups, and this box is 900px at its widest.
1641
- */
1642
- declare function PrefsDialog(props: PrefsDialogProps): react.JSX.Element;
1643
-
1644
- /** Props for {@link Sidebar}. */
1645
- interface SidebarProps {
1646
- /**
1647
- * Edge the sidebar docks to. Adds a class hook (`s.left` / `s.right`)
1648
- * so consumers can target either edge for borders, shadows, etc.
1649
- * Purely cosmetic — layout is the parent's job.
1650
- */
1651
- side?: 'left' | 'right';
1652
- /**
1653
- * Accessible label — rendered onto the `<aside>`. Without it, screen
1654
- * readers fall back to "complementary landmark," which is fine for
1655
- * apps with a single sidebar but ambiguous when there's both a left
1656
- * and a right.
1657
- */
1658
- ariaLabel?: string;
1659
- children?: ReactNode;
1660
- className?: string;
1661
- /** Inline style — useful for width-as-custom-property handles or any
1662
- * other one-off CSS property the consumer wants to set dynamically. */
1663
- style?: CSSProperties;
1664
- }
1665
- /**
1666
- * Generic sidebar shell — `<aside>` with column layout and token-driven
1667
- * surface treatment. Width, sticky positioning, and resize handles stay
1668
- * the consumer's concern (every app has its own layout grid); the kit
1669
- * just provides the chrome.
1670
- *
1671
- * Pair with `<SidebarPanel>` for collapsible sections.
1672
- */
1673
- declare function Sidebar(props: SidebarProps): react.JSX.Element;
1674
-
1675
- /** Props for {@link SidebarPanel}. */
1676
- interface SidebarPanelProps {
1677
- /** Title rendered in the panel's header row. */
1678
- title?: ReactNode;
1679
- /**
1680
- * Collapsed state — when true, only the header paints; the body is
1681
- * omitted. Caller owns the state (typically via prefs) and flips it
1682
- * back via `onToggleCollapse`.
1683
- */
1684
- collapsed?: boolean;
1685
- /**
1686
- * Click handler for the title row. When provided, the header renders
1687
- * as a button (fold mark + label) and acts as the collapse toggle.
1688
- * When omitted, the title is static text and the panel can't collapse.
1689
- */
1690
- onToggleCollapse?(): void;
1691
- /**
1692
- * Optional close handler — when provided, the header gains a `×`
1693
- * button on the trailing edge. Caller flips its "hidden" state and
1694
- * conditionally unmounts the panel from the parent.
1695
- */
1696
- onHide?(): void;
1697
- children?: ReactNode;
1698
- className?: string;
1699
- }
1700
- /**
1701
- * Generic collapsible panel section for sidebars. Pure presentation —
1702
- * caller manages `collapsed`/`hidden` state externally (the pattern is
1703
- * to drive it from app prefs so the Preferences modal and inline
1704
- * fold marks toggle the same map).
1705
- *
1706
- * Pair with `<Sidebar>` for the docked column layout.
1707
- */
1708
- declare function SidebarPanel(props: SidebarPanelProps): react.JSX.Element;
1709
-
1710
- /** Props for {@link ToolButton}. */
1711
- interface ToolButtonProps {
1712
- /** Icon node (typically an SVG component). */
1713
- icon: ReactNode;
1714
- /** Human-readable label shown under the icon. */
1715
- label: string;
1716
- /** Optional shortcut hint (e.g. "V" or "⌘Z"). */
1717
- shortcut?: string;
1718
- /** Selected/active state — toggles the active visual treatment. */
1719
- active?: boolean;
1720
- /** Disabled state — passes through to the underlying button. */
1721
- disabled?: boolean;
1722
- /**
1723
- * When true, sets `aria-disabled="true"` on the button without using the
1724
- * native `disabled` attribute. This keeps the button focusable and reachable
1725
- * by keyboard (roving-tabindex still applies) while marking it as ineligible
1726
- * to screen readers. The caller is responsible for making `onClick` a no-op.
1727
- */
1728
- ariaDisabled?: boolean;
1729
- /**
1730
- * Whether this button is the currently tabbable member of its toolbar.
1731
- * Toolbars use roving tabindex: exactly one button has `tabIndex=0` at
1732
- * a time; the rest are `-1`. Caller manages which.
1733
- */
1734
- tabbable?: boolean;
1735
- /** Click handler. */
1736
- onClick(): void;
1737
- /** Key handler for the underlying button — a toolbar's roving-tabindex
1738
- * navigation attaches here. */
1739
- onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
1740
- /**
1741
- * Tooltip content. Defaults to `label` (plus `shortcut` if provided).
1742
- */
1743
- title?: string;
1744
- /** Additional class for the root button. */
1745
- className?: string;
1746
- }
1747
- /**
1748
- * Generic icon-+-label toolbar button — building block for `ToolPalette`
1749
- * and similar surfaces. Headless about layout direction (parent group
1750
- * supplies flex direction via `ToolGroup`). Theme via `--wzl-*` tokens.
1751
- */
1752
- declare function ToolButton(props: ToolButtonProps): react.JSX.Element;
1753
-
1754
- /** Props for {@link ToolGroup}. */
1755
- interface ToolGroupProps {
1756
- children: ReactNode;
1757
- /**
1758
- * Lays children along an axis. `'vertical'` (default) stacks them in
1759
- * a column; `'horizontal'` lays them in a row. Independent of the
1760
- * parent toolbar's own orientation.
1761
- */
1762
- orientation?: 'vertical' | 'horizontal';
1763
- /**
1764
- * Optional `data-group` attribute — useful for parents that want to
1765
- * select the group from CSS or tests by name.
1766
- */
1767
- groupKey?: string;
1768
- /** Accessible name for the group (rendered as `aria-label`). */
1769
- ariaLabel?: string;
1770
- className?: string;
1771
- }
1772
- /**
1773
- * Generic toolbar group — a `role="group"` flex container that arranges
1774
- * `<ToolButton>`s (or any children) along a chosen axis. No visual chrome
1775
- * beyond layout; theming lives on the buttons.
1776
- */
1777
- declare function ToolGroup(props: ToolGroupProps): react.JSX.Element;
1778
-
1779
- /** The full vocabulary of capability tags shipped in the default preset.
1780
- * Apps and other consumers can add their own tags; this list is what
1781
- * `weasel-modes` itself uses. */
1782
- declare const ALL_TAGS: readonly ["navigation", "creates-selection", "creates-paths", "creates-shapes", "creates-text", "edits-anchors", "edits-text", "transforms-selection", "samples-color", "applies-fill", "edits-page"];
1783
- /** One capability a tool or contribution declares, and a mode allows. Any
1784
- * string is accepted so apps can add tags of their own; `ALL_TAGS` is the
1785
- * set this package ships. */
1786
- type CapabilityTag = (typeof ALL_TAGS)[number] | (string & {});
1787
-
1788
- /** How a mode tints the workspace — the area around the page — so the user
1789
- * can see at a glance which mode is active. */
1790
- interface WorkspaceVisual {
1791
- tint?: string;
1792
- gradient?: 'top-down' | 'bottom-up';
1793
- intensity?: number;
1794
- }
1795
- /**
1796
- * A mode: an app-level editing context that narrows which tools are usable and
1797
- * how the workspace looks. Tools live inside modes; a tool is never "in" one.
1798
- *
1799
- * `kind` picks the lifecycle. A `soft` mode (path-edit, isolation, text-edit)
1800
- * is a scoped context with no commit ceremony — every edit inside it is
1801
- * independently undoable and `exit` is non-destructive. A `strict` mode
1802
- * (free-transform, crop) is a transaction: the whole session collapses to one
1803
- * undoable step and leaving requires an explicit `commit` or `cancel`.
1804
- */
1805
- interface ModeDefinition {
1806
- id: string;
1807
- /** Human-readable name for chrome — a breadcrumb, a status bar. Falls back
1808
- * to `id`; read it through {@link modeLabel}. */
1809
- label?: string;
1810
- /** One sentence on what the mode is for, for a tooltip or a hint line. */
1811
- description?: string;
1812
- kind: 'soft' | 'strict';
1813
- /** Capability tags this mode allows beyond IMPLICIT_TAGS. */
1814
- allows: CapabilityTag[];
1815
- /** When true, out-of-target objects dim at the renderer layer. */
1816
- scoping: boolean;
1817
- workspace?: WorkspaceVisual;
1818
- entry?: {
1819
- shortcut?: string;
1820
- trigger?: 'double-click-target';
1821
- };
1822
- exit?: {
1823
- shortcut?: string;
1824
- };
1825
- commit?: {
1826
- shortcut?: string;
1827
- };
1828
- cancel?: {
1829
- shortcut?: string;
1830
- };
1831
- }
1832
-
1833
- /** Holds the set of available modes and which one is active, and notifies
1834
- * subscribers when that changes. `getVersion` is a monotonic counter for
1835
- * render-cache invalidation. Unknown mode ids throw rather than being
1836
- * ignored. */
1837
- interface ModeRegistry {
1838
- current(): ModeDefinition;
1839
- setMode(id: string): void;
1840
- byId(id: string): ModeDefinition;
1841
- getVersion(): number;
1842
- subscribe(listener: () => void): () => void;
1843
- }
1844
-
1845
- /** Props for {@link ToolPalette}. */
1846
- interface ToolPaletteProps {
1847
- tools: ToolsApi;
1848
- orientation?: 'vertical' | 'horizontal';
1849
- className?: string;
1850
- /** Derive the keyboard shortcut for a tool button from the action registry.
1851
- * Called with the tool's id; return `undefined` to suppress a chip. When
1852
- * omitted, falls back to `tool.keybinding` (legacy path). */
1853
- lookupShortcut?: (toolId: string) => ShortcutInput | undefined;
1854
- /**
1855
- * Optional mode registry. When provided, tools whose
1856
- * `eligibility.capabilities` do not match the current mode are rendered
1857
- * greyed-out, aria-disabled, and their onClick is suppressed. When omitted,
1858
- * all tools are treated as eligible (preserves existing behavior in
1859
- * consumers that haven't wired a registry).
1860
- */
1861
- modeRegistry?: ModeRegistry;
1862
- /**
1863
- * Presentation-group display order. Groups not listed keep their registry
1864
- * insertion order after the listed ones; `misc` always renders last.
1865
- * Defaults to `['select', 'shape', 'draw', 'type', 'view']`.
1866
- */
1867
- groupOrder?: readonly string[];
1868
- }
1869
- /**
1870
- * Toolbar of the registered tools, split into separator-divided groups by
1871
- * each tool's presentation group and navigable by arrow keys. Clicking a
1872
- * button makes that tool active.
1873
- *
1874
- * Given a `modeRegistry`, tools whose capabilities the current mode does not
1875
- * allow render greyed out and inert rather than disappearing.
1876
- */
1877
- declare function ToolPalette(props: ToolPaletteProps): react.JSX.Element;
1878
-
1879
- /**
1880
- * Props for {@link Checkbox}, on top of React Aria's `Checkbox` props. The
1881
- * label is passed as children.
1882
- */
1883
- type CheckboxProps = Omit<CheckboxProps$1, 'children' | 'className'> & {
1884
- children?: ReactNode;
1885
- className?: string;
1886
- };
1887
- /**
1888
- * Single checkbox wrapping React Aria's Checkbox. Supports indeterminate
1889
- * via `isIndeterminate`. The label is supplied as children.
1890
- */
1891
- declare const Checkbox: react.ForwardRefExoticComponent<Omit<CheckboxProps$1, "className" | "children"> & {
1892
- children?: ReactNode;
1893
- className?: string;
1894
- } & react.RefAttributes<HTMLLabelElement>>;
1895
-
1896
- /**
1897
- * Props for {@link Switch}, on top of React Aria's `Switch` props. The label
1898
- * is passed as children.
1899
- */
1900
- type SwitchProps = Omit<SwitchProps$1, 'children' | 'className'> & {
1901
- children?: ReactNode;
1902
- className?: string;
1903
- };
1904
- /**
1905
- * On/off toggle wrapping React Aria's Switch, skinned against the `--wzl-*`
1906
- * tokens. Use for a setting that takes effect immediately; use `Checkbox`
1907
- * for one that is submitted with a form.
1908
- *
1909
- * `ref` forwards to the underlying label element.
1910
- */
1911
- declare const Switch: react.ForwardRefExoticComponent<Omit<SwitchProps$1, "className" | "children"> & {
1912
- children?: ReactNode;
1913
- className?: string;
1914
- } & react.RefAttributes<HTMLLabelElement>>;
1915
-
1916
- /** Props for {@link Tabs}, on top of React Aria's `Tabs` props. */
1917
- type TabsProps = Omit<TabsProps$1, 'className' | 'children'> & {
1918
- children?: ReactNode;
1919
- className?: string;
1920
- };
1921
- /**
1922
- * Tab set wrapping React Aria's Tabs, skinned against the `--wzl-*` tokens.
1923
- * Holds a {@link TabList} and one {@link TabPanel} per tab.
1924
- */
1925
- declare function Tabs({ children, className, ...rest }: TabsProps): react.JSX.Element;
1926
- /** Props for {@link TabList}, on top of React Aria's `TabList` props. */
1927
- type TabListProps<T extends object> = Omit<TabListProps$1<T>, 'className'> & {
1928
- className?: string;
1929
- };
1930
- /** The row of tab buttons inside a {@link Tabs}. */
1931
- declare function TabList<T extends object>({ className, ...rest }: TabListProps<T>): react.JSX.Element;
1932
- /** Props for {@link Tab}, on top of React Aria's `Tab` props. */
1933
- type TabProps = Omit<TabProps$1, 'className' | 'children'> & {
1934
- children?: ReactNode;
1935
- className?: string;
1936
- };
1937
- /** One tab button. Its `id` selects the {@link TabPanel} it reveals. */
1938
- declare function Tab({ children, className, ...rest }: TabProps): react.JSX.Element;
1939
- /** Props for {@link TabPanel}, on top of React Aria's `TabPanel` props. */
1940
- type TabPanelProps = Omit<TabPanelProps$1, 'className' | 'children'> & {
1941
- children?: ReactNode;
1942
- className?: string;
1943
- };
1944
- /** The content shown for the {@link Tab} whose `id` matches this panel's. */
1945
- declare function TabPanel({ children, className, ...rest }: TabPanelProps): react.JSX.Element;
1946
-
1947
- /** Props for {@link RadioGroup}, on top of React Aria's `RadioGroup` props. */
1948
- type RadioGroupProps = Omit<RadioGroupProps$1, 'children' | 'className'> & {
1949
- label?: ReactNode;
1950
- description?: ReactNode;
1951
- errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
1952
- children?: ReactNode;
1953
- className?: string;
1954
- };
1955
- /**
1956
- * A set of mutually exclusive choices, wrapping React Aria's RadioGroup and
1957
- * supplying the same label / description / errorMessage slots as `Input`.
1958
- * Holds {@link Radio} children.
1959
- */
1960
- declare function RadioGroup(props: RadioGroupProps): react.JSX.Element;
1961
- /** Props for {@link Radio}, on top of React Aria's `Radio` props. */
1962
- type RadioProps = Omit<RadioProps$1, 'className' | 'children'> & {
1963
- children?: ReactNode;
1964
- className?: string;
1965
- };
1966
- /** One choice in a {@link RadioGroup}. The label is passed as children. */
1967
- declare function Radio({ children, className, ...rest }: RadioProps): react.JSX.Element;
1968
-
1969
- /** Props for {@link NumberField}, on top of React Aria's `NumberField` props. */
1970
- type NumberFieldProps = Omit<NumberFieldProps$1, 'children' | 'className'> & {
1971
- label?: ReactNode;
1972
- /**
1973
- * `'stacked'` (the default) puts the label above the field; `'row'` sets it
1974
- * beside the field at its own width, with any description or error on a
1975
- * line below. Same vocabulary as {@link Field}'s `orientation`.
1976
- */
1977
- orientation?: FieldOrientation;
1978
- description?: ReactNode;
1979
- errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
1980
- /** Hide the up/down stepper buttons. Defaults to false. */
1981
- hideSteppers?: boolean;
1982
- /** Render with no box until focused — the readout treatment the property
1983
- * rows use, for a value that sits inside other chrome rather than in a form. */
1984
- ghost?: boolean;
1985
- /** Native input placeholder — e.g. `'Mixed'` for a multi-selection
1986
- * editor with no shared value. */
1987
- placeholder?: string;
1988
- /**
1989
- * `'fill'` (the default) takes the width of whatever row the field sits in.
1990
- * `'fit'` sizes it to `--wzl-number-field-width` (`9ch` by default) plus its
1991
- * own chrome, rather than to the input's 20-character intrinsic width.
1992
- */
1993
- width?: 'fill' | 'fit';
1994
- className?: string;
1995
- };
1996
- /**
1997
- * Numeric input with stepper buttons, wrapping React Aria's NumberField and
1998
- * supplying the same label / description / errorMessage slots as `Input`.
1999
- * Arrow keys and scroll step the value; parsing and formatting are React
2000
- * Aria's.
2001
- *
2002
- * `ref` forwards to the underlying `<input>`.
2003
- */
2004
- declare const NumberField: react.ForwardRefExoticComponent<Omit<NumberFieldProps$1, "className" | "children"> & {
2005
- label?: ReactNode;
2006
- /**
2007
- * `'stacked'` (the default) puts the label above the field; `'row'` sets it
2008
- * beside the field at its own width, with any description or error on a
2009
- * line below. Same vocabulary as {@link Field}'s `orientation`.
2010
- */
2011
- orientation?: FieldOrientation;
2012
- description?: ReactNode;
2013
- errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
2014
- /** Hide the up/down stepper buttons. Defaults to false. */
2015
- hideSteppers?: boolean;
2016
- /** Render with no box until focused — the readout treatment the property
2017
- * rows use, for a value that sits inside other chrome rather than in a form. */
2018
- ghost?: boolean;
2019
- /** Native input placeholder — e.g. `'Mixed'` for a multi-selection
2020
- * editor with no shared value. */
2021
- placeholder?: string;
2022
- /**
2023
- * `'fill'` (the default) takes the width of whatever row the field sits in.
2024
- * `'fit'` sizes it to `--wzl-number-field-width` (`9ch` by default) plus its
2025
- * own chrome, rather than to the input's 20-character intrinsic width.
2026
- */
2027
- width?: "fill" | "fit";
2028
- className?: string;
2029
- } & react.RefAttributes<HTMLInputElement>>;
2030
-
2031
- /** One row in a {@link MenuButton}'s list. */
2032
- type MenuButtonItem<T extends string = string> = {
2033
- value: T;
2034
- label: ReactNode;
2035
- isDisabled?: boolean;
2036
- /** Plain-text form of `label`, for type-to-select and screen readers. A
2037
- * string label supplies this itself. */
2038
- textValue?: string;
2039
- };
2040
- /** Props for {@link MenuButton}. */
2041
- type MenuButtonProps<T extends string = string> = {
2042
- /** What the button says. It never changes to show a chosen row. */
2043
- label: ReactNode;
2044
- items: ReadonlyArray<MenuButtonItem<T>>;
2045
- /** Fired with the value of the row chosen. */
2046
- onAction: (value: T) => void;
2047
- isDisabled?: boolean;
2048
- className?: string;
2049
- 'aria-label'?: string;
2050
- } & SegmentTooltipFields & OverlayPortalProps;
2051
- /**
2052
- * A button that opens a list and acts on the row chosen — "Add trial…",
2053
- * "Load…". Unlike a {@link Select} it holds no value, so it sizes to its own
2054
- * label rather than to its widest row.
2055
- *
2056
- * `shortcut` adds a kit tooltip reading `Name (⌘N)`, named by `aria-label` or
2057
- * a string `label`, as `Button` does; `tooltip` replaces that text.
2058
- */
2059
- declare function MenuButton<T extends string = string>({ label, items, onAction, isDisabled, className, 'aria-label': ariaLabel, portalContainer, shortcut, tooltip, }: MenuButtonProps<T>): react.JSX.Element;
2060
-
2061
- /**
2062
- * One option in a {@link ComboBox}'s `options` list. `textValue` is the
2063
- * plain-text form used for filtering and screen readers, needed only when
2064
- * `label` isn't a bare string.
2065
- */
2066
- type ComboBoxOption = {
2067
- value: string;
2068
- label: ReactNode;
2069
- textValue?: string;
2070
- isDisabled?: boolean;
2071
- };
2072
- type Key$1 = string | number;
2073
- /**
2074
- * How the typed text narrows the options.
2075
- *
2076
- * `'contains'` is a locale-aware substring match over each option's text.
2077
- * `'none'` shows every option given — what a list a server already filtered
2078
- * and ranked needs, since a second pass would drop rows that do not contain
2079
- * the query and reorder whatever survived.
2080
- */
2081
- type ComboBoxFilter = 'contains' | 'none' | ((textValue: string, inputValue: string) => boolean);
2082
- /** What the user committed: an option they picked, or text they typed. */
2083
- type ComboBoxCommit<T extends Key$1 = string> = {
2084
- source: 'option';
2085
- key: T;
2086
- } | {
2087
- source: 'text';
2088
- text: string;
2089
- };
2090
- /**
2091
- * Props for {@link ComboBox}, on top of React Aria's `ComboBox` props, with
2092
- * the selection key narrowed to the option value type.
2093
- */
2094
- type ComboBoxProps<T extends Key$1 = string> = Omit<ComboBoxProps$1<object>, 'children' | 'className' | 'selectedKey' | 'defaultSelectedKey' | 'onSelectionChange'> & {
2095
- label?: ReactNode;
2096
- description?: ReactNode;
2097
- errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
2098
- placeholder?: string;
2099
- options?: ReadonlyArray<ComboBoxOption & {
2100
- value: T;
2101
- }>;
2102
- children?: ReactNode;
2103
- selectedKey?: T | null;
2104
- defaultSelectedKey?: T;
2105
- onSelectionChange?: (key: T | null) => void;
2106
- emptyLabel?: ReactNode;
2107
- /** Shown in place of `emptyLabel` while `loadError` is set. */
2108
- errorLabel?: ReactNode;
2109
- /**
2110
- * How typed text narrows `options`. Defaults to `'contains'`. `'none'` also
2111
- * keeps the popover open on an empty collection: a list the kit does not
2112
- * filter can arrive empty from a server mid-query, and without that the
2113
- * popover closes and `emptyLabel` is never seen.
2114
- */
2115
- filter?: ComboBoxFilter;
2116
- /** Marks the options as out of date while the next set is being fetched. */
2117
- isLoading?: boolean;
2118
- /** A failed load, shown as `errorLabel` rather than as an empty corpus. */
2119
- loadError?: unknown | null;
2120
- /**
2121
- * Fires when the user commits — Enter on the active option, a click on one,
2122
- * or Enter on text matching none of them when `allowsCustomValue` is set.
2123
- * Empty text commits nothing.
2124
- */
2125
- onCommit?: (commit: ComboBoxCommit<T>) => void;
2126
- /**
2127
- * `'fill'` (the default) takes the width of whatever row the combo box sits
2128
- * in. `'fit'` sizes the input to its widest option, so it neither swallows a
2129
- * toolbar's slack nor cuts a selection off once one is made.
2130
- */
2131
- width?: 'fill' | 'fit';
2132
- className?: string;
2133
- } & OverlayPortalProps;
2134
- /**
2135
- * Filterable single-select wrapping React Aria's ComboBox. The user can
2136
- * type to filter; selection commits to `onSelectionChange`. When no value
2137
- * is in the input, selection clears (key becomes null).
2138
- */
2139
- declare function ComboBox<T extends Key$1 = string>(props: ComboBoxProps<T>): react.JSX.Element;
2140
- /** Props for {@link ComboBoxItem}, on top of React Aria's `ListBoxItem` props. */
2141
- type ComboBoxItemProps = Omit<ListBoxItemProps, 'className'> & {
2142
- className?: string;
2143
- };
2144
- /** One row in a {@link ComboBox}'s filtered list. */
2145
- declare function ComboBoxItem({ className, ...rest }: ComboBoxItemProps): react.JSX.Element;
2146
-
2147
- /** Props for {@link RangeSlider}, on top of React Aria's `Slider` props. */
2148
- type RangeSliderProps = Omit<SliderProps$1, 'children' | 'className'> & {
2149
- label?: ReactNode;
2150
- /** Show the current value next to the label. Defaults to true when a
2151
- * label is supplied. */
2152
- showOutput?: boolean;
2153
- /** Format the rendered value(s). Useful for units (`v => `${v}%``). */
2154
- formatOutput?: (v: number | number[]) => ReactNode;
2155
- className?: string;
2156
- };
2157
- /**
2158
- * Linear range slider on React Aria. Single-value by default; pass an array
2159
- * to `value` / `defaultValue` for multi-thumb. Distinct from `Slider`, which
2160
- * is fully controlled and gives each thumb its own bounds and readout.
2161
- *
2162
- * The root is a column flex container and the track stretches to it, so
2163
- * `align-items` on the root or on a wrapper that replaces it governs the
2164
- * *horizontal* axis here and collapses the track to its content width. Style
2165
- * the wrapper around one, not the root.
2166
- */
2167
- declare function RangeSlider(props: RangeSliderProps): react.JSX.Element;
2168
-
2169
- /** Props for {@link Dialog}, on top of React Aria's `ModalOverlay` props. */
2170
- type DialogProps = Omit<WithoutPortalTarget<ModalOverlayProps>, 'children' | 'className'> & OverlayPortalProps & StanceProps & {
2171
- /** Heading rendered in the dialog's default header. Omit when supplying
2172
- * a custom `header` slot via children. */
2173
- title?: ReactNode;
2174
- /** Show the built-in close button. Defaults to true when `onOpenChange`
2175
- * is wired so the user has an escape hatch. */
2176
- showCloseButton?: boolean;
2177
- /** Body content. */
2178
- children?: ReactNode;
2179
- /** Footer slot — typically action buttons. */
2180
- footer?: ReactNode;
2181
- /** ARIA role. Defaults to `dialog`. Use `alertdialog` for confirms. */
2182
- role?: DialogProps$1['role'];
2183
- /** Class applied to the modal box (inside the overlay). */
2184
- className?: string;
2185
- /** Class applied to the scrolling body. For content that owns its own
2186
- * scrolling — a form with a fixed navigation rail beside a scrolling
2187
- * pane — this is where the body's padding and overflow come off. */
2188
- bodyClassName?: string;
2189
- };
2190
- /**
2191
- * Modal dialog wrapping React Aria. Supplies a default header (title +
2192
- * close), scrollable body, and footer slot. Pass `isOpen` + `onOpenChange`
2193
- * for controlled visibility, or omit both and use a `<DialogTrigger>` from
2194
- * `react-aria-components` upstream of this component.
2195
- *
2196
- * Escape, click-outside, focus trap, and scroll lock all come from the
2197
- * underlying primitives. `stance` and `tone` work as on `<PropertyPanel>` —
2198
- * a destructive confirm is `stance="danger"`.
2199
- */
2200
- declare function Dialog(props: DialogProps): react.JSX.Element;
2201
-
2202
- /** Props for {@link Callout}, on top of React Aria's `Popover` props. */
2203
- type CalloutProps = Omit<WithoutPortalTarget<PopoverProps>, 'children' | 'className' | 'isNonModal' | 'triggerRef'> & OverlayPortalProps & StanceProps & {
2204
- children?: ReactNode;
2205
- className?: string;
2206
- /** Optional heading rendered above the body. */
2207
- title?: ReactNode;
2208
- /** Footer slot — typically action buttons. */
2209
- footer?: ReactNode;
2210
- /**
2211
- * `true` — blocks interaction with the rest of the app until dismissed;
2212
- * inner dialog is `role="alertdialog"`. `false` (default) — non-blocking:
2213
- * the app stays interactive; Esc / outside click / close button dismiss.
2214
- */
2215
- modal?: boolean;
2216
- /**
2217
- * Show the × button. Defaults to `!modal`. In programmatic
2218
- * `triggerRef`/`anchorRect` modes the close button needs controlled open
2219
- * (`isOpen` + `onOpenChange`); with only `defaultOpen` it has no open-state
2220
- * setter to call and cannot close.
2221
- */
2222
- showCloseButton?: boolean;
2223
- /**
2224
- * The user asked for this callout to go away — the × button or Escape.
2225
- *
2226
- * Distinct from `onOpenChange`, which a non-modal popover *also* fires when
2227
- * interaction or focus merely leaves it. On a canvas that's every click on
2228
- * the artwork, so a consumer that pins `isOpen` and treats `onOpenChange`
2229
- * as dismissal retires messages nobody read. Use this instead: it fires
2230
- * only on a deliberate act, and never on incidental focus loss.
2231
- */
2232
- onDismiss?: () => void;
2233
- /** Anchor to an arbitrary element (programmatic use, with `isOpen`). */
2234
- triggerRef?: RefObject<Element | null>;
2235
- /**
2236
- * Anchor to a client-coordinate rect — e.g. a scene node's on-screen box.
2237
- * The callout re-anchors whenever this rect changes, so a consumer that
2238
- * recomputes it on pan, zoom, or scene edits keeps the arrow on its target.
2239
- * Takes precedence over `triggerRef`.
2240
- */
2241
- anchorRect?: {
2242
- x: number;
2243
- y: number;
2244
- width: number;
2245
- height: number;
2246
- };
2247
- };
2248
- /**
2249
- * Anchored callout with an arrow pointing at its source — a trigger
2250
- * element, an arbitrary `triggerRef`, or a client-space `anchorRect`.
2251
- * Wraps React Aria Popover + Dialog; positioning, collision flipping,
2252
- * dismissal, and focus behavior come from the underlying primitives.
2253
- */
2254
- declare function Callout(props: CalloutProps): react.JSX.Element;
2255
-
2256
- /**
2257
- * Coordinate transforms (model ↔ plot) for Plot2D. Pure / deterministic —
2258
- * no DOM, no React, no state.
2259
- *
2260
- * Model space: caller-defined xRange × yRange. Y axis goes UP.
2261
- * Plot space: 0..width × 0..height in CSS pixels. Y axis goes DOWN (SVG).
2262
- */
2263
- interface Point {
2264
- x: number;
2265
- y: number;
2266
- }
2267
-
2268
- /**
2269
- * Tick placement for a numeric axis. Pure — no DOM, no React.
2270
- */
2271
- /** What a tick label formatter knows about the column it is part of. */
2272
- interface TickFormatCtx {
2273
- /** Places after the point that every label in the column shares. */
2274
- decimals: number;
2275
- /** Distance between neighboring ticks, or 0 when the ticks were given
2276
- * explicitly and are not evenly spaced. */
2277
- step: number;
2278
- }
2279
- /** Turns a tick value into its label. */
2280
- type TickFormatter = (value: number, ctx: TickFormatCtx) => string;
2281
-
2282
- /** Background grid configuration for a {@link Plot2D}. */
2283
- interface GridSettings {
2284
- /** Number of evenly-spaced internal grid lines per axis (excluding
2285
- * the edges). Applied to both x and y. Default 3. */
2286
- divisions?: number;
2287
- /** Stroke color override. When omitted, uses `var(--plot-grid)`. */
2288
- color?: string;
2289
- }
2290
- /** Axis-line configuration for a {@link Plot2D}. */
2291
- interface AxesSettings {
2292
- /** Stroke color override. When omitted, uses `var(--plot-axis)`. */
2293
- color?: string;
2294
- }
2295
- /**
2296
- * Ticks along one axis of a {@link Plot2D}: a line across the plot at each
2297
- * tick value, and a label naming it. Every label in a column is formatted
2298
- * to the same number of decimal places.
2299
- */
2300
- interface TickSettings {
2301
- /** Tick values in model space; any outside the range are skipped.
2302
- * Omitted = round 1/2/5 steps, as many as `minSpacing` allows at the
2303
- * plot's current size. */
2304
- values?: readonly number[];
2305
- /** Smallest gap between generated ticks, in px. Default 24 on y, 64 on x. */
2306
- minSpacing?: number;
2307
- /** A generated tick nearer either end of the axis than this is dropped,
2308
- * so its label stays on the plot, in px. Default 4 on y, 16 on x. */
2309
- inset?: number;
2310
- /** Draw a line across the plot at each tick. Default true. */
2311
- lines?: boolean;
2312
- /** Where labels sit: `'inside'` the plot along its left (y) or bottom (x)
2313
- * edge, `'outside'` it past that edge in space the caller leaves free,
2314
- * or `false` for none. Default `'inside'`. */
2315
- labels?: 'inside' | 'outside' | false;
2316
- /** Space between a label and the plot edge it sits against, in px.
2317
- * Default 4. */
2318
- gap?: number;
2319
- /** Label text for a tick. Default {@link formatTick}. */
2320
- format?: TickFormatter;
2321
- }
2322
- /** A pointer position given in both of the plot's coordinate systems. */
2323
- interface Plot2DCoords {
2324
- plot: Point;
2325
- model: Point;
2326
- }
2327
- /** Props for {@link Plot2D}. */
2328
- interface Plot2DProps {
2329
- width: number;
2330
- height: number;
2331
- /** Model-space x range. Default [0, 1]. */
2332
- xRange?: readonly [number, number];
2333
- /** Model-space y range. Default [0, 1]. */
2334
- yRange?: readonly [number, number];
2335
- /** Background grid. `false` / `null` / omitted = no grid. Pass `{}`
2336
- * for default (3 divisions per axis) or populated GridSettings. */
2337
- grid?: GridSettings | false | null;
2338
- /** Axis lines. `false` / `null` = no axes. Omitted = default-styled
2339
- * axes (on). Pass AxesSettings to customize. */
2340
- axes?: AxesSettings | false | null;
2341
- /** Ticks at x values. `false` / `null` / omitted = none; `{}` = defaults. */
2342
- xTicks?: TickSettings | false | null;
2343
- /** Ticks at y values. `false` / `null` / omitted = none; `{}` = defaults. */
2344
- yTicks?: TickSettings | false | null;
2345
- /** Forwarded to the underlying svg. Consumer opts into focus this way. */
2346
- tabIndex?: number;
2347
- /** Default `'img'`. A plot holding focusable marks must not be an image,
2348
- * whose children are presentational to assistive technology. */
2349
- role?: string;
2350
- 'aria-label'?: string;
2351
- className?: string;
2352
- style?: CSSProperties;
2353
- /** Pointer down on the SVG. Receives both plot- and model-space coords
2354
- * pre-computed so consumers don't repeat the rect/transform dance. */
2355
- onPointerDown?: (e: PointerEvent<SVGSVGElement>, coords: Plot2DCoords) => void;
2356
- onKeyDown?: (e: KeyboardEvent<SVGSVGElement>) => void;
2357
- children?: ReactNode;
2358
- }
2359
- /**
2360
- * Imperative handle on a {@link Plot2D}: the SVG element, its size, and the
2361
- * coordinate conversions, including ones that start from a raw DOM event so a
2362
- * drag tracked on `window` can still map back into the plot.
2363
- */
2364
- interface Plot2DHandle {
2365
- readonly svg: SVGSVGElement | null;
2366
- plotToModel(pt: Point): Point;
2367
- modelToPlot(pt: Point): Point;
2368
- /** Convert a DOM event's clientX/clientY (e.g. from a window-attached
2369
- * pointermove during drag) to plot-space. */
2370
- clientToPlot(e: {
2371
- clientX: number;
2372
- clientY: number;
2373
- }): Point;
2374
- /** Convenience: clientToPlot → plotToModel. */
2375
- clientToModel(e: {
2376
- clientX: number;
2377
- clientY: number;
2378
- }): Point;
2379
- readonly width: number;
2380
- readonly height: number;
2381
- }
2382
- /**
2383
- * An SVG plotting surface with an optional grid, axes and ticks. It draws the
2384
- * frame and owns the model-space to plot-space mapping; the plotted content is
2385
- * whatever children are passed, positioned in plot space.
2386
- */
2387
- declare const Plot2D: react.ForwardRefExoticComponent<Plot2DProps & react.RefAttributes<Plot2DHandle>>;
2388
-
2389
- /**
2390
- * Interpolation mode dispatcher for CurveEditor. The vocabulary of
2391
- * supported algorithms and the unified `sample(...)` entry point that
2392
- * picks the right one. All algorithms produce
2393
- * `(n-1) * samplesPerSegment + 1` points and pass through every
2394
- * anchor — CurveEditor is strictly interpolating, never approximating.
2395
- */
2396
-
2397
- /** Supported interpolation modes. All are interpolating (pass through
2398
- * every anchor); the differences are in tangent computation and
2399
- * parameterization. */
2400
- type InterpolationMode = 'linear' | 'catmull-rom' | 'catmull-rom-uniform' | 'catmull-rom-chordal' | 'monotone';
2401
-
2402
- /**
2403
- * Built-in function/curve layer for LayeredCurveEditor. Bundles the
2404
- * curve-render + anchor-render + drag/insert/delete gestures that were
2405
- * the entirety of the original `CurveEditor`. Multiple instances coexist
2406
- * by id; consumers can compose several to plot e.g. a primary function
2407
- * and a derived (read-only) curve on the same chart.
2408
- */
2409
-
2410
- /** One anchor of a curve, in model space. */
2411
- interface ControlPoint {
2412
- x: number;
2413
- y: number;
2414
- /** When true, this control point can't be moved or deleted by the
2415
- * user. Render as a smaller diamond with locked styling. */
2416
- locked?: boolean;
2417
- }
2418
- /**
2419
- * Whether a curve's points keep their x order. In `'1d'` an anchor cannot be
2420
- * dragged past its neighbors and a new point is inserted at its x position;
2421
- * in `'2d'` points are free to move anywhere and keep their list order.
2422
- */
2423
- type CurveDomain = '1d' | '2d';
2424
- /**
2425
- * How much of a curve's first and last anchor the user may move: everything,
2426
- * only their y, or nothing.
2427
- */
2428
- type EndpointMode = 'free' | 'pinned-x' | 'pinned-both';
2429
- /**
2430
- * Where a click adds a new anchor — on the curve itself, anywhere in the
2431
- * plot, or nowhere.
2432
- */
2433
- type AddPointMode = 'click-curve' | 'click-empty' | 'never';
2434
- /**
2435
- * What a `renderAnchor` function is given for one anchor: the point, its
2436
- * index, its position in plot space (`cx`/`cy`), and the states that change
2437
- * how it should look.
2438
- */
2439
- interface AnchorRenderProps {
2440
- point: ControlPoint;
2441
- index: number;
2442
- cx: number;
2443
- cy: number;
2444
- isActive: boolean;
2445
- isLocked: boolean;
2446
- isPinnedEndpoint: boolean;
2447
- isEndpoint: boolean;
2448
- }
2449
- /**
2450
- * Per-instance curve-rendering overrides. Currently empty — passing `{}`
2451
- * means "draw the curve", and `false`/`null` means don't.
2452
- */
2453
- type CurveSettings = object;
2454
- /** Shades the region between the curve and one edge of the plot. */
2455
- interface FillSettings {
2456
- side: 'below' | 'above';
2457
- color?: string;
2458
- }
2459
-
2460
- /**
2461
- * Props for {@link CurveEditor}. `onInput` fires throughout a gesture and
2462
- * `onChange` once at its end, with the pre-gesture points as `prev`.
2463
- */
2464
- interface CurveEditorProps {
2465
- value: readonly ControlPoint[];
2466
- onInput: (next: ControlPoint[]) => void;
2467
- onChange?: (next: ControlPoint[], prev: readonly ControlPoint[]) => void;
2468
- domain?: CurveDomain;
2469
- interpolation?: InterpolationMode;
2470
- endpoints?: EndpointMode;
2471
- xRange?: readonly [number, number];
2472
- yRange?: readonly [number, number];
2473
- width: number;
2474
- height: number;
2475
- grid?: GridSettings | false | null;
2476
- axes?: AxesSettings | false | null;
2477
- xTicks?: TickSettings | false | null;
2478
- yTicks?: TickSettings | false | null;
2479
- curve?: CurveSettings | false | null;
2480
- fill?: FillSettings | false | null;
2481
- hideNonInteractive?: boolean;
2482
- constrain?: 'none' | 'function';
2483
- history?: boolean;
2484
- minPoints?: number;
2485
- maxPoints?: number;
2486
- addPointMode?: AddPointMode;
2487
- renderAnchor?: (info: AnchorRenderProps) => ReactNode;
2488
- /** Extra SVG content rendered behind the curve and anchors. */
2489
- decorations?: ReactNode;
2490
- className?: string;
2491
- style?: CSSProperties;
2492
- }
2493
- /**
2494
- * Editable curve through a list of control points: drag anchors, click to
2495
- * insert, right-click to delete, with optional built-in undo.
2496
- *
2497
- * This is the single-curve API, implemented as one `createFunctionLayer` on
2498
- * a `LayeredCurveEditor`. Reach for those directly to stack several curves
2499
- * on one plot.
2500
- */
2501
- declare function CurveEditor(props: CurveEditorProps): react.JSX.Element;
2502
-
2503
- /** Props for {@link PointPlotter}. */
2504
- interface PointPlotterProps {
2505
- /** Plotted points; caller-owned. */
2506
- value: readonly ControlPoint[];
2507
- /** Fires every frame during drag with the live in-flight value. */
2508
- onInput: (next: ControlPoint[]) => void;
2509
- /** Fires once per discrete user action (drag-end, add, delete) with
2510
- * the new value and the value at gesture start. Wire history here. */
2511
- onChange?: (next: ControlPoint[], prev: readonly ControlPoint[]) => void;
2512
- /** Model-space x range. Default [0, 1]. */
2513
- xRange?: readonly [number, number];
2514
- /** Model-space y range. Default [0, 1]. */
2515
- yRange?: readonly [number, number];
2516
- width: number;
2517
- height: number;
2518
- grid?: GridSettings | false | null;
2519
- axes?: AxesSettings | false | null;
2520
- xTicks?: TickSettings | false | null;
2521
- yTicks?: TickSettings | false | null;
2522
- /** Minimum allowed point count. User-initiated deletion is refused
2523
- * while `value.length <= minPoints`. */
2524
- minPoints?: number;
2525
- /** Maximum allowed point count. User-initiated insertion is refused
2526
- * while `value.length >= maxPoints`. */
2527
- maxPoints?: number;
2528
- /** How new points are added. Default `'click-empty'`. Set to `'never'`
2529
- * to disable insertion entirely. */
2530
- addPointMode?: 'click-empty' | 'never';
2531
- /** Built-in undo/redo via keyboard when the component has focus.
2532
- * Default `true`. See `CurveEditor.history` for details. */
2533
- history?: boolean;
2534
- /** Custom per-anchor renderer. See `CurveEditor.renderAnchor`. */
2535
- renderAnchor?: (info: AnchorRenderProps) => ReactNode;
2536
- /** Extra SVG content beneath the anchors. See `CurveEditor.decorations`. */
2537
- decorations?: ReactNode;
2538
- className?: string;
2539
- style?: CSSProperties;
2540
- }
2541
- /**
2542
- * 2D point plotter — a CurveEditor with the curve hidden. Anchors,
2543
- * drag, shift+click delete, right-click delete, and click-empty insert
2544
- * are inherited from CurveEditor verbatim, so the two components share
2545
- * gesture semantics and stay in sync as CurveEditor evolves.
2546
- *
2547
- * Differences from CurveEditor: no curve `<path>` drawn, no fill, no
2548
- * endpoint pinning, no interpolation, default `addPointMode` is
2549
- * `'click-empty'` (CurveEditor defaults to `'click-curve'`, which
2550
- * doesn't make sense without a curve to hit-test against).
2551
- */
2552
- declare function PointPlotter(props: PointPlotterProps): react.JSX.Element;
2553
-
2554
- /**
2555
- * Options for {@link paintGradientTrack}.
2556
- *
2557
- * `gradient` maps a normalized position along the track (0 to 1) to a CSS
2558
- * color; `samples` is how many stops the resulting linear-gradient uses.
2559
- * `activeRange`, given in the slider's own value units, keeps that span at
2560
- * full strength and dims + hatches the rest.
2561
- */
2562
- type GradientTrackOpts = {
2563
- gradient: (t: number) => string;
2564
- samples?: number;
2565
- activeRange?: [number, number];
2566
- hatch?: {
2567
- angleDeg?: number;
2568
- stripe?: number;
2569
- gap?: number;
2570
- dim?: number;
2571
- };
2572
- };
2573
- /**
2574
- * Builds a `Slider` `renderTrack` function that paints the track as a
2575
- * sampled color gradient, optionally dimming and hatching the portions
2576
- * outside an active range.
2577
- */
2578
- declare function paintGradientTrack(opts: GradientTrackOpts): (ctx: TrackCtx) => ReactNode;
2579
-
2580
- /**
2581
- * A chroma envelope over lightness, as three linear segments: flat at `cBot`
2582
- * below `lRange[0]`, rising to `cPeak` at `midL`, falling to `cTop` at
2583
- * `lRange[1]`, flat beyond. Keeps a color ramp inside gamut at the light and
2584
- * dark ends while staying saturated through the middle.
2585
- */
2586
- type ChromaCurve = {
2587
- lRange: [number, number];
2588
- midL: number;
2589
- cBot: number;
2590
- cPeak: number;
2591
- cTop: number;
2592
- };
2593
- /** A single lightness/chroma sample. */
2594
- type ChromaCurvePoint = {
2595
- L: number;
2596
- C: number;
2597
- };
2598
- /**
2599
- * Converts an OKLCH color to a gamut-clipped `#rrggbb` string. Hue is in
2600
- * degrees, unlike the kit's OKLab helpers which take radians.
2601
- */
2602
- declare const oklchToHex: typeof oklchDegToHex;
2603
- /** Evaluates a {@link ChromaCurve} at a lightness, clamping outside its range. */
2604
- declare function chromaAt(L: number, curve: ChromaCurve): number;
2605
-
2606
- type Key = string | number;
2607
- /** An option list keyed to the value type its combo box commits. */
2608
- type AsyncOption<T extends Key> = ComboBoxOption & {
2609
- value: T;
2610
- };
2611
- /** Options for {@link useAsyncOptions}. */
2612
- type UseAsyncOptionsProps<T extends Key> = {
2613
- /**
2614
- * Fetches the options for a query. The signal aborts when a later keystroke
2615
- * supersedes this call, so a `fetch` should forward it.
2616
- */
2617
- load: (query: string, signal: AbortSignal) => Promise<ReadonlyArray<AsyncOption<T>>>;
2618
- /** Quiet period before a query is sent. */
2619
- debounceMs?: number;
2620
- /** Shorter queries are not sent, and empty the options. */
2621
- minLength?: number;
2622
- };
2623
- /** What {@link useAsyncOptions} returns, shaped to spread into a `ComboBox`. */
2624
- type AsyncOptionsResult<T extends Key> = {
2625
- options: ReadonlyArray<AsyncOption<T>>;
2626
- isLoading: boolean;
2627
- loadError: unknown | null;
2628
- inputValue: string;
2629
- onInputChange: (next: string) => void;
2630
- };
2631
- /**
2632
- * Drives a combo box whose options come from a server: debounces the query,
2633
- * discards responses overtaken by a later one, and reports a failed load
2634
- * separately from an empty result.
2635
- *
2636
- * `options` holds the last *resolved* list and is never emptied to mean
2637
- * "working", so the previous results stay on screen — and stay arrowable —
2638
- * while the next request is in flight.
2639
- */
2640
- declare function useAsyncOptions<T extends Key = string>({ load, debounceMs, minLength, }: UseAsyncOptionsProps<T>): AsyncOptionsResult<T>;
2641
-
2642
- /** The only thing the hook needs to know about a bar's items: which are
2643
- * skipped by arrow navigation. */
2644
- type RovingItem = {
2645
- disabled?: boolean;
2646
- };
2647
- /** Options for {@link useRovingTabIndex}. */
2648
- type UseRovingTabIndexOptions = {
2649
- /** In the same order as the elements carrying `itemClassName`. */
2650
- items: readonly RovingItem[];
2651
- /** Class on the focusable element of each item, inside the container the
2652
- * returned `rootRef` is attached to. Their DOM order must match `items`. */
2653
- itemClassName: string;
2654
- /** Index that carries `tabIndex=0`. Defaults to the first enabled item; a
2655
- * radiogroup-style bar passes its selected index so Tab lands on the
2656
- * current value. */
2657
- tabStopIndex?: number;
2658
- /** Called with the new index as arrow/Home/End focus moves, before focus
2659
- * moves. This is where a selection-follows-focus bar commits the value. */
2660
- onNavigate?: (index: number) => void;
2661
- /** Space/Enter on the item at `index`. When omitted the keypress is left
2662
- * alone, which on a native `<button>` produces an ordinary click. */
2663
- onActivate?: (index: number) => void;
2664
- };
2665
- /**
2666
- * What {@link useRovingTabIndex} returns: a container ref plus the per-item
2667
- * `tabIndex` and `onKeyDown` values to spread onto each item.
2668
- */
2669
- type RovingTabIndex<T extends HTMLElement = HTMLDivElement> = {
2670
- /** Attach to the container element that holds the items. */
2671
- rootRef: RefObject<T | null>;
2672
- /** `tabIndex` value for the item at `index`. */
2673
- tabIndexFor: (index: number) => 0 | -1;
2674
- /** `onKeyDown` for the item at `index`. */
2675
- onKeyDown: (index: number) => (e: KeyboardEvent<HTMLElement>) => void;
2676
- };
2677
- /**
2678
- * Roving tabindex for a bar of items: one item is in the tab order, and the
2679
- * arrow keys move focus among the rest, skipping disabled ones and wrapping
2680
- * at both ends. Home and End go to the first and last enabled item. Both axes
2681
- * navigate, so the same bar works laid out either way.
2682
- *
2683
- * Backs `ButtonBar`, `OptionsBar`, and `ToggleBar`.
2684
- *
2685
- * **When a bar should not use this.** What decides it is the items, not who
2686
- * owns them. A container of compound controls — a number field, a select, a
2687
- * color field — must leave the arrow keys alone, because those controls edit
2688
- * their own value with them; taking the arrows over would break the control
2689
- * to navigate between controls. `ToolOptionsBar` is that case: it draws its
2690
- * own controls from a tool's schema now rather than taking arbitrary
2691
- * children, and a schema-drawn number field eats arrows exactly as a
2692
- * hand-placed one did, so it keeps plain DOM tab order. A bar whose items are
2693
- * all simple buttons is the case this hook is for.
2694
- *
2695
- * With every item disabled there is no tab stop and the bar drops out of the
2696
- * tab order entirely.
2697
- */
2698
- declare function useRovingTabIndex<T extends HTMLElement = HTMLDivElement>(options: UseRovingTabIndexOptions): RovingTabIndex<T>;
2699
-
2700
- export { ActionBar, Badge, ButtonBar, Callout, Checkbox, ColorModeControl, ComboBox, ComboBoxItem, CurveEditor, DataGrid, Dialog, Disclosure, DisclosureMark, DisclosureRow, DragGhost, DragHandleGlyph, EDGE_PROFILES, FieldOrientation, KeyCap, KeySequence, ListEditor, MenuButton, NumberField, OptionsBar, OverlayPortalProps, Plot2D, PointPlotter, Powerline, PrefRenderer, PrefsDialog, PrefsForm, Radio, RadioGroup, RangeSlider, SegmentTooltipFields, Sidebar, SidebarPanel, Slider, StanceProps, Switch, Tab, TabList, TabPanel, Tabs, ToggleBarSize, ToggleBarVariant, ToolButton, ToolGroup, ToolPalette, WithoutPortalTarget, chromaAt, detectPlatform, dlog, formatShortcut, formatShortcutParts, inferKeycapKind, isDebugEnabled, isPrefLeaf, keyGlyph, keySpecFromKey, keySpecsFromMods, keySpecsFromShortcut, oklchToHex, paintGradientTrack, prefValueAtPath, useAsyncOptions, useReorderDragList, useRovingTabIndex, visiblePrefSubtree };
2701
- export type { ActionBarProps, AddPointMode, AnchorRenderProps, AsyncOption, AsyncOptionsResult, AxesSettings, BadgeProps, BadgeShape, BadgeSize, BadgeStatus, BadgeVariant, BoundsCtx, BuiltInEdgeName, ButtonBarItem, ButtonBarProps, ButtonBarSize, ButtonBarVariant, CalloutProps, CheckboxProps, ChromaCurve, ChromaCurvePoint, ColorModeControlProps, ComboBoxCommit, ComboBoxFilter, ComboBoxItemProps, ComboBoxOption, ComboBoxProps, ControlPoint, CurveDomain, CurveEditorProps, DataGridColumn, DataGridProps, DialogProps, DisclosureMarkProps, DisclosureProps, DisclosureRowProps, DragGhostProps, DragHandleGlyphProps, EdgeCap, EdgeProfile, EndpointMode, FillSettings, GradientTrackOpts, GridSettings, InterpolationMode, KeyCapProps, KeyCapVariant, KeySequenceProps, KeySpec, KeycapKind, ListEditorProps, LogicalMod, LogicalModSpec, MenuButtonItem, MenuButtonProps, NumberFieldProps, OptionsBarItem, OptionsBarProps, OptionsBarSize, OptionsBarVariant, Platform, Plot2DCoords, Plot2DHandle, Plot2DProps, PointPlotterProps, PowerlineProps, PowerlineSegment, PrefsDialogProps, PrefsFormProps, PrefsLayout, RadioGroupProps, RadioProps, RangeSliderProps, ReorderDragHandlers, ReorderDragState, ReorderGhost, RovingItem, RovingTabIndex, SidebarPanelProps, SidebarProps, SliderProps, SwitchProps, TabListProps, TabPanelProps, TabProps, TabsProps, Thumb, ThumbRenderCtx, ThumbShape, ToolButtonProps, ToolGroupProps, ToolPaletteProps, TrackCtx, UseAsyncOptionsProps, UseReorderDragListOptions, UseRovingTabIndexOptions };
1
+ export { MINUS_SIGN, formatNumber } from '@weasel-js/quantity';
2
+ export { ActionBar, ActionBarProps, AddPointMode, AnchorRenderProps, AsyncOption, AsyncOptionsResult, AxesSettings, Badge, BadgeProps, BadgeShape, BadgeSize, BadgeStatus, BadgeVariant, BoundsCtx, BuiltInEdgeName, BuiltInProfileName, BuiltinPref, Button, ButtonBar, ButtonBarItem, ButtonBarProps, ButtonBarSize, ButtonBarVariant, ButtonProps, ButtonSize, ButtonVariant, COLOR_MODE_OPTIONS, Callout, CalloutProps, CalloutTrigger, Checkbox, CheckboxProps, ChromaCurve, ChromaCurvePoint, CloseButton, CloseButtonProps, ColorModeControl, ColorModeControlProps, ComboBox, ComboBoxCommit, ComboBoxFilter, ComboBoxItem, ComboBoxItemProps, ComboBoxOption, ComboBoxProps, ControlPoint, CurveDomain, CurveEditor, CurveEditorProps, DataGrid, DataGridColumn, DataGridProps, Dialog, DialogProps, Disclosure, DisclosureMark, DisclosureMarkProps, DisclosureProps, DisclosureRow, DisclosureRowProps, DragGhost, DragGhostProps, DragGrip, DragGripProps, EDGE_PROFILES, EdgeCap, EdgeProfile, EndpointMode, Field, FieldOrientation, FieldProps, FillSettings, GestureRoute, GestureRouteProps, GradientTrackOpts, GridSettings, ICON_PATHS, Icon, IconName, IconProps, Input, InputProps, InterpolationMode, KeyCap, KeyCapProps, KeyCapVariant, KeySequence, KeySequenceJoins, KeySequenceProps, KeySpec, KeycapKind, LayerList, LayerListItem, LayerListProps, LayerMove, ListEditor, ListEditorProps, LogicalMod, LogicalModSpec, MenuButton, MenuButtonItem, MenuButtonProps, NumberField, NumberFieldProps, OptionsBar, OptionsBarItem, OptionsBarProps, OptionsBarSize, OptionsBarVariant, OverlayPortalProps, Platform, Plot2D, Plot2DCoords, Plot2DHandle, Plot2DProps, PointPlotter, PointPlotterProps, Powerline, PowerlineProps, PowerlineSegment, PrefBoolean, PrefBooleanControl, PrefBooleanEncoding, PrefColor, PrefCustom, PrefEnum, PrefEnumControl, PrefEnumEncoding, PrefGroup, PrefKind, PrefLeaf, PrefNumber, PrefNumberControl, PrefNumberUnit, PrefObject, PrefPaint, PrefRenderContext, PrefRenderer, PrefString, PrefStringControl, PrefsDialog, PrefsDialogProps, PrefsForm, PrefsFormProps, PrefsLayout, PropertyAlign, PropertyDensity, PropertyMetricProps, Radio, RadioGroup, RadioGroupProps, RadioProps, RangeSlider, RangeSliderProps, ReorderDragHandlers, ReorderDragState, ReorderGhost, RovingOrientation, RovingTabIndex, SegmentTooltipFields, Select, SelectItem, SelectItemProps, SelectOption, SelectProps, Sidebar, SidebarPanel, SidebarPanelProps, SidebarProps, Slider, SliderProps, StanceProps, Switch, SwitchProps, Tab, TabList, TabListProps, TabPanel, TabPanelProps, TabProps, Tabs, TabsProps, ThemeSwitcher, ThemeSwitcherOption, ThemeSwitcherProps, Thumb, ThumbRenderCtx, ThumbShape, ToggleBar, ToggleBarItem, ToggleBarProps, ToggleBarSize, ToggleBarVariant, ToolButton, ToolButtonProps, ToolGroup, ToolGroupProps, ToolPalette, ToolPaletteProps, TrackCtx, UseAsyncOptionsProps, UseReorderDragListOptions, UseRovingTabIndexOptions, WithoutPortalTarget, chromaAt, detectPlatform, dlog, fieldClasses, formatShortcut, formatShortcutParts, gestureRouteSegments, inferKeycapKind, isDebugEnabled, isPrefLeaf, keyGlyph, keySpecFromKey, keySpecsFromMods, keySpecsFromShortcut, moveLayers, oklchToHex, paintGradientTrack, prefValueAtPath, sampleByInterpolation, useAsyncOptions, useReorderDragList, useRovingTabIndex, visiblePrefSubtree } from '@weasel-js/ui';