@jamesyong42/infinite-canvas 1.1.0 → 1.2.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 (63) hide show
  1. package/README.md +105 -8
  2. package/dist/SelectionRenderer-CR2PBQwx.d.cts +105 -0
  3. package/dist/SelectionRenderer-CR2PBQwx.d.cts.map +1 -0
  4. package/dist/SelectionRenderer-DlsBstAq.d.mts +105 -0
  5. package/dist/SelectionRenderer-DlsBstAq.d.mts.map +1 -0
  6. package/dist/WebGLWidgetLayer-BBMuwzHq.cjs +3560 -0
  7. package/dist/WebGLWidgetLayer-BBMuwzHq.cjs.map +1 -0
  8. package/dist/WebGLWidgetLayer-C3p1tnpm.mjs +3375 -0
  9. package/dist/WebGLWidgetLayer-C3p1tnpm.mjs.map +1 -0
  10. package/dist/advanced.cjs +110 -166
  11. package/dist/advanced.cjs.map +1 -1
  12. package/dist/advanced.d.cts +58 -42
  13. package/dist/advanced.d.cts.map +1 -0
  14. package/dist/advanced.d.mts +99 -0
  15. package/dist/advanced.d.mts.map +1 -0
  16. package/dist/advanced.mjs +105 -0
  17. package/dist/advanced.mjs.map +1 -0
  18. package/dist/devtools.cjs +378 -352
  19. package/dist/devtools.cjs.map +1 -1
  20. package/dist/devtools.d.cts +15 -11
  21. package/dist/devtools.d.cts.map +1 -0
  22. package/dist/devtools.d.mts +23 -0
  23. package/dist/devtools.d.mts.map +1 -0
  24. package/dist/devtools.mjs +652 -0
  25. package/dist/devtools.mjs.map +1 -0
  26. package/dist/engine-BfbvWXSk.d.mts +982 -0
  27. package/dist/engine-BfbvWXSk.d.mts.map +1 -0
  28. package/dist/engine-CCjuFMC-.d.cts +982 -0
  29. package/dist/engine-CCjuFMC-.d.cts.map +1 -0
  30. package/dist/hooks-BwY7rRHg.mjs +425 -0
  31. package/dist/hooks-BwY7rRHg.mjs.map +1 -0
  32. package/dist/hooks-DHShH86C.cjs +707 -0
  33. package/dist/hooks-DHShH86C.cjs.map +1 -0
  34. package/dist/index.cjs +909 -824
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +181 -74
  37. package/dist/index.d.cts.map +1 -0
  38. package/dist/index.d.mts +258 -0
  39. package/dist/index.d.mts.map +1 -0
  40. package/dist/index.mjs +855 -0
  41. package/dist/index.mjs.map +1 -0
  42. package/package.json +44 -17
  43. package/dist/SelectionRenderer-DRtwHWJ0.d.cts +0 -102
  44. package/dist/SelectionRenderer-rGYPadnn.d.ts +0 -102
  45. package/dist/advanced.d.ts +0 -83
  46. package/dist/advanced.js +0 -125
  47. package/dist/advanced.js.map +0 -1
  48. package/dist/chunk-2KBYGER3.cjs +0 -336
  49. package/dist/chunk-2KBYGER3.cjs.map +0 -1
  50. package/dist/chunk-FUPKRQB2.cjs +0 -3025
  51. package/dist/chunk-FUPKRQB2.cjs.map +0 -1
  52. package/dist/chunk-NILAZG6O.js +0 -292
  53. package/dist/chunk-NILAZG6O.js.map +0 -1
  54. package/dist/chunk-W2ZNA7HP.js +0 -2977
  55. package/dist/chunk-W2ZNA7HP.js.map +0 -1
  56. package/dist/devtools.d.ts +0 -19
  57. package/dist/devtools.js +0 -626
  58. package/dist/devtools.js.map +0 -1
  59. package/dist/engine-DqgJ82tq.d.cts +0 -805
  60. package/dist/engine-DqgJ82tq.d.ts +0 -805
  61. package/dist/index.d.ts +0 -151
  62. package/dist/index.js +0 -604
  63. package/dist/index.js.map +0 -1
