@dashfoo/core 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,12 +24,12 @@ slipped into `config` fails parsing instead of corrupting a saved layout.
24
24
 
25
25
  ```ts
26
26
  type Dashfoo = {
27
- version: number;
27
+ version: 1;
28
28
  global: GlobalAttributes;
29
29
  layout: RowNode; // the root is always a row
30
30
  activeTabsetId?: string;
31
31
  maximizedTabsetId?: string;
32
- floats?: FloatNode[]; // floating panels, each its own layout subtree
32
+ floats: FloatNode[]; // floating panels, each its own layout subtree
33
33
  };
34
34
  ```
35
35
 
@@ -164,7 +164,7 @@ tree canonical so downstream code never has to defend against degenerate shapes:
164
164
  - simplifies a single-child row by lifting its lone child (which inherits the
165
165
  lifted row's weight, so sizing is preserved)
166
166
  - absorbs a root that reduces to a single nested row
167
- - clamps every `selected` index into range
167
+ - preserves schema-normalized selection and weights (`parseModel` supplies defaults and clamps selection)
168
168
  - forces `activeTabsetId` / `maximizedTabsetId` to point at a tabset that exists
169
169
  (falling back to the first tabset, or clearing)
170
170
  - heals each floating panel's own layout and drops a float once it empties
@@ -183,10 +183,10 @@ getFirstTabset(model): TabsetNode | undefined;
183
183
  findTabset(model, tabsetId): TabsetNode | undefined;
184
184
  findTab(model, tabId): TabLocation | undefined; // searches tabsets
185
185
  findFloat(model, floatId): FloatNode | undefined;
186
- findRow(row, rowId): RowNode | undefined; // pass a root (model.layout or a float's layout)
186
+ findRow(model, rowId): RowNode | undefined;
187
187
  findRootContaining(model, nodeId): RowNode | undefined; // which root holds a node
188
188
  findAttributedNode(model, id): AttributedNode | undefined; // row, tabset, or tab
189
- findTabsetParent(row, tabsetId): { index: number; parent: RowNode } | undefined;
189
+ findTabsetParent(model, tabsetId): { index: number; parent: RowNode } | undefined;
190
190
  findDuplicateIds(model): Array<string>; // ids used more than once
191
191
  ```
192
192
 
@@ -210,8 +210,8 @@ import { reducer } from "@dashfoo/core";
210
210
  const floated = reducer(model, { type: "floatTabset", tabsetId: "left" });
211
211
  floated.floats; // [{ type: "float", id, layout: RowNode, geometry }]
212
212
 
213
- // Dock it back into the active main tabset (center) and drop the float.
214
- const docked = reducer(floated, { type: "dockFloat", floatId: floated.floats![0].id });
213
+ // Dock it back as its own panel and drop the float.
214
+ const docked = reducer(floated, { type: "dockFloat", floatId: floated.floats[0].id });
215
215
  ```
216
216
 
217
217
  `normalize` runs over each float's layout too and drops a float once its last
@@ -225,14 +225,14 @@ indicator rect. The @dnd-kit adapter in `@dashfoo/react` feeds them rects; you c
225
225
  call them directly for custom drag logic.
226
226
 
227
227
  ```ts
228
- resolveDockTarget(pointer, rect, opts?): DockTarget;
228
+ resolveDockTarget(pointer, rect, opts?): DockLocation;
229
229
  dockZonePolygons(rect, opts?): Array<DockZone>;
230
230
  zoneRect(rect, location): Rect;
231
231
  ```
232
232
 
233
- `resolveDockTarget` decides where a drag over a tabset should land: `{ kind: "tab" }`
234
- when the pointer is in the interior, or `{ kind: "split", edge }` when it is within
235
- an outer band of one of the four edges (default 22%; the closer edge wins in
233
+ `resolveDockTarget` decides where a drag over a tabset should land: `"center"`
234
+ when the pointer is in the interior, or `split-${edge}` when it is within an
235
+ outer band of one of the four edges (default 22%; the closer edge wins in
236
236
  corners). It accepts `{ bandFraction }` to tune the band. `zoneRect` returns the
237
237
  region the dock indicator highlights for a `DockLocation`: the whole tabset for a
238
238
  `center` stack, the matching half for a split. `Point` and `Rect` are exported.
@@ -251,19 +251,26 @@ it stays framework-free; the React adapter maps rrp's id-keyed layout to/from
251
251
  these arrays and supplies the dragged boundary index.
252
252
 
253
253
  ```ts
254
- resolveSnapTargets(config: SnapConfig, panelCount: number): number[]; // grid positions inside 0..100
255
- snapSizes(sizes: number[], boundaryIndex: number, config: SnapConfig): { sizes: number[]; snapped: boolean };
256
- snapEnabled(config: SnapConfig | null): boolean;
254
+ // resolveSnapGrid(config, panelCount).targets contains positions inside 0..100
255
+ resolveSnapGrid(config: SnapConfig | null, panelCount: number): SnapGrid;
256
+ snapSizes(sizes: number[], boundaryIndex: number, grid: SnapGrid): { sizes: number[]; snapped: boolean };
257
+ snapEnabled(grid: SnapGrid): boolean;
257
258
  ```
258
259
 
259
- `resolveSnapTargets` builds the grid for a row from its config and panel count: the
260
+ `resolveSnapGrid` builds the grid for a row from its config and panel count: the
260
261
  union of the `step` grid (multiples of a fixed percent) and the `divisions` grid
261
262
  (even splits: multiples of `100/d`, where `d` is the number or, for `"panels"`,
262
263
  the panel count). `snapSizes` snaps the boundary between panel `boundaryIndex` and
263
264
  the next onto the nearest target within `threshold` (default `4`), moving only that
264
265
  pair so siblings keep their size. It is a no-op when the grid is empty, the index
265
- is out of range, or the correction would drive a panel negative. `snapEnabled`
266
- reports whether a config produces any grid. `SnapConfig` is the
266
+ is out of range, or the correction would drive a panel negative.
267
+
268
+ `resolveSnapGrid` is the entry point: it resolves the targets once for a row and
269
+ carries the threshold alongside them, and every other function takes that
270
+ `SnapGrid`. `snapEnabled` is then just "does this grid have any target", which
271
+ is why a config with no reachable target (`{ step: 100 }`, or
272
+ `{ divisions: "panels" }` on a one-panel row) reports off rather than arming the
273
+ per-move snap path. `SnapConfig` is the
267
274
  `{ step?, divisions?, threshold? }` shape carried by `global.snap` and
268
275
  `RowNode.snap`.
269
276
 
@@ -330,7 +337,7 @@ const current = actor.getSnapshot().context.history.present;
330
337
  ### dragDockMachine
331
338
 
332
339
  The drag/dock interaction lifecycle (`idle` → `dragging` → `idle`), driven by
333
- abstract events the dnd-kit adapter maps from pointer and keyboard input. It owns
340
+ abstract events the dnd-kit adapter maps from pointer input. It owns
334
341
  transient drag state only and never touches the document. On a valid `DROP` it
335
342
  **emits** a `COMMIT` carrying a `moveNode` action (the drag subject is a tab), a
336
343
  `moveTabset` action (the subject is a whole tabset, dragged by its grip), or an
@@ -350,7 +357,7 @@ layout, carrying the `TabNode` to insert), which the React layer forwards to
350
357
  `schema`: `dashfooSchema`, `rowNodeSchema`, `tabsetNodeSchema`, `tabNodeSchema`,
351
358
  `floatNodeSchema`, `geometrySchema`, `dimensionSchema`, `snapSchema`, `edgeSchema`,
352
359
  `unitSchema`, `orientationSchema`, `globalAttributesSchema`,
353
- `jsonValueSchema`; types `Dashfoo`, `RowNode`, `TabsetNode`, `TabNode`,
360
+ `jsonValueSchema`, `tabsetNodeObjectSchema`; types `Dashfoo`, `DashfooInput`, `RowNodeInput`, `RowNode`, `TabsetNode`, `TabNode`,
354
361
  `FloatNode`, `Geometry`, `Dimension`, `SnapConfig`, `Edge`, `Unit`, `Orientation`,
355
362
  `GlobalAttributes`, `Node`, `Json`.
356
363
 
@@ -370,10 +377,10 @@ layout, carrying the `TabNode` to insert), which the React layer forwards to
370
377
  types `AttributedNode`, `TabContainer`, `TabLocation`.
