@dashfoo/react 0.6.2 → 0.6.4
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 +66 -66
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +188 -133
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# @dashfoo/react
|
|
2
2
|
|
|
3
3
|
The React layer for dashfoo: a headless docking-layout component in the
|
|
4
|
-
FlexLayout / VS-Code mold
|
|
4
|
+
FlexLayout / VS-Code mold: tiled, resizable, tabbed regions with drag-to-dock,
|
|
5
5
|
maximize, close, and inline rename.
|
|
6
6
|
|
|
7
7
|
"Headless" is the whole point. `@dashfoo/react` renders semantic markup tagged
|
|
8
8
|
with `data-dashfoo="..."` attributes and applies **zero** visual styling. It
|
|
9
9
|
sizes and positions nodes (flex, percentages, the resize handles) and wires up
|
|
10
|
-
roles, focus, and keyboard behavior. Everything you can see
|
|
11
|
-
radius, spacing, the look of a tab or a dock indicator
|
|
10
|
+
roles, focus, and keyboard behavior. Everything you can see (color, borders,
|
|
11
|
+
radius, spacing, the look of a tab or a dock indicator) is yours to write
|
|
12
12
|
against the `data-dashfoo` selectors. The package owns the geometry; you own the
|
|
13
13
|
paint.
|
|
14
14
|
|
|
15
15
|
It builds on three engines:
|
|
16
16
|
|
|
17
17
|
- **[react-resizable-panels](https://github.com/bvaughn/react-resizable-panels)** for splitter resize (the resize adapter is the only file that imports it).
|
|
18
|
-
- **[@dnd-kit/dom](https://github.com/clauderic/dnd-kit) 0.5
|
|
18
|
+
- **[@dnd-kit/dom](https://github.com/clauderic/dnd-kit) 0.5**, the framework-agnostic core (no React bindings), for drag (touched only by the drag adapter modules: `drag-adapter`/`drag-hooks`/`drag-overlays`; pointer-only). Tabsets are dnd-kit droppables behind a custom occlusion-aware collision detector; the preview chip rides the Feedback plugin's `overlay` accessor.
|
|
19
19
|
- **[@dashfoo/core](https://www.npmjs.com/package/@dashfoo/core)** for the document: a zod schema, a pure reducer, and the XState machines that drive state and the drag lifecycle.
|
|
20
20
|
|
|
21
21
|
## Install
|
|
@@ -36,7 +36,7 @@ import { DashfooLayout } from "@dashfoo/react";
|
|
|
36
36
|
import type { TabNode } from "@dashfoo/core";
|
|
37
37
|
import { model, row, tabset, tab } from "@dashfoo/core";
|
|
38
38
|
|
|
39
|
-
// Optional default skin
|
|
39
|
+
// Optional default skin; without it the chrome is unstyled (headless).
|
|
40
40
|
import "@dashfoo/theme/dashfoo.css";
|
|
41
41
|
|
|
42
42
|
const startingModel = model(
|
|
@@ -54,35 +54,35 @@ export const App = () => (
|
|
|
54
54
|
The `model` / `row` / `tabset` / `tab` builders come from `@dashfoo/core`; they
|
|
55
55
|
produce the same plain object you could write by hand. If you don't import
|
|
56
56
|
`@dashfoo/theme`, nothing renders until you style it: the container is
|
|
57
|
-
`[data-dashfoo="layout"]` with `display: flex; height: 100%; width: 100
|
|
57
|
+
`[data-dashfoo="layout"]` with `display: flex; height: 100%; width: 100%`; give it
|
|
58
58
|
a sized parent and add your CSS (see the [attribute reference](#data-dashfoo-attribute-reference)).
|
|
59
59
|
|
|
60
60
|
## `DashfooLayout` props
|
|
61
61
|
|
|
62
|
-
| Prop | Type | Default | Description
|
|
63
|
-
| ------------------------- | ----------------------------------------------------------------------- | ------- |
|
|
64
|
-
| `model` | `Dashfoo` |
|
|
65
|
-
| `defaultModel` | `Dashfoo` |
|
|
66
|
-
| `onModelChange` | `(model: Dashfoo, action?: Action) => void` |
|
|
67
|
-
| `components` | `Record<string, ComponentType<{ node: TabNode }>>` |
|
|
68
|
-
| `factory` | `(tab: TabNode) => ReactNode` |
|
|
69
|
-
| `persist` | `string \| { key; storage?; debounceMs? }` |
|
|
70
|
-
| `onAction` | `(action: Action) => Action \| null` |
|
|
71
|
-
| `onActiveTabsetChange` | `(id: string \| undefined) => void` |
|
|
72
|
-
| `onMaximizedTabsetChange` | `(id: string \| undefined) => void` |
|
|
73
|
-
| `renderTabLabel` | `(tab: TabNode) => ReactNode` |
|
|
74
|
-
| `renderTabsetToolbar` | `(tabset: TabsetNode) => ReactNode` |
|
|
75
|
-
| `editable` | `boolean` | `true` | `false` renders a static layout: no drag, close, rename, or splitter resize. Tab selection, maximize, and the ref API keep working.
|
|
76
|
-
| `closableTabs` | `boolean` | `true` | Show the per-tab close control.
|
|
77
|
-
| `renamableTabs` | `boolean` | `true` | Allow double-click inline rename.
|
|
78
|
-
| `maximizable` | `boolean` | `true` | Show the tabset maximize/restore control.
|
|
79
|
-
| `floatable` | `boolean` | `false` | Show a per-tabset control that floats the panel into a movable, resizable overlay, and render any floating panels. See below.
|
|
80
|
-
| `draggableTabs` | `boolean` | `true` | Allow individual tabs to be dragged between tabsets.
|
|
81
|
-
| `draggableTabsets` | `boolean` | `true` | Show the grip that drags a whole tabset.
|
|
82
|
-
| `resizableSplits` | `boolean` | `true` | Allow dragging the splitters; `false` disables them in place (gutters keep their size).
|
|
83
|
-
| `keepMounted` | `boolean` | `false` | Keep inactive tab panels mounted (hidden) so their state survives a tab switch.
|
|
84
|
-
| `responsive` | `{ maxWidth: number; orientation? }` |
|
|
85
|
-
| `snap` | `{ step?: number; divisions?: number \| "panels"; threshold?: number }` |
|
|
62
|
+
| Prop | Type | Default | Description |
|
|
63
|
+
| ------------------------- | ----------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
64
|
+
| `model` | `Dashfoo` | (none) | Controlled document. When set, the prop is the source of truth. |
|
|
65
|
+
| `defaultModel` | `Dashfoo` | (none) | Uncontrolled initial document. The component owns it from there. |
|
|
66
|
+
| `onModelChange` | `(model: Dashfoo, action?: Action) => void` | (none) | Called after every change with the next model and the action that caused it. |
|
|
67
|
+
| `components` | `Record<string, ComponentType<{ node: TabNode }>>` | (none) | Registry mapping `tab.component` keys to components. |
|
|
68
|
+
| `factory` | `(tab: TabNode) => ReactNode` | (none) | Render override. When provided, it resolves every tab and `components` is ignored. |
|
|
69
|
+
| `persist` | `string \| { key; storage?; debounceMs? }` | (none) | Auto-save the model (uncontrolled mode only). A bare string is a localStorage key. |
|
|
70
|
+
| `onAction` | `(action: Action) => Action \| null` | (none) | Intercept each action before it commits: return it, a replacement, or `null` to veto. |
|
|
71
|
+
| `onActiveTabsetChange` | `(id: string \| undefined) => void` | (none) | Fires when the active tabset changes. |
|
|
72
|
+
| `onMaximizedTabsetChange` | `(id: string \| undefined) => void` | (none) | Fires when a tabset is maximized or restored. |
|
|
73
|
+
| `renderTabLabel` | `(tab: TabNode) => ReactNode` | (none) | Override the tab label (the accessible name stays `tab.name`). |
|
|
74
|
+
| `renderTabsetToolbar` | `(tabset: TabsetNode) => ReactNode` | (none) | Inject custom controls into a tabset's toolbar. |
|
|
75
|
+
| `editable` | `boolean` | `true` | `false` renders a static layout: no drag, close, rename, or splitter resize. Tab selection, maximize, and the ref API keep working. |
|
|
76
|
+
| `closableTabs` | `boolean` | `true` | Show the per-tab close control. |
|
|
77
|
+
| `renamableTabs` | `boolean` | `true` | Allow double-click inline rename. |
|
|
78
|
+
| `maximizable` | `boolean` | `true` | Show the tabset maximize/restore control. |
|
|
79
|
+
| `floatable` | `boolean` | `false` | Show a per-tabset control that floats the panel into a movable, resizable overlay, and render any floating panels. See below. |
|
|
80
|
+
| `draggableTabs` | `boolean` | `true` | Allow individual tabs to be dragged between tabsets. |
|
|
81
|
+
| `draggableTabsets` | `boolean` | `true` | Show the grip that drags a whole tabset. |
|
|
82
|
+
| `resizableSplits` | `boolean` | `true` | Allow dragging the splitters; `false` disables them in place (gutters keep their size). |
|
|
83
|
+
| `keepMounted` | `boolean` | `false` | Keep inactive tab panels mounted (hidden) so their state survives a tab switch. |
|
|
84
|
+
| `responsive` | `{ maxWidth: number; orientation? }` | (none) | At/below `maxWidth` (the layout's own container width) render a stacked column and lock drag + resize. View-only projection: no remount, state preserved. See below. |
|
|
85
|
+
| `snap` | `{ step?: number; divisions?: number \| "panels"; threshold?: number }` | (none) | Magnetic splitter snapping onto a grid: the union of `step` (multiples of a fixed percent) and `divisions` (even splits: `100/d`, or `"panels"` to divide by the row's panel count, so a 3-panel row snaps to thirds). Within `threshold` percent (default `4`) it snaps and commits on release as one undo step. Off when omitted; replaces `global.snap`; a row overrides via its own `snap` (`{}` disables). Locked off in compact mode. |
|
|
86
86
|
|
|
87
87
|
You must pass either `model` or `defaultModel`. Passing neither throws.
|
|
88
88
|
|
|
@@ -137,10 +137,10 @@ is not registered renders nothing and logs a one-time dev warning:
|
|
|
137
137
|
<DashfooLayout factory={(tab) => <Pane id={tab.id}>{tab.name}</Pane>} ... />
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
### `Panel
|
|
140
|
+
### `Panel`: common panel chrome
|
|
141
141
|
|
|
142
142
|
`Panel` is an optional compound helper for common panel chrome: compose a root,
|
|
143
|
-
header, title/icon/badge slots, and body around your content. It's headless
|
|
143
|
+
header, title/icon/badge slots, and body around your content. It's headless: it
|
|
144
144
|
emits `data-dashfoo="panel*"` attributes and the theme styles them.
|
|
145
145
|
|
|
146
146
|
```tsx
|
|
@@ -174,12 +174,12 @@ const ChartPanel = ({ node }: { node: TabNode }) => (
|
|
|
174
174
|
The component renders interactive controls into the markup. Each is plain HTML
|
|
175
175
|
with the right role and ARIA wiring, ready for you to style.
|
|
176
176
|
|
|
177
|
-
- **Close
|
|
178
|
-
- **Rename
|
|
179
|
-
- **Maximize
|
|
180
|
-
- **Float
|
|
181
|
-
- **Tabs
|
|
182
|
-
- **Drag-to-dock
|
|
177
|
+
- **Close**: a `[data-dashfoo="tab-close"]` button next to each tab label, shown when closing is enabled. Dispatches `deleteTab`.
|
|
178
|
+
- **Rename**: double-click a tab to swap its label for a `[data-dashfoo="tab-rename"]` input. Enter commits, Escape cancels, blur commits. A trimmed, changed value dispatches `renameTab`; focus returns to the tab afterward.
|
|
179
|
+
- **Maximize**: a `[data-dashfoo="tabset-maximize"]` toggle in the tabset toolbar. Dispatches `setMaximizedTabset`; one maximized tabset fills the frame and `aria-pressed` reflects state.
|
|
180
|
+
- **Float**: a `[data-dashfoo="tabset-float"]` button in the tabset toolbar, shown when `floatable`. Floats the tabset into a movable, resizable overlay (`floatTabset`); the float's `[data-dashfoo="float-dock"]` control docks it back (`dockFloat`). See "Floating panels" below.
|
|
181
|
+
- **Tabs**: roving-tabindex keyboard model (WAI-ARIA APG): Arrow keys move and select, Home/End jump to the ends, focus follows selection.
|
|
182
|
+
- **Drag-to-dock**: drag a tab to restack it or split a tabset (when split-dock is on). A `[data-dashfoo="dock-indicator"]` previews where it lands.
|
|
183
183
|
|
|
184
184
|
### Per-node enable flags
|
|
185
185
|
|
|
@@ -187,7 +187,7 @@ The top-level chrome props are layout-wide gates. Individual nodes can opt out
|
|
|
187
187
|
through optional boolean fields in the model (a flag defaults to enabled unless
|
|
188
188
|
explicitly `false`). A control shows only when the `editable` umbrella, the
|
|
189
189
|
chrome prop, the model global, and the node's flag all allow it (`maximizable`
|
|
190
|
-
ignores `editable
|
|
190
|
+
ignores `editable`; maximize is view state, not a structural edit).
|
|
191
191
|
|
|
192
192
|
| Field | On node | Disables |
|
|
193
193
|
| ------------------- | ------- | ------------------------------------------------ |
|
|
@@ -213,8 +213,8 @@ is omitted, the React adapter falls back to `320px`.
|
|
|
213
213
|
|
|
214
214
|
## External drag sources
|
|
215
215
|
|
|
216
|
-
Tabs normally move within a layout. To drag new content in from outside it
|
|
217
|
-
widget list, a palette, a marketplace
|
|
216
|
+
Tabs normally move within a layout. To drag new content in from outside it (a
|
|
217
|
+
widget list, a palette, a marketplace), wrap both sides in `DashfooDragProvider`
|
|
218
218
|
and register each source with `useExternalTabSource`. Dropping a source on the
|
|
219
219
|
layout inserts the tab it creates (stacking on a strip or body, splitting on an
|
|
220
220
|
edge), exactly like an internal tab drop. A drop outside any tabset is a no-op.
|
|
@@ -242,18 +242,18 @@ const App = () => (
|
|
|
242
242
|
`createTab` runs at drag start and must return a fresh `TabNode` with a unique
|
|
243
243
|
id per call (`createNodeId` / `createTabId` from `@dashfoo/core` mint one). The
|
|
244
244
|
returned node is validated against the model schema; an invalid tab warns and
|
|
245
|
-
cancels the drag. `DashfooDragProvider` is optional everywhere else
|
|
245
|
+
cancels the drag. `DashfooDragProvider` is optional everywhere else; a
|
|
246
246
|
standalone layout needs no provider. Pointer drag is the only drag input, so
|
|
247
247
|
offer a click-to-add path (e.g. `ref.addTab(...)`) alongside the drag for
|
|
248
248
|
keyboard access.
|
|
249
249
|
|
|
250
250
|
`useExternalTabSource` options:
|
|
251
251
|
|
|
252
|
-
| Option | Type | Default
|
|
253
|
-
| ----------- | --------------- |
|
|
254
|
-
| `createTab` | `() => TabNode` |
|
|
255
|
-
| `label` | `string` | `""`
|
|
256
|
-
| `disabled` | `boolean` | `false`
|
|
252
|
+
| Option | Type | Default | Description |
|
|
253
|
+
| ----------- | --------------- | ---------- | ------------------------------------------ |
|
|
254
|
+
| `createTab` | `() => TabNode` | (required) | Builds the tab to insert; called per drag. |
|
|
255
|
+
| `label` | `string` | `""` | The drag preview chip text. |
|
|
256
|
+
| `disabled` | `boolean` | `false` | Unregisters the source while true. |
|
|
257
257
|
|
|
258
258
|
## Responsive layouts
|
|
259
259
|
|
|
@@ -264,13 +264,13 @@ _restructure_ on small screens, give `DashfooLayout` a `responsive` prop:
|
|
|
264
264
|
<DashfooLayout defaultModel={model} factory={renderPanel} responsive={{ maxWidth: 720 }} />
|
|
265
265
|
```
|
|
266
266
|
|
|
267
|
-
At or below `maxWidth`
|
|
268
|
-
|
|
267
|
+
At or below `maxWidth` (measured on the layout's own container, not the viewport),
|
|
268
|
+
the layout renders as a single stacked column and **locks every structural
|
|
269
269
|
interaction** (tab/tabset drag, split resize), leaving tap-to-switch and
|
|
270
270
|
maximize. This mirrors VS Code: docking is a desktop interaction, so narrow
|
|
271
271
|
screens get a read-only, navigable view instead of unusable hit targets.
|
|
272
272
|
|
|
273
|
-
The stacked view is a **derived projection
|
|
273
|
+
The stacked view is a **derived projection**: the model in the store is never
|
|
274
274
|
mutated, so the layout is never remounted and widening past `maxWidth` restores
|
|
275
275
|
the desktop arrangement exactly. Undo history, persistence, selection, and
|
|
276
276
|
mounted panels all survive the breakpoint cross. The theme grows tab hit targets
|
|
@@ -300,7 +300,7 @@ chip, and the `[data-dashfoo="float-dock"]` "Dock back" control to return it
|
|
|
300
300
|
How it works:
|
|
301
301
|
|
|
302
302
|
- **Same React tree, full drag-dock.** A float renders through the normal
|
|
303
|
-
`Layout.Rows` in the same tree, sharing one drag manager with the docked layout
|
|
303
|
+
`Layout.Rows` in the same tree, sharing one drag manager with the docked layout,
|
|
304
304
|
so app context (a theme provider, a query client), event handling, your
|
|
305
305
|
stylesheet, and **dragging tabs into and out of a float** all just work. The
|
|
306
306
|
overlay is `pointer-events: none`, so empty space stays click-through to the
|
|
@@ -309,13 +309,13 @@ How it works:
|
|
|
309
309
|
float drags across the whole page. Drag and resize update the DOM imperatively and
|
|
310
310
|
dispatch a single `moveFloat` on release, so a drag is one undo step.
|
|
311
311
|
- **Named, renamable title.** Each float carries its own name ("Panel", "Panel 1",
|
|
312
|
-
…), shown as the window title
|
|
312
|
+
…), shown as the window title, never the active tab's. Double-click the title to
|
|
313
313
|
rename it (`renameFloat`).
|
|
314
314
|
- **Minimize.** The minimize control collapses a float to a chip
|
|
315
315
|
(`setFloatMinimized`); tapping the chip restores it to its saved rect.
|
|
316
|
-
- **Dock back as a panel.** "Dock back" returns the float as its own panel
|
|
317
|
-
tabs, grouped
|
|
318
|
-
- **Bring to front.** Clicking anywhere in a float
|
|
316
|
+
- **Dock back as a panel.** "Dock back" returns the float as its own panel (all its
|
|
317
|
+
tabs, grouped) instead of flattening them into another tabset.
|
|
318
|
+
- **Bring to front.** Clicking anywhere in a float (body, a tab, or chrome)
|
|
319
319
|
raises it above the others.
|
|
320
320
|
- **Honors `editable`.** Under `editable={false}` a float is static: its content
|
|
321
321
|
stays selectable and it still raises to the front, but move, resize, rename,
|
|
@@ -355,7 +355,7 @@ const Layout = () => {
|
|
|
355
355
|
`persist` accepts a bare localStorage key or `{ key, storage?, debounceMs? }` for
|
|
356
356
|
a custom store (sessionStorage, in-memory, your own). A pending save flushes on
|
|
357
357
|
unmount and on page hide (reload, tab close, navigation, the page going to the
|
|
358
|
-
background), so the last change is never lost
|
|
358
|
+
background), so the last change is never lost, even inside the debounce window.
|
|
359
359
|
It applies to uncontrolled mode only; in controlled mode, save the model yourself
|
|
360
360
|
in `onModelChange`.
|
|
361
361
|
|
|
@@ -370,7 +370,7 @@ The full form of `persist` (`{ key, storage?, debounceMs? }`):
|
|
|
370
370
|
|
|
371
371
|
| Option | Type | Default | Description |
|
|
372
372
|
| ------------ | ---------------- | --------------------- | ------------------------------------------------- |
|
|
373
|
-
| `key` | `string` |
|
|
373
|
+
| `key` | `string` | (required) | Storage key. A bare `persist="key"` is shorthand. |
|
|
374
374
|
| `storage` | `StorageAdapter` | `localStorageAdapter` | Where to read and write. |
|
|
375
375
|
| `debounceMs` | `number` | `300` | Save debounce window. |
|
|
376
376
|
|
|
@@ -389,8 +389,8 @@ type StorageAdapter = {
|
|
|
389
389
|
|
|
390
390
|
Two adapters ship with the package:
|
|
391
391
|
|
|
392
|
-
- `localStorageAdapter
|
|
393
|
-
- `memoryStorageAdapter()
|
|
392
|
+
- `localStorageAdapter`: SSR-safe `window.localStorage`. Reads return `null` and writes are swallowed (with a warning) when storage is unavailable or throws (no window, private mode, quota exceeded). This is the default.
|
|
393
|
+
- `memoryStorageAdapter()`: a fresh in-memory `Map`, returned by a factory call. Good for tests and SSR previews.
|
|
394
394
|
|
|
395
395
|
```tsx
|
|
396
396
|
import { memoryStorageAdapter } from "@dashfoo/react";
|
|
@@ -497,11 +497,11 @@ const { index, tab } = useTab(); // which tab a part belongs to; throws outside
|
|
|
497
497
|
```
|
|
498
498
|
|
|
499
499
|
`useDragSubject()` returns the live drag subject (`{ kind, id }` for a tab or
|
|
500
|
-
tabset being dragged) or `null`
|
|
500
|
+
tabset being dragged) or `null` (including outside a drag layer) for
|
|
501
501
|
drag-aware styling in custom parts.
|
|
502
502
|
|
|
503
|
-
`useDropIntent()` returns the live drop intent (`{ targetId, location, index? }
|
|
504
|
-
|
|
503
|
+
`useDropIntent()` returns the live drop intent (`{ targetId, location, index? }`,
|
|
504
|
+
where the drag would land if dropped right now) or `null` when nothing is
|
|
505
505
|
dragging or the pointer is over no valid target (empty space, a non-editable
|
|
506
506
|
layout, or a no-op drop the library suppresses). Together with
|
|
507
507
|
`dockZonePolygons` from `@dashfoo/core` it supports consumer-rendered drop
|
|
@@ -512,7 +512,7 @@ and overlays outside the layout observe the same drag).
|
|
|
512
512
|
|
|
513
513
|
## Build your own layout
|
|
514
514
|
|
|
515
|
-
`DashfooLayout` is a thin assembly of exported primitives
|
|
515
|
+
`DashfooLayout` is a thin assembly of exported primitives; you can compose the
|
|
516
516
|
same parts yourself when you need custom chrome. Two compound namespaces, same
|
|
517
517
|
pattern as `Panel`:
|
|
518
518
|
|
|
@@ -521,7 +521,7 @@ pattern as `Panel`:
|
|
|
521
521
|
| `Layout.Root` | `div[data-dashfoo="layout"]` | Creates the layout store. Takes `model`, `dispatch`, `renderTab`, and the chrome flags `DashfooLayout` accepts. |
|
|
522
522
|
| `Layout.DragLayer` | none (overlays) | Opts the tree into drag-dock. Omit it and everything else still works, just without dragging. |
|
|
523
523
|
| `Layout.Rows` | rrp split tree | Renders a `RowNode` recursively. `renderTabset` swaps in a custom tabset composition at every leaf. |
|
|
524
|
-
| `Layout.Tabset` |
|
|
524
|
+
| `Layout.Tabset` | the stock `Tabset.*` composition | The stock tabset composition, for leaves that don't need custom chrome. |
|
|
525
525
|
| `Layout.FloatLayer` | overlay | Wrap the tree's content to enable floating panels; renders `model.floats` as draggable overlays. Takes `floats` + `global`. |
|
|
526
526
|
| `Tabset.Root` | `div[data-dashfoo="tabset"]` | Creates the per-tabset store; owns drop registration, overflow measurement, and focus restore after close. |
|
|
527
527
|
| `Tabset.TabStrip` | `div[data-dashfoo="tabstrip"]` | The strip row (drag hit-testing targets this attribute). |
|
|
@@ -582,7 +582,7 @@ const MyLayout = () => {
|
|
|
582
582
|
|
|
583
583
|
Maximize is the host's concern in a hand-built layout: when
|
|
584
584
|
`model.maximizedTabsetId` is set, render that tabset alone (via `findTabset`
|
|
585
|
-
from `@dashfoo/core`) instead of `Layout.Rows
|
|
585
|
+
from `@dashfoo/core`) instead of `Layout.Rows`; that's all `DashfooLayout`
|
|
586
586
|
does. The demo's "Raw primitives" page (`apps/demo-vite/src/pages/raw.tsx`) is
|
|
587
587
|
a complete working reference.
|
|
588
588
|
|
|
@@ -648,7 +648,7 @@ type Persistence;
|
|
|
648
648
|
type PersistConfig;
|
|
649
649
|
|
|
650
650
|
// Responsive
|
|
651
|
-
useContainerWidth; // [ref, width] via ResizeObserver
|
|
651
|
+
useContainerWidth; // [ref, width] via ResizeObserver; the hand-built building block
|
|
652
652
|
useResponsiveModel; // per-breakpoint model + lock flags (no remount)
|
|
653
653
|
matchBreakpoint; // does a breakpoint apply at a given width
|
|
654
654
|
activeBreakpoint; // first matching breakpoint, else the last (the catch-all)
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/hooks/persistence.ts","../src/components/dashfoo-layout.tsx","../src/components/drag-root.tsx","../src/hooks/drag-hooks.tsx","../src/components/drag-adapter.tsx","../src/components/float-layer.tsx","../src/components/layout-root.tsx","../src/components/row-view.tsx","../src/components/tabset/tabset-view.tsx","../src/components/layout.tsx","../src/components/panel.tsx","../src/components/tabset/tabset-tab-controls.tsx","../src/components/tabset/tabset-content.tsx","../src/components/tabset/tabset-toolbar.tsx","../src/components/tabset/tabset-root.tsx","../src/components/tabset/tabset-tab.tsx","../src/components/tabset/tabset-tablist.tsx","../src/components/tabset/tabset.ts","../src/components/tab-overflow.tsx","../src/components/tabset/tabset-store.ts","../src/hooks/layout-store.ts","../src/hooks/responsive.ts","../src/hooks/store.ts"],"mappings":";;;;;KAMK;EACH,UAAU;EACV,aAAa;EACb,UAAU,aAAa;;cAGnB,4BAA2B;cAa3B,qBAAqB;KAkCtB;EACH;EACA;EACA,SAAS;;KAGN;EACH;EAEA,cAAc;EACd,OAAO,OAAO;;cAGV,iBACJ,QAAQ,sBACR,cAAc,wBACb;;;KCjDE;EAA0B;EAAqB;EAAa,UAAU;;KAmBtE,eAAe;EAAgB,MAAM;;KAIrC;EACH,SACE,KAAK,SACL;IAAU;IAAgB,WAAW;IAAc;;EAErD;EACA;EACA,WAAW;EACX,WAAW,QAAQ;EAEnB,YAAY;EAEZ,WAAW;EACX,gBAAgB;EAChB,iBAAiB;EACjB;EACA,YAAY,eAAe;EAE3B;EACA,YAAY,kBAAkB;EAC9B;;KAGG;EACH;EACA,aAAa,eAAe;EAC5B,eAAe;EACf;EACA;EAEA;EACA,WAAW,KAAK,YAAY;EAE5B;EACA;EACA;EACA,QAAQ;EACR,YAAY,QAAQ,WAAW;EAC/B,wBAAwB;EACxB,2BAA2B;EAC3B,iBAAiB,OAAO,SAAS,SAAS;EAC1C,UAAU;EACV;EACA,kBAAkB,KAAK,YAAY;EACnC,uBAAuB,QAAQ,eAAe;EAE9C;EACA;IAAe;IAAkB,cAAc;;EAE/C,OAAO;;cAGH,+BAAa,0BAAA,qCAAA,cAAA;;;cCvFb,wBAAuB;EAAgB,UAAU;MAAc;;;KCkLhE;EACH,iBAAiB;EACjB;EACA;;cAGI,yBAAwB,WAAA,UAAA,SAI3B;EAA6B,MAAM,SAAS;;cAczC,sBAAqB;cAKrB,qBAAoB;;;KC7HrB;EACH,UAAU;EAEV,YAAY,QAAQ;EAEpB;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/hooks/persistence.ts","../src/components/dashfoo-layout.tsx","../src/components/drag-root.tsx","../src/hooks/drag-hooks.tsx","../src/components/drag-adapter.tsx","../src/components/float-layer.tsx","../src/components/layout-root.tsx","../src/components/row-view.tsx","../src/components/tabset/tabset-view.tsx","../src/components/layout.tsx","../src/components/panel.tsx","../src/components/tabset/tabset-tab-controls.tsx","../src/components/tabset/tabset-content.tsx","../src/components/tabset/tabset-toolbar.tsx","../src/components/tabset/tabset-root.tsx","../src/components/tabset/tabset-tab.tsx","../src/components/tabset/tabset-tablist.tsx","../src/components/tabset/tabset.ts","../src/components/tab-overflow.tsx","../src/components/tabset/tabset-store.ts","../src/hooks/layout-store.ts","../src/hooks/responsive.ts","../src/hooks/store.ts"],"mappings":"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"}
|