package/README.md CHANGED
@@ -17,6 +17,7 @@ Build Figma-style infinite canvases in React -- drag, resize, snap, zoom, nested
17
17
  - **Undo / redo** -- Command buffer with grouped operations (an entire drag is one undo step)
18
18
  - **Hierarchical navigation** -- Enter and exit nested containers with camera state preservation
19
19
  - **ECS architecture** -- Extensible via custom components, tags, and systems with topologically-sorted scheduling
20
+ - **Card widgets** -- iOS-style preset-sized tiles (small / medium / large / xl) with rounded corners, soft shadows, and lift-on-drag animation; DOM or R3F/PBR flavors via `createCardWidget` / `createGeometryCardWidget`
20
21
  - **Performance** -- SDF shaders for grid and selection chrome, RBush spatial indexing, viewport culling, per-system profiling
21
22
  - **Live ECS editor** -- Drop-in `<EcsDevtools>` panel for spawning, inspecting, and editing components and tags at runtime
22
23
  - **Dark mode** -- Full dark mode support across canvas, widgets, and UI chrome
@@ -215,6 +216,97 @@ Spawning is uniform: `engine.spawn(id, options)`. If `id` matches an archetype,
215
216
  | `parent` | Parent entity id for nesting. |
216
217
  | `rotation` | Initial rotation in radians. |
217
218
 