371
378
 
372
379
  `geometry`: `resolveDockTarget`, `dockZonePolygons`, `zoneRect`; types
373
- `DockTarget`, `DockZone`, `BandOptions`, `Point`, `Rect`.
380
+ `DockZone`, `BandOptions`, `Point`, `Rect`.
374
381
 
375
- `snap`: `resolveSnapTargets`, `snapSizes`, `snapEnabled`, `DEFAULT_SNAP_THRESHOLD`;
376
- type `SnapResult`.
382
+ `snap`: `resolveSnapGrid`, `decideSnap`, `settleSnap`, `snapSizes`, `snapEnabled`, `DEFAULT_SNAP_THRESHOLD`;
383
+ types `SnapResult`, `SnapGrid`, `SnapDecision`.
377
384
 
378
385
  `history`: `createHistory`, `dispatch`, `undo`, `redo`, `canUndo`, `canRedo`;
379
386
  type `History`.
@@ -384,7 +391,7 @@ type `History`.
384
391
  tabsets, the building block for a narrow-screen breakpoint).
385
392
 
386
393
  `machines`: `dashfooMachine`, `dragDockMachine`; types `DashfooContext`,
387
- `DashfooEvent`, `DashfooInput`, `DragContext`, `DragEvent`, `DragSubject`,
394
+ `DashfooEvent`, `DragContext`, `DragEvent`, `DragSubject`,
388
395
  `DragEmitted`.
389
396
 
390
397
  ## License