@kerfjs/ui 5.0.0-beta.90 → 5.0.0-beta.92
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/ai/public-api-signatures-v1.md +13 -7
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/index.mjs +4 -4
- package/dist/catalog.js +5 -5
- package/dist/{chunk-3CXRQAYT.js → chunk-6STQXRT4.js} +125 -8
- package/dist/chunk-6STQXRT4.js.map +1 -0
- package/dist/{chunk-SJW5BCEQ.js → chunk-75YOTZ25.js} +2 -2
- package/dist/{chunk-SJW5BCEQ.js.map → chunk-75YOTZ25.js.map} +1 -1
- package/dist/{chunk-TTGIHMDR.js → chunk-GIUOXAVL.js} +2 -2
- package/dist/{chunk-TTGIHMDR.js.map → chunk-GIUOXAVL.js.map} +1 -1
- package/dist/{chunk-2YPPNFYT.js → chunk-HWY4BSLS.js} +2 -2
- package/dist/{chunk-2YPPNFYT.js.map → chunk-HWY4BSLS.js.map} +1 -1
- package/dist/{chunk-KL3W6FUN.js → chunk-QCLLBMLA.js} +3 -3
- package/dist/{chunk-KL3W6FUN.js.map → chunk-QCLLBMLA.js.map} +1 -1
- package/dist/{chunk-5BZBIRQG.js → chunk-QLA25V2K.js} +50 -9
- package/dist/chunk-QLA25V2K.js.map +1 -0
- package/dist/{chunk-VLGQIYZ5.js → chunk-ROZLJULF.js} +2 -2
- package/dist/{chunk-VLGQIYZ5.js.map → chunk-ROZLJULF.js.map} +1 -1
- package/dist/{chunk-GPCAXYMT.js → chunk-RZYQFGMM.js} +2 -2
- package/dist/{chunk-GPCAXYMT.js.map → chunk-RZYQFGMM.js.map} +1 -1
- package/dist/chunk-TKDDTLG5.js +254 -0
- package/dist/chunk-TKDDTLG5.js.map +1 -0
- package/dist/{chunk-XNXKIPU5.js → chunk-TNG3XKHB.js} +12 -2
- package/dist/chunk-TNG3XKHB.js.map +1 -0
- package/dist/{chunk-NP3FSLNX.js → chunk-UKKRPP56.js} +46 -4
- package/dist/chunk-UKKRPP56.js.map +1 -0
- package/dist/{chunk-LFPW4YC6.js → chunk-YP2G67S7.js} +2 -2
- package/dist/{chunk-LFPW4YC6.js.map → chunk-YP2G67S7.js.map} +1 -1
- package/dist/collapsible-panel.js +3 -3
- package/dist/disclosure-arrow.js +1 -1
- package/dist/index.js +8 -8
- package/dist/list-header.js +1 -1
- package/dist/lucide-icon.d.ts +2 -2
- package/dist/lucide-icon.js +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/popup-menu.js +1 -1
- package/dist/select.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/token-search-field.js +1 -1
- package/dist/wire-catalog.js +3 -3
- package/dist/wire-scroll-dividers.d.ts +10 -4
- package/dist/wire-scroll-dividers.js +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/wire-workbench.js +1 -1
- package/dist/workbench.js +1 -1
- package/docs/component-contract.md +10 -0
- package/docs/ui-doctor.md +6 -2
- package/doctor/index.mjs +10 -1
- package/package.json +2 -1
- package/dist/chunk-3CXRQAYT.js.map +0 -1
- package/dist/chunk-5BZBIRQG.js.map +0 -1
- package/dist/chunk-NJZMR7HM.js +0 -135
- package/dist/chunk-NJZMR7HM.js.map +0 -1
- package/dist/chunk-NP3FSLNX.js.map +0 -1
- package/dist/chunk-XNXKIPU5.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.92` and `kerfjs@5.0.0-beta.92`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
|
|
4
4
|
|
|
5
5
|
## `@kerfjs/ui/css-values`
|
|
6
6
|
|
|
@@ -1279,10 +1279,16 @@ type Root = HTMLElement | Document;
|
|
|
1279
1279
|
* - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome
|
|
1280
1280
|
* draws the divider on its facing side.
|
|
1281
1281
|
*
|
|
1282
|
-
* Structure is re-read after every DOM change below root
|
|
1283
|
-
*
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1282
|
+
* Structure is re-read after every DOM change below root that can change a
|
|
1283
|
+
* pairing — a structural element or target id added, removed, or re-classed;
|
|
1284
|
+
* mutations inside scrolled content (a row's class, a list's rows) do not
|
|
1285
|
+
* re-read it. Either way the scrollers are re-measured once the next frame
|
|
1286
|
+
* has laid out, before it paints, so a large render never forces a layout
|
|
1287
|
+
* (where `ResizeObserver` is missing, structure is measured at once and
|
|
1288
|
+
* content in the next animation frame) — and a re-render that drops the
|
|
1289
|
+
* attributes gets them back before paint.
|
|
1290
|
+
* Scroll is tracked with one capturing listener per registered root, and size
|
|
1291
|
+
* changes of each scroller and its children with a `ResizeObserver`. Overlapping registrations
|
|
1286
1292
|
* share one attribute writer; each disposer removes its registration, and the
|
|
1287
1293
|
* final disposer removes the wiring-owned attributes. See
|
|
1288
1294
|
* `docs/23-app-layouts.md` §3.7.
|
|
@@ -3287,7 +3293,7 @@ export { Chip, type ChipProps };
|
|
|
3287
3293
|
## `@kerfjs/ui/lucide-icon`
|
|
3288
3294
|
|
|
3289
3295
|
```ts
|
|
3290
|
-
import
|
|
3296
|
+
import { SafeHtml } from 'kerfjs';
|
|
3291
3297
|
import { IconNode } from 'lucide';
|
|
3292
3298
|
import { CssForegroundColor } from './css-values.js';
|
|
3293
3299
|
|
|
@@ -3310,7 +3316,7 @@ interface LucideIconProps {
|
|
|
3310
3316
|
slot?: string;
|
|
3311
3317
|
}
|
|
3312
3318
|
/** Render a Lucide-compatible icon node without copying icon SVG strings. */
|
|
3313
|
-
declare function LucideIcon({ icon, name, appearance, className, color, inline, label, size, slot, }: LucideIconProps):
|
|
3319
|
+
declare function LucideIcon({ icon, name, appearance, className, color, inline, label, size, slot, }: LucideIconProps): SafeHtml;
|
|
3314
3320
|
|
|
3315
3321
|
export { LucideIcon, type LucideIconProps, type LucideIconSize, type LucideNode };
|
|
3316
3322
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web Awesome JSX signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from the emitted `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.92` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
6
|
import { KerfCustomElement } from 'kerfjs/jsx-runtime';
|
package/analyzer/index.mjs
CHANGED
|
@@ -1413,7 +1413,7 @@ function inspectCssValues(
|
|
|
1413
1413
|
diagnostic(
|
|
1414
1414
|
'KUI-L016',
|
|
1415
1415
|
at,
|
|
1416
|
-
`\`${entry.name}.${contract.path}\` is a forbidden declaration-list escape; use \`className\`, public tokens, or cataloged props.`,
|
|
1416
|
+
`\`${entry.name}.${contract.path}\` is a forbidden declaration-list escape hatch; use \`className\`, public tokens, or cataloged props.`,
|
|
1417
1417
|
{ component: entry.key, path: contract.path },
|
|
1418
1418
|
),
|
|
1419
1419
|
);
|
|
@@ -1426,7 +1426,7 @@ function inspectCssValues(
|
|
|
1426
1426
|
diagnostic(
|
|
1427
1427
|
'KUI-L017',
|
|
1428
1428
|
at,
|
|
1429
|
-
`\`${literal}\` is exceptional for \`${entry.name}.${contract.path}\`; prefer ${preferred} unless the off-scale choice is deliberate.`,
|
|
1429
|
+
`\`${literal}\` is an exceptional shorthand for \`${entry.name}.${contract.path}\`; prefer ${preferred} unless the off-scale choice is deliberate.`,
|
|
1430
1430
|
{ component: entry.key, path: contract.path, value: literal },
|
|
1431
1431
|
),
|
|
1432
1432
|
);
|
|
@@ -1458,7 +1458,7 @@ function inspectCssValues(
|
|
|
1458
1458
|
diagnostic(
|
|
1459
1459
|
'KUI-L015',
|
|
1460
1460
|
at,
|
|
1461
|
-
`\`${helper}()\` is not standalone for \`${entry.name}.${contract.path}\`; wrap it with an accepted composer such as \`calc()\`.`,
|
|
1461
|
+
`\`${helper}()\` is not a standalone CSS value for \`${entry.name}.${contract.path}\`; wrap it with an accepted composer such as \`calc()\`.`,
|
|
1462
1462
|
{ component: entry.key, path: contract.path, helper },
|
|
1463
1463
|
),
|
|
1464
1464
|
);
|
|
@@ -1470,7 +1470,7 @@ function inspectCssValues(
|
|
|
1470
1470
|
diagnostic(
|
|
1471
1471
|
'KUI-L014',
|
|
1472
1472
|
at,
|
|
1473
|
-
`\`${helper}()\`
|
|
1473
|
+
`\`${helper}()\` produces the wrong grammar for \`${entry.name}.${contract.path}\`; use ${preferred}.`,
|
|
1474
1474
|
{ component: entry.key, path: contract.path, helper },
|
|
1475
1475
|
),
|
|
1476
1476
|
);
|
package/dist/catalog.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Workbench } from './chunk-
|
|
1
|
+
import { Workbench } from './chunk-QCLLBMLA.js';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
import { TokenSearchField } from './chunk-
|
|
4
|
+
import { TokenSearchField } from './chunk-ROZLJULF.js';
|
|
5
5
|
import { ToolbarText } from './chunk-3DXHNLME.js';
|
|
6
|
-
import { PopupMenu } from './chunk-
|
|
6
|
+
import { PopupMenu } from './chunk-TKDDTLG5.js';
|
|
7
7
|
|
|
8
8
|
import { Row } from './chunk-MORVLMDG.js';
|
|
9
|
-
import { ListHeader } from './chunk-
|
|
9
|
+
import { ListHeader } from './chunk-RZYQFGMM.js';
|
|
10
10
|
import { Text } from './chunk-4Y4L5YEI.js';
|
|
11
11
|
import { ListInsetControl } from './chunk-AN5IWMTM.js';
|
|
12
12
|
import { ListInsetText } from './chunk-NMWDHZVM.js';
|
|
@@ -22,7 +22,7 @@ import { Toolbar } from './chunk-BYHGRKC3.js';
|
|
|
22
22
|
|
|
23
23
|
import { List } from './chunk-QQICWWNX.js';
|
|
24
24
|
|
|
25
|
-
import { LucideIcon } from './chunk-
|
|
25
|
+
import { LucideIcon } from './chunk-UKKRPP56.js';
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
|
|
@@ -97,6 +97,27 @@ function wireScrollDividers(root, { targets = [] } = {}) {
|
|
|
97
97
|
}
|
|
98
98
|
return register({ root, targets });
|
|
99
99
|
}
|
|
100
|
+
var STRUCTURAL_CLASSES = [
|
|
101
|
+
"kui-pane",
|
|
102
|
+
"kui-pane__content",
|
|
103
|
+
"kui-pane__header",
|
|
104
|
+
"kui-pane__toolbar",
|
|
105
|
+
"kui-pane__footer",
|
|
106
|
+
"kui-nav-stack",
|
|
107
|
+
"kui-nav-stack__viewport",
|
|
108
|
+
"kui-nav-stack__view",
|
|
109
|
+
"kui-nav-stack__chrome",
|
|
110
|
+
"kui-nav-stack__bottom",
|
|
111
|
+
"kui-tab-scaffold",
|
|
112
|
+
"kui-tab-scaffold__scenes",
|
|
113
|
+
"kui-tab-scaffold__scene",
|
|
114
|
+
"kui-tab-scaffold__bar"
|
|
115
|
+
];
|
|
116
|
+
var STRUCTURAL_SELECTOR = [
|
|
117
|
+
...STRUCTURAL_CLASSES.map((name) => `.${name}`),
|
|
118
|
+
"[data-kui-tab-list]"
|
|
119
|
+
].join(", ");
|
|
120
|
+
var hasStructuralClass = (value) => !!value && value.split(/\s+/).some((token) => STRUCTURAL_CLASSES.includes(token));
|
|
100
121
|
function createController(ownerDocument) {
|
|
101
122
|
const view = ownerDocument.defaultView;
|
|
102
123
|
let disposed = false;
|
|
@@ -175,10 +196,18 @@ function createController(ownerDocument) {
|
|
|
175
196
|
}
|
|
176
197
|
};
|
|
177
198
|
const observed = /* @__PURE__ */ new Set();
|
|
199
|
+
let probe;
|
|
200
|
+
let probePending = false;
|
|
178
201
|
const resizeObserver = view?.ResizeObserver ? new view.ResizeObserver((entries) => {
|
|
179
202
|
if (disposed) return;
|
|
180
203
|
const scrollers = new Set(pairings.map(({ scroller }) => scroller));
|
|
181
204
|
for (const { target } of entries) {
|
|
205
|
+
if (target === probe) {
|
|
206
|
+
probePending = false;
|
|
207
|
+
for (const scroller2 of overflow.keys())
|
|
208
|
+
overflow.set(scroller2, measure(scroller2));
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
182
211
|
const scroller = scrollers.has(target) ? target : target.parentElement;
|
|
183
212
|
if (scroller && scrollers.has(scroller))
|
|
184
213
|
overflow.set(scroller, measure(scroller));
|
|
@@ -203,13 +232,50 @@ function createController(ownerDocument) {
|
|
|
203
232
|
observed.add(element);
|
|
204
233
|
}
|
|
205
234
|
};
|
|
206
|
-
const refresh = () => {
|
|
235
|
+
const refresh = (afterLayout = false) => {
|
|
236
|
+
const deferred = afterLayout && resizeObserver !== void 0;
|
|
237
|
+
const previous = deferred ? new Map(overflow) : void 0;
|
|
207
238
|
pairings = collect();
|
|
208
239
|
overflow.clear();
|
|
209
240
|
for (const { scroller } of pairings)
|
|
210
|
-
overflow.set(
|
|
241
|
+
overflow.set(
|
|
242
|
+
scroller,
|
|
243
|
+
previous ? previous.get(scroller) ?? "" : measure(scroller)
|
|
244
|
+
);
|
|
211
245
|
observeSizes();
|
|
212
246
|
apply();
|
|
247
|
+
if (deferred) scheduleRemeasure();
|
|
248
|
+
};
|
|
249
|
+
const remeasure = () => {
|
|
250
|
+
let changed = false;
|
|
251
|
+
for (const scroller of overflow.keys()) {
|
|
252
|
+
const edges = measure(scroller);
|
|
253
|
+
if (edges === overflow.get(scroller)) continue;
|
|
254
|
+
overflow.set(scroller, edges);
|
|
255
|
+
changed = true;
|
|
256
|
+
}
|
|
257
|
+
if (changed) apply();
|
|
258
|
+
};
|
|
259
|
+
let remeasureFrame;
|
|
260
|
+
const scheduleRemeasure = () => {
|
|
261
|
+
if (resizeObserver) {
|
|
262
|
+
if (probePending) return;
|
|
263
|
+
probePending = true;
|
|
264
|
+
if (!probe) {
|
|
265
|
+
probe = ownerDocument.createElement("div");
|
|
266
|
+
probe.setAttribute("aria-hidden", "true");
|
|
267
|
+
probe.style.cssText = "position:fixed;top:0;left:0;width:0;height:0;overflow:hidden;visibility:hidden;pointer-events:none;contain:strict";
|
|
268
|
+
resizeObserver.observe(probe);
|
|
269
|
+
}
|
|
270
|
+
if (!probe.isConnected) ownerDocument.documentElement.append(probe);
|
|
271
|
+
probe.style.width = probe.style.width === "1px" ? "0px" : "1px";
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (remeasureFrame !== void 0 || !view?.requestAnimationFrame) return;
|
|
275
|
+
remeasureFrame = view.requestAnimationFrame(() => {
|
|
276
|
+
remeasureFrame = void 0;
|
|
277
|
+
remeasure();
|
|
278
|
+
});
|
|
213
279
|
};
|
|
214
280
|
const onScroll = (event) => {
|
|
215
281
|
const scroller = event.target;
|
|
@@ -221,12 +287,55 @@ function createController(ownerDocument) {
|
|
|
221
287
|
};
|
|
222
288
|
const mutationObserver = view?.MutationObserver ? new view.MutationObserver((records) => {
|
|
223
289
|
if (disposed) return;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
290
|
+
const ids = targetIds();
|
|
291
|
+
const selector = [
|
|
292
|
+
STRUCTURAL_SELECTOR,
|
|
293
|
+
...[...ids].map((id) => `[id=${quoted(id)}]`)
|
|
294
|
+
].join(", ");
|
|
295
|
+
if (records.some((record) => changesPairings(record, ids, selector)))
|
|
296
|
+
refresh(true);
|
|
297
|
+
else {
|
|
298
|
+
if (records.some(
|
|
299
|
+
({ attributeName }) => attributeName === SCROLL_OVERFLOW || attributeName === SCROLL_DIVIDER
|
|
300
|
+
))
|
|
301
|
+
apply();
|
|
302
|
+
if (records.some(
|
|
303
|
+
({ attributeName }) => attributeName !== SCROLL_OVERFLOW && attributeName !== SCROLL_DIVIDER
|
|
304
|
+
))
|
|
305
|
+
scheduleRemeasure();
|
|
306
|
+
}
|
|
229
307
|
}) : void 0;
|
|
308
|
+
const targetIds = () => {
|
|
309
|
+
const ids = /* @__PURE__ */ new Set();
|
|
310
|
+
for (const { targets } of registrations)
|
|
311
|
+
for (const target of targets) {
|
|
312
|
+
ids.add(target.scroller);
|
|
313
|
+
for (const edge of EDGES) {
|
|
314
|
+
const id = target[TARGET_EDGES[edge]];
|
|
315
|
+
if (id) ids.add(id);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return ids;
|
|
319
|
+
};
|
|
320
|
+
const holds = (node, selector) => node.nodeType === 1 && (node.matches(selector) || !!node.querySelector(selector));
|
|
321
|
+
const changesPairings = ({
|
|
322
|
+
type,
|
|
323
|
+
target,
|
|
324
|
+
attributeName,
|
|
325
|
+
oldValue,
|
|
326
|
+
addedNodes,
|
|
327
|
+
removedNodes
|
|
328
|
+
}, ids, selector) => {
|
|
329
|
+
if (type === "attributes" && (attributeName === SCROLL_OVERFLOW || attributeName === SCROLL_DIVIDER))
|
|
330
|
+
return false;
|
|
331
|
+
if (target.nodeType === 1 && target.matches(selector))
|
|
332
|
+
return true;
|
|
333
|
+
if (type === "attributes")
|
|
334
|
+
return attributeName === "class" ? hasStructuralClass(oldValue) : attributeName === "id" && oldValue !== null && ids.has(oldValue);
|
|
335
|
+
for (const node of [...addedNodes, ...removedNodes])
|
|
336
|
+
if (holds(node, selector)) return true;
|
|
337
|
+
return false;
|
|
338
|
+
};
|
|
230
339
|
const syncRoots = () => {
|
|
231
340
|
const roots = new Set([...registrations].map(({ root }) => root));
|
|
232
341
|
for (const root of listenedRoots)
|
|
@@ -248,6 +357,8 @@ function createController(ownerDocument) {
|
|
|
248
357
|
subtree: true,
|
|
249
358
|
childList: true,
|
|
250
359
|
attributes: true,
|
|
360
|
+
// Old values tell a class or id that stopped being structural.
|
|
361
|
+
attributeOldValue: true,
|
|
251
362
|
// The shown NavStack view and TabNavigator scene change by attribute.
|
|
252
363
|
attributeFilter: [
|
|
253
364
|
SCROLL_OVERFLOW,
|
|
@@ -270,7 +381,13 @@ function createController(ownerDocument) {
|
|
|
270
381
|
if (registrations.size) refresh();
|
|
271
382
|
else {
|
|
272
383
|
disposed = true;
|
|
384
|
+
if (remeasureFrame !== void 0)
|
|
385
|
+
view?.cancelAnimationFrame(remeasureFrame);
|
|
386
|
+
remeasureFrame = void 0;
|
|
273
387
|
resizeObserver?.disconnect();
|
|
388
|
+
probe?.remove();
|
|
389
|
+
probe = void 0;
|
|
390
|
+
probePending = false;
|
|
274
391
|
for (const [element, values] of written)
|
|
275
392
|
for (const name of values.keys()) write(element, name, "");
|
|
276
393
|
written.clear();
|
|
@@ -285,4 +402,4 @@ function createController(ownerDocument) {
|
|
|
285
402
|
|
|
286
403
|
export { wireScrollDividers };
|
|
287
404
|
|
|
288
|
-
//# sourceMappingURL=chunk-
|
|
405
|
+
//# sourceMappingURL=chunk-6STQXRT4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wiring/wire-scroll-dividers.ts"],"names":["view","scroller"],"mappings":"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","file":"chunk-6STQXRT4.js","sourcesContent":["/**\n * An app-owned scroll arrangement outside a `Pane`: the `id` of the element\n * that scrolls and the `id`s of the pinned chrome on each physical side of it.\n * Each named chrome element shows its divider on the side facing the scroller\n * while content is scrolled away beyond that side. Ids are resolved below the\n * wired root on every refresh, so a re-render that replaces an element keeps\n * the pairing.\n */\nexport interface ScrollDividerTarget {\n /** The `id` of the scrolling element. */\n scroller: string;\n /** Chrome above the scroller: shows its bottom divider once scrolled down. */\n top?: string;\n /**\n * Chrome right of the scroller: shows its left divider while content is\n * hidden beyond the scroller's right edge (never when nothing overflows).\n */\n right?: string;\n /**\n * Chrome below the scroller: shows its top divider while content is hidden\n * beyond the scroller's bottom edge (never when nothing overflows).\n */\n bottom?: string;\n /** Chrome left of the scroller: shows its right divider once scrolled right. */\n left?: string;\n}\n\nexport interface WireScrollDividersOptions {\n /**\n * App-owned scroll arrangements to pair beyond the ones found by structure\n * (every `Pane`'s header and footer around its content, every `NavStack`'s\n * and `TabNavigator`'s chrome around its active region, and every `TabBar`\n * strip).\n */\n targets?: readonly ScrollDividerTarget[];\n}\n\ntype Edge = 't' | 'r' | 'b' | 'l';\n\nconst EDGES: readonly Edge[] = ['t', 'r', 'b', 'l'];\n\n/** The side of a chrome element that faces a scroller it sits on `edge` of. */\nconst FACING: Record<Edge, Edge> = { t: 'b', r: 'l', b: 't', l: 'r' };\n\nconst TARGET_EDGES: Record<Edge, 'top' | 'right' | 'bottom' | 'left'> = {\n t: 'top',\n r: 'right',\n b: 'bottom',\n l: 'left',\n};\n\n/** On a scroller: the edges beyond which content is currently hidden. */\nconst SCROLL_OVERFLOW = 'data-scroll-overflow';\n/** On a chrome element: its sides that currently show a scroll divider. */\nconst SCROLL_DIVIDER = 'data-scroll-divider';\n\n/**\n * Scroll distance, in px, that must be exceeded to count as \"away from an\n * edge\": `scrollWidth`/`scrollHeight` are rounded to whole pixels while the\n * scroll position is fractional, so a scroller at its end can report up to a\n * pixel still to go.\n */\nconst THRESHOLD = 1;\n\ninterface Pairing {\n scroller: HTMLElement;\n chrome: Partial<Record<Edge, HTMLElement>>;\n}\n\n/** A double-quoted CSS attribute-selector value. */\nconst quoted = (value: string) =>\n `\"${value.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"')}\"`;\n\n/** Elements matching `selector` at and below root. */\nfunction within<T extends Element>(\n root: HTMLElement | Document,\n selector: string,\n): T[] {\n const found = [...root.querySelectorAll<T>(selector)];\n if (root.nodeType === 1 && (root as HTMLElement).matches(selector))\n found.unshift(root as unknown as T);\n return found;\n}\n\nconst directChild = (parent: Element, selector: string) =>\n [...parent.children].find((child): child is HTMLElement =>\n child.matches(selector),\n );\n\nconst PANE_CHROME = {\n t: '.kui-pane__header, .kui-pane__toolbar',\n b: '.kui-pane__footer',\n} as const;\n\n/** A NavStack's live (not cross-fading copy) chrome on `edge`. */\nconst NAV_STACK_CHROME = {\n t: '.kui-nav-stack__chrome:not([data-nav-chrome-copy])',\n b: '.kui-nav-stack__bottom:not([data-nav-chrome-copy])',\n} as const;\n\n/** A NavStack's active view: the top entry, never one sliding out. */\nfunction activeView(stack: Element): HTMLElement | undefined {\n const viewport = directChild(stack, '.kui-nav-stack__viewport');\n if (!viewport) return undefined;\n return [...viewport.children]\n .filter((child): child is HTMLElement =>\n child.matches(\n '.kui-nav-stack__view[data-nav-active=\"true\"]:not([data-nav-exiting=\"true\"])',\n ),\n )\n .at(-1);\n}\n\n/** A TabNavigator's shown scene. */\nfunction activeScene(scaffold: Element): HTMLElement | undefined {\n const scenes = directChild(scaffold, '.kui-tab-scaffold__scenes');\n return scenes\n ? directChild(scenes, '.kui-tab-scaffold__scene[data-active=\"true\"]')\n : undefined;\n}\n\n/**\n * The elements that may scroll against a layout region's `edge` (the top or\n * bottom of a NavStack view or a TabNavigator scene): the region itself, then,\n * through a sole child that puts no chrome of its own on that edge, a Pane's\n * content slot or a nested NavStack's or TabNavigator's active region. Every\n * candidate is paired with the layout's chrome; one that does not overflow\n * reports nothing, so the chrome keys on whichever element actually scrolls.\n * A sole child with chrome on that edge (a Pane header, a nested NavStack's\n * top chrome, a TabNavigator's bar) stops the walk: that chrome draws its own\n * divider against its own content.\n */\nfunction regionScrollers(region: HTMLElement, edge: 't' | 'b'): HTMLElement[] {\n const found: HTMLElement[] = [];\n let current: HTMLElement | undefined = region;\n while (current) {\n found.push(current);\n if (current.children.length !== 1) break;\n const child: Element = current.children[0]!;\n if (child.matches('.kui-pane')) {\n current = directChild(child, PANE_CHROME[edge])\n ? undefined\n : directChild(child, '.kui-pane__content');\n if (current) found.push(current);\n break;\n }\n if (child.matches('.kui-nav-stack'))\n current = directChild(child, NAV_STACK_CHROME[edge])\n ? undefined\n : activeView(child);\n else if (child.matches('.kui-tab-scaffold') && edge === 't')\n current = activeScene(child);\n else current = undefined;\n }\n return found;\n}\n\n/** Canonical top/right/bottom/left string of the given edges. */\nconst sides = (edges: ReadonlySet<Edge>) =>\n EDGES.filter((edge) => edges.has(edge)).join('');\n\n/**\n * Which edges of `scroller` currently have content hidden beyond them. Nothing\n * overflows when the content fits, so the far edges report no divider then.\n * Horizontal edges are physical, so a right-to-left scroller (whose\n * `scrollLeft` runs from the negative maximum to 0) reports the same sides.\n */\nfunction measure(scroller: HTMLElement): string {\n const edges = new Set<Edge>();\n const maxY = scroller.scrollHeight - scroller.clientHeight;\n if (maxY > THRESHOLD) {\n if (scroller.scrollTop > THRESHOLD) edges.add('t');\n if (maxY - scroller.scrollTop > THRESHOLD) edges.add('b');\n }\n const maxX = scroller.scrollWidth - scroller.clientWidth;\n if (maxX > THRESHOLD) {\n const view = scroller.ownerDocument.defaultView;\n const rtl = view?.getComputedStyle(scroller).direction === 'rtl';\n const left = rtl ? maxX + scroller.scrollLeft : scroller.scrollLeft;\n if (left > THRESHOLD) edges.add('l');\n if (maxX - left > THRESHOLD) edges.add('r');\n }\n return sides(edges);\n}\n\ntype StateAttribute = typeof SCROLL_OVERFLOW | typeof SCROLL_DIVIDER;\ntype Root = HTMLElement | Document;\n\ninterface Registration {\n root: Root;\n targets: readonly ScrollDividerTarget[];\n}\n\n// A document has one attribute writer even when registrations overlap. The\n// WeakMap ties this coordination cache to the document's lifetime.\nconst CONTROLLERS = new WeakMap<\n Document,\n (registration: Registration) => () => void\n>();\n\n/** Set (or, for an empty value, remove) one of this wiring's attributes. */\nfunction write(element: Element, name: StateAttribute, value: string) {\n if (element.getAttribute(name) === (value || null)) return;\n if (name === SCROLL_OVERFLOW) {\n if (value) element.setAttribute(SCROLL_OVERFLOW, value);\n else element.removeAttribute(SCROLL_OVERFLOW);\n } else if (value) element.setAttribute(SCROLL_DIVIDER, value);\n else element.removeAttribute(SCROLL_DIVIDER);\n}\n\n/**\n * Wire scroll dividers below `root`: a divider between pinned chrome and the\n * content that scrolls beside it shows only while content is scrolled away\n * from that edge. Near edges (top, left) hide at the scroll start; far edges\n * (bottom, right) hide at the scroll end and whenever nothing overflows.\n *\n * The wiring only reports scroll state; each component draws its own divider\n * from it. It writes `data-scroll-overflow` (the edges with hidden content, in\n * canonical `t`/`r`/`b`/`l` order) on each scroller, and `data-scroll-divider`\n * (the sides to draw) on each paired chrome element:\n *\n * - every `Pane` with a header or footer: its header shows a bottom divider and\n * its footer a top divider (drawn by the Pane, per its `chromeDividers`);\n * - every `NavStack`'s top chrome and bottom toolbar around its active view,\n * and every `TabNavigator`'s bar under its active scene: the chrome shows a\n * bottom (top chrome) or top (bottom toolbar, bar) divider. The scroller is\n * whichever element actually scrolls there: the view or scene itself, or,\n * through a sole child with no chrome of its own on that edge, a `Pane`'s\n * content or a nested `NavStack` / `TabNavigator` region (a Pane's own header\n * or footer draws that boundary instead);\n * - every `TabBar` strip: the bar draws a divider on each side of the strip\n * whose tabs are scrolled out of view;\n * - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome\n * draws the divider on its facing side.\n *\n * Structure is re-read after every DOM change below root that can change a\n * pairing — a structural element or target id added, removed, or re-classed;\n * mutations inside scrolled content (a row's class, a list's rows) do not\n * re-read it. Either way the scrollers are re-measured once the next frame\n * has laid out, before it paints, so a large render never forces a layout\n * (where `ResizeObserver` is missing, structure is measured at once and\n * content in the next animation frame) — and a re-render that drops the\n * attributes gets them back before paint.\n * Scroll is tracked with one capturing listener per registered root, and size\n * changes of each scroller and its children with a `ResizeObserver`. Overlapping registrations\n * share one attribute writer; each disposer removes its registration, and the\n * final disposer removes the wiring-owned attributes. See\n * `docs/23-app-layouts.md` §3.7.\n */\nexport function wireScrollDividers(\n root: Root,\n { targets = [] }: WireScrollDividersOptions = {},\n): () => void {\n const ownerDocument = (\n root.nodeType === 9 ? (root as Document) : root.ownerDocument\n )!;\n let register = CONTROLLERS.get(ownerDocument);\n if (!register) {\n register = createController(ownerDocument);\n CONTROLLERS.set(ownerDocument, register);\n }\n return register({ root, targets });\n}\n\n/**\n * Every class `collect()` and `regionScrollers()` select by. An element that\n * carries none of them (and no target id) can never become or stop being part\n * of a pairing.\n */\nconst STRUCTURAL_CLASSES = [\n 'kui-pane',\n 'kui-pane__content',\n 'kui-pane__header',\n 'kui-pane__toolbar',\n 'kui-pane__footer',\n 'kui-nav-stack',\n 'kui-nav-stack__viewport',\n 'kui-nav-stack__view',\n 'kui-nav-stack__chrome',\n 'kui-nav-stack__bottom',\n 'kui-tab-scaffold',\n 'kui-tab-scaffold__scenes',\n 'kui-tab-scaffold__scene',\n 'kui-tab-scaffold__bar',\n] as const;\n\nconst STRUCTURAL_SELECTOR = [\n ...STRUCTURAL_CLASSES.map((name) => `.${name}`),\n '[data-kui-tab-list]',\n].join(', ');\n\n/** Whether a class attribute value names a structural class. */\nconst hasStructuralClass = (value: string | null) =>\n !!value &&\n value\n .split(/\\s+/)\n .some((token) => (STRUCTURAL_CLASSES as readonly string[]).includes(token));\n\nfunction createController(\n ownerDocument: Document,\n): (registration: Registration) => () => void {\n const view = ownerDocument.defaultView;\n let disposed = false;\n const registrations = new Set<Registration>();\n const listenedRoots = new Set<Root>();\n let pairings: Pairing[] = [];\n const overflow = new Map<HTMLElement, string>();\n /** Every element this wiring has written, with what it wrote. */\n const written = new Map<Element, Map<StateAttribute, string>>();\n\n const byId = (root: Root, id: string | undefined) => {\n if (!id) return undefined;\n const [match] = within<HTMLElement>(root, `[id=${quoted(id)}]`);\n return match;\n };\n\n const collect = (): Pairing[] => {\n const found: Pairing[] = [];\n for (const { root, targets } of registrations) {\n for (const pane of within<HTMLElement>(root, '.kui-pane')) {\n const scroller = directChild(pane, '.kui-pane__content');\n const header = directChild(pane, PANE_CHROME.t);\n const footer = directChild(pane, PANE_CHROME.b);\n if (scroller && (header || footer))\n found.push({ scroller, chrome: { t: header, b: footer } });\n }\n const pairRegion = (\n region: HTMLElement | undefined,\n edge: 't' | 'b',\n chrome: HTMLElement | undefined,\n ) => {\n if (!region || !chrome) return;\n for (const scroller of regionScrollers(region, edge))\n found.push({ scroller, chrome: { [edge]: chrome } });\n };\n for (const stack of within<HTMLElement>(root, '.kui-nav-stack')) {\n const view = activeView(stack);\n for (const edge of ['t', 'b'] as const)\n pairRegion(view, edge, directChild(stack, NAV_STACK_CHROME[edge]));\n }\n for (const scaffold of within<HTMLElement>(root, '.kui-tab-scaffold'))\n pairRegion(\n activeScene(scaffold),\n 'b',\n directChild(scaffold, '.kui-tab-scaffold__bar'),\n );\n for (const strip of within<HTMLElement>(root, '[data-kui-tab-list]'))\n found.push({ scroller: strip, chrome: {} });\n for (const target of targets) {\n const scroller = byId(root, target.scroller);\n if (!scroller) continue;\n const chrome: Pairing['chrome'] = {};\n for (const edge of EDGES)\n chrome[edge] = byId(root, target[TARGET_EDGES[edge]]);\n found.push({ scroller, chrome });\n }\n }\n return found;\n };\n\n /** Write every paired element's attributes from the measured overflow. */\n const apply = () => {\n const current = new Map<Element, Map<StateAttribute, string>>();\n const dividers = new Map<HTMLElement, Set<Edge>>();\n for (const { scroller, chrome } of pairings) {\n const edges = overflow.get(scroller)!;\n (\n current.get(scroller) ?? current.set(scroller, new Map()).get(scroller)!\n ).set(SCROLL_OVERFLOW, edges);\n for (const edge of EDGES) {\n const element = chrome[edge];\n if (!element) continue;\n const shown = dividers.get(element) ?? new Set<Edge>();\n dividers.set(element, shown);\n if (edges.includes(edge)) shown.add(FACING[edge]);\n }\n }\n for (const [element, shown] of dividers)\n (\n current.get(element) ?? current.set(element, new Map()).get(element)!\n ).set(SCROLL_DIVIDER, sides(shown));\n // Anything written before that is no longer paired gets its attributes back.\n for (const [element, values] of written)\n for (const name of values.keys())\n if (!current.get(element)?.has(name)) write(element, name, '');\n written.clear();\n for (const [element, values] of current) {\n written.set(element, values);\n for (const [name, value] of values) write(element, name, value);\n }\n };\n\n const observed = new Set<Element>();\n /**\n * A post-layout hook for the content re-measure: an inert zero-height box\n * outside the app tree whose width a content mutation toggles. The\n * ResizeObserver reports it after the frame's layout, so the re-measure\n * reads scroll extents from a clean layout instead of forcing one on the\n * freshly rendered tree.\n */\n let probe: HTMLElement | undefined;\n /** Whether a toggled probe has yet to be reported. */\n let probePending = false;\n const resizeObserver = view?.ResizeObserver\n ? new view.ResizeObserver((entries) => {\n if (disposed) return;\n const scrollers = new Set(pairings.map(({ scroller }) => scroller));\n for (const { target } of entries) {\n if (target === probe) {\n probePending = false;\n for (const scroller of overflow.keys())\n overflow.set(scroller, measure(scroller));\n continue;\n }\n const scroller = scrollers.has(target as HTMLElement)\n ? (target as HTMLElement)\n : target.parentElement;\n if (scroller && scrollers.has(scroller))\n overflow.set(scroller, measure(scroller));\n }\n apply();\n })\n : undefined;\n\n const observeSizes = () => {\n if (!resizeObserver) return;\n const wanted = new Set<Element>();\n for (const { scroller } of pairings) {\n wanted.add(scroller);\n for (const child of scroller.children) wanted.add(child);\n }\n for (const element of observed)\n if (!wanted.has(element)) {\n resizeObserver.unobserve(element);\n observed.delete(element);\n }\n for (const element of wanted)\n if (!observed.has(element)) {\n resizeObserver.observe(element);\n observed.add(element);\n }\n };\n\n /**\n * Re-read every pairing. A registration measures at once; a mutation\n * (`afterLayout`) keeps each still-paired scroller's last measurement and\n * re-measures through the probe once the frame has laid out, before it\n * paints, so a structural re-render does not force a layout either.\n */\n const refresh = (afterLayout = false) => {\n const deferred = afterLayout && resizeObserver !== undefined;\n const previous = deferred ? new Map(overflow) : undefined;\n pairings = collect();\n overflow.clear();\n for (const { scroller } of pairings)\n overflow.set(\n scroller,\n previous ? (previous.get(scroller) ?? '') : measure(scroller),\n );\n observeSizes();\n apply();\n if (deferred) scheduleRemeasure();\n };\n\n /** Re-measure every scroller (pairings unchanged); write what changed. */\n const remeasure = () => {\n let changed = false;\n for (const scroller of overflow.keys()) {\n const edges = measure(scroller);\n if (edges === overflow.get(scroller)) continue;\n overflow.set(scroller, edges);\n changed = true;\n }\n if (changed) apply();\n };\n\n let remeasureFrame: number | undefined;\n const scheduleRemeasure = () => {\n if (resizeObserver) {\n // Toggle once per report: a second toggle before the frame would undo\n // the size change and the report with it.\n if (probePending) return;\n probePending = true;\n if (!probe) {\n probe = ownerDocument.createElement('div');\n probe.setAttribute('aria-hidden', 'true');\n probe.style.cssText =\n 'position:fixed;top:0;left:0;width:0;height:0;overflow:hidden;visibility:hidden;pointer-events:none;contain:strict';\n resizeObserver.observe(probe);\n }\n // Outside body, so an app that renders into body never removes it; an\n // app that removed it anyway gets it back.\n if (!probe.isConnected) ownerDocument.documentElement.append(probe);\n probe.style.width = probe.style.width === '1px' ? '0px' : '1px';\n return;\n }\n if (remeasureFrame !== undefined || !view?.requestAnimationFrame) return;\n // The final disposer cancels a pending frame.\n remeasureFrame = view.requestAnimationFrame(() => {\n remeasureFrame = undefined;\n remeasure();\n });\n };\n\n const onScroll = (event: Event) => {\n const scroller = event.target as HTMLElement;\n if (!overflow.has(scroller)) return;\n const edges = measure(scroller);\n if (edges === overflow.get(scroller)) return;\n overflow.set(scroller, edges);\n apply();\n };\n\n const mutationObserver = view?.MutationObserver\n ? new view.MutationObserver((records) => {\n if (disposed) return;\n // Structure changes re-read every pairing. A re-render that only\n // dropped or changed attributes this wiring owns gets them back\n // without re-measuring.\n // Everything else (a row's selection class, a list morph's rows)\n // cannot change a pairing. It is re-measured after the next frame's\n // layout instead (through the probe, else in the next animation\n // frame), which catches what the scrollers' own observations cannot:\n // an extent change that resizes no direct child (an absolutely\n // positioned popup, a `display: contents` child), without forcing a\n // layout of the freshly rendered tree.\n const ids = targetIds();\n const selector = [\n STRUCTURAL_SELECTOR,\n ...[...ids].map((id) => `[id=${quoted(id)}]`),\n ].join(', ');\n if (records.some((record) => changesPairings(record, ids, selector)))\n refresh(true);\n else {\n if (\n records.some(\n ({ attributeName }) =>\n attributeName === SCROLL_OVERFLOW ||\n attributeName === SCROLL_DIVIDER,\n )\n )\n apply();\n if (\n records.some(\n ({ attributeName }) =>\n attributeName !== SCROLL_OVERFLOW &&\n attributeName !== SCROLL_DIVIDER,\n )\n )\n scheduleRemeasure();\n }\n })\n : undefined;\n\n /** Every target id any registration resolves. */\n const targetIds = () => {\n const ids = new Set<string>();\n for (const { targets } of registrations)\n for (const target of targets) {\n ids.add(target.scroller);\n for (const edge of EDGES) {\n const id = target[TARGET_EDGES[edge]];\n if (id) ids.add(id);\n }\n }\n return ids;\n };\n\n /** Whether `node` is or contains an element matching `selector`. */\n const holds = (node: Node, selector: string) =>\n node.nodeType === 1 &&\n ((node as Element).matches(selector) ||\n !!(node as Element).querySelector(selector));\n\n /**\n * Whether a mutation record can change what `collect()` finds: a structural\n * element or target-id element (or, through its old class or id, a former\n * one) changed, or one was added or removed. Every scroller is itself\n * structural or a target id, so a child-list change of a scroller (whose\n * child count `regionScrollers` reads, and whose children the\n * ResizeObserver watches) always counts.\n */\n const changesPairings = (\n {\n type,\n target,\n attributeName,\n oldValue,\n addedNodes,\n removedNodes,\n }: MutationRecord,\n ids: ReadonlySet<string>,\n selector: string,\n ) => {\n if (\n type === 'attributes' &&\n (attributeName === SCROLL_OVERFLOW || attributeName === SCROLL_DIVIDER)\n )\n return false;\n if (target.nodeType === 1 && (target as Element).matches(selector))\n return true;\n if (type === 'attributes')\n return attributeName === 'class'\n ? hasStructuralClass(oldValue)\n : attributeName === 'id' && oldValue !== null && ids.has(oldValue);\n for (const node of [...addedNodes, ...removedNodes])\n if (holds(node, selector)) return true;\n return false;\n };\n\n const syncRoots = () => {\n const roots = new Set([...registrations].map(({ root }) => root));\n for (const root of listenedRoots)\n if (!roots.has(root)) {\n root.removeEventListener('scroll', onScroll, { capture: true });\n listenedRoots.delete(root);\n }\n for (const root of roots)\n if (!listenedRoots.has(root)) {\n root.addEventListener('scroll', onScroll, {\n capture: true,\n passive: true,\n });\n listenedRoots.add(root);\n }\n mutationObserver?.disconnect();\n for (const root of roots)\n mutationObserver?.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n // Old values tell a class or id that stopped being structural.\n attributeOldValue: true,\n // The shown NavStack view and TabNavigator scene change by attribute.\n attributeFilter: [\n SCROLL_OVERFLOW,\n SCROLL_DIVIDER,\n 'id',\n 'class',\n 'data-nav-active',\n 'data-nav-exiting',\n 'data-active',\n ],\n });\n };\n\n return (registration) => {\n registrations.add(registration);\n syncRoots();\n refresh();\n return () => {\n if (!registrations.delete(registration)) return;\n syncRoots();\n if (registrations.size) refresh();\n else {\n disposed = true;\n if (remeasureFrame !== undefined)\n view?.cancelAnimationFrame(remeasureFrame);\n remeasureFrame = undefined;\n resizeObserver?.disconnect();\n probe?.remove();\n probe = undefined;\n probePending = false;\n for (const [element, values] of written)\n for (const name of values.keys()) write(element, name, '');\n written.clear();\n overflow.clear();\n observed.clear();\n pairings = [];\n CONTROLLERS.delete(ownerDocument);\n }\n };\n };\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { ToolbarControlGroup } from './chunk-MTCTX25G.js';
|
|
|
3
3
|
import { Toolbar } from './chunk-BYHGRKC3.js';
|
|
4
4
|
import { Pane } from './chunk-FL6J644M.js';
|
|
5
5
|
import { List } from './chunk-QQICWWNX.js';
|
|
6
|
-
import { LucideIcon } from './chunk-
|
|
6
|
+
import { LucideIcon } from './chunk-UKKRPP56.js';
|
|
7
7
|
import { ChevronLeft } from 'lucide';
|
|
8
8
|
import { jsxs, jsx, Fragment } from 'kerfjs/jsx-runtime';
|
|
9
9
|
|
|
@@ -171,4 +171,4 @@ function NavStack({
|
|
|
171
171
|
|
|
172
172
|
export { NavStack };
|
|
173
173
|
|
|
174
|
-
//# sourceMappingURL=chunk-
|
|
174
|
+
//# sourceMappingURL=chunk-75YOTZ25.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/navigation/nav-stack/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-SJW5BCEQ.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport type { NavPane } from '../../../shared/panels/nav-pane.js';\nimport type { PanelBottomToolbar } from '../../../shared/panels/panel-toolbar.js';\nimport { Toolbar, type ToolbarConfig } from '../../actions/toolbar/toolbar.js';\nimport { ToolbarControlGroup } from '../../actions/toolbar-control-group/toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from '../../actions/toolbar-text/toolbar-text.js';\nimport { List, type ListConfig } from '../../collections/list/list.js';\nimport { Pane } from '../../layout/pane/pane.js';\nimport { LucideIcon } from '../../media/lucide-icon/lucide-icon.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView extends NavPane<\n NavStackViewToolbar,\n PanelBottomToolbar\n> {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n}\n\n/** Per-view top toolbar. The stack supplies its back control before `leading`. */\nexport interface NavStackViewToolbar extends NavStackToolbarConfig {\n title?: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\n/** A view's structured bottom toolbar; it cross-fades on navigation. */\nexport type NavStackViewBottomToolbar = PanelBottomToolbar;\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */\n panelToggle?: KerfUiContent;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: NavStackViewBottomToolbar;\n /**\n * Stack chrome separator. `auto` (default) draws both available edges\n * against a sunken active Pane and otherwise follows `chromeDividers`;\n * `hidden` suppresses the stack-owned edges.\n */\n separator?: 'auto' | 'hidden';\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * A sunken active Pane still draws the separator unless\n * `separator=\"hidden\"`. A `toolbarConfig.dividerSides` edge is the Toolbar's\n * own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\nconst DEFAULT_BOTTOM_SAFE_AREA_EDGES = [\n 'block-end',\n 'inline-start',\n 'inline-end',\n] as const;\n\nfunction chromeList(content: KerfUiContent, config?: ListConfig) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `toolbar` fills the zones,\n * and `toolbarConfig` supplies defaults. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n panelToggle,\n hideToolbar = false,\n bottomToolbar,\n separator = 'auto',\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const topToolbar = top?.toolbar;\n const bottom = top?.bottomToolbar ?? bottomToolbar;\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-separator={separator}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={topToolbar?.label ?? toolbarConfig.label}\n dividerSides={\n topToolbar?.dividerSides ?? toolbarConfig.dividerSides\n }\n centerAlign={topToolbar?.centerAlign ?? toolbarConfig.centerAlign}\n responsive={topToolbar?.responsive ?? toolbarConfig.responsive}\n responsiveAt={\n topToolbar?.responsiveAt ?? toolbarConfig.responsiveAt\n }\n safeAreaEdges={\n topToolbar?.safeAreaEdges ??\n toolbarConfig.safeAreaEdges ??\n DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {topToolbar?.leading}\n <ToolbarText\n text={topToolbar?.title ?? ''}\n size={\n topToolbar?.titleSize ?? toolbarConfig.titleSize ?? 'large'\n }\n headingLevel={\n topToolbar?.headingLevel ?? toolbarConfig.headingLevel\n }\n fill\n />\n </>\n }\n center={topToolbar?.center}\n trailing={\n <>\n {topToolbar?.trailing}\n {panelToggle}\n </>\n }\n />\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n aria-hidden={String(index !== topIndex)}\n >\n {view.pane ||\n view.header !== undefined ||\n view.footer !== undefined ? (\n <Pane\n appearance={view.pane?.appearance}\n deepInset={view.pane?.deepInset}\n tabIndex={view.pane?.tabIndex}\n outlined={view.pane?.outlined}\n contentElement={view.pane?.contentElement}\n contentLabel={view.pane?.contentLabel}\n separators={view.pane?.separators}\n safeAreaEdges={view.pane?.safeAreaEdges}\n chromeDividers={view.pane?.chromeDividers}\n header={\n view.header === undefined ? undefined : (\n <div data-nav-stack-header>\n {chromeList(view.header, view.headerList)}\n </div>\n )\n }\n footer={\n view.footer === undefined ? undefined : (\n <div data-nav-stack-footer>\n {chromeList(view.footer, view.footerList)}\n </div>\n )\n }\n >\n {view.content}\n </Pane>\n ) : (\n view.content\n )}\n </article>\n ))}\n </div>\n {bottom && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n <Toolbar\n position=\"footer\"\n label={bottom.label}\n dividerSides={bottom.dividerSides}\n centerAlign={bottom.centerAlign}\n responsive={bottom.responsive}\n responsiveAt={bottom.responsiveAt}\n safeAreaEdges={\n bottom.safeAreaEdges ?? DEFAULT_BOTTOM_SAFE_AREA_EDGES\n }\n leading={bottom.leading}\n center={bottom.center}\n trailing={bottom.trailing}\n />\n </footer>\n )}\n </section>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/navigation/nav-stack/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-75YOTZ25.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport type { NavPane } from '../../../shared/panels/nav-pane.js';\nimport type { PanelBottomToolbar } from '../../../shared/panels/panel-toolbar.js';\nimport { Toolbar, type ToolbarConfig } from '../../actions/toolbar/toolbar.js';\nimport { ToolbarControlGroup } from '../../actions/toolbar-control-group/toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from '../../actions/toolbar-text/toolbar-text.js';\nimport { List, type ListConfig } from '../../collections/list/list.js';\nimport { Pane } from '../../layout/pane/pane.js';\nimport { LucideIcon } from '../../media/lucide-icon/lucide-icon.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView extends NavPane<\n NavStackViewToolbar,\n PanelBottomToolbar\n> {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n}\n\n/** Per-view top toolbar. The stack supplies its back control before `leading`. */\nexport interface NavStackViewToolbar extends NavStackToolbarConfig {\n title?: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\n/** A view's structured bottom toolbar; it cross-fades on navigation. */\nexport type NavStackViewBottomToolbar = PanelBottomToolbar;\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */\n panelToggle?: KerfUiContent;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: NavStackViewBottomToolbar;\n /**\n * Stack chrome separator. `auto` (default) draws both available edges\n * against a sunken active Pane and otherwise follows `chromeDividers`;\n * `hidden` suppresses the stack-owned edges.\n */\n separator?: 'auto' | 'hidden';\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * A sunken active Pane still draws the separator unless\n * `separator=\"hidden\"`. A `toolbarConfig.dividerSides` edge is the Toolbar's\n * own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\nconst DEFAULT_BOTTOM_SAFE_AREA_EDGES = [\n 'block-end',\n 'inline-start',\n 'inline-end',\n] as const;\n\nfunction chromeList(content: KerfUiContent, config?: ListConfig) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `toolbar` fills the zones,\n * and `toolbarConfig` supplies defaults. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n panelToggle,\n hideToolbar = false,\n bottomToolbar,\n separator = 'auto',\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const topToolbar = top?.toolbar;\n const bottom = top?.bottomToolbar ?? bottomToolbar;\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-separator={separator}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={topToolbar?.label ?? toolbarConfig.label}\n dividerSides={\n topToolbar?.dividerSides ?? toolbarConfig.dividerSides\n }\n centerAlign={topToolbar?.centerAlign ?? toolbarConfig.centerAlign}\n responsive={topToolbar?.responsive ?? toolbarConfig.responsive}\n responsiveAt={\n topToolbar?.responsiveAt ?? toolbarConfig.responsiveAt\n }\n safeAreaEdges={\n topToolbar?.safeAreaEdges ??\n toolbarConfig.safeAreaEdges ??\n DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {topToolbar?.leading}\n <ToolbarText\n text={topToolbar?.title ?? ''}\n size={\n topToolbar?.titleSize ?? toolbarConfig.titleSize ?? 'large'\n }\n headingLevel={\n topToolbar?.headingLevel ?? toolbarConfig.headingLevel\n }\n fill\n />\n </>\n }\n center={topToolbar?.center}\n trailing={\n <>\n {topToolbar?.trailing}\n {panelToggle}\n </>\n }\n />\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n aria-hidden={String(index !== topIndex)}\n >\n {view.pane ||\n view.header !== undefined ||\n view.footer !== undefined ? (\n <Pane\n appearance={view.pane?.appearance}\n deepInset={view.pane?.deepInset}\n tabIndex={view.pane?.tabIndex}\n outlined={view.pane?.outlined}\n contentElement={view.pane?.contentElement}\n contentLabel={view.pane?.contentLabel}\n separators={view.pane?.separators}\n safeAreaEdges={view.pane?.safeAreaEdges}\n chromeDividers={view.pane?.chromeDividers}\n header={\n view.header === undefined ? undefined : (\n <div data-nav-stack-header>\n {chromeList(view.header, view.headerList)}\n </div>\n )\n }\n footer={\n view.footer === undefined ? undefined : (\n <div data-nav-stack-footer>\n {chromeList(view.footer, view.footerList)}\n </div>\n )\n }\n >\n {view.content}\n </Pane>\n ) : (\n view.content\n )}\n </article>\n ))}\n </div>\n {bottom && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n <Toolbar\n position=\"footer\"\n label={bottom.label}\n dividerSides={bottom.dividerSides}\n centerAlign={bottom.centerAlign}\n responsive={bottom.responsive}\n responsiveAt={bottom.responsiveAt}\n safeAreaEdges={\n bottom.safeAreaEdges ?? DEFAULT_BOTTOM_SAFE_AREA_EDGES\n }\n leading={bottom.leading}\n center={bottom.center}\n trailing={bottom.trailing}\n />\n </footer>\n )}\n </section>\n );\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { ToolbarControlGroup, isRelocatableGroup } from './chunk-MTCTX25G.js';
|
|
|
2
2
|
import { Toolbar } from './chunk-BYHGRKC3.js';
|
|
3
3
|
import { Pane } from './chunk-FL6J644M.js';
|
|
4
4
|
import { List } from './chunk-QQICWWNX.js';
|
|
5
|
-
import { LucideIcon } from './chunk-
|
|
5
|
+
import { LucideIcon } from './chunk-UKKRPP56.js';
|
|
6
6
|
import { PanelLeftOpen, PanelLeftClose, PanelRightOpen, PanelRightClose, PanelBottomOpen, PanelBottomClose } from 'lucide';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
|
|
8
8
|
|
|
@@ -146,4 +146,4 @@ function relocatedPanelGroups(toolbar, side, collapsed, attributes) {
|
|
|
146
146
|
|
|
147
147
|
export { collapsiblePanelToggleIcon, composedPanelBody, panelToggleGroup, relocatedPanelGroups };
|
|
148
148
|
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-GIUOXAVL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/panels/panel-toolbar.tsx"],"names":[],"mappings":"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","file":"chunk-TTGIHMDR.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport {\n PanelBottomClose,\n PanelBottomOpen,\n PanelLeftClose,\n PanelLeftOpen,\n PanelRightClose,\n PanelRightOpen,\n} from 'lucide';\n\nimport {\n Toolbar,\n type ToolbarConfig,\n} from '../../components/actions/toolbar/toolbar.js';\nimport { ToolbarControlGroup } from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport {\n List,\n type ListConfig,\n} from '../../components/collections/list/list.js';\nimport { Pane, type PaneConfig } from '../../components/layout/pane/pane.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport type { KerfUiContent } from '../content/semantic-content.js';\nimport { isRelocatableGroup } from './panel-toolbar-group.js';\n\n/** Which edge a collapsible panel docks to. */\nexport type PanelSide = 'left' | 'right' | 'bottom';\n\n/**\n * The standard collapse/expand icon for a panel `side` and `collapsed` state,\n * so every app's sidebars and drawers use one recognizable convention:\n * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`\n * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while\n * collapsed. Exposed so an app can render its own toggle affordance.\n */\nexport function collapsiblePanelToggleIcon(\n side: PanelSide,\n collapsed: boolean,\n): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left')\n return collapsed\n ? { icon: PanelLeftOpen, name: 'panel-left-open' }\n : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right')\n return collapsed\n ? { icon: PanelRightOpen, name: 'panel-right-open' }\n : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed\n ? { icon: PanelBottomOpen, name: 'panel-bottom-open' }\n : { icon: PanelBottomClose, name: 'panel-bottom-close' };\n}\n\n/**\n * The standard collapse toggle a panel toolbar renders. The app handles the\n * button's `data-action` and flips its own `collapsed` flag.\n */\nexport interface PanelToggle {\n /** The `data-action` the toggle button carries. */\n action: string;\n /** The panel's short name, for the accessible \"Show …\" / \"Hide …\" label. */\n name: string;\n /** Accessible label while the panel is collapsed. Defaults to `Show {name}`. */\n showLabel?: string;\n /** Accessible label while the panel is open. Defaults to `Hide {name}`. */\n hideLabel?: string;\n}\n\n/**\n * A collapsible panel's top toolbar, composed so its groups follow the\n * panel's open state.\n *\n * - `title` precedes the `leading` zone. Groups may appear in any of the\n * `leading`, `center`, and `trailing` zones while the panel is open.\n * - Groups marked `relocateOnCollapse` move to the work area's toolbar while\n * the panel is collapsed, preserving their order across the three zones.\n * - `toggle` is always the last group: in the panel's toolbar while it is\n * open, and right after the relocated groups in the work area's toolbar\n * while it is collapsed.\n *\n * Relocated content renders in both places while the panel is collapsed (the\n * panel's copy is inert), so give it no `id`s. Pass groups directly or in\n * arrays so their render-time annotation remains available to the panel.\n *\n * The toolbar's configuration (`dividerSides`, `centerAlign`, `responsive`,\n * `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar`. It draws no\n * divider of its own: the panel's `Pane` draws the line under it while the\n * content is scrolled (its `chromeDividers`, wired by `wireScrollDividers`).\n */\nexport interface PanelToolbar extends ToolbarConfig {\n /** Accessible name of the panel's toolbar. */\n label: string;\n title?: KerfUiContent;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n toggle?: PanelToggle;\n}\n\n/** A panel's fixed bottom toolbar, below its optional footer content. */\nexport interface PanelBottomToolbar extends ToolbarConfig {\n label: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\n/** Whether panel chrome stays fixed, scrolls, or follows Pane's auto rule. */\nexport type PanelChromePlacement = 'fixed' | 'scroll' | 'auto';\n\nfunction panelChromeList(content: KerfUiContent, config?: ListConfig) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/** Owner-specific attributes a toggle button carries (its wiring hooks). */\nexport type PanelToggleAttributes = Readonly<Record<string, string>>;\n\n/** The standard toggle, alone in a borderless group. */\nexport function panelToggleGroup(\n side: PanelSide,\n toggle: PanelToggle,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n return (\n <ToolbarControlGroup label={toggle.name} appearance=\"borderless\" single>\n <button\n type=\"button\"\n {...attributes}\n data-action={toggle.action}\n aria-expanded={String(!collapsed)}\n aria-label={\n collapsed\n ? (toggle.showLabel ?? `Show ${toggle.name}`)\n : (toggle.hideLabel ?? `Hide ${toggle.name}`)\n }\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n </ToolbarControlGroup>\n );\n}\n\n/**\n * The panel's own toolbar: content keeps its chosen zones and the toggle trails.\n */\nexport function composedPanelToolbar(\n toolbar: PanelToolbar,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n return (\n <Toolbar\n label={toolbar.label}\n dividerSides={toolbar.dividerSides}\n centerAlign={toolbar.centerAlign}\n responsive={toolbar.responsive}\n responsiveAt={toolbar.responsiveAt}\n safeAreaEdges={toolbar.safeAreaEdges}\n center={toolbar.center}\n leading={\n <>\n {toolbar.title}\n {toolbar.leading}\n </>\n }\n trailing={\n <>\n {toolbar.trailing}\n {toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, collapsed, attributes)\n : null}\n </>\n }\n />\n );\n}\n\n/**\n * A toolbar panel's body: its content in a `Pane` under its composed toolbar,\n * with its optional `footer` below. The panel's `pane` configuration forwards\n * to that `Pane`; an omitted or `undefined` field keeps the `Pane` default.\n */\nexport function composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes,\n pane,\n header,\n headerList,\n headerPlacement = 'fixed',\n footer,\n footerList,\n bottomToolbar,\n footerPlacement = 'fixed',\n content,\n}: {\n toolbar: PanelToolbar;\n side: PanelSide;\n collapsed: boolean;\n attributes: PanelToggleAttributes;\n pane: PaneConfig | undefined;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: PanelChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: PanelBottomToolbar;\n footerPlacement?: PanelChromePlacement;\n content: KerfUiContent;\n}): SafeHtml {\n const panelHeader = (\n <>\n {composedPanelToolbar(toolbar, side, collapsed, attributes)}\n {header ? panelChromeList(header, headerList) : null}\n </>\n );\n const panelFooter =\n footer || bottomToolbar ? (\n <>\n {footer ? panelChromeList(footer, footerList) : null}\n {bottomToolbar ? (\n <Toolbar\n position=\"footer\"\n label={bottomToolbar.label}\n dividerSides={bottomToolbar.dividerSides}\n centerAlign={bottomToolbar.centerAlign}\n responsive={bottomToolbar.responsive}\n responsiveAt={bottomToolbar.responsiveAt}\n safeAreaEdges={bottomToolbar.safeAreaEdges}\n leading={bottomToolbar.leading}\n center={bottomToolbar.center}\n trailing={bottomToolbar.trailing}\n />\n ) : null}\n </>\n ) : undefined;\n const scrollHeader = headerPlacement === 'scroll';\n const scrollFooter = footerPlacement === 'scroll';\n return (\n <Pane\n header={scrollHeader ? undefined : panelHeader}\n footer={scrollFooter ? undefined : panelFooter}\n chromePlacement={\n headerPlacement === 'auto' || footerPlacement === 'auto'\n ? 'auto'\n : 'fixed'\n }\n contentElement={pane?.contentElement}\n contentLabel={pane?.contentLabel}\n separators={pane?.separators}\n safeAreaEdges={pane?.safeAreaEdges}\n chromeDividers={pane?.chromeDividers}\n appearance={pane?.appearance}\n deepInset={pane?.deepInset}\n tabIndex={pane?.tabIndex}\n outlined={pane?.outlined}\n >\n {scrollHeader ? panelHeader : null}\n {content}\n {scrollFooter ? panelFooter : null}\n </Pane>\n );\n}\n\n/**\n * The groups a collapsed panel hands to the work area, in zone order, then its\n * toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedPanelGroups(\n toolbar: PanelToolbar | undefined,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): KerfUiContent[] {\n if (!collapsed || !toolbar) return [];\n const groups: KerfUiContent[] = [];\n const collect = (content: KerfUiContent): void => {\n if (Array.isArray(content)) {\n for (const item of content) collect(item);\n } else if (isRelocatableGroup(content)) {\n groups.push(content);\n }\n };\n collect(toolbar.leading);\n collect(toolbar.center);\n collect(toolbar.trailing);\n return [\n ...groups,\n toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, true, attributes)\n : null,\n ].filter((group) => group !== undefined && group !== null && group !== false);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shared/panels/panel-toolbar.tsx"],"names":[],"mappings":"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","file":"chunk-GIUOXAVL.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport {\n PanelBottomClose,\n PanelBottomOpen,\n PanelLeftClose,\n PanelLeftOpen,\n PanelRightClose,\n PanelRightOpen,\n} from 'lucide';\n\nimport {\n Toolbar,\n type ToolbarConfig,\n} from '../../components/actions/toolbar/toolbar.js';\nimport { ToolbarControlGroup } from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport {\n List,\n type ListConfig,\n} from '../../components/collections/list/list.js';\nimport { Pane, type PaneConfig } from '../../components/layout/pane/pane.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport type { KerfUiContent } from '../content/semantic-content.js';\nimport { isRelocatableGroup } from './panel-toolbar-group.js';\n\n/** Which edge a collapsible panel docks to. */\nexport type PanelSide = 'left' | 'right' | 'bottom';\n\n/**\n * The standard collapse/expand icon for a panel `side` and `collapsed` state,\n * so every app's sidebars and drawers use one recognizable convention:\n * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`\n * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while\n * collapsed. Exposed so an app can render its own toggle affordance.\n */\nexport function collapsiblePanelToggleIcon(\n side: PanelSide,\n collapsed: boolean,\n): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left')\n return collapsed\n ? { icon: PanelLeftOpen, name: 'panel-left-open' }\n : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right')\n return collapsed\n ? { icon: PanelRightOpen, name: 'panel-right-open' }\n : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed\n ? { icon: PanelBottomOpen, name: 'panel-bottom-open' }\n : { icon: PanelBottomClose, name: 'panel-bottom-close' };\n}\n\n/**\n * The standard collapse toggle a panel toolbar renders. The app handles the\n * button's `data-action` and flips its own `collapsed` flag.\n */\nexport interface PanelToggle {\n /** The `data-action` the toggle button carries. */\n action: string;\n /** The panel's short name, for the accessible \"Show …\" / \"Hide …\" label. */\n name: string;\n /** Accessible label while the panel is collapsed. Defaults to `Show {name}`. */\n showLabel?: string;\n /** Accessible label while the panel is open. Defaults to `Hide {name}`. */\n hideLabel?: string;\n}\n\n/**\n * A collapsible panel's top toolbar, composed so its groups follow the\n * panel's open state.\n *\n * - `title` precedes the `leading` zone. Groups may appear in any of the\n * `leading`, `center`, and `trailing` zones while the panel is open.\n * - Groups marked `relocateOnCollapse` move to the work area's toolbar while\n * the panel is collapsed, preserving their order across the three zones.\n * - `toggle` is always the last group: in the panel's toolbar while it is\n * open, and right after the relocated groups in the work area's toolbar\n * while it is collapsed.\n *\n * Relocated content renders in both places while the panel is collapsed (the\n * panel's copy is inert), so give it no `id`s. Pass groups directly or in\n * arrays so their render-time annotation remains available to the panel.\n *\n * The toolbar's configuration (`dividerSides`, `centerAlign`, `responsive`,\n * `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar`. It draws no\n * divider of its own: the panel's `Pane` draws the line under it while the\n * content is scrolled (its `chromeDividers`, wired by `wireScrollDividers`).\n */\nexport interface PanelToolbar extends ToolbarConfig {\n /** Accessible name of the panel's toolbar. */\n label: string;\n title?: KerfUiContent;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n toggle?: PanelToggle;\n}\n\n/** A panel's fixed bottom toolbar, below its optional footer content. */\nexport interface PanelBottomToolbar extends ToolbarConfig {\n label: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\n/** Whether panel chrome stays fixed, scrolls, or follows Pane's auto rule. */\nexport type PanelChromePlacement = 'fixed' | 'scroll' | 'auto';\n\nfunction panelChromeList(content: KerfUiContent, config?: ListConfig) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/** Owner-specific attributes a toggle button carries (its wiring hooks). */\nexport type PanelToggleAttributes = Readonly<Record<string, string>>;\n\n/** The standard toggle, alone in a borderless group. */\nexport function panelToggleGroup(\n side: PanelSide,\n toggle: PanelToggle,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n return (\n <ToolbarControlGroup label={toggle.name} appearance=\"borderless\" single>\n <button\n type=\"button\"\n {...attributes}\n data-action={toggle.action}\n aria-expanded={String(!collapsed)}\n aria-label={\n collapsed\n ? (toggle.showLabel ?? `Show ${toggle.name}`)\n : (toggle.hideLabel ?? `Hide ${toggle.name}`)\n }\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n </ToolbarControlGroup>\n );\n}\n\n/**\n * The panel's own toolbar: content keeps its chosen zones and the toggle trails.\n */\nexport function composedPanelToolbar(\n toolbar: PanelToolbar,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n return (\n <Toolbar\n label={toolbar.label}\n dividerSides={toolbar.dividerSides}\n centerAlign={toolbar.centerAlign}\n responsive={toolbar.responsive}\n responsiveAt={toolbar.responsiveAt}\n safeAreaEdges={toolbar.safeAreaEdges}\n center={toolbar.center}\n leading={\n <>\n {toolbar.title}\n {toolbar.leading}\n </>\n }\n trailing={\n <>\n {toolbar.trailing}\n {toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, collapsed, attributes)\n : null}\n </>\n }\n />\n );\n}\n\n/**\n * A toolbar panel's body: its content in a `Pane` under its composed toolbar,\n * with its optional `footer` below. The panel's `pane` configuration forwards\n * to that `Pane`; an omitted or `undefined` field keeps the `Pane` default.\n */\nexport function composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes,\n pane,\n header,\n headerList,\n headerPlacement = 'fixed',\n footer,\n footerList,\n bottomToolbar,\n footerPlacement = 'fixed',\n content,\n}: {\n toolbar: PanelToolbar;\n side: PanelSide;\n collapsed: boolean;\n attributes: PanelToggleAttributes;\n pane: PaneConfig | undefined;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: PanelChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: PanelBottomToolbar;\n footerPlacement?: PanelChromePlacement;\n content: KerfUiContent;\n}): SafeHtml {\n const panelHeader = (\n <>\n {composedPanelToolbar(toolbar, side, collapsed, attributes)}\n {header ? panelChromeList(header, headerList) : null}\n </>\n );\n const panelFooter =\n footer || bottomToolbar ? (\n <>\n {footer ? panelChromeList(footer, footerList) : null}\n {bottomToolbar ? (\n <Toolbar\n position=\"footer\"\n label={bottomToolbar.label}\n dividerSides={bottomToolbar.dividerSides}\n centerAlign={bottomToolbar.centerAlign}\n responsive={bottomToolbar.responsive}\n responsiveAt={bottomToolbar.responsiveAt}\n safeAreaEdges={bottomToolbar.safeAreaEdges}\n leading={bottomToolbar.leading}\n center={bottomToolbar.center}\n trailing={bottomToolbar.trailing}\n />\n ) : null}\n </>\n ) : undefined;\n const scrollHeader = headerPlacement === 'scroll';\n const scrollFooter = footerPlacement === 'scroll';\n return (\n <Pane\n header={scrollHeader ? undefined : panelHeader}\n footer={scrollFooter ? undefined : panelFooter}\n chromePlacement={\n headerPlacement === 'auto' || footerPlacement === 'auto'\n ? 'auto'\n : 'fixed'\n }\n contentElement={pane?.contentElement}\n contentLabel={pane?.contentLabel}\n separators={pane?.separators}\n safeAreaEdges={pane?.safeAreaEdges}\n chromeDividers={pane?.chromeDividers}\n appearance={pane?.appearance}\n deepInset={pane?.deepInset}\n tabIndex={pane?.tabIndex}\n outlined={pane?.outlined}\n >\n {scrollHeader ? panelHeader : null}\n {content}\n {scrollFooter ? panelFooter : null}\n </Pane>\n );\n}\n\n/**\n * The groups a collapsed panel hands to the work area, in zone order, then its\n * toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedPanelGroups(\n toolbar: PanelToolbar | undefined,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): KerfUiContent[] {\n if (!collapsed || !toolbar) return [];\n const groups: KerfUiContent[] = [];\n const collect = (content: KerfUiContent): void => {\n if (Array.isArray(content)) {\n for (const item of content) collect(item);\n } else if (isRelocatableGroup(content)) {\n groups.push(content);\n }\n };\n collect(toolbar.leading);\n collect(toolbar.center);\n collect(toolbar.trailing);\n return [\n ...groups,\n toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, true, attributes)\n : null,\n ].filter((group) => group !== undefined && group !== null && group !== false);\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LucideIcon } from './chunk-
|
|
1
|
+
import { LucideIcon } from './chunk-UKKRPP56.js';
|
|
2
2
|
import { ChevronRight } from 'lucide';
|
|
3
3
|
import { jsx } from 'kerfjs/jsx-runtime';
|
|
4
4
|
|
|
@@ -43,4 +43,4 @@ function DisclosureArrow({
|
|
|
43
43
|
|
|
44
44
|
export { DisclosureArrow };
|
|
45
45
|
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-HWY4BSLS.js.map
|