219
+ The `interactive` field on `Archetype` accepts a boolean or an object. Pass `{ selectable, draggable, resizable, selectionFrame }` (any subset) when you want finer control. Cards that move, select, but never resize and render their own chrome: `{ selectable: true, draggable: true, resizable: false, selectionFrame: false }`. Omitted keys default to `false`, except `selectionFrame` which follows `selectable` (an entity you can select gets a frame unless you opt out).
220
+
221
+ ## Card Widgets
222
+
223
+ **Card widgets** are fixed-size, non-resizable widgets that sit on an iOS-style preset grid. They ship with rounded corners, a soft drop shadow, a hairline ring, and a subtle lift animation while dragging. Use them when you want dashboard-style tiles rather than free-form resizable surfaces.
224
+
225
+ ```tsx
226
+ import { createCardWidget } from '@jamesyong42/infinite-canvas';
227
+ import { z } from 'zod';
228
+
229
+ const schema = z.object({ label: z.string().default('Hi') });
230
+
231
+ export const Greeting = createCardWidget<{ label: string }>({
232
+ type: 'greeting-card',
233
+ size: 'small', // 'small' | 'medium' | 'large' | 'xl'
234
+ schema,
235
+ defaultData: { label: 'Hi' },
236
+ render: ({ data }) => (
237
+ <div className="flex h-full w-full items-center justify-center bg-white">
238
+ {data.label}
239
+ </div>
240
+ ),
241
+ });
242
+
243
+ // Register both the widget and the matching archetype.
244
+ const engine = createLayoutEngine({
245
+ widgets: [Greeting.widget],
246
+ archetypes: [Greeting.archetype],
247
+ });
248
+ engine.spawn('greeting-card', { at: { x: 50, y: 50 } });
249
+ ```
250
+
251
+ Preset sizes (default, matching iOS widget conventions on a 19 px grid):
252
+
253
+ | Preset | Width × Height |
254
+ |--------|----------------|
255
+ | `small` | 155 × 155 |
256
+ | `medium` | 329 × 155 |
257
+ | `large` | 329 × 345 |
258
+ | `xl` | 329 × 535 |
259
+
260
+ Override per-engine via `createLayoutEngine({ cardPresets: { presets: { small: { width: 200, height: 200 } }, gap: 24 } })`. Omitted presets keep their defaults.
261
+
262
+ Under the hood: the returned widget wraps your `render` in `<CardFrame>` (exported for manual composition), the archetype is non-resizable, and it bundles a `Card` component. A built-in `cardSystem` stamps `Transform2D.width/height` from `Card.preset` each tick — to change a card's size at runtime, update the preset: `engine.set(id, Card, { preset: 'large' })`. Reading the `Dragging` tag from the frame drives the lift affordance; you can read it elsewhere too via `useTag(entityId, Dragging)`.
263
+
264
+ Cards also opt out of the engine-drawn selection + hover outline (`selectionFrame: false` in their archetype) — the iOS rounded chrome in `<CardFrame>` is the card's visual contract, so the standard blue frame would fight it. If you need a selected/hover affordance inside a card, read `useIsSelected(entityId)` / `useTag(entityId, /* Hovered tag */)` from within `render` and style accordingly.
265
+
266
+ ### 3D Card Widgets
267
+
268
+ `createGeometryCardWidget` is the R3F counterpart — same preset sizes, non-resizable archetype, and drag-lift behavior, but the widget body is a three.js scene instead of DOM content. The helper pairs cleanly with PBR materials.
269
+
270
+ ```tsx
271
+ import { createGeometryCardWidget } from '@jamesyong42/infinite-canvas';
272
+ import { useFrame } from '@react-three/fiber';
273
+ import { useRef } from 'react';
274
+ import type { Mesh } from 'three';
275
+ import { z } from 'zod';
276
+
277
+ const schema = z.object({ color: z.string().default('#F5B8D0') });
278
+
279
+ export const Sphere = createGeometryCardWidget<{ color: string }>({
280
+ type: 'sphere',
281
+ size: 'small',
282
+ schema,
283
+ defaultData: { color: '#F5B8D0' },
284
+ background: 'card', // or 'transparent' — the geometry floats over the canvas
285
+ geometry: ({ data, width }) => {
286
+ const ref = useRef<Mesh>(null);
287
+ useFrame((_, dt) => { if (ref.current) ref.current.rotation.y += dt * 0.3; });
288
+ return (
289
+ <group>
290
+ <pointLight position={[80, 80, 120]} intensity={160} distance={300} decay={1.4} />
291
+ <ambientLight intensity={0.3} />
292
+ <mesh ref={ref}>
293
+ <sphereGeometry args={[width * 0.32, 48, 48]} />
294
+ <meshStandardMaterial color={data.color} roughness={0.35} />
295
+ </mesh>
296
+ </group>
297
+ );
298
+ },
299
+ });
300
+ ```
301
+
302
+ `background` options:
303
+
304
+ - `'card'` (default) — a rounded iOS-style card mesh sits behind the geometry in the same widget group.
305
+ - `'transparent'` — no back plane; the geometry floats over whatever's behind the widget.
306
+ - `{ color, roughness?, metalness? }` — card back with custom PBR parameters for tinted or glossy variants.
307
+
308
+ **Lighting caveat.** All R3F widgets share a single `<Canvas>`, so lights and `envMap`s you declare inside one widget's render function affect every other 3D widget. Keep per-widget lights `pointLight`s with `distance` scoped to the widget's size, or add one shared `<Environment>` at the app level (if you control the R3F canvas). The helper itself adds no lights — declare what you need inside your `geometry` component.
309
+
218
310
  ## WebGL Widgets (R3F)
219
311
 
220
312
  Define an `R3FWidget<T>` with `surface: 'webgl'` to render 3D content via React Three Fiber. R3F widget views receive `{ entityId, width, height }` and render in local coordinates (origin at widget centre):
@@ -525,20 +617,25 @@ z:3 UI chrome
525
617
  | `InteractionRole` | Interaction behavior (drag, select, resize, etc.) |
526
618
  | `HandleSet` | Child handle entity references |
527
619
  | `CursorHint` | Cursor style on hover/active |
620
+ | `Card` | Marks an iOS-style card; carries the preset (`small`/`medium`/`large`/`xl`) |
528
621
 
529
622
  ### ECS Tags
530
623
 
531
- `Selectable` `Draggable` `Resizable` `Locked` `Selected` `Active` `Visible`
624
+ `Selectable` `Draggable` `Resizable` `SelectionFrame` `Locked` `Selected` `Dragging` `Active` `Visible`
625
+
626
+ - `Dragging` — transient state tag (parallels `Selected`): added when the drag dead zone is crossed, removed on pointer up or cancel. Read via `useTag(entityId, Dragging)` to drive drag-time affordances.
627
+ - `SelectionFrame` — opts an entity into the engine-drawn selection + hover outline. Granted automatically to Selectable entities via the archetype's `interactive` caps; widgets that render their own chrome (e.g. cards) opt out.
532
628
 
