vireuikit 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -27,135 +27,129 @@ function presentationFor(mode, wantsGlass) {
27
27
  function sameA11y(a, b) {
28
28
  return a.reduceTransparency === b.reduceTransparency && a.increaseContrast === b.increaseContrast && a.reduceMotion === b.reduceMotion;
29
29
  }
30
- var ATOM_AT_REST = {
31
- pressed: 0,
32
- hovered: 0,
33
- selected: 0,
34
- disabled: false
35
- };
36
- function atomLift(kind) {
37
- switch (kind) {
38
- case "iconButton":
39
- case "switch":
40
- case "slider":
41
- return 1;
42
- default:
43
- return 0;
44
- }
30
+
31
+ // src/kit/adaptive/classes.ts
32
+ var WIDTH_CLASSES = ["compact", "medium", "expanded", "large", "xlarge"];
33
+ var HEIGHT_CLASSES = ["compact", "medium", "expanded"];
34
+ var WIDTH_BREAKPOINTS = { medium: 600, expanded: 840, large: 1200, xlarge: 1600 };
35
+ var HEIGHT_BREAKPOINTS = { medium: 480, expanded: 900 };
36
+ function widthClass(width) {
37
+ if (!(width >= WIDTH_BREAKPOINTS.medium)) return "compact";
38
+ if (width < WIDTH_BREAKPOINTS.expanded) return "medium";
39
+ if (width < WIDTH_BREAKPOINTS.large) return "expanded";
40
+ return width < WIDTH_BREAKPOINTS.xlarge ? "large" : "xlarge";
45
41
  }
46
- var DISABLED_PRESENCE = 0.25;
47
- var HOVER_GAIN = 0.35;
48
- function activation(state) {
49
- if (state.disabled) return 0;
50
- const clamp2 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
51
- return Math.max(clamp2(state.selected), clamp2(state.pressed), clamp2(state.hovered) * HOVER_GAIN);
42
+ function heightClass(height) {
43
+ if (!(height >= HEIGHT_BREAKPOINTS.medium)) return "compact";
44
+ return height < HEIGHT_BREAKPOINTS.expanded ? "medium" : "expanded";
52
45
  }
53
- function atomMaterial(base, kind, state = ATOM_AT_REST) {
54
- const out = vireglass.activeMaterial(base, activation(state));
55
- if (!state.disabled) return out;
56
- return { ...out, presence: out.presence * DISABLED_PRESENCE };
46
+ function classifyWindow(size) {
47
+ return { width: widthClass(size.width), height: heightClass(size.height) };
57
48
  }
58
- function atomAtRest(state) {
59
- return state.pressed === 0 && state.hovered === 0 && state.selected === 0 && state.disabled === false;
60
- }
61
- var REST_BODY = { alpha: 0.25, white: 0.15, lift: 0.1 };
62
- var PRESSED_BODY = { alpha: 0.34, white: 0.35, lift: 0 };
63
- var FROST_LIFT = 0.26;
64
- function atomBody(base, state = ATOM_AT_REST, frost = false) {
65
- const on = activation(state);
66
- const mix2 = (key) => REST_BODY[key] + (PRESSED_BODY[key] - REST_BODY[key]) * on;
67
- let alpha = mix2("alpha");
68
- let white = mix2("white");
69
- let lift = mix2("lift");
70
- if (state.disabled) alpha *= DISABLED_PRESENCE;
71
- if (frost) {
72
- const density = vireglass.applyAccessibility(vireglass.resolveOptics(base), {
73
- reduceTransparency: true,
74
- increaseContrast: false,
75
- reduceMotion: false
76
- }).bodyDensity;
77
- alpha = Math.max(alpha, density);
78
- white = 0;
79
- lift = FROST_LIFT;
80
- }
81
- return { alpha, white, lift };
49
+ function widthAtLeast(value, minimum) {
50
+ return WIDTH_CLASSES.indexOf(value) >= WIDTH_CLASSES.indexOf(minimum);
82
51
  }
83
52
 
84
- // src/kit/behavior/focus.ts
85
- function stepFocus(event) {
86
- return event.type === "focus" && event.visible;
53
+ // src/kit/geometry.ts
54
+ function intersectRect(a, b) {
55
+ const x = Math.max(a.x, b.x);
56
+ const y = Math.max(a.y, b.y);
57
+ const right = Math.min(a.x + a.width, b.x + b.width);
58
+ const bottom = Math.min(a.y + a.height, b.y + b.height);
59
+ return right > x && bottom > y ? { x, y, width: right - x, height: bottom - y } : null;
87
60
  }
88
-
89
- // src/kit/behavior/hover.ts
90
- function stepHover(event, canHover) {
91
- return canHover && event.type === "enter";
61
+ function rectContains(outer, inner, tolerance = 0) {
62
+ return inner.x >= outer.x - tolerance && inner.y >= outer.y - tolerance && inner.x + inner.width <= outer.x + outer.width + tolerance && inner.y + inner.height <= outer.y + outer.height + tolerance;
92
63
  }
93
64
 
94
- // src/kit/behavior/press.ts
95
- var PRESS_IDLE = { by: null };
96
- function stepPress(state, event, enabled2) {
97
- switch (event.type) {
98
- case "down":
99
- if (!enabled2 || state.by !== null) return { state, activated: false };
100
- return { state: { by: event.source }, activated: false };
101
- case "up":
102
- if (state.by !== event.source) return { state, activated: false };
103
- return { state: PRESS_IDLE, activated: enabled2 };
104
- case "cancel":
105
- return { state: PRESS_IDLE, activated: false };
106
- case "leave":
107
- return state.by === "pointer" ? { state: PRESS_IDLE, activated: false } : { state, activated: false };
65
+ // src/kit/adaptive/context.ts
66
+ var INPUT_TOUCH = { primary: "coarse", anyCoarse: true, hover: false, keyboard: false };
67
+ var INPUT_POINTER = { primary: "fine", anyCoarse: false, hover: true, keyboard: true };
68
+ var INPUT_MIXED = { primary: "fine", anyCoarse: true, hover: true, keyboard: true };
69
+ var INPUT_TABLET_KEYBOARD = { primary: "coarse", anyCoarse: true, hover: true, keyboard: true };
70
+ var POSTURE_FLAT = { kind: "flat" };
71
+ function adaptiveContext(partial) {
72
+ return {
73
+ window: partial.window,
74
+ input: partial.input ?? INPUT_POINTER,
75
+ posture: partial.posture ?? POSTURE_FLAT,
76
+ reduceMotion: partial.reduceMotion ?? false
77
+ };
78
+ }
79
+ function halfOpen(kind, window, options = {}) {
80
+ const band = Math.max(options.band ?? 0, 0);
81
+ const span = kind === "tabletop" ? window.height : window.width;
82
+ const at = options.at ?? span / 2;
83
+ const start = at - band / 2;
84
+ const bounds = kind === "tabletop" ? { x: 0, y: start, width: window.width, height: band } : { x: start, y: 0, width: band, height: window.height };
85
+ return { kind, fold: { bounds, occluding: options.occluding ?? band > 0 } };
86
+ }
87
+ function windowSegments(ctx) {
88
+ const { width, height } = ctx.window;
89
+ const whole = { x: 0, y: 0, width, height };
90
+ if (ctx.posture.kind === "flat") return [whole];
91
+ const { bounds, occluding } = ctx.posture.fold;
92
+ const tabletop = ctx.posture.kind === "tabletop";
93
+ const span = tabletop ? height : width;
94
+ const lo = Math.min(Math.max(tabletop ? bounds.y : bounds.x, 0), span);
95
+ const hi = Math.min(Math.max(lo + (tabletop ? bounds.height : bounds.width), lo), span);
96
+ const end = occluding ? lo : (lo + hi) / 2;
97
+ const start = occluding ? hi : (lo + hi) / 2;
98
+ const parts = tabletop ? [
99
+ { x: 0, y: 0, width, height: end },
100
+ { x: 0, y: start, width, height: height - start }
101
+ ] : [
102
+ { x: 0, y: 0, width: end, height },
103
+ { x: start, y: 0, width: width - start, height }
104
+ ];
105
+ const kept = parts.filter((r) => r.width > 0 && r.height > 0);
106
+ return kept.length ? kept : [whole];
107
+ }
108
+ function postureFromSegments(window, segments) {
109
+ if (segments.length !== 2) return POSTURE_FLAT;
110
+ const [a, b] = [...segments].sort((p, q) => p.x - q.x || p.y - q.y);
111
+ const gapX = b.x - (a.x + a.width);
112
+ if (gapX >= 0 && a.y < b.y + b.height && b.y < a.y + a.height) {
113
+ return { kind: "book", fold: { bounds: { x: a.x + a.width, y: 0, width: gapX, height: window.height }, occluding: gapX > 0 } };
108
114
  }
115
+ const [top, bottom] = [...segments].sort((p, q) => p.y - q.y);
116
+ const gapY = bottom.y - (top.y + top.height);
117
+ if (gapY >= 0) {
118
+ return { kind: "tabletop", fold: { bounds: { x: 0, y: top.y + top.height, width: window.width, height: gapY }, occluding: gapY > 0 } };
119
+ }
120
+ return POSTURE_FLAT;
109
121
  }
110
-
111
- // src/kit/behavior/control.ts
112
- var TOUCH_INPUT = { hover: false };
113
- var POINTER_INPUT = { hover: true };
114
- var CONTROL_IDLE = {
115
- press: PRESS_IDLE,
116
- hovered: false,
117
- focused: false,
118
- disabled: false
119
- };
120
- function stepControl(state, event, caps) {
121
- switch (event.type) {
122
- case "down":
123
- case "up":
124
- case "cancel": {
125
- const next = stepPress(state.press, event, !state.disabled);
126
- return { state: { ...state, press: next.state }, activated: next.activated };
127
- }
128
- case "leave": {
129
- const next = stepPress(state.press, event, !state.disabled);
130
- return { state: { ...state, press: next.state, hovered: false }, activated: false };
122
+ var area = (r) => r ? r.width * r.height : 0;
123
+ function segmentOf(box2, segments) {
124
+ const cx = box2.x + box2.width / 2;
125
+ const cy = box2.y + box2.height / 2;
126
+ const holding = segments.find((s) => cx >= s.x && cx < s.x + s.width && cy >= s.y && cy < s.y + s.height);
127
+ if (holding) return holding;
128
+ let best;
129
+ let most = 0;
130
+ for (const s of segments) {
131
+ const overlap = area(intersectRect(s, box2));
132
+ if (overlap > most) {
133
+ most = overlap;
134
+ best = s;
131
135
  }
132
- case "enter":
133
- return {
134
- state: { ...state, hovered: !state.disabled && stepHover(event, caps.hover) },
135
- activated: false
136
- };
137
- case "focus":
138
- case "blur": {
139
- const press = event.type === "blur" && state.press.by === "keyboard" ? PRESS_IDLE : state.press;
140
- return {
141
- state: { ...state, press, focused: !state.disabled && stepFocus(event) },
142
- activated: false
143
- };
136
+ }
137
+ if (best) return best;
138
+ let nearest;
139
+ let distance = Number.POSITIVE_INFINITY;
140
+ for (const s of segments) {
141
+ const d = Math.hypot(s.x + s.width / 2 - cx, s.y + s.height / 2 - cy);
142
+ if (d < distance) {
143
+ distance = d;
144
+ nearest = s;
144
145
  }
145
- case "disable":
146
- return {
147
- state: event.disabled ? { press: PRESS_IDLE, hovered: false, focused: false, disabled: true } : { ...state, disabled: false },
148
- activated: false
149
- };
150
146
  }
147
+ return nearest;
151
148
  }
152
- function controlTargets(state) {
153
- return {
154
- pressed: state.press.by !== null ? 1 : 0,
155
- hovered: state.hovered ? 1 : 0,
156
- focus: state.focused ? 1 : 0,
157
- disabled: state.disabled
158
- };
149
+ function surfaceRegion(ctx, source) {
150
+ const segments = windowSegments(ctx);
151
+ if (source) return segmentOf(source, segments) ?? segments[0];
152
+ return segments.reduce((best, s) => area(s) > area(best) ? s : best, segments[0]);
159
153
  }
160
154
  function stepSpring(s, dt, response, damping, instant = false) {
161
155
  if (instant) {
@@ -209,7 +203,7 @@ function growthFrame(source, target, anchor, phase) {
209
203
  const len = Math.hypot(dx, dy) || 1;
210
204
  const sourceSize = vireglass.halfMinDp(source.geometry) * 2;
211
205
  const lift = DROP_LIFT * sourceSize;
212
- const drop = {
206
+ const drop2 = {
213
207
  x: source.center.x + dx / len * lift,
214
208
  y: source.center.y + dy / len * lift
215
209
  };
@@ -228,13 +222,13 @@ function growthFrame(source, target, anchor, phase) {
228
222
  );
229
223
  const shrunk = {
230
224
  geometry: shrunkGeometry,
231
- center: { x: mix(source.center.x, drop.x, a), y: mix(source.center.y, drop.y, a) }
225
+ center: { x: mix(source.center.x, drop2.x, a), y: mix(source.center.y, drop2.y, a) }
232
226
  };
233
227
  const seed = d * Math.sqrt(a);
234
228
  const cornerX = Math.sign(anchor.x - source.center.x);
235
229
  const cornerY = Math.sign(anchor.y - source.center.y);
236
- const edgeX = mix(drop.x + cornerX * (seed / 2), anchor.x, Math.min(b, 1));
237
- const edgeY = mix(drop.y + cornerY * (seed / 2), anchor.y, Math.min(b, 1));
230
+ const edgeX = mix(drop2.x + cornerX * (seed / 2), anchor.x, Math.min(b, 1));
231
+ const edgeY = mix(drop2.y + cornerY * (seed / 2), anchor.y, Math.min(b, 1));
238
232
  const width = mix(seed, target.geometry.width, b);
239
233
  const height = mix(seed, target.geometry.height, b);
240
234
  const grownGeometry = { width, height, cornerRadius: 0 };
@@ -311,6 +305,424 @@ function stepGrowth(state, dt, open, reduceMotion = false, timing = DEFAULT_GROW
311
305
  return movedShrink || movedGrow;
312
306
  }
313
307
 
308
+ // src/kit/adaptive/form-morph.ts
309
+ var HIDDEN = /* @__PURE__ */ new Set(["hidden", "closed", "none"]);
310
+ function formMorph(change, ctx, options = {}) {
311
+ const instant = ctx.reduceMotion;
312
+ if (options.anchorGone) return { ...change, mode: "retract", staysOpen: false, instant };
313
+ if (change.from === change.to) return { ...change, mode: "none", staysOpen: true, instant };
314
+ const mode = HIDDEN.has(change.from) ? "appear" : HIDDEN.has(change.to) ? "disappear" : "reshape";
315
+ return { ...change, mode, staysOpen: mode !== "disappear", instant };
316
+ }
317
+ var FORM_MORPH_TIMING = { response: DEFAULT_GROWTH_TIMING.growOpen, damping: 1 };
318
+ var createFormMorph = () => ({ t: { x: 0, v: 0, target: 0 }, fromInk: 1 });
319
+ function stepFormMorph(state, dt, toward, instant = false) {
320
+ state.t.target = toward;
321
+ return stepSpring(state.t, dt, FORM_MORPH_TIMING.response, FORM_MORPH_TIMING.damping, instant);
322
+ }
323
+ var OUT_END = 0.45;
324
+ var IN_START = 0.55;
325
+ function formMorphFrame(from, to, state) {
326
+ const t = Math.min(Math.max(state.t.x, 0), 1);
327
+ const mix3 = (a, b) => a + (b - a) * t;
328
+ return {
329
+ box: {
330
+ x: mix3(from.x, to.x),
331
+ y: mix3(from.y, to.y),
332
+ width: mix3(from.width, to.width),
333
+ height: mix3(from.height, to.height),
334
+ radius: mix3(from.radius, to.radius)
335
+ },
336
+ ink: inkAt(state, t),
337
+ showing: t < 0.5 ? "from" : "to"
338
+ };
339
+ }
340
+ function inkAt(state, t) {
341
+ return { outgoing: (state.fromInk ?? 1) * (1 - smoothstep(0, OUT_END, t)), incoming: smoothstep(IN_START, 1, t) };
342
+ }
343
+ function rebaseFormMorph(state) {
344
+ const t = Math.min(Math.max(state.t.x, 0), 1);
345
+ const ink = inkAt(state, t);
346
+ state.fromInk = t < 0.5 ? ink.outgoing : ink.incoming;
347
+ state.t = { x: 0, v: 0, target: 0 };
348
+ }
349
+ var CONTROL_SIZES = ["touch", "small", "medium", "large", "xlarge"];
350
+ var MIN_TOUCH_TARGET_DP = 44;
351
+ var MIN_POINTER_TARGET_DP = 24;
352
+ var capsule = (height, paddingX) => ({
353
+ height,
354
+ paddingX,
355
+ icon: Math.round(height / 2),
356
+ radius: height / 2,
357
+ shape: "capsule"
358
+ });
359
+ var rounded = (height, paddingX) => ({
360
+ height,
361
+ paddingX,
362
+ icon: Math.round(height / 2),
363
+ radius: height / 4,
364
+ shape: "rounded"
365
+ });
366
+ var BUTTON_SIZES = {
367
+ touch: capsule(44, 20),
368
+ small: rounded(24, 10),
369
+ medium: rounded(32, 14),
370
+ large: capsule(40, 18),
371
+ xlarge: capsule(48, 22)
372
+ };
373
+ function iconButtonSize(size) {
374
+ const spec = BUTTON_SIZES[size];
375
+ return { ...spec, width: spec.height, paddingX: 0 };
376
+ }
377
+ var MENU_PADDING = 0.3;
378
+ function menuSize(size) {
379
+ const spec = BUTTON_SIZES[size];
380
+ const padding = Math.round(spec.height * MENU_PADDING);
381
+ return {
382
+ row: spec.height,
383
+ padding,
384
+ itemRadius: spec.radius,
385
+ radius: spec.radius + padding,
386
+ icon: spec.icon,
387
+ labelPad: spec.paddingX
388
+ };
389
+ }
390
+ function nestedRadius(outerRadius, inset2, minimum = 0) {
391
+ return vireglass.concentricRadius(outerRadius, inset2, minimum);
392
+ }
393
+ function defaultSize(input) {
394
+ return input.touch ? "touch" : "medium";
395
+ }
396
+ function hitSlop(bodyDp, minTargetDp) {
397
+ return bodyDp >= minTargetDp ? 0 : (minTargetDp - bodyDp) / 2;
398
+ }
399
+ function minTarget(input) {
400
+ return input.touch ? MIN_TOUCH_TARGET_DP : MIN_POINTER_TARGET_DP;
401
+ }
402
+
403
+ // src/kit/adaptive/input.ts
404
+ function sizeTier(input) {
405
+ return defaultSize({ touch: input.primary === "coarse" });
406
+ }
407
+ function hitTarget(input) {
408
+ return minTarget({ touch: input.anyCoarse });
409
+ }
410
+ function hoversWith(pointerType) {
411
+ return pointerType !== "touch";
412
+ }
413
+
414
+ // src/kit/adaptive/navigation.ts
415
+ var BAR_SLOTS = 5;
416
+ function formFor(ctx, spec) {
417
+ const { width, height } = classifyWindow(ctx.window);
418
+ if (ctx.posture.kind === "tabletop") return "bar";
419
+ if (widthAtLeast(width, "large")) return spec.sidebarCollapsed ? "rail" : "sidebar";
420
+ if (height === "compact") return "rail";
421
+ if (width === "compact") return "bar";
422
+ if (width === "medium" && (spec.panes ?? 1) > 1 && ctx.posture.kind !== "book") return "bar";
423
+ return "rail";
424
+ }
425
+ function navigationForm(ctx, spec) {
426
+ const form = formFor(ctx, spec);
427
+ const width = classifyWindow(ctx.window).width;
428
+ const large = widthAtLeast(width, "large");
429
+ const slots = BAR_SLOTS - (spec.search ? 1 : 0);
430
+ const primary = Math.max(0, Math.min(spec.primary, slots));
431
+ const secondary = Math.max(0, spec.secondary ?? 0) + Math.max(0, spec.primary - primary);
432
+ let search = null;
433
+ if (spec.search) {
434
+ const shortcut = large || ctx.input.keyboard;
435
+ if (large) search = { form: "field", place: form === "sidebar" ? "sidebar" : "toolbar", shortcut };
436
+ else search = form === "bar" ? { form: "button", place: "bar", shortcut } : { form: "item", place: "rail", shortcut };
437
+ }
438
+ return {
439
+ form,
440
+ edge: form === "bar" ? "bottom" : "leading",
441
+ primary,
442
+ secondary,
443
+ secondaryVisible: form === "sidebar",
444
+ search,
445
+ expandable: form !== "rail" ? null : large ? "beside" : width === "expanded" ? "over" : null,
446
+ collapsible: form === "sidebar"
447
+ };
448
+ }
449
+ function bottomAccessory(nav, state = {}) {
450
+ if (nav.form !== "bar") return { placement: "content-bottom", compact: false };
451
+ return state.barMinimized ? { placement: "in-bar", compact: true } : { placement: "above-bar", compact: false };
452
+ }
453
+
454
+ // src/kit/adaptive/panes.ts
455
+ var LIST_PANE_WIDTH = { expanded: 360, large: 412 };
456
+ var SUPPORTING_PANE_MAX_WIDTH = 400;
457
+ function splitFor(ctx, sparse) {
458
+ const { width, height } = classifyWindow(ctx.window);
459
+ if (ctx.posture.kind === "book") return { kind: "fold", gap: ctx.posture.fold.bounds };
460
+ if (height === "compact") return null;
461
+ if (widthAtLeast(width, "large")) return { kind: "fixed", list: LIST_PANE_WIDTH.large };
462
+ if (width === "expanded") return { kind: "fixed", list: LIST_PANE_WIDTH.expanded };
463
+ return width === "medium" && sparse ? { kind: "half" } : null;
464
+ }
465
+ function paneLayout(ctx, state) {
466
+ const split = splitFor(ctx, state.sparse ?? false);
467
+ if (split) {
468
+ return { panes: 2, visible: ["list", "detail"], split, placeholder: !state.selected, back: false, selectionShown: state.selected };
469
+ }
470
+ const detail = state.selected && state.showing === "detail";
471
+ return { panes: 1, visible: [detail ? "detail" : "list"], split: null, placeholder: false, back: detail, selectionShown: false };
472
+ }
473
+ function supportingPane(ctx, state) {
474
+ const width = classifyWindow(ctx.window).width;
475
+ const base = { edge: "trailing", maxWidth: SUPPORTING_PANE_MAX_WIDTH, remembered: state.pinned };
476
+ if (widthAtLeast(width, "large")) return { ...base, form: state.pinned || state.open ? "beside" : "hidden", scrim: false };
477
+ if (width === "expanded" && state.open) return { ...base, form: "over", scrim: true };
478
+ return { ...base, form: "hidden", scrim: false };
479
+ }
480
+ function postureSplit(ctx) {
481
+ if (ctx.posture.kind === "flat") return { kind: "single" };
482
+ const segments = windowSegments(ctx);
483
+ if (segments.length < 2) return { kind: "single" };
484
+ return { kind: "split", axis: ctx.posture.kind === "tabletop" ? "horizontal" : "vertical", primary: segments[0], secondary: segments[1] };
485
+ }
486
+
487
+ // src/kit/adaptive/presentation.ts
488
+ var SURFACE_KINDS = ["menu", "picker", "popover", "sheet", "modal-sheet", "alert", "dialog"];
489
+ var BOTTOM_SHEET_MAX_WIDTH = 640;
490
+ var SIDE_SHEET_MAX_WIDTH = 400;
491
+ var DIALOG_MAX_WIDTH = 560;
492
+ function baseForm(kind, ctx) {
493
+ const { width, height } = classifyWindow(ctx.window);
494
+ const compactWidth = width === "compact";
495
+ const plain = { fromSource: false, scrim: false, compresses: false, maxWidth: null };
496
+ const sheet = (form) => height === "compact" ? { ...plain, form: "full-screen", scrim: true } : form;
497
+ switch (kind) {
498
+ case "menu":
499
+ return { ...plain, form: "grown", fromSource: true };
500
+ case "popover":
501
+ return compactWidth ? sheet({ ...plain, form: "bottom-sheet", fromSource: true, scrim: true }) : { ...plain, form: "popover", fromSource: true };
502
+ case "picker":
503
+ case "modal-sheet":
504
+ return sheet(
505
+ compactWidth ? { ...plain, form: "bottom-sheet", scrim: true } : { ...plain, form: "centered-sheet", scrim: true, maxWidth: DIALOG_MAX_WIDTH }
506
+ );
507
+ case "sheet":
508
+ if (width === "xlarge") return { ...plain, form: "side-pane", compresses: true, maxWidth: SIDE_SHEET_MAX_WIDTH };
509
+ if (widthAtLeast(width, "expanded")) return { ...plain, form: "side-sheet", compresses: true, maxWidth: SIDE_SHEET_MAX_WIDTH };
510
+ return sheet({ ...plain, form: "bottom-sheet", maxWidth: compactWidth ? null : BOTTOM_SHEET_MAX_WIDTH });
511
+ case "alert":
512
+ return { ...plain, form: "alert", scrim: true, maxWidth: DIALOG_MAX_WIDTH };
513
+ case "dialog":
514
+ return compactWidth ? { ...plain, form: "full-screen", scrim: true } : { ...plain, form: "basic-dialog", scrim: true, maxWidth: DIALOG_MAX_WIDTH };
515
+ }
516
+ }
517
+ function presentationForm(kind, ctx, source) {
518
+ const base = baseForm(kind, ctx);
519
+ const side = base.form === "side-sheet" || base.form === "side-pane";
520
+ const region = side && ctx.posture.kind === "book" ? windowSegments(ctx).at(-1) : surfaceRegion(ctx, source);
521
+ return { ...base, region };
522
+ }
523
+
524
+ // src/kit/adaptive/toolbar.ts
525
+ var TOOLBAR_GAP = 8;
526
+ var MORE_ID = "\u2026";
527
+ function toolbarPlacement(ctx) {
528
+ const { width, height } = classifyWindow(ctx.window);
529
+ if (height === "compact") {
530
+ return { edge: "trailing", orientation: "vertical", maxGroups: Number.POSITIVE_INFINITY };
531
+ }
532
+ if (width === "compact") return { edge: "bottom", orientation: "horizontal", maxGroups: 3 };
533
+ return { edge: "top", orientation: "horizontal", maxGroups: Number.POSITIVE_INFINITY };
534
+ }
535
+ function toolbarLayout(items, options) {
536
+ const orientation = options.orientation ?? "horizontal";
537
+ const gap = options.gap ?? TOOLBAR_GAP;
538
+ const maxGroups = options.maxGroups ?? Number.POSITIVE_INFINITY;
539
+ const side = BUTTON_SIZES[options.tier].height;
540
+ const vertical = orientation === "vertical";
541
+ const aside = vertical ? items.filter((i) => i.kind === "text").map((i) => i.id) : [];
542
+ const pool = items.map((item, index) => ({ item, index })).filter((e) => !vertical || e.item.kind === "icon");
543
+ const extentOf = (item) => item.kind === "icon" ? side : item.width ?? 3 * side;
544
+ const lay = (visible2, merge, more) => {
545
+ const ordered = [...visible2.filter((e) => !e.item.primary)];
546
+ const capsules = [];
547
+ let open = null;
548
+ const close = () => {
549
+ if (open) capsules.push({ kind: open.kind, items: open.items, extent: open.extent });
550
+ open = null;
551
+ };
552
+ for (const { item } of ordered) {
553
+ const kind = item.kind;
554
+ const group = item.group ?? `kind:${kind}`;
555
+ if (merge && open && open.kind === kind && open.group === group) {
556
+ open.items.push(item.id);
557
+ open.extent += extentOf(item);
558
+ } else {
559
+ close();
560
+ open = { kind, group, items: [item.id], extent: extentOf(item) };
561
+ }
562
+ }
563
+ close();
564
+ if (more) capsules.push({ kind: "more", items: [MORE_ID], extent: side });
565
+ for (const { item } of visible2) if (item.primary) capsules.push({ kind: "primary", items: [item.id], extent: extentOf(item) });
566
+ const extent = capsules.reduce((sum, c) => sum + c.extent, 0) + gap * Math.max(capsules.length - 1, 0);
567
+ return { capsules, extent, fits: extent <= options.available && capsules.length <= maxGroups };
568
+ };
569
+ const done = (stage, laid2, overflow) => ({
570
+ orientation,
571
+ stage,
572
+ capsules: laid2.capsules,
573
+ overflow,
574
+ aside,
575
+ extent: laid2.extent,
576
+ fits: laid2.fits
577
+ });
578
+ const separate = lay(pool, false, false);
579
+ if (separate.fits) return done("separate", separate, []);
580
+ const merged = lay(pool, true, false);
581
+ if (merged.fits) return done("merged", merged, []);
582
+ const candidates = pool.filter((e) => !e.item.badge && !e.item.primary).sort((a, b) => (a.item.priority ?? 0) - (b.item.priority ?? 0) || b.index - a.index);
583
+ let visible = pool;
584
+ const hidden = [];
585
+ let laid = merged;
586
+ for (const candidate of candidates) {
587
+ visible = visible.filter((e) => e !== candidate);
588
+ hidden.push(candidate);
589
+ laid = lay(visible, true, true);
590
+ if (laid.fits) break;
591
+ }
592
+ if (!hidden.length) return done("merged", merged, []);
593
+ return done("overflow", laid, hidden.sort((a, b) => a.index - b.index).map((e) => e.item.id));
594
+ }
595
+ var ATOM_AT_REST = {
596
+ pressed: 0,
597
+ hovered: 0,
598
+ selected: 0,
599
+ disabled: false
600
+ };
601
+ function atomLift(kind) {
602
+ switch (kind) {
603
+ case "iconButton":
604
+ case "switch":
605
+ case "slider":
606
+ return 1;
607
+ default:
608
+ return 0;
609
+ }
610
+ }
611
+ var DISABLED_PRESENCE = 0.25;
612
+ var HOVER_GAIN = 0.35;
613
+ function activation(state) {
614
+ if (state.disabled) return 0;
615
+ const clamp2 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
616
+ return Math.max(clamp2(state.selected), clamp2(state.pressed), clamp2(state.hovered) * HOVER_GAIN);
617
+ }
618
+ function atomMaterial(base, kind, state = ATOM_AT_REST) {
619
+ const out = vireglass.activeMaterial(base, activation(state));
620
+ if (!state.disabled) return out;
621
+ return { ...out, presence: out.presence * DISABLED_PRESENCE };
622
+ }
623
+ function atomAtRest(state) {
624
+ return state.pressed === 0 && state.hovered === 0 && state.selected === 0 && state.disabled === false;
625
+ }
626
+ var REST_BODY = { alpha: 0.25, white: 0.15, lift: 0.1 };
627
+ var PRESSED_BODY = { alpha: 0.34, white: 0.35, lift: 0 };
628
+ var FROST_LIFT = 0.26;
629
+ function atomBody(base, state = ATOM_AT_REST, frost = false) {
630
+ const on = activation(state);
631
+ const mix3 = (key) => REST_BODY[key] + (PRESSED_BODY[key] - REST_BODY[key]) * on;
632
+ let alpha = mix3("alpha");
633
+ let white = mix3("white");
634
+ let lift = mix3("lift");
635
+ if (state.disabled) alpha *= DISABLED_PRESENCE;
636
+ if (frost) {
637
+ const density = vireglass.applyAccessibility(vireglass.resolveOptics(base), {
638
+ reduceTransparency: true,
639
+ increaseContrast: false,
640
+ reduceMotion: false
641
+ }).bodyDensity;
642
+ alpha = Math.max(alpha, density);
643
+ white = 0;
644
+ lift = FROST_LIFT;
645
+ }
646
+ return { alpha, white, lift };
647
+ }
648
+
649
+ // src/kit/behavior/focus.ts
650
+ function stepFocus(event) {
651
+ return event.type === "focus" && event.visible;
652
+ }
653
+
654
+ // src/kit/behavior/hover.ts
655
+ function stepHover(event, canHover) {
656
+ return canHover && event.type === "enter";
657
+ }
658
+
659
+ // src/kit/behavior/press.ts
660
+ var PRESS_IDLE = { by: null };
661
+ function stepPress(state, event, enabled2) {
662
+ switch (event.type) {
663
+ case "down":
664
+ if (!enabled2 || state.by !== null) return { state, activated: false };
665
+ return { state: { by: event.source }, activated: false };
666
+ case "up":
667
+ if (state.by !== event.source) return { state, activated: false };
668
+ return { state: PRESS_IDLE, activated: enabled2 };
669
+ case "cancel":
670
+ return { state: PRESS_IDLE, activated: false };
671
+ case "leave":
672
+ return state.by === "pointer" ? { state: PRESS_IDLE, activated: false } : { state, activated: false };
673
+ }
674
+ }
675
+
676
+ // src/kit/behavior/control.ts
677
+ var TOUCH_INPUT = { hover: false };
678
+ var POINTER_INPUT = { hover: true };
679
+ var CONTROL_IDLE = {
680
+ press: PRESS_IDLE,
681
+ hovered: false,
682
+ focused: false,
683
+ disabled: false
684
+ };
685
+ function stepControl(state, event, caps) {
686
+ switch (event.type) {
687
+ case "down":
688
+ case "up":
689
+ case "cancel": {
690
+ const next = stepPress(state.press, event, !state.disabled);
691
+ return { state: { ...state, press: next.state }, activated: next.activated };
692
+ }
693
+ case "leave": {
694
+ const next = stepPress(state.press, event, !state.disabled);
695
+ return { state: { ...state, press: next.state, hovered: false }, activated: false };
696
+ }
697
+ case "enter":
698
+ return {
699
+ state: { ...state, hovered: !state.disabled && stepHover(event, caps.hover) },
700
+ activated: false
701
+ };
702
+ case "focus":
703
+ case "blur": {
704
+ const press = event.type === "blur" && state.press.by === "keyboard" ? PRESS_IDLE : state.press;
705
+ return {
706
+ state: { ...state, press, focused: !state.disabled && stepFocus(event) },
707
+ activated: false
708
+ };
709
+ }
710
+ case "disable":
711
+ return {
712
+ state: event.disabled ? { press: PRESS_IDLE, hovered: false, focused: false, disabled: true } : { ...state, disabled: false },
713
+ activated: false
714
+ };
715
+ }
716
+ }
717
+ function controlTargets(state) {
718
+ return {
719
+ pressed: state.press.by !== null ? 1 : 0,
720
+ hovered: state.hovered ? 1 : 0,
721
+ focus: state.focused ? 1 : 0,
722
+ disabled: state.disabled
723
+ };
724
+ }
725
+
314
726
  // src/kit/behavior/visual.ts
315
727
  var createControlVisual = () => ({
316
728
  pressed: { x: 0, v: 0, target: 0 },
@@ -403,40 +815,46 @@ var MENU_CORNERS = {
403
815
  "bottom-left": { x: -1, y: 1 },
404
816
  "bottom-right": { x: 1, y: 1 }
405
817
  };
406
- function menuCorner(trigger, viewport) {
818
+ function menuCorner(trigger, region) {
819
+ const x0 = region.x ?? 0;
820
+ const y0 = region.y ?? 0;
407
821
  return {
408
- x: trigger.x + trigger.width / 2 <= viewport.width / 2 ? -1 : 1,
409
- y: trigger.y + trigger.height / 2 <= viewport.height / 2 ? -1 : 1
822
+ x: trigger.x + trigger.width / 2 <= x0 + region.width / 2 ? -1 : 1,
823
+ y: trigger.y + trigger.height / 2 <= y0 + region.height / 2 ? -1 : 1
410
824
  };
411
825
  }
412
826
  function along(start, length, size, side) {
413
827
  return side < 0 ? start : start + length - size;
414
828
  }
415
- function fits(at, size, limit, margin) {
416
- return at >= margin && at + size <= limit - margin;
829
+ function fits(at, size, lo, hi, margin) {
830
+ return at >= lo + margin && at + size <= hi - margin;
417
831
  }
418
832
  var clamp = (v, lo, hi) => Math.min(Math.max(v, lo), Math.max(lo, hi));
419
- function menuPlacement(trigger, menu, viewport, options = {}) {
833
+ function menuPlacement(trigger, menu, region, options = {}) {
420
834
  const margin = options.margin ?? 8;
421
- const width = Math.min(menu.width, viewport.width - 2 * margin);
422
- const height = Math.min(menu.height, viewport.height - 2 * margin);
423
- const corner = { ...options.corner ?? menuCorner(trigger, viewport) };
835
+ const x0 = region.x ?? 0;
836
+ const y0 = region.y ?? 0;
837
+ const x1 = x0 + region.width;
838
+ const y1 = y0 + region.height;
839
+ const width = Math.max(0, Math.min(menu.width, region.width - 2 * margin));
840
+ const height = Math.max(0, Math.min(menu.height, region.height - 2 * margin));
841
+ const corner = { ...options.corner ?? menuCorner(trigger, region) };
424
842
  let x = along(trigger.x, trigger.width, width, corner.x);
425
843
  let y = along(trigger.y, trigger.height, height, corner.y);
426
844
  if (!options.corner) {
427
845
  const fx = along(trigger.x, trigger.width, width, corner.x === -1 ? 1 : -1);
428
- if (!fits(x, width, viewport.width, margin) && fits(fx, width, viewport.width, margin)) {
846
+ if (!fits(x, width, x0, x1, margin) && fits(fx, width, x0, x1, margin)) {
429
847
  corner.x = corner.x === -1 ? 1 : -1;
430
848
  x = fx;
431
849
  }
432
850
  const fy = along(trigger.y, trigger.height, height, corner.y === -1 ? 1 : -1);
433
- if (!fits(y, height, viewport.height, margin) && fits(fy, height, viewport.height, margin)) {
851
+ if (!fits(y, height, y0, y1, margin) && fits(fy, height, y0, y1, margin)) {
434
852
  corner.y = corner.y === -1 ? 1 : -1;
435
853
  y = fy;
436
854
  }
437
855
  }
438
- x = clamp(x, margin, viewport.width - margin - width);
439
- y = clamp(y, margin, viewport.height - margin - height);
856
+ x = clamp(x, x0 + margin, x1 - margin - width);
857
+ y = clamp(y, y0 + margin, y1 - margin - height);
440
858
  const rect = { x, y, width, height };
441
859
  return {
442
860
  rect,
@@ -450,7 +868,7 @@ function menuActivity(phase) {
450
868
  const grow = Math.min(Math.max(phase.grow, 0), 1);
451
869
  return shrink * (1 - grow);
452
870
  }
453
- function menuSurfaceFrame(trigger, menu, anchor, phase) {
871
+ function menuSurfaceFrame(trigger, menu, anchor, phase, bounds) {
454
872
  const frame = growthFrame(
455
873
  { geometry: { width: trigger.width, height: trigger.height, cornerRadius: trigger.radius }, center: center(trigger) },
456
874
  { geometry: { width: menu.width, height: menu.height, cornerRadius: menu.radius }, center: center(menu) },
@@ -458,17 +876,25 @@ function menuSurfaceFrame(trigger, menu, anchor, phase) {
458
876
  phase
459
877
  );
460
878
  const { geometry, center: c } = frame.body;
461
- const box = {
879
+ let box2 = {
462
880
  x: c.x - geometry.width / 2,
463
881
  y: c.y - geometry.height / 2,
464
882
  width: geometry.width,
465
883
  height: geometry.height,
466
884
  radius: geometry.cornerRadius
467
885
  };
886
+ let morph = frame.merge;
887
+ const held = bounds ? intersectRect(box2, bounds) : null;
888
+ if (held && (held.width < box2.width || held.height < box2.height)) {
889
+ const was = center(box2);
890
+ const now = center(held);
891
+ box2 = { ...held, radius: Math.min(box2.radius, held.width / 2, held.height / 2) };
892
+ if (morph) morph = { ...morph, offsetX: morph.offsetX + was.x - now.x, offsetY: morph.offsetY + was.y - now.y };
893
+ }
468
894
  return {
469
- box,
470
- morph: frame.merge,
471
- content: { x: menu.x - box.x, y: menu.y - box.y },
895
+ box: box2,
896
+ morph,
897
+ content: { x: menu.x - box2.x, y: menu.y - box2.y },
472
898
  ink: frame.ink,
473
899
  activity: menuActivity(phase)
474
900
  };
@@ -484,8 +910,8 @@ function menuBody(base, activity, frost = false) {
484
910
  const rest = atomBody(base, ATOM_AT_REST, frost);
485
911
  if (frost) return rest;
486
912
  const k = Math.min(Math.max(activity, 0), 1);
487
- const mix2 = (key) => rest[key] + (MENU_DROP_BODY[key] - rest[key]) * k;
488
- return { alpha: mix2("alpha"), white: mix2("white"), lift: mix2("lift") };
913
+ const mix3 = (key) => rest[key] + (MENU_DROP_BODY[key] - rest[key]) * k;
914
+ return { alpha: mix3("alpha"), white: mix3("white"), lift: mix3("lift") };
489
915
  }
490
916
  var MENU_ITEM_FILL = { active: 0.1, pressed: 0.18 };
491
917
  function menuItemFill(state) {
@@ -494,95 +920,612 @@ function menuItemFill(state) {
494
920
  return state.active ? MENU_ITEM_FILL.active : 0;
495
921
  }
496
922
 
497
- // src/kit/response.ts
498
- var LIFTING = { grow: 0.18, defocus: 1.6 };
499
- var SINKING = { grow: 0.06, defocus: 1 };
500
- function pressResponse(kind) {
501
- return atomLift(kind) === 1 ? LIFTING : SINKING;
923
+ // src/kit/nav/layout.ts
924
+ var NAV_SIZES = {
925
+ bar: { height: 56, item: 74, minItem: 44, inset: 3, margin: 16, searchGap: 8, minimized: 44 },
926
+ rail: { width: 80, item: 56, gap: 4, padding: 8, margin: 8, head: 48 },
927
+ sidebar: { width: 280, row: { touch: 44, pointer: 36 }, padding: 8, margin: 8, head: 48, separator: 12 },
928
+ accessory: { height: 48, gap: 8, inline: 44, content: 56, margin: 8 },
929
+ lens: { inflate: 6 },
930
+ toggle: 44
931
+ };
932
+ var box = (x, y, width, height, radius) => ({ x, y, width, height, radius });
933
+ function barLayout(input, items, minimized) {
934
+ const { bar, accessory } = NAV_SIZES;
935
+ const { width, height } = input.window;
936
+ const bottom = Math.max(input.bottomInset ?? 0, bar.margin);
937
+ const hasSearch = input.search?.form === "button";
938
+ const placement = input.accessory ? bottomAccessory({ form: "bar" }, { barMinimized: minimized }).placement : null;
939
+ const selected = input.selected >= 0 && input.selected < items ? input.selected : -1;
940
+ if (minimized) {
941
+ const centre = height - bottom - bar.height / 2;
942
+ const d = bar.minimized;
943
+ const body2 = box(bar.margin, centre - d / 2, d, d, d / 2);
944
+ const search2 = hasSearch ? box(width - bar.margin - d, body2.y, d, d, d / 2) : null;
945
+ let acc2 = null;
946
+ if (placement) {
947
+ const x2 = body2.x + d + accessory.gap;
948
+ const right = search2 ? search2.x - accessory.gap : width - bar.margin;
949
+ acc2 = box(x2, body2.y, Math.max(0, right - x2), accessory.inline, accessory.inline / 2);
950
+ }
951
+ return {
952
+ form: "bar",
953
+ minimized: true,
954
+ body: body2,
955
+ items: Array.from({ length: items }, () => ({ ...body2 })),
956
+ pill: selected >= 0 ? { ...body2 } : null,
957
+ search: search2,
958
+ accessory: acc2,
959
+ toggle: null,
960
+ accessoryPlacement: placement,
961
+ insets: { bottom: height - body2.y, start: 0 }
962
+ };
963
+ }
964
+ const searchBlock = hasSearch ? bar.height + bar.searchGap : 0;
965
+ const fit = items > 0 ? (width - 2 * bar.margin - searchBlock - 2 * bar.inset) / items : bar.item;
966
+ const itemWidth = Math.max(bar.minItem, Math.min(bar.item, fit));
967
+ const bodyWidth = items * itemWidth + 2 * bar.inset;
968
+ const x = Math.max(bar.margin, (width - bodyWidth - searchBlock) / 2);
969
+ const body = box(x, height - bottom - bar.height, bodyWidth, bar.height, bar.height / 2);
970
+ const cellHeight = bar.height - 2 * bar.inset;
971
+ const cells = Array.from(
972
+ { length: items },
973
+ (_, i) => box(x + bar.inset + i * itemWidth, body.y + bar.inset, itemWidth, cellHeight, cellHeight / 2)
974
+ );
975
+ const search = hasSearch ? box(x + bodyWidth + bar.searchGap, body.y, bar.height, bar.height, bar.height / 2) : null;
976
+ let acc = null;
977
+ if (placement) {
978
+ acc = box(body.x, body.y - accessory.gap - accessory.height, bodyWidth + searchBlock, accessory.height, accessory.height / 2);
979
+ }
980
+ return {
981
+ form: "bar",
982
+ minimized: false,
983
+ body,
984
+ items: cells,
985
+ pill: selected >= 0 ? { ...cells[selected] } : null,
986
+ search,
987
+ accessory: acc,
988
+ toggle: null,
989
+ accessoryPlacement: placement,
990
+ insets: { bottom: height - body.y + (acc ? accessory.height + accessory.gap : 0), start: 0 }
991
+ };
502
992
  }
503
- var CONTROL_SIZES = ["touch", "small", "medium", "large", "xlarge"];
504
- var MIN_TOUCH_TARGET_DP = 44;
505
- var MIN_POINTER_TARGET_DP = 24;
506
- var capsule = (height, paddingX) => ({
507
- height,
508
- paddingX,
509
- icon: Math.round(height / 2),
510
- radius: height / 2,
511
- shape: "capsule"
993
+ function contentAccessory(input, start) {
994
+ const { accessory } = NAV_SIZES;
995
+ const base = input.bottomInset ?? 0;
996
+ if (!input.accessory) return { box: null, bottom: base };
997
+ const bottom = Math.max(base, accessory.margin);
998
+ const width = Math.max(0, input.window.width - start - accessory.margin);
999
+ const acc = box(start, input.window.height - bottom - accessory.content, width, accessory.content, accessory.content / 2);
1000
+ return { box: acc, bottom: bottom + accessory.content };
1001
+ }
1002
+ function headToggle(body, padding, head, dx) {
1003
+ const d = NAV_SIZES.toggle;
1004
+ return box(body.x + dx, body.y + padding + (head - d) / 2, d, d, d / 2);
1005
+ }
1006
+ function inset(b, d) {
1007
+ return box(b.x + d, b.y + d, b.width - 2 * d, b.height - 2 * d, (Math.min(b.width, b.height) - 2 * d) / 2);
1008
+ }
1009
+ function railLayout(input, items) {
1010
+ const { rail, bar } = NAV_SIZES;
1011
+ const hasSearch = input.search?.form === "item";
1012
+ const n = items + (hasSearch ? 1 : 0);
1013
+ const head = input.toggle ? rail.head : 0;
1014
+ const natural = rail.padding * 2 + head + n * rail.item + Math.max(n - 1, 0) * rail.gap;
1015
+ const height = Math.min(natural, Math.max(input.window.height - 2 * rail.margin, 0));
1016
+ const body = box(rail.margin, rail.margin, rail.width, height, 28);
1017
+ const cell = (i) => box(body.x + rail.padding, body.y + rail.padding + head + i * (rail.item + rail.gap), rail.width - 2 * rail.padding, rail.item, 24);
1018
+ const cells = Array.from({ length: items }, (_, i) => cell(i));
1019
+ const selected = input.selected >= 0 && input.selected < items ? input.selected : -1;
1020
+ const start = body.x + body.width + rail.margin;
1021
+ const acc = contentAccessory(input, start);
1022
+ return {
1023
+ form: "rail",
1024
+ minimized: false,
1025
+ body,
1026
+ items: cells,
1027
+ pill: selected >= 0 ? inset(cells[selected], bar.inset) : null,
1028
+ search: hasSearch ? cell(items) : null,
1029
+ accessory: acc.box,
1030
+ toggle: input.toggle ? headToggle(body, rail.padding, rail.head, (rail.width - NAV_SIZES.toggle) / 2) : null,
1031
+ accessoryPlacement: acc.box ? "content-bottom" : null,
1032
+ insets: { bottom: acc.bottom, start }
1033
+ };
1034
+ }
1035
+ function sidebarLayout(input, items, secondary) {
1036
+ const { sidebar } = NAV_SIZES;
1037
+ const row = sidebar.row[input.tier];
1038
+ const body = box(sidebar.margin, sidebar.margin, sidebar.width, input.window.height - 2 * sidebar.margin, 24);
1039
+ const rowWidth = sidebar.width - 2 * sidebar.padding;
1040
+ const rowAt = (y2) => box(body.x + sidebar.padding, y2, rowWidth, row, row / 2);
1041
+ let y = body.y + sidebar.padding + (input.toggle ? sidebar.head : 0);
1042
+ let search = null;
1043
+ if (input.search?.form === "field") {
1044
+ search = rowAt(y);
1045
+ y += row;
1046
+ }
1047
+ const cells = [];
1048
+ for (let i = 0; i < items; i += 1, y += row) cells.push(rowAt(y));
1049
+ if (secondary > 0) y += sidebar.separator;
1050
+ for (let i = 0; i < secondary; i += 1, y += row) cells.push(rowAt(y));
1051
+ const selected = input.selected >= 0 && input.selected < cells.length ? input.selected : -1;
1052
+ const start = body.x + body.width + sidebar.margin;
1053
+ const acc = contentAccessory(input, start);
1054
+ return {
1055
+ form: "sidebar",
1056
+ minimized: false,
1057
+ body,
1058
+ items: cells,
1059
+ pill: selected >= 0 ? { ...cells[selected] } : null,
1060
+ search,
1061
+ accessory: acc.box,
1062
+ toggle: input.toggle ? headToggle(body, sidebar.padding, sidebar.head, sidebar.width - sidebar.padding - NAV_SIZES.toggle) : null,
1063
+ accessoryPlacement: acc.box ? "content-bottom" : null,
1064
+ insets: { bottom: acc.bottom, start }
1065
+ };
1066
+ }
1067
+ function navLayout(input) {
1068
+ const items = Math.max(0, Math.floor(input.items));
1069
+ const secondary = Math.max(0, Math.floor(input.secondary));
1070
+ if (input.form === "bar") return barLayout(input, items, !!input.minimized);
1071
+ return input.form === "rail" ? railLayout(input, items) : sidebarLayout(input, items, secondary);
1072
+ }
1073
+
1074
+ // src/kit/nav/drag.ts
1075
+ var MAX_STRETCH = 0.25;
1076
+ var SATURATION_SPEED = 1500;
1077
+ var STRETCH_TAU = 0.05;
1078
+ var OVERHANG = 4;
1079
+ var LAND = { response: 0.2, damping: 0.8 };
1080
+ var LIFT = { response: 0.2, damping: 1 };
1081
+ var createNavDrag = () => ({
1082
+ active: false,
1083
+ x: { x: 0, v: 0, target: 0 },
1084
+ lift: { x: 0, v: 0, target: 0 },
1085
+ stretch: 0,
1086
+ index: 0,
1087
+ lastX: 0
512
1088
  });
513
- var rounded = (height, paddingX) => ({
514
- height,
515
- paddingX,
516
- icon: Math.round(height / 2),
517
- radius: height / 4,
518
- shape: "rounded"
1089
+ var draggable = (layout) => layout.form === "bar" && !layout.minimized && layout.items.length > 0;
1090
+ function lensSize(layout) {
1091
+ const cell = layout.items[0];
1092
+ const pad = 2 * NAV_SIZES.lens.inflate;
1093
+ return { width: cell.width + pad, height: cell.height + pad };
1094
+ }
1095
+ function clampCentre(layout, x) {
1096
+ const half = lensSize(layout).width / 2;
1097
+ const { body } = layout;
1098
+ return Math.min(Math.max(x, body.x + half - OVERHANG), body.x + body.width - half + OVERHANG);
1099
+ }
1100
+ function indexAt(layout, x) {
1101
+ const first2 = layout.items[0];
1102
+ const i = Math.floor((x - first2.x) / first2.width);
1103
+ return Math.min(Math.max(i, 0), layout.items.length - 1);
1104
+ }
1105
+ var centreOf = (layout, index) => layout.items[index].x + layout.items[index].width / 2;
1106
+ function drop(state) {
1107
+ state.active = false;
1108
+ state.lift.x = 0;
1109
+ state.lift.v = 0;
1110
+ state.lift.target = 0;
1111
+ }
1112
+ function settleTowards(state, layout, index) {
1113
+ state.active = false;
1114
+ state.index = index;
1115
+ state.x.target = centreOf(layout, index);
1116
+ state.lift.target = 0;
1117
+ }
1118
+ function pressNavDrag(state, layout, pointerX) {
1119
+ if (!draggable(layout)) return;
1120
+ const x = clampCentre(layout, pointerX);
1121
+ state.active = true;
1122
+ state.x.x = x;
1123
+ state.x.v = 0;
1124
+ state.x.target = x;
1125
+ state.lift.target = 1;
1126
+ state.stretch = 0;
1127
+ state.lastX = pointerX;
1128
+ state.index = indexAt(layout, x);
1129
+ }
1130
+ function moveNavDrag(state, layout, pointerX, dt) {
1131
+ if (!state.active || !draggable(layout)) return;
1132
+ const x = clampCentre(layout, pointerX);
1133
+ state.x.x = x;
1134
+ state.x.v = 0;
1135
+ state.x.target = x;
1136
+ const speed = dt > 0 ? Math.abs(pointerX - state.lastX) / dt : 0;
1137
+ const goal = MAX_STRETCH * Math.min(speed / SATURATION_SPEED, 1);
1138
+ state.stretch += (goal - state.stretch) * (dt > 0 ? 1 - Math.exp(-dt / STRETCH_TAU) : 1);
1139
+ state.lastX = pointerX;
1140
+ state.index = indexAt(layout, x);
1141
+ }
1142
+ function releaseNavDrag(state, layout) {
1143
+ if (!draggable(layout)) {
1144
+ drop(state);
1145
+ return state.index;
1146
+ }
1147
+ const index = indexAt(layout, state.x.x);
1148
+ settleTowards(state, layout, index);
1149
+ return index;
1150
+ }
1151
+ function cancelNavDrag(state, layout, selected) {
1152
+ if (!draggable(layout)) {
1153
+ drop(state);
1154
+ return;
1155
+ }
1156
+ const index = selected >= 0 && selected < layout.items.length ? selected : indexAt(layout, state.x.x);
1157
+ settleTowards(state, layout, index);
1158
+ }
1159
+ function stepNavDrag(state, dt, reduceMotion = false) {
1160
+ let moving = state.active;
1161
+ if (state.stretch > 0) {
1162
+ state.stretch *= Math.exp(-Math.max(dt, 0) / STRETCH_TAU);
1163
+ if (reduceMotion || state.stretch < 1e-3) state.stretch = 0;
1164
+ else moving = true;
1165
+ }
1166
+ if (!state.active && stepSpring(state.x, dt, LAND.response, LAND.damping, reduceMotion)) moving = true;
1167
+ if (stepSpring(state.lift, dt, LIFT.response, LIFT.damping, reduceMotion)) moving = true;
1168
+ return moving;
1169
+ }
1170
+ function navDragFrame(state, layout) {
1171
+ if (!draggable(layout)) return null;
1172
+ const lift = Math.min(Math.max(state.lift.x, 0), 1);
1173
+ if (!state.active && lift === 0 && state.x.x === state.x.target) return null;
1174
+ const size = lensSize(layout);
1175
+ const width = size.width * (1 + state.stretch);
1176
+ const height = size.height * (1 - state.stretch / 2);
1177
+ const cy = layout.body.y + layout.body.height / 2;
1178
+ return {
1179
+ lens: { x: state.x.x - width / 2, y: cy - height / 2, width, height, radius: height / 2 },
1180
+ lift,
1181
+ hover: indexAt(layout, state.x.x)
1182
+ };
1183
+ }
1184
+
1185
+ // src/kit/nav/form.ts
1186
+ var SEARCH = {
1187
+ bar: { form: "button", place: "bar" },
1188
+ rail: { form: "item", place: "rail" },
1189
+ sidebar: { form: "field", place: "sidebar" }
1190
+ };
1191
+ function fixedNavigationForm(nav, form) {
1192
+ if (nav.form === form) return nav;
1193
+ return {
1194
+ ...nav,
1195
+ form,
1196
+ edge: form === "bar" ? "bottom" : "leading",
1197
+ secondaryVisible: form === "sidebar",
1198
+ search: nav.search ? { ...nav.search, ...SEARCH[form] } : null,
1199
+ expandable: form === "rail" ? nav.expandable : null,
1200
+ collapsible: form === "sidebar"
1201
+ };
1202
+ }
1203
+
1204
+ // src/kit/nav/minimize.ts
1205
+ var MINIMIZE_THRESHOLD = 24;
1206
+ var MINIMIZE_JITTER = 4;
1207
+ var createMinimize = (scrollTop = 0) => ({ minimized: false, run: 0, last: scrollTop });
1208
+ function stepMinimize(state, scrollTop) {
1209
+ const delta = scrollTop - state.last;
1210
+ state.last = scrollTop;
1211
+ if (scrollTop <= 0) {
1212
+ state.minimized = false;
1213
+ state.run = 0;
1214
+ return false;
1215
+ }
1216
+ if (delta === 0) return state.minimized;
1217
+ const along2 = Math.sign(delta) === Math.sign(state.run) || Math.abs(delta) < MINIMIZE_JITTER;
1218
+ state.run = along2 ? state.run + delta : delta;
1219
+ if (state.run >= MINIMIZE_THRESHOLD) state.minimized = true;
1220
+ else if (state.run <= -MINIMIZE_THRESHOLD) state.minimized = false;
1221
+ return state.minimized;
1222
+ }
1223
+ var clampScrollTop = (scrollTop, scrollHeight, clientHeight) => Math.min(Math.max(scrollTop, 0), Math.max(scrollHeight - clientHeight, 0));
1224
+ function expandMinimize(state) {
1225
+ state.minimized = false;
1226
+ state.run = 0;
1227
+ }
1228
+
1229
+ // src/kit/nav/morph.ts
1230
+ var NAV_MORPH_TIMING = { response: 1.06, damping: 1 };
1231
+ var NAV_MINIMIZE_TIMING = FORM_MORPH_TIMING;
1232
+ var LIFT_END = 0.12;
1233
+ var CONTRACT = [0.08, 0.38];
1234
+ var TRAVEL = [0.36, 0.56];
1235
+ var GROW = [0.52, 0.86];
1236
+ var SETTLE_START = 0.82;
1237
+ var INK_OUT = [0.08, 0.28];
1238
+ var INK_IN = [0.62, 0.86];
1239
+ var SWAP_AT = 0.46;
1240
+ var SMOOTHING = 24;
1241
+ var SEED = 8;
1242
+ var STAND_IN = 44;
1243
+ var clamp01 = (x) => Math.min(Math.max(x, 0), 1);
1244
+ var mix2 = (a, b, t) => a + (b - a) * t;
1245
+ var mixBox = (a, b, t) => ({
1246
+ x: mix2(a.x, b.x, t),
1247
+ y: mix2(a.y, b.y, t),
1248
+ width: mix2(a.width, b.width, t),
1249
+ height: mix2(a.height, b.height, t),
1250
+ radius: mix2(a.radius, b.radius, t)
519
1251
  });
520
- var BUTTON_SIZES = {
521
- touch: capsule(44, 20),
522
- small: rounded(24, 10),
523
- medium: rounded(32, 14),
524
- large: capsule(40, 18),
525
- xlarge: capsule(48, 22)
1252
+ var inflate = (b, d) => ({
1253
+ x: b.x - d,
1254
+ y: b.y - d,
1255
+ width: b.width + 2 * d,
1256
+ height: b.height + 2 * d,
1257
+ radius: b.radius + d
1258
+ });
1259
+ var centred = (cx, cy, size) => ({ x: cx - size / 2, y: cy - size / 2, width: size, height: size, radius: size / 2 });
1260
+ var trailingEnd = (body, size) => centred(body.x + body.width - body.height / 2, body.y + body.height / 2, size);
1261
+ var pillOrStandIn = (layout) => layout.pill ?? centred(layout.body.x + layout.body.width / 2, layout.body.y + layout.body.height / 2, STAND_IN);
1262
+ var separateSearch = (layout) => layout.form === "bar" ? layout.search : null;
1263
+ function restFrame(layout, side) {
1264
+ const search = separateSearch(layout);
1265
+ return {
1266
+ phase: "rest",
1267
+ body: layout.body,
1268
+ second: search ? { box: search, smoothing: 0 } : null,
1269
+ lens: null,
1270
+ ink: side === "from" ? { outgoing: 1, incoming: 0 } : { outgoing: 0, incoming: 1 },
1271
+ showing: side
1272
+ };
1273
+ }
1274
+ var layoutOrigin = (layout) => {
1275
+ const search = separateSearch(layout);
1276
+ return {
1277
+ body: layout.body,
1278
+ second: search ? { box: search, smoothing: 0 } : null,
1279
+ lens: { box: pillOrStandIn(layout), lift: 0 },
1280
+ ink: 1,
1281
+ lead: 0,
1282
+ hold: null
1283
+ };
526
1284
  };
527
- function iconButtonSize(size) {
528
- const spec = BUTTON_SIZES[size];
529
- return { ...spec, width: spec.height, paddingX: 0 };
1285
+ var frameOrigin = (frame) => ({
1286
+ body: frame.body,
1287
+ second: frame.second,
1288
+ lens: frame.lens ?? { box: centred(frame.body.x + frame.body.width / 2, frame.body.y + frame.body.height / 2, STAND_IN), lift: 0 },
1289
+ ink: Math.max(frame.ink.outgoing, frame.ink.incoming),
1290
+ lead: CONTRACT[0],
1291
+ hold: null
1292
+ });
1293
+ function phaseAt(tau) {
1294
+ if (tau < CONTRACT[0]) return "lift";
1295
+ if (tau < TRAVEL[0]) return "contract";
1296
+ if (tau < GROW[0]) return "travel";
1297
+ return tau < SETTLE_START ? "grow" : "settle";
530
1298
  }
531
- var MENU_PADDING = 0.3;
532
- function menuSize(size) {
533
- const spec = BUTTON_SIZES[size];
534
- const padding = Math.round(spec.height * MENU_PADDING);
1299
+ function lensFrame(o, to, t) {
1300
+ const tau = o.lead + (1 - o.lead) * t;
1301
+ const u = smoothstep(o.lead, LIFT_END, tau);
1302
+ const base = inflate(o.lens.box, NAV_SIZES.lens.inflate * (1 - o.lens.lift) * u);
1303
+ const lift = mix2(o.lens.lift, 1, u);
1304
+ const toPill = pillOrStandIn(to);
1305
+ const k = smoothstep(TRAVEL[0], TRAVEL[1], tau);
1306
+ const kk = o.hold ? clamp01((k - o.hold.k0) / (1 - o.hold.k0)) : k;
1307
+ const travelling = mixBox(o.hold?.box ?? base, inflate(toPill, NAV_SIZES.lens.inflate), kk);
1308
+ const c = smoothstep(CONTRACT[0], CONTRACT[1], tau);
1309
+ const g = smoothstep(GROW[0], GROW[1], tau);
1310
+ const s = smoothstep(SETTLE_START, 1, tau);
1311
+ const contracted = mixBox(o.body, travelling, c);
1312
+ const body = mixBox(contracted, to.body, g);
1313
+ let second = null;
1314
+ const budding = separateSearch(to);
1315
+ if (o.second && c < 1) {
1316
+ second = {
1317
+ box: mixBox(o.second.box, trailingEnd(contracted, 0), c),
1318
+ smoothing: mix2(o.second.smoothing, SMOOTHING, c)
1319
+ };
1320
+ } else if (budding && g > 0) {
1321
+ second = { box: mixBox(trailingEnd(body, SEED), budding, g), smoothing: SMOOTHING * (1 - g) };
1322
+ }
535
1323
  return {
536
- row: spec.height,
537
- padding,
538
- itemRadius: spec.radius,
539
- radius: spec.radius + padding,
540
- icon: spec.icon,
541
- labelPad: spec.paddingX
1324
+ phase: phaseAt(tau),
1325
+ body,
1326
+ second,
1327
+ lens: { box: mixBox(travelling, toPill, s), lift: lift * (1 - s) },
1328
+ ink: {
1329
+ outgoing: o.ink * (1 - smoothstep(INK_OUT[0], INK_OUT[1], tau)),
1330
+ incoming: smoothstep(INK_IN[0], INK_IN[1], tau)
1331
+ },
1332
+ showing: tau < SWAP_AT ? "from" : "to"
542
1333
  };
543
1334
  }
544
- function nestedRadius(outerRadius, inset, minimum = 0) {
545
- return vireglass.concentricRadius(outerRadius, inset, minimum);
1335
+ function contractFrame(o, to, t) {
1336
+ const body = mixBox(o.body, to.body, t);
1337
+ const target = separateSearch(to);
1338
+ let second = null;
1339
+ if (o.second && target) {
1340
+ second = { box: mixBox(o.second.box, target, t), smoothing: mix2(o.second.smoothing, 0, t) };
1341
+ } else if (o.second) {
1342
+ second = { box: mixBox(o.second.box, trailingEnd(body, 0), t), smoothing: mix2(o.second.smoothing, SMOOTHING, t) };
1343
+ } else if (target) {
1344
+ second = { box: mixBox(trailingEnd(body, SEED), target, t), smoothing: SMOOTHING * (1 - t) };
1345
+ }
1346
+ return {
1347
+ phase: "contract",
1348
+ body,
1349
+ second,
1350
+ lens: null,
1351
+ ink: { outgoing: o.ink * (1 - smoothstep(0, 0.45, t)), incoming: smoothstep(0.55, 1, t) },
1352
+ showing: t < 0.5 ? "from" : "to"
1353
+ };
546
1354
  }
547
- function defaultSize(input) {
548
- return input.touch ? "touch" : "medium";
1355
+ var frameFrom = (o, to, t, via) => via === "lens" ? lensFrame(o, to, t) : contractFrame(o, to, t);
1356
+ function navMorphFrame(from, to, t, via = "lens") {
1357
+ if (t <= 0) return restFrame(from, "from");
1358
+ if (t >= 1) return restFrame(to, "to");
1359
+ return frameFrom(layoutOrigin(from), to, t, via);
549
1360
  }
550
- function hitSlop(bodyDp, minTargetDp) {
551
- return bodyDp >= minTargetDp ? 0 : (minTargetDp - bodyDp) / 2;
1361
+ var createNavMorph = (at) => ({
1362
+ t: { x: 0, v: 0, target: 0 },
1363
+ from: at,
1364
+ to: at,
1365
+ via: "lens",
1366
+ pivot: null,
1367
+ pivotAt: 0
1368
+ });
1369
+ var sameForm = (a, b) => a.form === b.form && a.minimized === b.minimized;
1370
+ var atRest = (s) => s.t.v === 0 && s.t.x === s.t.target && (s.t.x === 0 || s.t.x === 1);
1371
+ function currentNavFrame(state) {
1372
+ const x = clamp01(state.t.x);
1373
+ if (x >= 1) return restFrame(state.to, "to");
1374
+ const { pivot } = state;
1375
+ if (!pivot) return navMorphFrame(state.from, state.to, x, state.via);
1376
+ if (state.pivotAt > 0 && pivot.lens) {
1377
+ const origin = layoutOrigin(state.from);
1378
+ origin.hold = { box: pivot.lens.box, k0: smoothstep(TRAVEL[0], TRAVEL[1], state.pivotAt) };
1379
+ return lensFrame(origin, state.to, x);
1380
+ }
1381
+ return frameFrom(frameOrigin(pivot), state.to, x, state.via);
552
1382
  }
553
- function minTarget(input) {
554
- return input.touch ? MIN_TOUCH_TARGET_DP : MIN_POINTER_TARGET_DP;
1383
+ function aimNavMorph(state, next, via = "lens") {
1384
+ const { t } = state;
1385
+ if (atRest(state)) {
1386
+ const current = t.x >= 1 ? state.to : state.from;
1387
+ if (sameForm(current, next)) {
1388
+ if (t.x >= 1) state.to = next;
1389
+ else state.from = next;
1390
+ state.pivot = null;
1391
+ return;
1392
+ }
1393
+ state.from = current;
1394
+ state.to = next;
1395
+ state.via = via;
1396
+ state.pivot = null;
1397
+ state.pivotAt = 0;
1398
+ t.x = 0;
1399
+ t.v = 0;
1400
+ t.target = 1;
1401
+ return;
1402
+ }
1403
+ if (!state.pivot) {
1404
+ if (sameForm(next, state.from)) {
1405
+ state.from = next;
1406
+ t.target = 0;
1407
+ return;
1408
+ }
1409
+ if (sameForm(next, state.to)) {
1410
+ state.to = next;
1411
+ t.target = 1;
1412
+ return;
1413
+ }
1414
+ const x = clamp01(t.x);
1415
+ if (via === "lens" && state.via === "lens" && x < GROW[0]) {
1416
+ if (x >= TRAVEL[0]) {
1417
+ state.pivot = currentNavFrame(state);
1418
+ state.pivotAt = x;
1419
+ }
1420
+ state.to = next;
1421
+ t.target = 1;
1422
+ return;
1423
+ }
1424
+ } else if (sameForm(next, state.to)) {
1425
+ state.to = next;
1426
+ t.target = 1;
1427
+ return;
1428
+ }
1429
+ const frozen = currentNavFrame(state);
1430
+ if (frozen.showing === "to") state.from = state.to;
1431
+ state.pivot = frozen;
1432
+ state.pivotAt = 0;
1433
+ state.to = next;
1434
+ state.via = via;
1435
+ t.x = 0;
1436
+ t.v = 0;
1437
+ t.target = 1;
1438
+ }
1439
+ function stepNavMorph(state, dt, reduceMotion = false) {
1440
+ const timing = state.via === "lens" ? NAV_MORPH_TIMING : NAV_MINIMIZE_TIMING;
1441
+ const moved = stepSpring(state.t, dt, timing.response, timing.damping, reduceMotion);
1442
+ if (!moved && state.t.x >= 1) {
1443
+ state.pivot = null;
1444
+ state.pivotAt = 0;
1445
+ }
1446
+ return moved;
1447
+ }
1448
+
1449
+ // src/kit/response.ts
1450
+ var LIFTING = { grow: 0.18, defocus: 1.6 };
1451
+ var SINKING = { grow: 0.06, defocus: 1 };
1452
+ function pressResponse(kind) {
1453
+ return atomLift(kind) === 1 ? LIFTING : SINKING;
555
1454
  }
556
1455
 
557
1456
  exports.A11Y_NONE = A11Y_NONE;
558
1457
  exports.ATOM_AT_REST = ATOM_AT_REST;
1458
+ exports.BAR_SLOTS = BAR_SLOTS;
1459
+ exports.BOTTOM_SHEET_MAX_WIDTH = BOTTOM_SHEET_MAX_WIDTH;
559
1460
  exports.BUTTON_SIZES = BUTTON_SIZES;
560
1461
  exports.CONTROL_IDLE = CONTROL_IDLE;
561
1462
  exports.CONTROL_SIZES = CONTROL_SIZES;
562
1463
  exports.DEFAULT_GROWTH_TIMING = DEFAULT_GROWTH_TIMING;
1464
+ exports.DIALOG_MAX_WIDTH = DIALOG_MAX_WIDTH;
1465
+ exports.FORM_MORPH_TIMING = FORM_MORPH_TIMING;
1466
+ exports.HEIGHT_BREAKPOINTS = HEIGHT_BREAKPOINTS;
1467
+ exports.HEIGHT_CLASSES = HEIGHT_CLASSES;
1468
+ exports.INPUT_MIXED = INPUT_MIXED;
1469
+ exports.INPUT_POINTER = INPUT_POINTER;
1470
+ exports.INPUT_TABLET_KEYBOARD = INPUT_TABLET_KEYBOARD;
1471
+ exports.INPUT_TOUCH = INPUT_TOUCH;
1472
+ exports.LIST_PANE_WIDTH = LIST_PANE_WIDTH;
563
1473
  exports.MENU_CLOSED = MENU_CLOSED;
564
1474
  exports.MENU_CORNERS = MENU_CORNERS;
565
1475
  exports.MENU_DROP_BODY = MENU_DROP_BODY;
566
1476
  exports.MENU_ITEM_FILL = MENU_ITEM_FILL;
1477
+ exports.MINIMIZE_JITTER = MINIMIZE_JITTER;
1478
+ exports.MINIMIZE_THRESHOLD = MINIMIZE_THRESHOLD;
567
1479
  exports.MIN_POINTER_TARGET_DP = MIN_POINTER_TARGET_DP;
568
1480
  exports.MIN_TOUCH_TARGET_DP = MIN_TOUCH_TARGET_DP;
1481
+ exports.MORE_ID = MORE_ID;
1482
+ exports.NAV_MINIMIZE_TIMING = NAV_MINIMIZE_TIMING;
1483
+ exports.NAV_MORPH_TIMING = NAV_MORPH_TIMING;
1484
+ exports.NAV_SIZES = NAV_SIZES;
569
1485
  exports.POINTER_INPUT = POINTER_INPUT;
1486
+ exports.POSTURE_FLAT = POSTURE_FLAT;
570
1487
  exports.PRESS_IDLE = PRESS_IDLE;
1488
+ exports.SIDE_SHEET_MAX_WIDTH = SIDE_SHEET_MAX_WIDTH;
1489
+ exports.SUPPORTING_PANE_MAX_WIDTH = SUPPORTING_PANE_MAX_WIDTH;
1490
+ exports.SURFACE_KINDS = SURFACE_KINDS;
1491
+ exports.TOOLBAR_GAP = TOOLBAR_GAP;
571
1492
  exports.TOUCH_INPUT = TOUCH_INPUT;
572
1493
  exports.TYPEAHEAD_SECONDS = TYPEAHEAD_SECONDS;
1494
+ exports.WIDTH_BREAKPOINTS = WIDTH_BREAKPOINTS;
1495
+ exports.WIDTH_CLASSES = WIDTH_CLASSES;
1496
+ exports.adaptiveContext = adaptiveContext;
1497
+ exports.aimNavMorph = aimNavMorph;
573
1498
  exports.atomAtRest = atomAtRest;
574
1499
  exports.atomBody = atomBody;
575
1500
  exports.atomLift = atomLift;
576
1501
  exports.atomMaterial = atomMaterial;
1502
+ exports.bottomAccessory = bottomAccessory;
1503
+ exports.cancelNavDrag = cancelNavDrag;
1504
+ exports.clampScrollTop = clampScrollTop;
1505
+ exports.classifyWindow = classifyWindow;
577
1506
  exports.controlTargets = controlTargets;
578
1507
  exports.createControlVisual = createControlVisual;
1508
+ exports.createFormMorph = createFormMorph;
579
1509
  exports.createGrowthState = createGrowthState;
1510
+ exports.createMinimize = createMinimize;
1511
+ exports.createNavDrag = createNavDrag;
1512
+ exports.createNavMorph = createNavMorph;
1513
+ exports.currentNavFrame = currentNavFrame;
580
1514
  exports.defaultSize = defaultSize;
1515
+ exports.expandMinimize = expandMinimize;
1516
+ exports.fixedNavigationForm = fixedNavigationForm;
1517
+ exports.formMorph = formMorph;
1518
+ exports.formMorphFrame = formMorphFrame;
581
1519
  exports.growthFrame = growthFrame;
582
1520
  exports.growthInk = growthInk;
583
1521
  exports.growthPhase = growthPhase;
1522
+ exports.halfOpen = halfOpen;
1523
+ exports.heightClass = heightClass;
584
1524
  exports.hitSlop = hitSlop;
1525
+ exports.hitTarget = hitTarget;
1526
+ exports.hoversWith = hoversWith;
585
1527
  exports.iconButtonSize = iconButtonSize;
1528
+ exports.intersectRect = intersectRect;
586
1529
  exports.menuActivity = menuActivity;
587
1530
  exports.menuBody = menuBody;
588
1531
  exports.menuCorner = menuCorner;
@@ -593,21 +1536,47 @@ exports.menuPlacement = menuPlacement;
593
1536
  exports.menuSize = menuSize;
594
1537
  exports.menuSurfaceFrame = menuSurfaceFrame;
595
1538
  exports.minTarget = minTarget;
1539
+ exports.moveNavDrag = moveNavDrag;
1540
+ exports.navDragFrame = navDragFrame;
1541
+ exports.navLayout = navLayout;
1542
+ exports.navMorphFrame = navMorphFrame;
1543
+ exports.navigationForm = navigationForm;
596
1544
  exports.nestedRadius = nestedRadius;
1545
+ exports.paneLayout = paneLayout;
1546
+ exports.postureFromSegments = postureFromSegments;
1547
+ exports.postureSplit = postureSplit;
597
1548
  exports.presentationFor = presentationFor;
1549
+ exports.presentationForm = presentationForm;
1550
+ exports.pressNavDrag = pressNavDrag;
598
1551
  exports.pressResponse = pressResponse;
1552
+ exports.rebaseFormMorph = rebaseFormMorph;
1553
+ exports.rectContains = rectContains;
1554
+ exports.releaseNavDrag = releaseNavDrag;
599
1555
  exports.resolveA11y = resolveA11y;
600
1556
  exports.sameA11y = sameA11y;
1557
+ exports.segmentOf = segmentOf;
601
1558
  exports.settleControlVisual = settleControlVisual;
1559
+ exports.sizeTier = sizeTier;
602
1560
  exports.smoothstep = smoothstep;
603
1561
  exports.stepControl = stepControl;
604
1562
  exports.stepControlVisual = stepControlVisual;
605
1563
  exports.stepFocus = stepFocus;
1564
+ exports.stepFormMorph = stepFormMorph;
606
1565
  exports.stepGrowth = stepGrowth;
607
1566
  exports.stepHover = stepHover;
608
1567
  exports.stepMenu = stepMenu;
1568
+ exports.stepMinimize = stepMinimize;
1569
+ exports.stepNavDrag = stepNavDrag;
1570
+ exports.stepNavMorph = stepNavMorph;
609
1571
  exports.stepPress = stepPress;
610
1572
  exports.stepSpring = stepSpring;
1573
+ exports.supportingPane = supportingPane;
1574
+ exports.surfaceRegion = surfaceRegion;
1575
+ exports.toolbarLayout = toolbarLayout;
1576
+ exports.toolbarPlacement = toolbarPlacement;
611
1577
  exports.visualAtomState = visualAtomState;
1578
+ exports.widthAtLeast = widthAtLeast;
1579
+ exports.widthClass = widthClass;
1580
+ exports.windowSegments = windowSegments;
612
1581
  //# sourceMappingURL=index.cjs.map
613
1582
  //# sourceMappingURL=index.cjs.map