@weasel-js/labkit 1.3.0-pre.0 → 1.4.0-pre.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/dist/_dts/CanvasStackContext-DtAn_3O-.d.ts +42 -0
  2. package/dist/_dts/DrawCommand-B3bskUsC.d.ts +564 -0
  3. package/dist/_dts/{PrefsForm-BYa6cWnO.d.ts → PrefsForm-BkUJZx0A.d.ts} +4 -1
  4. package/dist/_dts/fitViewToBounds-dZ2UDB6e.d.ts +21 -0
  5. package/dist/_dts/frac-Cp3NivlC.d.ts +728 -0
  6. package/dist/_dts/index-BDVzvRzQ.d.ts +236 -0
  7. package/dist/_dts/shapeKinds-Cx_rxwsa.d.ts +87 -0
  8. package/dist/_dts/{DrawCommand-DBB45NfN.d.ts → types-C-gh9Ap-.d.ts} +1 -582
  9. package/dist/_dts/{types-AHlQxBNN.d.ts → types-D6s4b7if.d.ts} +2 -2
  10. package/dist/_dts/{types-1Sdxy_Pv.d.ts → types-DYMaEvM5.d.ts} +26 -1
  11. package/dist/_dts/{useTrialState-CsGMjhu9.d.ts → useTrialState-gmMvZqPc.d.ts} +7 -2
  12. package/dist/canvas/index.d.ts +43 -25
  13. package/dist/canvas/index.js +5 -3
  14. package/dist/chrome/index.d.ts +9 -6
  15. package/dist/chrome/index.js +7 -6
  16. package/dist/chunk-2AYGEN57.js +32 -0
  17. package/dist/chunk-2AYGEN57.js.map +1 -0
  18. package/dist/{chunk-RVNN4CHQ.js → chunk-3P5TTTA7.js} +16 -8
  19. package/dist/chunk-3P5TTTA7.js.map +1 -0
  20. package/dist/{chunk-NS54R52R.js → chunk-3ZELRRBV.js} +45 -40
  21. package/dist/chunk-3ZELRRBV.js.map +1 -0
  22. package/dist/{chunk-HFDVGF4X.js → chunk-4EY67BKJ.js} +32 -7
  23. package/dist/chunk-4EY67BKJ.js.map +1 -0
  24. package/dist/chunk-5TCEVMPI.js +140 -0
  25. package/dist/chunk-5TCEVMPI.js.map +1 -0
  26. package/dist/{chunk-O7NVSCLN.js → chunk-6JMU56CU.js} +133 -134
  27. package/dist/chunk-6JMU56CU.js.map +1 -0
  28. package/dist/{chunk-CPUJ3QXL.js → chunk-CQLQPQ4P.js} +2 -2
  29. package/dist/chunk-CQLQPQ4P.js.map +1 -0
  30. package/dist/chunk-CTRKTLYZ.js +33 -0
  31. package/dist/chunk-CTRKTLYZ.js.map +1 -0
  32. package/dist/chunk-EQIB2PGC.js +458 -0
  33. package/dist/chunk-EQIB2PGC.js.map +1 -0
  34. package/dist/chunk-HEORBLVT.js +7128 -0
  35. package/dist/chunk-HEORBLVT.js.map +1 -0
  36. package/dist/{chunk-V7PRSIRQ.js → chunk-JDDIZSLL.js} +4 -4
  37. package/dist/chunk-JDDIZSLL.js.map +1 -0
  38. package/dist/chunk-LITE5YFB.js +669 -0
  39. package/dist/chunk-LITE5YFB.js.map +1 -0
  40. package/dist/{chunk-Z6HJ5FEM.js → chunk-ROQDRXKW.js} +732 -315
  41. package/dist/chunk-ROQDRXKW.js.map +1 -0
  42. package/dist/chunk-SBXNQW4G.js +3 -0
  43. package/dist/chunk-SBXNQW4G.js.map +1 -0
  44. package/dist/{chunk-4TMMVIDM.js → chunk-XJ6N32QP.js} +50 -6
  45. package/dist/chunk-XJ6N32QP.js.map +1 -0
  46. package/dist/chunk-YQJNT4XQ.js +293 -0
  47. package/dist/chunk-YQJNT4XQ.js.map +1 -0
  48. package/dist/controls/index.d.ts +4 -28
  49. package/dist/controls/index.js +3 -3
  50. package/dist/dragdrop/index.d.ts +50 -5
  51. package/dist/dragdrop/index.js +3 -1
  52. package/dist/index.d.ts +660 -302
  53. package/dist/index.js +1793 -587
  54. package/dist/index.js.map +1 -1
  55. package/dist/layers/index.d.ts +6 -5
  56. package/dist/layers/index.js +4 -2
  57. package/dist/loupe/index.d.ts +187 -0
  58. package/dist/loupe/index.js +7 -0
  59. package/dist/loupe/index.js.map +1 -0
  60. package/dist/passthrough/weasel-canvas.d.ts +3 -1
  61. package/dist/passthrough/weasel-canvas.js +1 -1
  62. package/dist/passthrough/weasel-ui.d.ts +151 -91
  63. package/dist/passthrough/weasel-ui.js +3 -2
  64. package/dist/primitives/index.d.ts +3 -1
  65. package/dist/primitives/index.js +6 -5
  66. package/dist/state/index.d.ts +3 -3
  67. package/dist/state/index.js +2 -2
  68. package/dist/styles.css +229 -703
  69. package/dist/surface/index.d.ts +18 -2
  70. package/dist/surface/index.js +2 -2
  71. package/dist/ui/layers/index.d.ts +8 -2
  72. package/dist/ui/layers/index.js +2 -4
  73. package/dist/undo/index.d.ts +5 -4
  74. package/package.json +14 -7
  75. package/src/annotations/AnnotationOverlay.tsx +205 -0
  76. package/src/annotations/AnnotationTargets.tsx +37 -0
  77. package/src/annotations/Annotations.less +129 -0
  78. package/src/annotations/Annotations.meaning.test.tsx +111 -0
  79. package/src/annotations/Annotations.overlay.test.tsx +142 -0
  80. package/src/annotations/AnnotationsContext.ts +49 -0
  81. package/src/annotations/ExportMenu.test.tsx +86 -0
  82. package/src/annotations/ExportMenu.tsx +182 -0
  83. package/src/annotations/MarkList.tsx +75 -0
  84. package/src/annotations/capture.test.ts +140 -0
  85. package/src/annotations/capture.ts +237 -0
  86. package/src/annotations/drawOne.test.ts +56 -0
  87. package/src/annotations/drawOne.ts +47 -0
  88. package/src/annotations/frac.test.ts +59 -0
  89. package/src/annotations/frac.ts +66 -0
  90. package/src/annotations/history.test.ts +82 -0
  91. package/src/annotations/history.ts +118 -0
  92. package/src/annotations/index.ts +37 -0
  93. package/src/annotations/paint.test.ts +125 -0
  94. package/src/annotations/paint.ts +130 -0
  95. package/src/annotations/staleness.test.ts +56 -0
  96. package/src/annotations/staleness.ts +41 -0
  97. package/src/annotations/store.test.ts +175 -0
  98. package/src/annotations/store.ts +317 -0
  99. package/src/annotations/svgNodes.test.ts +77 -0
  100. package/src/annotations/svgNodes.ts +74 -0
  101. package/src/annotations/toolMap.test.ts +36 -0
  102. package/src/annotations/toolMap.ts +54 -0
  103. package/src/annotations/types.ts +222 -0
  104. package/src/annotations/view.test.ts +37 -0
  105. package/src/annotations/view.ts +40 -0
  106. package/src/canvas/AGENTS.md +55 -5
  107. package/src/canvas/CanvasStack.test.tsx +27 -1
  108. package/src/canvas/CanvasStack.tsx +29 -4
  109. package/src/canvas/CanvasStackContext.ts +23 -4
  110. package/src/canvas/camera.test.ts +78 -0
  111. package/src/canvas/camera.ts +62 -0
  112. package/src/canvas/canvasCoords.test.ts +26 -0
  113. package/src/canvas/canvasCoords.ts +20 -7
  114. package/src/canvas/index.ts +5 -1
  115. package/src/canvas/useLayerScheduler.ts +7 -3
  116. package/src/canvas/usePanZoom.test.ts +36 -5
  117. package/src/canvas/usePanZoom.ts +20 -15
  118. package/src/canvas/worldSpec.test.ts +63 -0
  119. package/src/canvas/worldSpec.ts +48 -0
  120. package/src/chrome/builtins.test.ts +31 -1
  121. package/src/chrome/builtins.tsx +63 -19
  122. package/src/chrome/regions/PaletteRegion.test.tsx +22 -1
  123. package/src/chrome/regions/PaletteRegion.tsx +4 -0
  124. package/src/chrome/regions/SidebarRegion.tsx +37 -13
  125. package/src/chrome/regions/ToolbarRegion.tsx +2 -1
  126. package/src/chrome/regions/ViewportRegion.tsx +9 -1
  127. package/src/chrome/regions/regions.test.tsx +6 -1
  128. package/src/chrome/types.ts +20 -0
  129. package/src/config/builder.test.ts +7 -1
  130. package/src/config/builder.ts +1 -5
  131. package/src/config/resolve.test.ts +1 -2
  132. package/src/controls/ControlPanel.stories.tsx +41 -2
  133. package/src/controls/ControlPanel.test.tsx +69 -9
  134. package/src/controls/ControlPanel.tsx +106 -25
  135. package/src/dragdrop/DragDropRuntime.tsx +8 -2
  136. package/src/dragdrop/dragDrop.test.tsx +29 -2
  137. package/src/dragdrop/index.ts +11 -0
  138. package/src/index.test.ts +22 -0
  139. package/src/index.ts +136 -4
  140. package/src/instrument/SineWave.smoke.test.tsx +1 -0
  141. package/src/instrument/types.ts +24 -1
  142. package/src/lab/Lab.surface.test.tsx +162 -0
  143. package/src/lab/Lab.tsx +102 -17
  144. package/src/lab/Lab.undock.test.tsx +85 -0
  145. package/src/lab/LabFullChrome.stories.tsx +20 -0
  146. package/src/lab/LabShell.less +11 -0
  147. package/src/lab/Workspace.less +73 -0
  148. package/src/lab/Workspace.surface.test.tsx +2 -0
  149. package/src/lab/Workspace.tsx +97 -8
  150. package/src/lab/index.ts +1 -1
  151. package/src/lab/panelHost.ts +37 -0
  152. package/src/layers/AGENTS.md +1 -1
  153. package/src/layers/LayerList.tsx +1 -1
  154. package/src/loupe/AGENTS.md +49 -0
  155. package/src/loupe/CanvasLoupe.tsx +83 -0
  156. package/src/loupe/DomLoupe.tsx +62 -0
  157. package/src/loupe/Loupe.less +38 -0
  158. package/src/loupe/LoupeBubble.tsx +32 -0
  159. package/src/loupe/TrialLoupe.tsx +93 -0
  160. package/src/loupe/canvasLens.test.ts +205 -0
  161. package/src/loupe/canvasLens.ts +141 -0
  162. package/src/loupe/index.ts +19 -0
  163. package/src/loupe/types.test.ts +29 -0
  164. package/src/loupe/types.ts +90 -0
  165. package/src/loupe/useHostSize.ts +30 -0
  166. package/src/loupe/useLoupe.test.tsx +197 -0
  167. package/src/loupe/useLoupe.ts +189 -0
  168. package/src/passthrough/weasel-ui.ts +25 -17
  169. package/src/primitives/FloatingPanel.test.tsx +76 -1
  170. package/src/primitives/FloatingPanel.tsx +19 -3
  171. package/src/primitives/ScaleIndicator.test.tsx +7 -2
  172. package/src/primitives/Sidebar.less +18 -0
  173. package/src/primitives/Toolbar.less +8 -0
  174. package/src/primitives/Toolbar.tsx +5 -0
  175. package/src/primitives/useRovingTabIndex.test.ts +21 -0
  176. package/src/primitives/useRovingTabIndex.ts +26 -17
  177. package/src/state/document.test.ts +23 -0
  178. package/src/state/document.ts +14 -2
  179. package/src/state/index.ts +2 -0
  180. package/src/state/store.test.ts +24 -0
  181. package/src/state/store.ts +35 -1
  182. package/src/state/types.ts +11 -0
  183. package/src/state/undock.test.ts +40 -0
  184. package/src/state/undock.ts +39 -0
  185. package/src/styles.less +2 -4
  186. package/src/surface/SurfaceContext.ts +4 -0
  187. package/src/surface/index.ts +8 -3
  188. package/src/surface/useSurfaceTile.test.tsx +2 -0
  189. package/src/surface/useSurfaceTile.ts +7 -1
  190. package/src/surface/useTiledSurface.test.tsx +58 -0
  191. package/src/surface/useTiledSurface.ts +38 -3
  192. package/src/theme/Interstellar.stories.tsx +1 -1
  193. package/src/trial/Trial.annotations.persist.test.tsx +166 -0
  194. package/src/trial/Trial.annotations.test.tsx +121 -0
  195. package/src/trial/Trial.canvas.test.tsx +76 -1
  196. package/src/trial/Trial.config.test.tsx +3 -8
  197. package/src/trial/Trial.less +19 -0
  198. package/src/trial/Trial.loupe.test.tsx +128 -0
  199. package/src/trial/Trial.stories.tsx +1 -0
  200. package/src/trial/Trial.test.tsx +12 -0
  201. package/src/trial/Trial.trialId.test.tsx +36 -0
  202. package/src/trial/Trial.tsx +215 -40
  203. package/src/trial/TrialChrome.tsx +35 -0
  204. package/src/trial/UndockedSections.tsx +65 -0
  205. package/src/trial/trialOps.test.ts +21 -0
  206. package/src/trial/trialOps.ts +5 -3
  207. package/src/ui/layers/index.ts +5 -1
  208. package/dist/_dts/index-DgcNdEdh.d.ts +0 -314
  209. package/dist/chunk-4TMMVIDM.js.map +0 -1
  210. package/dist/chunk-CPUJ3QXL.js.map +0 -1
  211. package/dist/chunk-HFDVGF4X.js.map +0 -1
  212. package/dist/chunk-NS54R52R.js.map +0 -1
  213. package/dist/chunk-O2BULFHX.js +0 -152
  214. package/dist/chunk-O2BULFHX.js.map +0 -1
  215. package/dist/chunk-O7NVSCLN.js.map +0 -1
  216. package/dist/chunk-PO6L3NSH.js +0 -366
  217. package/dist/chunk-PO6L3NSH.js.map +0 -1
  218. package/dist/chunk-PQJ5B2U2.js +0 -27
  219. package/dist/chunk-PQJ5B2U2.js.map +0 -1
  220. package/dist/chunk-RVNN4CHQ.js.map +0 -1
  221. package/dist/chunk-TLGRYALP.js +0 -6151
  222. package/dist/chunk-TLGRYALP.js.map +0 -1
  223. package/dist/chunk-V7PRSIRQ.js.map +0 -1
  224. package/dist/chunk-Z6HJ5FEM.js.map +0 -1
  225. package/dist/chunk-ZZAYVX4X.js +0 -505
  226. package/dist/chunk-ZZAYVX4X.js.map +0 -1
  227. package/src/primitives/DragHandleGlyph.tsx +0 -29
  228. package/src/ui/format.test.ts +0 -33
  229. package/src/ui/format.ts +0 -30
  230. package/src/ui/layers/LayerStack.less +0 -143
  231. package/src/ui/layers/LayerStack.stories.tsx +0 -45
  232. package/src/ui/layers/LayerStack.test.tsx +0 -170
  233. package/src/ui/layers/LayerStack.tsx +0 -208
  234. package/src/ui/properties/CheckboxRow.stories.tsx +0 -27
  235. package/src/ui/properties/ColorRow.stories.tsx +0 -106
  236. package/src/ui/properties/CurveField.less +0 -48
  237. package/src/ui/properties/CurveField.stories.tsx +0 -20
  238. package/src/ui/properties/CurveField.test.tsx +0 -127
  239. package/src/ui/properties/CurveField.tsx +0 -184
  240. package/src/ui/properties/EffectCard.tsx +0 -324
  241. package/src/ui/properties/Gallery.stories.tsx +0 -178
  242. package/src/ui/properties/NumberRow.stories.tsx +0 -65
  243. package/src/ui/properties/PropertyGroup.less +0 -50
  244. package/src/ui/properties/PropertyGroup.stories.tsx +0 -34
  245. package/src/ui/properties/PropertyGroup.test.tsx +0 -33
  246. package/src/ui/properties/PropertyGroup.tsx +0 -45
  247. package/src/ui/properties/PropertyList.stories.tsx +0 -83
  248. package/src/ui/properties/PropertyPanel.less +0 -606
  249. package/src/ui/properties/PropertyPanel.stories.tsx +0 -190
  250. package/src/ui/properties/PropertyPanel.test.tsx +0 -193
  251. package/src/ui/properties/PropertyPanel.tsx +0 -469
  252. package/src/ui/properties/PropertyRow.stories.tsx +0 -53
  253. package/src/ui/properties/SelectRow.stories.tsx +0 -58
  254. package/src/ui/properties/SliderRow.stories.tsx +0 -74
  255. package/src/ui/properties/SpeechBalloonPanels.stories.tsx +0 -398
  256. package/src/ui/properties/TextRow.stories.tsx +0 -62
  257. package/src/ui/properties/ToggleRow.stories.tsx +0 -57
  258. package/src/ui/properties/index.ts +0 -39
  259. package/src/ui/properties/storyLayouts.tsx +0 -36