533
629
  ### Systems (execution order)
534
630
 
535
- 1. `transformPropagate` -- Propagate transforms down hierarchy, compute WorldBounds
536
- 2. `handleSync` -- Synchronize resize handle entities with parent widgets
537
- 3. `hitboxWorldBounds` -- Compute world-space hitbox bounds
538
- 4. `navigationFilter` -- Filter entities to active navigation layer
539
- 5. `cull` -- Mark viewport-visible entities
540
- 6. `breakpoint` -- Compute responsive breakpoints
541
- 7. `sort` -- Z-index ordering
631
+ 1. `card` -- Stamp Transform2D size from Card preset
632
+ 2. `transformPropagate` -- Propagate transforms down hierarchy, compute WorldBounds
633
+ 3. `handleSync` -- Synchronize resize handle entities with parent widgets
634
+ 4. `hitboxWorldBounds` -- Compute world-space hitbox bounds
635
+ 5. `navigationFilter` -- Filter entities to active navigation layer
636
+ 6. `cull` -- Mark viewport-visible entities
637
+ 7. `breakpoint` -- Compute responsive breakpoints
638
+ 8. `sort` -- Z-index ordering
542
639
 
543
640
  ## Performance Profiling
544
641
 
@@ -0,0 +1,105 @@
1
+ import { F as DomWidgetProps, L as R3FWidgetProps, b as EqualSpacingIndicator, n as LayoutEngine, x as SnapGuide } from "./engine-CCjuFMC-.cjs";
2
+ import { EntityId } from "@jamesyong42/reactive-ecs";
3
+ import * as _$react from "react";
4
+ import * as THREE from "three";
5
+
6
+ //#region src/react/context.d.ts
7
+ declare const EngineProvider: _$react.Provider<LayoutEngine | null>;
8
+ declare const ContainerRefProvider: _$react.Provider<_$react.RefObject<HTMLDivElement | null> | null>;
9
+ declare function useContainerRef(): React.RefObject<HTMLDivElement | null> | null;
10
+ /**
11
+ * Returns the LayoutEngine instance from the nearest InfiniteCanvas context.
12
+ * Throws if used outside an InfiniteCanvas provider.
13
+ */
14
+ declare function useLayoutEngine(): LayoutEngine;
15
+ /**
16
+ * Discriminated resolution of a widget by type. The surface determines which
17
+ * layer renders the component and with what prop shape.
18
+ */
19
+ type ResolvedWidget = {
20
+ surface: 'dom';
21
+ component: React.ComponentType<DomWidgetProps>;
22
+ } | {
23
+ surface: 'webgl';
24
+ component: React.ComponentType<R3FWidgetProps>;
25
+ };
26
+ type WidgetResolver = (entityId: EntityId, widgetType: string) => ResolvedWidget | null;
27
+ declare const WidgetResolverProvider: _$react.Provider<WidgetResolver | null>;
28
+ declare function useWidgetResolver(): WidgetResolver | null;
29
+ //#endregion
30
+ //#region src/react/webgl/GridRenderer.d.ts
31
+ interface GridConfig {
32
+ /** World-unit spacings for up to 3 grid levels [fine, medium, coarse]. */
33
+ spacings: [number, number, number];
34
+ /** Dot RGB color as [r, g, b] in 0–1 range. */
35
+ dotColor: [number, number, number];
36
+ /** Base dot opacity multiplier (0–1). */
37
+ dotAlpha: number;
38
+ /** CSS-pixel range where a grid level fades in: [start, end]. */
39
+ fadeIn: [number, number];
40
+ /** CSS-pixel range where a grid level fades out: [start, end]. */
41
+ fadeOut: [number, number];
42
+ /** Dot radius range in CSS pixels [min, max]. Scaled by DPR internally. */
43
+ dotRadius: [number, number];
44
+ /** Per-level opacity weight: level i gets (base + i * step). */
45
+ levelWeight: [number, number];
46
+ }
47
+ declare const DEFAULT_GRID_CONFIG: GridConfig;
48
+ declare class GridRenderer {
49
+ private renderer;
50
+ private scene;
51
+ private camera;
52
+ private material;
53
+ private mesh;
54
+ constructor(canvas: HTMLCanvasElement);
55
+ /** Apply a (partial) grid config. Only provided fields are updated. */
56
+ setConfig(config: Partial<GridConfig>): void;
57
+ setSize(width: number, height: number, dpr?: number): void;
58
+ render(cameraX: number, cameraY: number, zoom: number): void;
59
+ dispose(): void;
60
+ /** Expose for future WebGL widget rendering */
61
+ getWebGLRenderer(): THREE.WebGLRenderer;
62
+ }
63
+ //#endregion
64
+ //#region src/react/webgl/SelectionRenderer.d.ts
65
+ interface SelectionConfig {
66
+ /** Selection outline color [r,g,b] 0-1. Default: Figma blue. */
67
+ outlineColor: [number, number, number];
68
+ /** Selection outline width in screen px. */
69
+ outlineWidth: number;
70
+ /** Hover outline color [r,g,b] 0-1. */
71
+ hoverColor: [number, number, number];
72
+ /** Hover outline width in screen px. */
73
+ hoverWidth: number;
74
+ /** Handle size in screen px. */
75
+ handleSize: number;
76
+ /** Handle fill color [r,g,b] 0-1 (white). */
77
+ handleFill: [number, number, number];
78
+ /** Handle border color [r,g,b] 0-1 (same as outline). */
79
+ handleBorder: [number, number, number];
80
+ /** Handle border width in screen px. */
81
+ handleBorderWidth: number;
82
+ /** Group bbox dash length in screen px (0 = solid). */
83
+ groupDash: number;
84
+ }
85
+ declare const DEFAULT_SELECTION_CONFIG: SelectionConfig;
86
+ interface SelectionBounds {
87
+ x: number;
88
+ y: number;
89
+ width: number;
90
+ height: number;
91
+ }
92
+ declare class SelectionRenderer {
93
+ private material;
94
+ private mesh;
95
+ private scene;
96
+ private camera;
97
+ constructor();
98
+ setConfig(config: Partial<SelectionConfig>): void;
99
+ setSize(resolution: THREE.Vector2, dpr: number): void;
100
+ render(renderer: THREE.WebGLRenderer, cameraX: number, cameraY: number, zoom: number, selected: SelectionBounds[], hovered: SelectionBounds | null, guides?: SnapGuide[], spacings?: EqualSpacingIndicator[]): void;
101
+ dispose(): void;
102
+ }
103
+ //#endregion
104
+ export { DEFAULT_GRID_CONFIG as a, ContainerRefProvider as c, WidgetResolverProvider as d, useContainerRef as f, SelectionRenderer as i, EngineProvider as l, useWidgetResolver as m, SelectionBounds as n, GridConfig as o, useLayoutEngine as p, SelectionConfig as r, GridRenderer as s, DEFAULT_SELECTION_CONFIG as t, ResolvedWidget as u };
105
+ //# sourceMappingURL=SelectionRenderer-CR2PBQwx.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionRenderer-CR2PBQwx.d.cts","names":[],"sources":["../src/react/context.ts","../src/react/webgl/GridRenderer.ts","../src/react/webgl/SelectionRenderer.ts"],"mappings":";;;;;;cASa,cAAA,EAAc,OAAA,CAAA,QAAA,CAAA,YAAA;AAAA,cAOd,oBAAA,EAAoB,OAAA,CAAA,QAAA,CAAA,OAAA,CAAA,SAAA,CAAA,cAAA;AAAA,iBAEjB,eAAA,CAAA,GAAmB,KAAA,CAAM,SAAA,CAAU,cAAA;AATnD;;;;AAAA,iBAiBgB,eAAA,CAAA,GAAmB,YAAA;;;;;KAgBvB,cAAA;EACP,OAAA;EAAgB,SAAA,EAAW,KAAA,CAAM,aAAA,CAAc,cAAA;AAAA;EAC/C,OAAA;EAAkB,SAAA,EAAW,KAAA,CAAM,aAAA,CAAc,cAAA;AAAA;AAAA,KAE1C,cAAA,IAAkB,QAAA,EAAU,QAAA,EAAU,UAAA,aAAuB,cAAA;AAAA,cAI5D,sBAAA,EAAsB,OAAA,CAAA,QAAA,CAAA,cAAA;AAAA,iBAEnB,iBAAA,CAAA,GAAqB,cAAA;;;UChDpB,UAAA;;EAEhB,QAAA;;EAEA,QAAA;EDCY;ECCZ,QAAA;;EAEA,MAAA;EDH0B;ECK1B,OAAA;EDE+D;ECA/D,SAAA;EDAgC;ECEhC,WAAA;AAAA;AAAA,cAGY,mBAAA,EAAqB,UAAA;AAAA,cAoFrB,YAAA;EAAA,QACJ,QAAA;EAAA,QACA,KAAA;EAAA,QACA,MAAA;EAAA,QACA,QAAA;EAAA,QACA,IAAA;cAEI,MAAA,EAAQ,iBAAA;ED9FU;EC8I9B,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,UAAA;EAW1B,OAAA,CAAQ,KAAA,UAAe,MAAA,UAAgB,GAAA;EAQvC,MAAA,CAAO,OAAA,UAAiB,OAAA,UAAiB,IAAA;EAOzC,OAAA,CAAA;EDxKkD;EC+KlD,gBAAA,CAAA,GAAoB,KAAA,CAAM,aAAA;AAAA;;;UC3LV,eAAA;;EAEhB,YAAA;;EAEA,YAAA;EFDmD;EEGnD,UAAA;EFH0B;EEK1B,UAAA;EFEY;EEAZ,UAAA;;EAEA,UAAA;EFFgC;EEIhC,YAAA;EFJgC;EEMhC,iBAAA;EFNgC;EEQhC,SAAA;AAAA;AAAA,cAGY,wBAAA,EAA0B,eAAA;AAAA,UActB,eAAA;EAChB,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,cAoOY,iBAAA;EAAA,QACJ,QAAA;EAAA,QACA,IAAA;EAAA,QACA,KAAA;EAAA,QACA,MAAA;;EAsDR,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,eAAA;EAc1B,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,OAAA,EAAS,GAAA;EAKnC,MAAA,CACC,QAAA,EAAU,KAAA,CAAM,aAAA,EAChB,OAAA,UACA,OAAA,UACA,IAAA,UACA,QAAA,EAAU,eAAA,IACV,OAAA,EAAS,eAAA,SACT,MAAA,GAAQ,SAAA,IACR,QAAA,GAAU,qBAAA;EAiFX,OAAA,CAAA;AAAA"}
@@ -0,0 +1,105 @@
1
+ import { F as DomWidgetProps, L as R3FWidgetProps, b as EqualSpacingIndicator, n as LayoutEngine, x as SnapGuide } from "./engine-BfbvWXSk.mjs";
2
+ import { EntityId } from "@jamesyong42/reactive-ecs";
3
+ import * as _$react from "react";
4
+ import * as THREE from "three";
5
+
6
+ //#region src/react/context.d.ts
7
+ declare const EngineProvider: _$react.Provider<LayoutEngine | null>;
8
+ declare const ContainerRefProvider: _$react.Provider<_$react.RefObject<HTMLDivElement | null> | null>;
9
+ declare function useContainerRef(): React.RefObject<HTMLDivElement | null> | null;
10
+ /**
11
+ * Returns the LayoutEngine instance from the nearest InfiniteCanvas context.
12
+ * Throws if used outside an InfiniteCanvas provider.
13
+ */
14
+ declare function useLayoutEngine(): LayoutEngine;
15
+ /**
16
+ * Discriminated resolution of a widget by type. The surface determines which
17
+ * layer renders the component and with what prop shape.
18
+ */
19
+ type ResolvedWidget = {
20
+ surface: 'dom';
21
+ component: React.ComponentType<DomWidgetProps>;
22
+ } | {
23
+ surface: 'webgl';
24
+ component: React.ComponentType<R3FWidgetProps>;
25
+ };
26
+ type WidgetResolver = (entityId: EntityId, widgetType: string) => ResolvedWidget | null;
27
+ declare const WidgetResolverProvider: _$react.Provider<WidgetResolver | null>;
28
+ declare function useWidgetResolver(): WidgetResolver | null;
29
+ //#endregion
30
+ //#region src/react/webgl/GridRenderer.d.ts
31
+ interface GridConfig {
32
+ /** World-unit spacings for up to 3 grid levels [fine, medium, coarse]. */
33
+ spacings: [number, number, number];
34
+ /** Dot RGB color as [r, g, b] in 0–1 range. */
35
+ dotColor: [number, number, number];
36
+ /** Base dot opacity multiplier (0–1). */
37
+ dotAlpha: number;
38
+ /** CSS-pixel range where a grid level fades in: [start, end]. */
39
+ fadeIn: [number, number];
40
+ /** CSS-pixel range where a grid level fades out: [start, end]. */
41
+ fadeOut: [number, number];
42
+ /** Dot radius range in CSS pixels [min, max]. Scaled by DPR internally. */
43
+ dotRadius: [number, number];
44
+ /** Per-level opacity weight: level i gets (base + i * step). */
45
+ levelWeight: [number, number];
46
+ }
47
+ declare const DEFAULT_GRID_CONFIG: GridConfig;
48
+ declare class GridRenderer {
49
+ private renderer;
50
+ private scene;
51
+ private camera;
52
+ private material;
53
+ private mesh;
54
+ constructor(canvas: HTMLCanvasElement);
55
+ /** Apply a (partial) grid config. Only provided fields are updated. */
56
+ setConfig(config: Partial<GridConfig>): void;
57
+ setSize(width: number, height: number, dpr?: number): void;
58
+ render(cameraX: number, cameraY: number, zoom: number): void;
59
+ dispose(): void;
60
+ /** Expose for future WebGL widget rendering */
61
+ getWebGLRenderer(): THREE.WebGLRenderer;
62
+ }
63
+ //#endregion
64
+ //#region src/react/webgl/SelectionRenderer.d.ts
65
+ interface SelectionConfig {
66
+ /** Selection outline color [r,g,b] 0-1. Default: Figma blue. */
67
+ outlineColor: [number, number, number];
68
+ /** Selection outline width in screen px. */
69
+ outlineWidth: number;
70
+ /** Hover outline color [r,g,b] 0-1. */
71
+ hoverColor: [number, number, number];
72
+ /** Hover outline width in screen px. */
73
+ hoverWidth: number;
74
+ /** Handle size in screen px. */
75
+ handleSize: number;
76
+ /** Handle fill color [r,g,b] 0-1 (white). */
77
+ handleFill: [number, number, number];
78
+ /** Handle border color [r,g,b] 0-1 (same as outline). */
79
+ handleBorder: [number, number, number];
80
+ /** Handle border width in screen px. */
81
+ handleBorderWidth: number;
82
+ /** Group bbox dash length in screen px (0 = solid). */
83
+ groupDash: number;
84
+ }
85
+ declare const DEFAULT_SELECTION_CONFIG: SelectionConfig;
86
+ interface SelectionBounds {
87
+ x: number;
88
+ y: number;
89
+ width: number;
90
+ height: number;
91
+ }
92
+ declare class SelectionRenderer {
93
+ private material;
94
+ private mesh;
95
+ private scene;
96
+ private camera;
97
+ constructor();
98
+ setConfig(config: Partial<SelectionConfig>): void;
99
+ setSize(resolution: THREE.Vector2, dpr: number): void;
100
+ render(renderer: THREE.WebGLRenderer, cameraX: number, cameraY: number, zoom: number, selected: SelectionBounds[], hovered: SelectionBounds | null, guides?: SnapGuide[], spacings?: EqualSpacingIndicator[]): void;
101
+ dispose(): void;
102
+ }
103
+ //#endregion
104
+ export { DEFAULT_GRID_CONFIG as a, ContainerRefProvider as c, WidgetResolverProvider as d, useContainerRef as f, SelectionRenderer as i, EngineProvider as l, useWidgetResolver as m, SelectionBounds as n, GridConfig as o, useLayoutEngine as p, SelectionConfig as r, GridRenderer as s, DEFAULT_SELECTION_CONFIG as t, ResolvedWidget as u };
105
+ //# sourceMappingURL=SelectionRenderer-DlsBstAq.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionRenderer-DlsBstAq.d.mts","names":[],"sources":["../src/react/context.ts","../src/react/webgl/GridRenderer.ts","../src/react/webgl/SelectionRenderer.ts"],"mappings":";;;;;;cASa,cAAA,EAAc,OAAA,CAAA,QAAA,CAAA,YAAA;AAAA,cAOd,oBAAA,EAAoB,OAAA,CAAA,QAAA,CAAA,OAAA,CAAA,SAAA,CAAA,cAAA;AAAA,iBAEjB,eAAA,CAAA,GAAmB,KAAA,CAAM,SAAA,CAAU,cAAA;AATnD;;;;AAAA,iBAiBgB,eAAA,CAAA,GAAmB,YAAA;;;;;KAgBvB,cAAA;EACP,OAAA;EAAgB,SAAA,EAAW,KAAA,CAAM,aAAA,CAAc,cAAA;AAAA;EAC/C,OAAA;EAAkB,SAAA,EAAW,KAAA,CAAM,aAAA,CAAc,cAAA;AAAA;AAAA,KAE1C,cAAA,IAAkB,QAAA,EAAU,QAAA,EAAU,UAAA,aAAuB,cAAA;AAAA,cAI5D,sBAAA,EAAsB,OAAA,CAAA,QAAA,CAAA,cAAA;AAAA,iBAEnB,iBAAA,CAAA,GAAqB,cAAA;;;UChDpB,UAAA;;EAEhB,QAAA;;EAEA,QAAA;EDCY;ECCZ,QAAA;;EAEA,MAAA;EDH0B;ECK1B,OAAA;EDE+D;ECA/D,SAAA;EDAgC;ECEhC,WAAA;AAAA;AAAA,cAGY,mBAAA,EAAqB,UAAA;AAAA,cAoFrB,YAAA;EAAA,QACJ,QAAA;EAAA,QACA,KAAA;EAAA,QACA,MAAA;EAAA,QACA,QAAA;EAAA,QACA,IAAA;cAEI,MAAA,EAAQ,iBAAA;ED9FU;EC8I9B,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,UAAA;EAW1B,OAAA,CAAQ,KAAA,UAAe,MAAA,UAAgB,GAAA;EAQvC,MAAA,CAAO,OAAA,UAAiB,OAAA,UAAiB,IAAA;EAOzC,OAAA,CAAA;EDxKkD;EC+KlD,gBAAA,CAAA,GAAoB,KAAA,CAAM,aAAA;AAAA;;;UC3LV,eAAA;;EAEhB,YAAA;;EAEA,YAAA;EFDmD;EEGnD,UAAA;EFH0B;EEK1B,UAAA;EFEY;EEAZ,UAAA;;EAEA,UAAA;EFFgC;EEIhC,YAAA;EFJgC;EEMhC,iBAAA;EFNgC;EEQhC,SAAA;AAAA;AAAA,cAGY,wBAAA,EAA0B,eAAA;AAAA,UActB,eAAA;EAChB,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,cAoOY,iBAAA;EAAA,QACJ,QAAA;EAAA,QACA,IAAA;EAAA,QACA,KAAA;EAAA,QACA,MAAA;;EAsDR,SAAA,CAAU,MAAA,EAAQ,OAAA,CAAQ,eAAA;EAc1B,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,OAAA,EAAS,GAAA;EAKnC,MAAA,CACC,QAAA,EAAU,KAAA,CAAM,aAAA,EAChB,OAAA,UACA,OAAA,UACA,IAAA,UACA,QAAA,EAAU,eAAA,IACV,OAAA,EAAS,eAAA,SACT,MAAA,GAAQ,SAAA,IACR,QAAA,GAAU,qBAAA;EAiFX,OAAA,CAAA;AAAA"}