@@ -1,398 +0,0 @@
1
- // Visual parity check: rebuild a slice of the speech-balloons lab side panels
2
- // using only labkit primitives. If the readouts, units, alpha, two-per-row
3
- // effect bodies, subpanels, and accent-tinted effect cards look the same as
4
- // the SB reference, we've captured the styling correctly.
5
-
6
- import type { Meta, StoryObj } from '@storybook/react-vite';
7
- import { useState } from 'react';
8
- import {
9
- CheckboxRow,
10
- ColorRow,
11
- EffectCard,
12
- EffectCardList,
13
- PropertyList,
14
- PropertyPanel,
15
- SelectRow,
16
- SliderRow,
17
- Subpanel,
18
- } from './';
19
-
20
- const meta: Meta = {
21
- title: 'labkit/UI/Properties/PropertyPanel/SpeechBalloonPanels',
22
- };
23
- export default meta;
24
- type Story = StoryObj;
25
-
26
- function BodyPanel() {
27
- const [base, setBase] = useState<'rectangle' | 'oval' | 'polygon' | 'cloud'>('rectangle');
28
- const [width, setWidth] = useState(220);
29
- const [height, setHeight] = useState(140);
30
- const [lean, setLean] = useState(0);
31
- const [textColor, setTextColor] = useState('#e6e7ec');
32
- const [textAlpha, setTextAlpha] = useState(1);
33
-
34
- return (
35
- <PropertyPanel title={`Body — ${base}`}>
36
- <PropertyList>
37
- <SelectRow
38
- label="Base shape"
39
- value={base}
40
- onChange={(v) => setBase(v as typeof base)}
41
- options={[
42
- { value: 'rectangle', label: 'rectangle' },
43
- { value: 'oval', label: 'oval' },
44
- { value: 'polygon', label: 'polygon' },
45
- { value: 'cloud', label: 'cloud' },
46
- ]}
47
- />
48
- <SliderRow
49
- label="Width"
50
- value={width}
51
- min={60}
52
- max={500}
53
- step={2}
54
- unit="px"
55
- onChange={setWidth}
56
- />
57
- <SliderRow
58
- label="Height"
59
- value={height}
60
- min={20}
61
- max={500}
62
- step={2}
63
- unit="px"
64
- onChange={setHeight}
65
- />
66
- <SliderRow
67
- label="Italic lean"
68
- value={lean}
69
- min={-25}
70
- max={25}
71
- step={0.5}
72
- unit={<sup>°</sup>}
73
- onChange={setLean}
74
- />
75
- <ColorRow
76
- label="Text color"
77
- value={textColor}
78
- onChange={setTextColor}
79
- alpha={textAlpha}
80
- onAlphaChange={setTextAlpha}
81
- />
82
- </PropertyList>
83
- </PropertyPanel>
84
- );
85
- }
86
-
87
- // A single tail's editor body — demonstrates pack='pairs' + a Subpanel
88
- // divider for the shape-specific section (e.g. Bubbles parameters).
89
- function TailBody() {
90
- const [shape, setShape] = useState<'classic' | 'bubbles' | 'lightning' | 'wavy'>('bubbles');
91
- const [angle, setAngle] = useState(115);
92
- const [outAngle, setOutAngle] = useState(0);
93
- const [arc, setArc] = useState(0);
94
- const [size, setSize] = useState(60);
95
- const [bubbleDiameter, setBubbleDiameter] = useState(30);
96
- const [count, setCount] = useState(3);
97
- const [gap, setGap] = useState(0.15);
98
- const [radial, setRadial] = useState(0);
99
-
100
- return (
101
- <PropertyList pack="pairs">
102
- <SelectRow
103
- label="Shape"
104
- value={shape}
105
- onChange={(v) => setShape(v as typeof shape)}
106
- options={[
107
- { value: 'classic', label: 'classic' },
108
- { value: 'bubbles', label: 'bubbles' },
109
- { value: 'lightning', label: 'lightning' },
110
- { value: 'wavy', label: 'wavy' },
111
- ]}
112
- />
113
- <SliderRow
114
- label="Angle"
115
- value={angle}
116
- min={0}
117
- max={359}
118
- unit={<sup>°</sup>}
119
- onChange={setAngle}
120
- />
121
- <SliderRow
122
- label="Tip angle"
123
- value={outAngle}
124
- min={-90}
125
- max={90}
126
- unit={<sup>°</sup>}
127
- onChange={setOutAngle}
128
- />
129
- <SliderRow
130
- label="Bend"
131
- value={arc}
132
- min={-1}
133
- max={1}
134
- step={0.02}
135
- format={(v) => v.toFixed(2)}
136
- onChange={setArc}
137
- />
138
- <SliderRow
139
- label="Length"
140
- value={size}
141
- min={8}
142
- max={220}
143
- step={0.5}
144
- unit="px"
145
- onChange={setSize}
146
- />
147
- {shape === 'bubbles' && (
148
- <Subpanel title="Bubbles">
149
- <SliderRow
150
- label="Size"
151
- value={bubbleDiameter}
152
- min={8}
153
- max={120}
154
- unit="px"
155
- onChange={setBubbleDiameter}
156
- />
157
- <SliderRow label="Count" value={count} min={1} max={8} onChange={setCount} />
158
- <SliderRow
159
- label="Gap"
160
- value={gap}
161
- min={-1}
162
- max={1}
163
- step={0.02}
164
- format={(v) => v.toFixed(2)}
165
- onChange={setGap}
166
- />
167
- <SliderRow
168
- label="Base distance"
169
- value={radial}
170
- min={-60}
171
- max={60}
172
- step={0.5}
173
- unit="px"
174
- onChange={setRadial}
175
- />
176
- </Subpanel>
177
- )}
178
- </PropertyList>
179
- );
180
- }
181
-
182
- function StrokePanel() {
183
- const [width, setWidth] = useState(2);
184
- const [color, setColor] = useState('#161921');
185
- const [alpha, setAlpha] = useState(1);
186
- return (
187
- <PropertyPanel title="Stroke">
188
- <PropertyList pack="pairs">
189
- <SliderRow
190
- label="Width"
191
- value={width}
192
- min={0.5}
193
- max={12}
194
- step={0.5}
195
- unit="px"
196
- format={(v) => v.toFixed(1)}
197
- onChange={setWidth}
198
- />
199
- <ColorRow
200
- label="Color"
201
- value={color}
202
- onChange={setColor}
203
- alpha={alpha}
204
- onAlphaChange={setAlpha}
205
- />
206
- </PropertyList>
207
- </PropertyPanel>
208
- );
209
- }
210
-
211
- function ShadowPanel() {
212
- const [dx, setDx] = useState(4);
213
- const [dy, setDy] = useState(8);
214
- const [blur, setBlur] = useState(10);
215
- const [opacity, setOpacity] = useState(0.4);
216
- const [enabled, setEnabled] = useState(true);
217
- return (
218
- <PropertyPanel title="Shadow">
219
- <PropertyList pack="pairs">
220
- <div className="lk-property-list__span">
221
- <CheckboxRow label="Enabled" value={enabled} onChange={setEnabled} />
222
- </div>
223
- <SliderRow
224
- label="Offset X"
225
- value={dx}
226
- min={-20}
227
- max={20}
228
- step={0.5}
229
- unit="px"
230
- format={(v) => v.toFixed(1)}
231
- onChange={setDx}
232
- />
233
- <SliderRow
234
- label="Offset Y"
235
- value={dy}
236
- min={-20}
237
- max={20}
238
- step={0.5}
239
- unit="px"
240
- format={(v) => v.toFixed(1)}
241
- onChange={setDy}
242
- />
243
- <SliderRow
244
- label="Blur"
245
- value={blur}
246
- min={0}
247
- max={30}
248
- step={0.5}
249
- unit="px"
250
- format={(v) => v.toFixed(1)}
251
- onChange={setBlur}
252
- />
253
- <SliderRow
254
- label="Opacity"
255
- value={opacity}
256
- min={0}
257
- max={1}
258
- step={0.05}
259
- format={(v) => v.toFixed(2)}
260
- onChange={setOpacity}
261
- />
262
- </PropertyList>
263
- </PropertyPanel>
264
- );
265
- }
266
-
267
- export const LeftSidebar: Story = {
268
- render: () => (
269
- <div style={{ width: 360, display: 'flex', flexDirection: 'column', gap: 8 }}>
270
- <BodyPanel />
271
- <StrokePanel />
272
- <ShadowPanel />
273
- </div>
274
- ),
275
- };
276
-
277
- // ── Right sidebar: tails ───────────────────────────────────────────
278
- // Each tail is an EffectCard with a per-instance accent (--lk-panel-accent)
279
- // that re-binds --wzl-accent inside the card. Drag the badge handle to reorder.
280
-
281
- interface TailItem {
282
- id: number;
283
- shape: string;
284
- accent: string;
285
- }
286
-
287
- const TAIL_PALETTE = ['#7ec8e3', '#f0a35c', '#a48bd4', '#7fb069', '#d46aaa'];
288
-
289
- export const RightSidebarTails: Story = {
290
- render: () => {
291
- function TailsList() {
292
- const [tails, setTails] = useState<TailItem[]>([
293
- { id: 1, shape: 'classic', accent: TAIL_PALETTE[0] },
294
- { id: 2, shape: 'bubbles', accent: TAIL_PALETTE[1] },
295
- { id: 3, shape: 'wavy', accent: TAIL_PALETTE[2] },
296
- ]);
297
- const reorder = (sourceId: number, targetId: number, position: 'before' | 'after') => {
298
- setTails((prev) => {
299
- const next = prev.filter((t) => t.id !== sourceId);
300
- const idx = next.findIndex((t) => t.id === targetId);
301
- const insertAt = position === 'before' ? idx : idx + 1;
302
- const src = prev.find((t) => t.id === sourceId);
303
- if (!src) return prev;
304
- next.splice(insertAt, 0, src);
305
- return next;
306
- });
307
- };
308
- const remove = (id: number) => setTails((prev) => prev.filter((t) => t.id !== id));
309
- return (
310
- <EffectCardList
311
- items={tails}
312
- onReorder={reorder}
313
- defaultExpandedIds={tails.map((t) => t.id)}
314
- renderItem={(tail, { cardProps }) => (
315
- <EffectCard
316
- {...cardProps}
317
- accent={tail.accent}
318
- index={tails.findIndex((t) => t.id === tail.id)}
319
- title={tail.shape}
320
- primary={<>{Math.round(60 + tail.id * 30)}°</>}
321
- onRemove={() => remove(tail.id)}
322
- >
323
- <TailBody />
324
- </EffectCard>
325
- )}
326
- />
327
- );
328
- }
329
- return (
330
- <div style={{ width: 360, display: 'flex', flexDirection: 'column', gap: 8 }}>
331
- <TailsList />
332
- </div>
333
- );
334
- },
335
- };
336
-
337
- // ── Effect cards without accent — for fill / stroke / shadow stacks ─
338
-
339
- export const LayerStack: Story = {
340
- render: () => {
341
- function Stack() {
342
- const [items, setItems] = useState([
343
- { id: 1, kind: 'fill' },
344
- { id: 2, kind: 'stroke' },
345
- { id: 3, kind: 'shadow' },
346
- ]);
347
- const reorder = (sourceId: number, targetId: number, position: 'before' | 'after') => {
348
- setItems((prev) => {
349
- const next = prev.filter((t) => t.id !== sourceId);
350
- const idx = next.findIndex((t) => t.id === targetId);
351
- const insertAt = position === 'before' ? idx : idx + 1;
352
- const src = prev.find((t) => t.id === sourceId);
353
- if (!src) return prev;
354
- next.splice(insertAt, 0, src);
355
- return next;
356
- });
357
- };
358
- return (
359
- <EffectCardList
360
- items={items}
361
- onReorder={reorder}
362
- defaultExpandedIds={items.map((i) => i.id)}
363
- renderItem={(item, { cardProps }) => (
364
- <EffectCard
365
- {...cardProps}
366
- title={item.kind}
367
- onRemove={() => setItems((prev) => prev.filter((t) => t.id !== item.id))}
368
- >
369
- <PropertyList pack="pairs">
370
- <SliderRow
371
- label="Sample A"
372
- value={12}
373
- min={0}
374
- max={64}
375
- unit="px"
376
- onChange={() => {}}
377
- />
378
- <SliderRow
379
- label="Sample B"
380
- value={45}
381
- min={-180}
382
- max={180}
383
- unit={<sup>°</sup>}
384
- onChange={() => {}}
385
- />
386
- </PropertyList>
387
- </EffectCard>
388
- )}
389
- />
390
- );
391
- }
392
- return (
393
- <div style={{ width: 360, display: 'flex', flexDirection: 'column', gap: 8 }}>
394
- <Stack />
395
- </div>
396
- );
397
- },
398
- };
@@ -1,62 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { useState } from 'react';
3
- import { TextRow } from './PropertyPanel';
4
- import { SideBySide } from './storyLayouts';
5
-
6
- const meta: Meta<typeof TextRow> = {
7
- title: 'labkit/UI/Properties/Rows/TextRow',
8
- component: TextRow,
9
- };
10
- export default meta;
11
- type Story = StoryObj<typeof TextRow>;
12
-
13
- function Controlled({
14
- initial,
15
- label,
16
- placeholder,
17
- maxLength,
18
- layout,
19
- }: {
20
- initial: string;
21
- label: string;
22
- placeholder?: string;
23
- maxLength?: number;
24
- layout?: 'block' | 'inline';
25
- }) {
26
- const [value, setValue] = useState(initial);
27
- return (
28
- <TextRow
29
- label={label}
30
- value={value}
31
- onChange={setValue}
32
- placeholder={placeholder}
33
- maxLength={maxLength}
34
- layout={layout}
35
- />
36
- );
37
- }
38
-
39
- export const BothLayouts: Story = {
40
- render: () => (
41
- <SideBySide
42
- block={<Controlled initial="Untitled" label="Name" />}
43
- inline={<Controlled initial="Untitled" label="Name" layout="inline" />}
44
- />
45
- ),
46
- };
47
-
48
- export const Empty: Story = {
49
- render: () => (
50
- <div style={{ width: 280 }}>
51
- <Controlled initial="" label="Name" placeholder="Type a name…" />
52
- </div>
53
- ),
54
- };
55
-
56
- export const Capped: Story = {
57
- render: () => (
58
- <div style={{ width: 280 }}>
59
- <Controlled initial="ABCD" label="Tag" maxLength={4} />
60
- </div>
61
- ),
62
- };
@@ -1,57 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { useState } from 'react';
3
- import { ToggleRow } from './PropertyPanel';
4
- import { SideBySide } from './storyLayouts';
5
-
6
- const meta: Meta<typeof ToggleRow> = {
7
- title: 'labkit/UI/Properties/Rows/ToggleRow',
8
- component: ToggleRow,
9
- };
10
- export default meta;
11
- type Story = StoryObj<typeof ToggleRow>;
12
-
13
- const ALIGN_OPTIONS = [
14
- { value: 'left', label: 'L' },
15
- { value: 'center', label: 'C' },
16
- { value: 'right', label: 'R' },
17
- ] as const;
18
-
19
- function Align({ layout }: { layout?: 'block' | 'inline' }) {
20
- const [value, setValue] = useState<'left' | 'center' | 'right'>('center');
21
- return (
22
- <ToggleRow
23
- label="Align"
24
- value={value}
25
- onChange={setValue}
26
- options={ALIGN_OPTIONS}
27
- layout={layout}
28
- />
29
- );
30
- }
31
-
32
- export const BothLayouts: Story = {
33
- render: () => <SideBySide block={<Align />} inline={<Align layout="inline" />} />,
34
- };
35
-
36
- function TwoOptions() {
37
- const [value, setValue] = useState<'on' | 'off'>('on');
38
- return (
39
- <ToggleRow
40
- label="Snapping"
41
- value={value}
42
- onChange={setValue}
43
- options={[
44
- { value: 'on', label: 'On' },
45
- { value: 'off', label: 'Off' },
46
- ]}
47
- />
48
- );
49
- }
50
-
51
- export const TwoOption: Story = {
52
- render: () => (
53
- <div style={{ width: 280 }}>
54
- <TwoOptions />
55
- </div>
56
- ),
57
- };
@@ -1,39 +0,0 @@
1
- export type { CurveFieldProps, CurveMark } from './CurveField';
2
- export { CurveField } from './CurveField';
3
- export type {
4
- EffectCardListItem,
5
- EffectCardListProps,
6
- EffectCardProps,
7
- SubpanelProps,
8
- } from './EffectCard';
9
- export { EffectCard, EffectCardList, Subpanel } from './EffectCard';
10
- export type { PropertyGroupProps } from './PropertyGroup';
11
- export { PropertyGroup } from './PropertyGroup';
12
- export type {
13
- CheckboxRowProps,
14
- ColorRowProps,
15
- NumberRowProps,
16
- PropertyListPack,
17
- PropertyListProps,
18
- PropertyPanelProps,
19
- PropertyRowLayout,
20
- PropertyRowProps,
21
- PropertyRowVariant,
22
- SelectOption,
23
- SelectRowProps,
24
- SliderRowProps,
25
- TextRowProps,
26
- ToggleRowProps,
27
- } from './PropertyPanel';
28
- export {
29
- CheckboxRow,
30
- ColorRow,
31
- NumberRow,
32
- PropertyList,
33
- PropertyPanel,
34
- PropertyRow,
35
- SelectRow,
36
- SliderRow,
37
- TextRow,
38
- ToggleRow,
39
- } from './PropertyPanel';
@@ -1,36 +0,0 @@
1
- import type { ReactNode } from 'react';
2
-
3
- /**
4
- * Side-by-side comparison used by row stories to show block + inline layouts
5
- * at the same time. Not a stories file — name has no .stories. suffix so
6
- * Storybook's glob skips it.
7
- */
8
- export function SideBySide({ block, inline }: { block: ReactNode; inline: ReactNode }) {
9
- const labelStyle = {
10
- font: 'var(--wzl-font-weight-normal) var(--wzl-font-size-sm)/var(--wzl-leading-tight) var(--wzl-font-ui)',
11
- color: 'var(--wzl-fg-muted)',
12
- textTransform: 'uppercase' as const,
13
- letterSpacing: 'var(--wzl-tracking-wider)',
14
- margin: '0 0 8px',
15
- };
16
- return (
17
- <div
18
- style={{
19
- display: 'grid',
20
- gridTemplateColumns: '1fr 1fr',
21
- gap: 24,
22
- width: 720,
23
- alignItems: 'start',
24
- }}
25
- >
26
- <div>
27
- <div style={labelStyle}>Block</div>
28
- {block}
29
- </div>
30
- <div>
31
- <div style={labelStyle}>Inline</div>
32
- {inline}
33
- </div>
34
- </div>
35
- );
36
- }