@stealthscale/component-navigation 0.1.0 → 0.3.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.js CHANGED
@@ -1,56 +1,72 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { n as recipe, t as recipe$1 } from "./recipe-TfPpeGkM.js";
3
- import "react";
2
+ import { a as recipe$2, i as CLASS, n as recipe$4, o as recipe$1, r as recipe$3, s as recipe, t as recipe$5 } from "./recipe-wIXGUbM7.js";
4
3
  import { createRecipeContext, createSlotRecipeContext } from "@stealthscale/theme";
4
+ import { c } from "react/compiler-runtime";
5
+ import { createRequiredContext, omitUndefined, splitEnumerable, useControllableState, useCrowded, useFilterActive, useFilteredRow, usePresence } from "@stealthscale/hooks";
6
+ import { createContext, use, useContext, useEffect, useId, useState } from "react";
7
+ import * as collapsible from "@zag-js/collapsible";
8
+ import { mergeProps, normalizeProps, useMachine } from "@zag-js/react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { Tooltip } from "@stealthscale/component-disclosure";
11
+ import { Portal, ScrollArea } from "@stealthscale/component-primitives";
12
+ import * as navigationMenu from "@zag-js/navigation-menu";
13
+ import * as pagination from "@zag-js/pagination";
14
+ import { Button, ButtonPropsProvider } from "@stealthscale/component-actions";
15
+ import * as toc from "@zag-js/toc";
5
16
  //#region src/breadcrumb/context.ts
6
17
  /**
7
- * Binds the breadcrumb's recipe to the elements that draw its parts.
18
+ * Binds the breadcrumb slot recipe to React.
8
19
  *
9
20
  * @remarks
10
- * Apart from the recipe, because an application's compiler reads the recipe at build time and
11
- * the binding needs the runtime.
21
+ * The binding is a separate module from the recipe, because an application's compiler imports the
22
+ * recipe at build time and the binding needs the React runtime.
12
23
  */
13
24
  /**
14
- * Binds the recipe once. The root provides the variants and every other part reads them.
25
+ * Factories for the parts. The root resolves the variants once and the other parts read them.
15
26
  */
16
- const { withContext: withContext$1, withProvider } = createSlotRecipeContext(recipe);
27
+ const { withContext: withContext$5, withProvider: withProvider$4 } = createSlotRecipeContext(recipe);
17
28
  //#endregion
18
29
  //#region src/breadcrumb/current-link.ts
19
30
  /**
20
- * Draws the name of the page itself, at full strength against the muted crumbs above it.
31
+ * Renders a span with `aria-current="page"` in the default ink.
32
+ */
33
+ const CurrentLink = withContext$5("span", "currentLink", { defaultProps: { "aria-current": "page" } });
34
+ //#endregion
35
+ //#region src/breadcrumb/ellipsis.ts
36
+ /**
37
+ * Renders a list item in the muted ink.
21
38
  */
22
- const CurrentLink = withContext$1("span", "currentLink", { defaultProps: { "aria-current": "page" } });
39
+ const Ellipsis$1 = withContext$5("li", "ellipsis");
23
40
  //#endregion
24
41
  //#region src/breadcrumb/item.ts
25
42
  /**
26
- * Draws one row of the trail, carrying either a link to somewhere above or the name of the page
27
- * itself.
43
+ * Renders a list item that holds a `Breadcrumb.Link` or the `Breadcrumb.CurrentLink`.
28
44
  */
29
- const Item = withContext$1("li", "item");
45
+ const Item$4 = withContext$5("li", "item");
30
46
  //#endregion
31
47
  //#region src/breadcrumb/link.ts
32
48
  /**
33
- * Draws a link to somewhere above the page.
49
+ * Renders an anchor in the muted ink that darkens on hover.
34
50
  */
35
- const Link$1 = withContext$1("a", "link");
51
+ const Link$4 = withContext$5("a", "link");
36
52
  //#endregion
37
53
  //#region src/breadcrumb/list.ts
38
54
  /**
39
- * Draws the crumbs in order, at the gap its size states.
55
+ * Renders an ordered list with `role="list"` and the gap of the size axis.
40
56
  */
41
- const List = withContext$1("ol", "list", { defaultProps: { role: "list" } });
57
+ const List$2 = withContext$5("ol", "list", { defaultProps: { role: "list" } });
42
58
  //#endregion
43
59
  //#region src/breadcrumb/root.ts
44
60
  /**
45
- * Draws the landmark and sets the size and look every part below it reads.
61
+ * Renders a `nav` and provides the size and variant to every part inside it.
46
62
  */
47
- const Root = withProvider("nav", "root", { defaultProps: { "aria-label": "Breadcrumb" } });
63
+ const Root$4 = withProvider$4("nav", "root", { defaultProps: { "aria-label": "Breadcrumb" } });
48
64
  //#endregion
49
65
  //#region src/breadcrumb/separator.ts
50
66
  /**
51
- * Draws the mark between two crumbs, saying nothing to a screen reader.
67
+ * Renders a list item hidden from the accessibility tree.
52
68
  */
53
- const Separator = withContext$1("li", "separator", { defaultProps: {
69
+ const Separator = withContext$5("li", "separator", { defaultProps: {
54
70
  "aria-hidden": true,
55
71
  role: "presentation"
56
72
  } });
@@ -58,30 +74,2232 @@ const Separator = withContext$1("li", "separator", { defaultProps: {
58
74
  //#region src/breadcrumb/index.ts
59
75
  var breadcrumb_exports = /* @__PURE__ */ __exportAll({
60
76
  CurrentLink: () => CurrentLink,
61
- Item: () => Item,
62
- Link: () => Link$1,
63
- List: () => List,
64
- Root: () => Root,
77
+ Ellipsis: () => Ellipsis$1,
78
+ Item: () => Item$4,
79
+ Link: () => Link$4,
80
+ List: () => List$2,
81
+ Root: () => Root$4,
65
82
  Separator: () => Separator
66
83
  });
67
84
  //#endregion
68
85
  //#region src/link/context.ts
69
86
  /**
70
- * Binds the link's recipe to the element that draws it.
87
+ * Binds the link recipe to React.
71
88
  *
72
89
  * @remarks
73
- * Apart from the recipe, because an application's compiler reads the recipe at build time and
74
- * the binding needs the runtime.
90
+ * The binding is a separate module from the recipe, because an application's compiler imports the
91
+ * recipe at build time and the binding needs the React runtime.
75
92
  */
76
93
  /**
77
- * Binds the recipe once, for the link and for whatever sets its variants from above.
94
+ * Factory for the link element and the provider that sets its variants for descendants.
78
95
  */
79
- const { PropsProvider, withContext } = createRecipeContext(recipe$1);
96
+ const { PropsProvider, withContext: withContext$4 } = createRecipeContext(recipe$1);
80
97
  //#endregion
81
98
  //#region src/link/link.ts
82
99
  /**
83
- * Draws words a person follows to somewhere else.
100
+ * Renders an anchor with the link recipe's classes.
101
+ */
102
+ const Link = withContext$4("a");
103
+ //#endregion
104
+ //#region src/nav-list/context.ts
105
+ /**
106
+ * Binds the navigation list recipe to the elements that render its parts.
107
+ *
108
+ * @remarks
109
+ * The binding is kept out of `recipe.ts` because an application's style compiler imports the
110
+ * recipe at build time, and a binding there would pull the React runtime into that import.
111
+ */
112
+ /**
113
+ * Supplies the root's factory, which receives the variants, and the part factory every other part
114
+ * reads them through.
115
+ */
116
+ const { withContext: withContext$3, withProvider: withProvider$3 } = createSlotRecipeContext(recipe$2);
117
+ //#endregion
118
+ //#region src/nav-list/action.ts
119
+ /**
120
+ * Renders the action `button` with the list's variants and `type` defaulting to `button`.
121
+ */
122
+ const Action = withContext$3("button", "action", { defaultProps: { type: "button" } });
123
+ //#endregion
124
+ //#region src/nav-list/badge.ts
125
+ /**
126
+ * Renders the count `span` with the list's variants.
127
+ */
128
+ const Badge = withContext$3("span", "badge");
129
+ //#endregion
130
+ //#region src/nav-list/machine.ts
131
+ /**
132
+ * Connects the collapsible machine for a branch and provides its api to the branch's parts.
133
+ *
134
+ * @remarks
135
+ * A branch uses the collapsible machine because the machine measures the nested list, writes its
136
+ * height to a custom property that the collapse animation reads, and keeps the list mounted
137
+ * until that animation ends. The branch takes the machine and not the collapsible recipe. The
138
+ * collapsible trigger's control sizing would conflict with the row height the nav-list recipe
139
+ * sets. The branch starts one machine, and its trigger, indicator and content read the api from
140
+ * context.
141
+ */
142
+ /**
143
+ * Creates the context through which a branch provides the connected api to its parts.
144
+ *
145
+ * @remarks
146
+ * `useBranch` throws when no `NavList.Branch` is mounted above the calling part.
147
+ */
148
+ const [BranchProvider, useBranch] = createRequiredContext("NavList.Branch");
149
+ /**
150
+ * Starts the collapsible machine for a branch and returns its connected api.
151
+ *
152
+ * @param options - Machine settings split from the branch's props. A generated id is used when
153
+ * `id` is absent.
154
+ */
155
+ function useBranchMachine(options) {
156
+ const $ = c(5);
157
+ const generated = useId();
158
+ let t0;
159
+ if ($[0] !== options) {
160
+ t0 = omitUndefined(options);
161
+ $[0] = options;
162
+ $[1] = t0;
163
+ } else t0 = $[1];
164
+ const t1 = options.id ?? generated;
165
+ let t2;
166
+ if ($[2] !== t0 || $[3] !== t1) {
167
+ t2 = {
168
+ ...t0,
169
+ id: t1
170
+ };
171
+ $[2] = t0;
172
+ $[3] = t1;
173
+ $[4] = t2;
174
+ } else t2 = $[4];
175
+ return collapsible.connect(useMachine(collapsible.machine, t2), normalizeProps);
176
+ }
177
+ /**
178
+ * Splits a branch's props into machine settings and element props.
179
+ *
180
+ * @remarks
181
+ * The key list comes from the machine's own `splitProps`, so it follows the installed version.
182
+ */
183
+ const splitBranchProps = splitEnumerable(collapsible.splitProps);
184
+ //#endregion
185
+ //#region src/nav-list/branch.tsx
186
+ /**
187
+ * Renders the branch `li` with the list's variants.
188
+ */
189
+ const Held$1 = withContext$3("li", "branch");
190
+ /**
191
+ * Renders the branch and provides the running machine to its trigger, indicator and content.
192
+ *
193
+ * @remarks
194
+ * Inside a search's scope, the branch registers the words it renders, its nested rows' words
195
+ * among them, and is hidden while the scope's query is not in them. While the scope has a query
196
+ * the branch is open, so a nested row that matches is visible, and a press on its trigger
197
+ * changes nothing. The branch keeps its own open state and passes the machine a boolean `open`
198
+ * at all times, so a cleared query returns the branch to the state it had before the query.
199
+ */
200
+ function Branch(props) {
201
+ const $ = c(25);
202
+ let t0;
203
+ if ($[0] !== props) {
204
+ t0 = splitBranchProps(props);
205
+ $[0] = props;
206
+ $[1] = t0;
207
+ } else t0 = $[1];
208
+ const [options, rest] = t0;
209
+ const searching = useFilterActive();
210
+ const { hidden, ref } = useFilteredRow();
211
+ const t1 = options.defaultOpen ?? false;
212
+ let t2;
213
+ if ($[2] !== options) {
214
+ t2 = (next) => {
215
+ options.onOpenChange?.({ open: next });
216
+ };
217
+ $[2] = options;
218
+ $[3] = t2;
219
+ } else t2 = $[3];
220
+ let t3;
221
+ if ($[4] !== options.open || $[5] !== t1 || $[6] !== t2) {
222
+ t3 = {
223
+ defaultValue: t1,
224
+ onChange: t2,
225
+ value: options.open
226
+ };
227
+ $[4] = options.open;
228
+ $[5] = t1;
229
+ $[6] = t2;
230
+ $[7] = t3;
231
+ } else t3 = $[7];
232
+ const [open, setOpen] = useControllableState(t3);
233
+ let t4;
234
+ if ($[8] !== searching || $[9] !== setOpen) {
235
+ t4 = (details) => {
236
+ if (!searching) setOpen(details.open);
237
+ };
238
+ $[8] = searching;
239
+ $[9] = setOpen;
240
+ $[10] = t4;
241
+ } else t4 = $[10];
242
+ const t5 = searching || open;
243
+ let t6;
244
+ if ($[11] !== options || $[12] !== t4 || $[13] !== t5) {
245
+ t6 = {
246
+ ...options,
247
+ onOpenChange: t4,
248
+ open: t5
249
+ };
250
+ $[11] = options;
251
+ $[12] = t4;
252
+ $[13] = t5;
253
+ $[14] = t6;
254
+ } else t6 = $[14];
255
+ const api = useBranchMachine(t6);
256
+ let t7;
257
+ if ($[15] !== api) {
258
+ t7 = api.getRootProps();
259
+ $[15] = api;
260
+ $[16] = t7;
261
+ } else t7 = $[16];
262
+ const t8 = hidden || rest.hidden === true;
263
+ let t9;
264
+ if ($[17] !== ref || $[18] !== rest || $[19] !== t7 || $[20] !== t8) {
265
+ t9 = /* @__PURE__ */ jsx(Held$1, {
266
+ ...rest,
267
+ ...t7,
268
+ hidden: t8,
269
+ ref
270
+ });
271
+ $[17] = ref;
272
+ $[18] = rest;
273
+ $[19] = t7;
274
+ $[20] = t8;
275
+ $[21] = t9;
276
+ } else t9 = $[21];
277
+ let t10;
278
+ if ($[22] !== api || $[23] !== t9) {
279
+ t10 = /* @__PURE__ */ jsx(BranchProvider, {
280
+ value: api,
281
+ children: t9
282
+ });
283
+ $[22] = api;
284
+ $[23] = t9;
285
+ $[24] = t10;
286
+ } else t10 = $[24];
287
+ return t10;
288
+ }
289
+ //#endregion
290
+ //#region src/nav-list/content.tsx
291
+ /**
292
+ * Renders the nested `ul` with the list's variants.
293
+ */
294
+ const Shown$1 = withContext$3("ul", "content");
295
+ /**
296
+ * Renders the nested list with the machine's content props merged under the caller's.
297
+ */
298
+ function Content$1(props) {
299
+ const $ = c(5);
300
+ const api = useBranch();
301
+ let t0;
302
+ if ($[0] !== api || $[1] !== props) {
303
+ t0 = mergeProps(api.getContentProps(), props);
304
+ $[0] = api;
305
+ $[1] = props;
306
+ $[2] = t0;
307
+ } else t0 = $[2];
308
+ let t1;
309
+ if ($[3] !== t0) {
310
+ t1 = /* @__PURE__ */ jsx(Shown$1, { ...t0 });
311
+ $[3] = t0;
312
+ $[4] = t1;
313
+ } else t1 = $[4];
314
+ return t1;
315
+ }
316
+ //#endregion
317
+ //#region src/nav-list/indicator.tsx
318
+ /**
319
+ * Renders the indicator `span`, hidden from assistive technology.
320
+ */
321
+ const Turned = withContext$3("span", "indicator", { defaultProps: { "aria-hidden": true } });
322
+ /**
323
+ * Renders the indicator with the machine's indicator props merged under the caller's.
324
+ */
325
+ function Indicator$2(props) {
326
+ const $ = c(5);
327
+ const api = useBranch();
328
+ let t0;
329
+ if ($[0] !== api || $[1] !== props) {
330
+ t0 = mergeProps(api.getIndicatorProps(), props);
331
+ $[0] = api;
332
+ $[1] = props;
333
+ $[2] = t0;
334
+ } else t0 = $[2];
335
+ let t1;
336
+ if ($[3] !== t0) {
337
+ t1 = /* @__PURE__ */ jsx(Turned, { ...t0 });
338
+ $[3] = t0;
339
+ $[4] = t1;
340
+ } else t1 = $[4];
341
+ return t1;
342
+ }
343
+ //#endregion
344
+ //#region src/nav-list/item.tsx
345
+ /**
346
+ * Renders the row `li` with the list's variants.
347
+ */
348
+ const Row = withContext$3("li", "item");
349
+ /**
350
+ * Renders the row, hidden while a search's query leaves it out.
351
+ *
352
+ * @param props - The `li` element's props.
353
+ * @returns The `li` element.
354
+ */
355
+ function Item$3(props) {
356
+ const $ = c(4);
357
+ const { hidden, ref } = useFilteredRow();
358
+ const t0 = hidden || props.hidden === true;
359
+ let t1;
360
+ if ($[0] !== props || $[1] !== ref || $[2] !== t0) {
361
+ t1 = /* @__PURE__ */ jsx(Row, {
362
+ ...props,
363
+ hidden: t0,
364
+ ref
365
+ });
366
+ $[0] = props;
367
+ $[1] = ref;
368
+ $[2] = t0;
369
+ $[3] = t1;
370
+ } else t1 = $[3];
371
+ return t1;
372
+ }
373
+ //#endregion
374
+ //#region src/nav-list/state.ts
375
+ /**
376
+ * Provides the defaults a list below a provider starts from, and the state a list gives its rows.
377
+ *
378
+ * @remarks
379
+ * A sidebar collapsed to a rail sets `iconic` once through the provider, and every list in it
380
+ * renders its rows as icons. A list's own prop overrides the provider. A row reads whether its
381
+ * list is iconic to decide whether it shows its tooltip.
382
+ */
383
+ /**
384
+ * Context through which a provider sets the defaults of the lists below it.
385
+ */
386
+ const DefaultsContext = createContext({});
387
+ /**
388
+ * Reads the defaults the nearest provider sets, or none outside a provider.
389
+ */
390
+ function useDefaults() {
391
+ return use(DefaultsContext);
392
+ }
393
+ /**
394
+ * Creates the context through which a list provides its state to its rows.
395
+ */
396
+ const [ListProvider, useList] = createRequiredContext("NavList");
397
+ //#endregion
398
+ //#region src/nav-list/tip.tsx
399
+ /**
400
+ * Renders an `a` element with the tooltip's trigger props.
401
+ *
402
+ * @param props - The props of an anchor.
403
+ * @returns The `a` element.
404
+ */
405
+ function Tip(props) {
406
+ const $ = c(2);
407
+ const t0 = props;
408
+ let t1;
409
+ if ($[0] !== t0) {
410
+ t1 = /* @__PURE__ */ jsx(Tooltip.Trigger, {
411
+ as: "a",
412
+ ...t0
413
+ });
414
+ $[0] = t0;
415
+ $[1] = t1;
416
+ } else t1 = $[1];
417
+ return t1;
418
+ }
419
+ //#endregion
420
+ //#region src/nav-list/link.tsx
421
+ /**
422
+ * Renders the link `a` with the list's variants.
423
+ */
424
+ const Anchored = withContext$3("a", "link");
425
+ /**
426
+ * Placement of the tooltip: beside the icon, towards the page.
427
+ */
428
+ const BESIDE = { placement: "right" };
429
+ /**
430
+ * Renders the link, as the trigger of its tooltip while the list is iconic.
431
+ *
432
+ * @param props - The tooltip and the props of an anchor.
433
+ * @returns The `a` element, inside the tooltip's root on an iconic list.
434
+ */
435
+ function Link$3(t0) {
436
+ const $ = c(12);
437
+ let rest;
438
+ let tooltip;
439
+ if ($[0] !== t0) {
440
+ ({tooltip, ...rest} = t0);
441
+ $[0] = t0;
442
+ $[1] = rest;
443
+ $[2] = tooltip;
444
+ } else {
445
+ rest = $[1];
446
+ tooltip = $[2];
447
+ }
448
+ const { iconic } = useList();
449
+ if (!iconic || tooltip === void 0) {
450
+ let t1;
451
+ if ($[3] !== rest) {
452
+ t1 = /* @__PURE__ */ jsx(Anchored, { ...rest });
453
+ $[3] = rest;
454
+ $[4] = t1;
455
+ } else t1 = $[4];
456
+ return t1;
457
+ }
458
+ let t1;
459
+ if ($[5] !== rest) {
460
+ t1 = /* @__PURE__ */ jsx(Anchored, {
461
+ as: Tip,
462
+ ...rest
463
+ });
464
+ $[5] = rest;
465
+ $[6] = t1;
466
+ } else t1 = $[6];
467
+ let t2;
468
+ if ($[7] !== tooltip) {
469
+ t2 = /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, { children: /* @__PURE__ */ jsx(Tooltip.Content, { children: tooltip }) }) });
470
+ $[7] = tooltip;
471
+ $[8] = t2;
472
+ } else t2 = $[8];
473
+ let t3;
474
+ if ($[9] !== t1 || $[10] !== t2) {
475
+ t3 = /* @__PURE__ */ jsxs(Tooltip.Root, {
476
+ positioning: BESIDE,
477
+ children: [t1, t2]
478
+ });
479
+ $[9] = t1;
480
+ $[10] = t2;
481
+ $[11] = t3;
482
+ } else t3 = $[11];
483
+ return t3;
484
+ }
485
+ //#endregion
486
+ //#region src/nav-list/mark.ts
487
+ /**
488
+ * Renders the mark `span` with the list's variants, hidden from assistive technology.
489
+ */
490
+ const Mark = withContext$3("span", "mark", { defaultProps: { "aria-hidden": true } });
491
+ //#endregion
492
+ //#region src/nav-list/props-provider.tsx
493
+ /**
494
+ * Renders the tree with the defaults in context.
495
+ *
496
+ * @param props - The defaults and the tree.
497
+ * @returns The tree inside the context.
498
+ */
499
+ function PropsProvider$1(t0) {
500
+ const $ = c(3);
501
+ const { children, value } = t0;
502
+ let t1;
503
+ if ($[0] !== children || $[1] !== value) {
504
+ t1 = /* @__PURE__ */ jsx(DefaultsContext, {
505
+ value,
506
+ children
507
+ });
508
+ $[0] = children;
509
+ $[1] = value;
510
+ $[2] = t1;
511
+ } else t1 = $[2];
512
+ return t1;
513
+ }
514
+ //#endregion
515
+ //#region src/nav-list/keys.ts
516
+ /**
517
+ * Selects the rows the arrow keys step through: links and branch triggers.
518
+ *
519
+ * @remarks
520
+ * The control beside a row is excluded. It acts on the row, and including it would add a second
521
+ * stop for every row that has one.
522
+ */
523
+ const ROWS = `.${CLASS}__link, .${CLASS}__trigger`;
524
+ /**
525
+ * Maps each arrow key to its step, before the writing direction is applied to the inline pair.
526
+ */
527
+ const STEPS = {
528
+ ArrowDown: 1,
529
+ ArrowLeft: -1,
530
+ ArrowRight: 1,
531
+ ArrowUp: -1
532
+ };
533
+ /**
534
+ * The arrow keys on the inline axis.
535
+ */
536
+ const ALONG_THE_LINE = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight"]);
537
+ /**
538
+ * Returns where a key moves focus, or `undefined` when the list does not handle the key.
539
+ *
540
+ * @param key - The `key` value of the keyboard event.
541
+ * @param along - Whether the rows run along the inline axis, as in the dock.
542
+ * @param forward - 1 in a left-to-right list and -1 in a right-to-left list.
543
+ */
544
+ function intentOf(key, along, forward) {
545
+ if (key === "Home") return "start";
546
+ if (key === "End") return "end";
547
+ const step = STEPS[key];
548
+ if (step === void 0 || ALONG_THE_LINE.has(key) !== along) return void 0;
549
+ return along ? step * forward : step;
550
+ }
551
+ /**
552
+ * Returns whether a row is visible.
553
+ *
554
+ * @remarks
555
+ * A row is hidden in two ways. A closed branch sets `hidden` on its nested list, an attribute on
556
+ * an ancestor. The iconic list removes nested lists from the layout, a computed style that no
557
+ * attribute reports.
558
+ */
559
+ function shown(row) {
560
+ return row.closest("[hidden]") === null && row.checkVisibility();
561
+ }
562
+ /**
563
+ * Returns the visible rows in document order.
564
+ */
565
+ function rowsOf(root) {
566
+ return [...root.querySelectorAll(ROWS)].filter((row) => shown(row));
567
+ }
568
+ /**
569
+ * Returns the row focus moves to, stopping at the first and last rows instead of wrapping.
570
+ *
571
+ * @remarks
572
+ * A person holding the down arrow to reach the end of a list does not expect to arrive back at
573
+ * the top.
574
+ */
575
+ function nextOf(rows, from, intent) {
576
+ if (intent === "start") return rows[0];
577
+ if (intent === "end") return rows.at(-1);
578
+ return rows[Math.min(rows.length - 1, Math.max(0, from + intent))];
579
+ }
580
+ /**
581
+ * Returns the list's key handler.
582
+ *
583
+ * @remarks
584
+ * The handler finds the current row from the focused element, not from the event target, because
585
+ * a key press can bubble up from an icon or a count inside the row.
586
+ * @param along - Whether the rows run along the inline axis, as in the `dock` variant.
587
+ * @returns The handler, which ignores every key the list does not handle.
588
+ */
589
+ function useRowKeys(along) {
590
+ const $ = c(2);
591
+ let t0;
592
+ if ($[0] !== along) {
593
+ t0 = (event) => {
594
+ if (event.defaultPrevented || event.ctrlKey || event.metaKey || event.altKey) return;
595
+ const root = event.currentTarget;
596
+ const direction = globalThis.getComputedStyle(root).direction;
597
+ const intent = intentOf(event.key, along, direction === "rtl" ? -1 : 1);
598
+ if (intent === void 0) return;
599
+ const rows = rowsOf(root);
600
+ const at = rows.findIndex((row) => row.contains(root.ownerDocument.activeElement));
601
+ if (at === -1) return;
602
+ nextOf(rows, at, intent)?.focus();
603
+ event.preventDefault();
604
+ };
605
+ $[0] = along;
606
+ $[1] = t0;
607
+ } else t0 = $[1];
608
+ return t0;
609
+ }
610
+ //#endregion
611
+ //#region src/nav-list/root.tsx
612
+ /**
613
+ * Renders the list `ul` and provides the variants to every part below it.
614
+ */
615
+ const Listed$1 = withProvider$3("ul", "root");
616
+ /**
617
+ * The variant whose rows run along the inline axis.
618
+ */
619
+ const DOCK = "dock";
620
+ /**
621
+ * Renders the list and handles the arrow keys that move focus between rows.
622
+ *
623
+ * @param props - The recipe's variants and the `ul` element's props.
624
+ * @returns The list.
625
+ */
626
+ function Root$3(t0) {
627
+ const $ = c(13);
628
+ const { iconic, size, ...rest } = t0;
629
+ const defaults = useDefaults();
630
+ const drawn = iconic ?? defaults.iconic ?? false;
631
+ const onKeyDown = useRowKeys(rest.variant === DOCK);
632
+ let t1;
633
+ if ($[0] !== drawn) {
634
+ t1 = { iconic: drawn };
635
+ $[0] = drawn;
636
+ $[1] = t1;
637
+ } else t1 = $[1];
638
+ const state = t1;
639
+ const T0 = ListProvider;
640
+ const T1 = Listed$1;
641
+ const t2 = mergeProps({ onKeyDown }, rest);
642
+ const t3 = size ?? defaults.size;
643
+ let t4;
644
+ if ($[2] !== t3) {
645
+ t4 = omitUndefined({ size: t3 });
646
+ $[2] = t3;
647
+ $[3] = t4;
648
+ } else t4 = $[3];
649
+ let t5;
650
+ if ($[4] !== T1 || $[5] !== drawn || $[6] !== t2 || $[7] !== t4) {
651
+ t5 = /* @__PURE__ */ jsx(T1, {
652
+ ...t2,
653
+ ...t4,
654
+ iconic: drawn
655
+ });
656
+ $[4] = T1;
657
+ $[5] = drawn;
658
+ $[6] = t2;
659
+ $[7] = t4;
660
+ $[8] = t5;
661
+ } else t5 = $[8];
662
+ let t6;
663
+ if ($[9] !== T0 || $[10] !== state || $[11] !== t5) {
664
+ t6 = /* @__PURE__ */ jsx(T0, {
665
+ value: state,
666
+ children: t5
667
+ });
668
+ $[9] = T0;
669
+ $[10] = state;
670
+ $[11] = t5;
671
+ $[12] = t6;
672
+ } else t6 = $[12];
673
+ return t6;
674
+ }
675
+ //#endregion
676
+ //#region src/nav-list/skeleton.ts
677
+ /**
678
+ * Renders the placeholder row `li` with the list's variants.
679
+ */
680
+ const Skeleton = withContext$3("li", "skeleton");
681
+ //#endregion
682
+ //#region src/nav-list/trigger.tsx
683
+ /**
684
+ * Renders the trigger `button` with the list's variants.
685
+ */
686
+ const Opened = withContext$3("button", "trigger");
687
+ /**
688
+ * Renders the trigger with the machine's trigger props merged under the caller's.
689
+ */
690
+ function Trigger$1(props) {
691
+ const $ = c(5);
692
+ const api = useBranch();
693
+ let t0;
694
+ if ($[0] !== api || $[1] !== props) {
695
+ t0 = mergeProps(api.getTriggerProps(), props);
696
+ $[0] = api;
697
+ $[1] = props;
698
+ $[2] = t0;
699
+ } else t0 = $[2];
700
+ let t1;
701
+ if ($[3] !== t0) {
702
+ t1 = /* @__PURE__ */ jsx(Opened, { ...t0 });
703
+ $[3] = t0;
704
+ $[4] = t1;
705
+ } else t1 = $[4];
706
+ return t1;
707
+ }
708
+ //#endregion
709
+ //#region src/nav-list/index.ts
710
+ var nav_list_exports = /* @__PURE__ */ __exportAll({
711
+ Action: () => Action,
712
+ Badge: () => Badge,
713
+ Branch: () => Branch,
714
+ Content: () => Content$1,
715
+ Indicator: () => Indicator$2,
716
+ Item: () => Item$3,
717
+ Link: () => Link$3,
718
+ Mark: () => Mark,
719
+ PropsProvider: () => PropsProvider$1,
720
+ Root: () => Root$3,
721
+ Skeleton: () => Skeleton,
722
+ Trigger: () => Trigger$1
723
+ });
724
+ //#endregion
725
+ //#region src/navigation-menu/context.ts
726
+ /**
727
+ * Binds the navigation menu recipe to React.
728
+ *
729
+ * @remarks
730
+ * The binding is a separate module because an application's compiler reads `recipe.ts` at build
731
+ * time and the binding needs the runtime. The behaviour is in `machine.ts`.
732
+ */
733
+ /**
734
+ * Binds the recipe once. The root receives the variants and every other part reads them.
735
+ */
736
+ const { withContext: withContext$2, withProvider: withProvider$2 } = createSlotRecipeContext(recipe$3);
737
+ //#endregion
738
+ //#region src/navigation-menu/machine.ts
739
+ /**
740
+ * Connects the navigation menu machine and provides its api to the parts.
741
+ *
742
+ * @remarks
743
+ * The root starts one machine and every part reads the api from context, so the triggers, the
744
+ * panels, the indicator and the viewport report one open item. The machine derives every
745
+ * element's ID from `id` and an item's `value`.
746
+ */
747
+ /**
748
+ * Provides the connected api to the parts, and reads it back.
749
+ *
750
+ * @remarks
751
+ * `useNavigationMenu` throws for a part rendered outside `NavigationMenu.Root`.
752
+ */
753
+ const [ApiProvider$1, useNavigationMenu] = createRequiredContext("NavigationMenu");
754
+ /**
755
+ * Starts the navigation menu machine and returns its connected api.
756
+ *
757
+ * @remarks
758
+ * The machine measures the open trigger and tracks Escape and presses outside the open panel
759
+ * when its value changes after mount, and never for the value it mounts with. The hook keeps the
760
+ * value, from `value` or `defaultValue`, and hands the machine an item open at mount from the
761
+ * render after the first commit, so the machine sees that item open as a change. `onValueChange`
762
+ * receives each change the machine makes, and never the value the menu mounts with.
763
+ * @param options - The machine options split from the root's props. React generates `id` when the
764
+ * caller states none.
765
+ * @returns The connected api.
766
+ */
767
+ function useNavigationMenuMachine(options) {
768
+ const $ = c(17);
769
+ const { defaultValue, onValueChange, value: stated, ...rest } = options;
770
+ const generated = useId();
771
+ const t0 = defaultValue ?? "";
772
+ let t1;
773
+ if ($[0] !== onValueChange) {
774
+ t1 = (next) => onValueChange?.({ value: next });
775
+ $[0] = onValueChange;
776
+ $[1] = t1;
777
+ } else t1 = $[1];
778
+ let t2;
779
+ if ($[2] !== stated || $[3] !== t0 || $[4] !== t1) {
780
+ t2 = {
781
+ defaultValue: t0,
782
+ onChange: t1,
783
+ value: stated
784
+ };
785
+ $[2] = stated;
786
+ $[3] = t0;
787
+ $[4] = t1;
788
+ $[5] = t2;
789
+ } else t2 = $[5];
790
+ const [value, setValue] = useControllableState(t2);
791
+ const [committed, setCommitted] = useState(value === "");
792
+ let t3;
793
+ let t4;
794
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
795
+ t3 = () => {
796
+ setCommitted(true);
797
+ };
798
+ t4 = [];
799
+ $[6] = t3;
800
+ $[7] = t4;
801
+ } else {
802
+ t3 = $[6];
803
+ t4 = $[7];
804
+ }
805
+ useEffect(t3, t4);
806
+ const t5 = omitUndefined(rest);
807
+ const t6 = rest.id ?? generated;
808
+ let t7;
809
+ if ($[8] !== setValue) {
810
+ t7 = (details) => {
811
+ setValue(details.value);
812
+ };
813
+ $[8] = setValue;
814
+ $[9] = t7;
815
+ } else t7 = $[9];
816
+ const t8 = committed ? value : "";
817
+ let t9;
818
+ if ($[10] !== t5 || $[11] !== t6 || $[12] !== t7 || $[13] !== t8) {
819
+ t9 = {
820
+ ...t5,
821
+ id: t6,
822
+ onValueChange: t7,
823
+ value: t8
824
+ };
825
+ $[10] = t5;
826
+ $[11] = t6;
827
+ $[12] = t7;
828
+ $[13] = t8;
829
+ $[14] = t9;
830
+ } else t9 = $[14];
831
+ const service = useMachine(navigationMenu.machine, t9);
832
+ let t10;
833
+ if ($[15] !== service) {
834
+ t10 = navigationMenu.connect(service, normalizeProps);
835
+ $[15] = service;
836
+ $[16] = t10;
837
+ } else t10 = $[16];
838
+ return t10;
839
+ }
840
+ /**
841
+ * Splits the root's props into the machine's options and the element's props, without
842
+ * `translations`.
843
+ *
844
+ * @remarks
845
+ * The key list comes from the machine's own `splitProps`, so it follows the installed machine.
846
+ * @typeParam Props - Type of the root's props.
847
+ * @param props - The root's props.
848
+ * @returns The machine options and the element props.
849
+ */
850
+ function splitNavigationMenuProps(props) {
851
+ const [options, rest] = splitEnumerable(navigationMenu.splitProps)(props);
852
+ const { translations: _translations, ...kept } = options;
853
+ return [kept, rest];
854
+ }
855
+ //#endregion
856
+ //#region src/navigation-menu/scopes.ts
857
+ /**
858
+ * Provides the item a part renders in, the viewport's alignment, and whether a panel closes once
859
+ * the pointer leaves it, to the parts that read them.
860
+ *
861
+ * @remarks
862
+ * A trigger, a panel and a link read the value of the item they belong to, and the viewport reads
863
+ * the alignment its positioner states. `useItem` throws for a part rendered outside an item.
864
+ */
865
+ /**
866
+ * Provides the item to the parts inside `NavigationMenu.Item`, and reads it back.
867
+ */
868
+ const [ItemProvider, useItem] = createRequiredContext("NavigationMenu.Item");
869
+ /**
870
+ * Carries the alignment `NavigationMenu.ViewportPositioner` states to the viewport inside it.
871
+ */
872
+ const Aligned = createContext(void 0);
873
+ /**
874
+ * Provides the positioner's alignment to the viewport.
875
+ */
876
+ const AlignProvider = Aligned.Provider;
877
+ /**
878
+ * Returns the alignment of the positioner around the calling part.
879
+ *
880
+ * @returns The alignment, or nothing outside a positioner.
881
+ */
882
+ function useAlign() {
883
+ return useContext(Aligned);
884
+ }
885
+ /**
886
+ * Carries whether a panel closes once the pointer leaves it.
887
+ */
888
+ const Leaving = createContext(true);
889
+ /**
890
+ * Provides whether a panel closes once the pointer leaves it to the panels, which the root sets
891
+ * from `disablePointerLeaveClose`.
892
+ */
893
+ const LeavingProvider = Leaving.Provider;
894
+ /**
895
+ * Returns whether a panel closes once the pointer leaves it.
896
+ *
897
+ * @returns False under a root with `disablePointerLeaveClose`, and true otherwise.
898
+ */
899
+ function useClosesOnLeave() {
900
+ return useContext(Leaving);
901
+ }
902
+ //#endregion
903
+ //#region src/navigation-menu/content.tsx
904
+ /**
905
+ * Renders the `div` with the navigation menu's content class.
906
+ */
907
+ const Drawn = withContext$2("div", "content");
908
+ /**
909
+ * Renders the panel with the machine's content props and the presence props merged over the
910
+ * caller's, inside the viewport while the menu renders one.
911
+ *
912
+ * @param props - The links and the props of a `div`.
913
+ * @returns The `div` element, or the two elements of the machine's beside a portal to the viewport.
914
+ */
915
+ function Content(props) {
916
+ const $ = c(32);
917
+ const api = useNavigationMenu();
918
+ const { value } = useItem();
919
+ const t0 = api.value === value;
920
+ let t1;
921
+ if ($[0] !== t0) {
922
+ t1 = { present: t0 };
923
+ $[0] = t0;
924
+ $[1] = t1;
925
+ } else t1 = $[1];
926
+ const { props: presented, setNode } = usePresence(t1);
927
+ const closes = useClosesOnLeave();
928
+ let T0;
929
+ let t2;
930
+ if ($[2] !== api || $[3] !== closes || $[4] !== presented || $[5] !== props || $[6] !== value) {
931
+ const machine = api.getContentProps({ value });
932
+ const { onPointerLeave: _leave, ...kept } = machine;
933
+ T0 = Drawn;
934
+ t2 = mergeProps(closes ? machine : kept, presented, props);
935
+ $[2] = api;
936
+ $[3] = closes;
937
+ $[4] = presented;
938
+ $[5] = props;
939
+ $[6] = value;
940
+ $[7] = T0;
941
+ $[8] = t2;
942
+ } else {
943
+ T0 = $[7];
944
+ t2 = $[8];
945
+ }
946
+ let t3;
947
+ if ($[9] !== T0 || $[10] !== setNode || $[11] !== t2) {
948
+ t3 = /* @__PURE__ */ jsx(T0, {
949
+ ...t2,
950
+ ref: setNode
951
+ });
952
+ $[9] = T0;
953
+ $[10] = setNode;
954
+ $[11] = t2;
955
+ $[12] = t3;
956
+ } else t3 = $[12];
957
+ const panel = t3;
958
+ let t4;
959
+ if ($[13] !== api) {
960
+ t4 = api.getViewportNode();
961
+ $[13] = api;
962
+ $[14] = t4;
963
+ } else t4 = $[14];
964
+ const viewport = t4;
965
+ if (!api.isViewportRendered || viewport === null) return panel;
966
+ let t5;
967
+ if ($[15] !== api || $[16] !== value) {
968
+ t5 = api.getViewportProxyProps({ value });
969
+ $[15] = api;
970
+ $[16] = value;
971
+ $[17] = t5;
972
+ } else t5 = $[17];
973
+ let t6;
974
+ if ($[18] !== t5) {
975
+ t6 = /* @__PURE__ */ jsx("div", { ...t5 });
976
+ $[18] = t5;
977
+ $[19] = t6;
978
+ } else t6 = $[19];
979
+ let t7;
980
+ if ($[20] !== api || $[21] !== value) {
981
+ t7 = api.getTriggerProxyProps({ value });
982
+ $[20] = api;
983
+ $[21] = value;
984
+ $[22] = t7;
985
+ } else t7 = $[22];
986
+ let t8;
987
+ if ($[23] !== t7) {
988
+ t8 = /* @__PURE__ */ jsx("div", { ...t7 });
989
+ $[23] = t7;
990
+ $[24] = t8;
991
+ } else t8 = $[24];
992
+ let t9;
993
+ if ($[25] !== panel || $[26] !== viewport) {
994
+ t9 = /* @__PURE__ */ jsx(Portal, {
995
+ container: viewport,
996
+ children: panel
997
+ });
998
+ $[25] = panel;
999
+ $[26] = viewport;
1000
+ $[27] = t9;
1001
+ } else t9 = $[27];
1002
+ let t10;
1003
+ if ($[28] !== t6 || $[29] !== t8 || $[30] !== t9) {
1004
+ t10 = /* @__PURE__ */ jsxs(Fragment, { children: [
1005
+ t6,
1006
+ t8,
1007
+ t9
1008
+ ] });
1009
+ $[28] = t6;
1010
+ $[29] = t8;
1011
+ $[30] = t9;
1012
+ $[31] = t10;
1013
+ } else t10 = $[31];
1014
+ return t10;
1015
+ }
1016
+ //#endregion
1017
+ //#region src/navigation-menu/indicator.tsx
1018
+ /**
1019
+ * Renders the `li` with the navigation menu's indicator class.
1020
+ */
1021
+ const Marked = withContext$2("li", "indicator");
1022
+ /**
1023
+ * Renders the indicator with the machine's indicator props and the presence props merged over the
1024
+ * caller's.
1025
+ *
1026
+ * @param props - The props of an `li`.
1027
+ * @returns The `li` element.
1028
+ */
1029
+ function Indicator$1(props) {
1030
+ const $ = c(9);
1031
+ const api = useNavigationMenu();
1032
+ let t0;
1033
+ if ($[0] !== api.open) {
1034
+ t0 = { present: api.open };
1035
+ $[0] = api.open;
1036
+ $[1] = t0;
1037
+ } else t0 = $[1];
1038
+ const { props: presented, setNode } = usePresence(t0);
1039
+ let t1;
1040
+ if ($[2] !== api || $[3] !== presented || $[4] !== props) {
1041
+ t1 = mergeProps(api.getIndicatorProps(), presented, props);
1042
+ $[2] = api;
1043
+ $[3] = presented;
1044
+ $[4] = props;
1045
+ $[5] = t1;
1046
+ } else t1 = $[5];
1047
+ let t2;
1048
+ if ($[6] !== setNode || $[7] !== t1) {
1049
+ t2 = /* @__PURE__ */ jsx(Marked, {
1050
+ ...t1,
1051
+ ref: setNode
1052
+ });
1053
+ $[6] = setNode;
1054
+ $[7] = t1;
1055
+ $[8] = t2;
1056
+ } else t2 = $[8];
1057
+ return t2;
1058
+ }
1059
+ //#endregion
1060
+ //#region src/navigation-menu/item.tsx
1061
+ /**
1062
+ * Renders the `li` with the navigation menu's item class.
1063
+ */
1064
+ const Held = withContext$2("li", "item");
1065
+ /**
1066
+ * Renders the item with the machine's item props, and provides the item to its parts.
1067
+ *
1068
+ * @param props - The value, the disabled state, the trigger and panel or the link, and the props of
1069
+ * an `li`.
1070
+ * @returns The `li` element.
1071
+ */
1072
+ function Item$2(t0) {
1073
+ const $ = c(3);
1074
+ const { disabled, value, ...props } = t0;
1075
+ const api = useNavigationMenu();
1076
+ const item = {
1077
+ ...omitUndefined({ disabled }),
1078
+ value
1079
+ };
1080
+ const T0 = Held;
1081
+ const t1 = mergeProps(api.getItemProps(item), props);
1082
+ let t2;
1083
+ if ($[0] !== T0 || $[1] !== t1) {
1084
+ t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
1085
+ $[0] = T0;
1086
+ $[1] = t1;
1087
+ $[2] = t2;
1088
+ } else t2 = $[2];
1089
+ return /* @__PURE__ */ jsx(ItemProvider, {
1090
+ value: item,
1091
+ children: t2
1092
+ });
1093
+ }
1094
+ //#endregion
1095
+ //#region src/navigation-menu/link.tsx
1096
+ /**
1097
+ * Renders the `a` with the navigation menu's link class.
1098
+ */
1099
+ const Linked = withContext$2("a", "link");
1100
+ /**
1101
+ * Runs on a press of a link whose caller passes no `onSelect`, so the machine registers a function
1102
+ * as the press's listener in every environment.
1103
+ */
1104
+ function selected() {}
1105
+ /**
1106
+ * Renders the link with the machine's link props for its item.
1107
+ *
1108
+ * @param props - Whether it is current, whether a press closes the menu, the press handler, the
1109
+ * words and the props of an `a`.
1110
+ * @returns The `a` element.
1111
+ */
1112
+ function Link$2(t0) {
1113
+ const $ = c(3);
1114
+ const { closeOnClick, current, onSelect: t1, ...props } = t0;
1115
+ const onSelect = t1 === void 0 ? selected : t1;
1116
+ const api = useNavigationMenu();
1117
+ const { value } = useItem();
1118
+ const T0 = Linked;
1119
+ const t2 = mergeProps(api.getLinkProps({
1120
+ ...omitUndefined({
1121
+ closeOnClick,
1122
+ current
1123
+ }),
1124
+ onSelect,
1125
+ value
1126
+ }), props);
1127
+ let t3;
1128
+ if ($[0] !== T0 || $[1] !== t2) {
1129
+ t3 = /* @__PURE__ */ jsx(T0, { ...t2 });
1130
+ $[0] = T0;
1131
+ $[1] = t2;
1132
+ $[2] = t3;
1133
+ } else t3 = $[2];
1134
+ return t3;
1135
+ }
1136
+ //#endregion
1137
+ //#region src/navigation-menu/list.tsx
1138
+ /**
1139
+ * Renders the `ul` with the navigation menu's list class.
84
1140
  */
85
- const Link = withContext("a");
1141
+ const Listed = withContext$2("ul", "list");
1142
+ /**
1143
+ * Renders the list with the machine's list props merged under the caller's.
1144
+ *
1145
+ * @param props - The items and the props of a `ul`.
1146
+ * @returns The `ul` element.
1147
+ */
1148
+ function List$1(props) {
1149
+ const $ = c(5);
1150
+ const t0 = useNavigationMenu();
1151
+ let t1;
1152
+ if ($[0] !== props || $[1] !== t0) {
1153
+ t1 = mergeProps(t0.getListProps(), props);
1154
+ $[0] = props;
1155
+ $[1] = t0;
1156
+ $[2] = t1;
1157
+ } else t1 = $[2];
1158
+ let t2;
1159
+ if ($[3] !== t1) {
1160
+ t2 = /* @__PURE__ */ jsx(Listed, { ...t1 });
1161
+ $[3] = t1;
1162
+ $[4] = t2;
1163
+ } else t2 = $[4];
1164
+ return t2;
1165
+ }
1166
+ //#endregion
1167
+ //#region src/navigation-menu/root.tsx
1168
+ /**
1169
+ * Renders the `nav` that provides the recipe's variants.
1170
+ */
1171
+ const Framed$1 = withProvider$2("nav", "root");
1172
+ /**
1173
+ * Renders the root and provides the machine's api to the parts.
1174
+ *
1175
+ * @param props - The machine's options, the recipe's variants and the props of a `nav`.
1176
+ * @returns The `nav` element inside the providers.
1177
+ */
1178
+ function Root$2(t0) {
1179
+ const $ = c(15);
1180
+ const { palette, size, ...props } = t0;
1181
+ const [options, rest] = splitNavigationMenuProps(props);
1182
+ const api = useNavigationMenuMachine(options);
1183
+ const T0 = ApiProvider$1;
1184
+ const T1 = LeavingProvider;
1185
+ const t1 = options.disablePointerLeaveClose !== true;
1186
+ const T2 = Framed$1;
1187
+ const t2 = mergeProps(api.getRootProps(), rest);
1188
+ let t3;
1189
+ if ($[0] !== palette || $[1] !== size) {
1190
+ t3 = omitUndefined({
1191
+ palette,
1192
+ size
1193
+ });
1194
+ $[0] = palette;
1195
+ $[1] = size;
1196
+ $[2] = t3;
1197
+ } else t3 = $[2];
1198
+ let t4;
1199
+ if ($[3] !== T2 || $[4] !== t2 || $[5] !== t3) {
1200
+ t4 = /* @__PURE__ */ jsx(T2, {
1201
+ ...t2,
1202
+ ...t3
1203
+ });
1204
+ $[3] = T2;
1205
+ $[4] = t2;
1206
+ $[5] = t3;
1207
+ $[6] = t4;
1208
+ } else t4 = $[6];
1209
+ let t5;
1210
+ if ($[7] !== T1 || $[8] !== t1 || $[9] !== t4) {
1211
+ t5 = /* @__PURE__ */ jsx(T1, {
1212
+ value: t1,
1213
+ children: t4
1214
+ });
1215
+ $[7] = T1;
1216
+ $[8] = t1;
1217
+ $[9] = t4;
1218
+ $[10] = t5;
1219
+ } else t5 = $[10];
1220
+ let t6;
1221
+ if ($[11] !== T0 || $[12] !== api || $[13] !== t5) {
1222
+ t6 = /* @__PURE__ */ jsx(T0, {
1223
+ value: api,
1224
+ children: t5
1225
+ });
1226
+ $[11] = T0;
1227
+ $[12] = api;
1228
+ $[13] = t5;
1229
+ $[14] = t6;
1230
+ } else t6 = $[14];
1231
+ return t6;
1232
+ }
1233
+ //#endregion
1234
+ //#region src/navigation-menu/trigger.tsx
1235
+ /**
1236
+ * Renders the `button` with the navigation menu's trigger class.
1237
+ */
1238
+ const Pressed = withContext$2("button", "trigger");
1239
+ /**
1240
+ * Renders the trigger with the machine's props for its item.
1241
+ *
1242
+ * @param props - The words, the glyph and the props of a `button`.
1243
+ * @returns The `button` element.
1244
+ */
1245
+ function Trigger(props) {
1246
+ const $ = c(2);
1247
+ const api = useNavigationMenu();
1248
+ const t0 = mergeProps(api.getTriggerProps(useItem()), props);
1249
+ let t1;
1250
+ if ($[0] !== t0) {
1251
+ t1 = /* @__PURE__ */ jsx(Pressed, { ...t0 });
1252
+ $[0] = t0;
1253
+ $[1] = t1;
1254
+ } else t1 = $[1];
1255
+ return t1;
1256
+ }
1257
+ //#endregion
1258
+ //#region src/navigation-menu/viewport-positioner.tsx
1259
+ /**
1260
+ * Renders the `div` with the navigation menu's viewport positioner class.
1261
+ */
1262
+ const Placed = withContext$2("div", "viewportPositioner");
1263
+ /**
1264
+ * Renders the positioner with the machine's props, and provides the alignment to the viewport.
1265
+ *
1266
+ * @param props - The alignment, the viewport and the props of a `div`.
1267
+ * @returns The `div` element.
1268
+ */
1269
+ function ViewportPositioner(t0) {
1270
+ const $ = c(7);
1271
+ const { align, ...props } = t0;
1272
+ const api = useNavigationMenu();
1273
+ const T0 = AlignProvider;
1274
+ const T1 = Placed;
1275
+ const t1 = mergeProps(api.getViewportPositionerProps(omitUndefined({ align })), props);
1276
+ let t2;
1277
+ if ($[0] !== T1 || $[1] !== t1) {
1278
+ t2 = /* @__PURE__ */ jsx(T1, { ...t1 });
1279
+ $[0] = T1;
1280
+ $[1] = t1;
1281
+ $[2] = t2;
1282
+ } else t2 = $[2];
1283
+ let t3;
1284
+ if ($[3] !== T0 || $[4] !== align || $[5] !== t2) {
1285
+ t3 = /* @__PURE__ */ jsx(T0, {
1286
+ value: align,
1287
+ children: t2
1288
+ });
1289
+ $[3] = T0;
1290
+ $[4] = align;
1291
+ $[5] = t2;
1292
+ $[6] = t3;
1293
+ } else t3 = $[6];
1294
+ return t3;
1295
+ }
1296
+ //#endregion
1297
+ //#region src/navigation-menu/viewport.tsx
1298
+ /**
1299
+ * Renders the `div` with the navigation menu's viewport class.
1300
+ */
1301
+ const Shown = withContext$2("div", "viewport");
1302
+ /**
1303
+ * Renders the viewport with the machine's viewport props and the presence props merged over the
1304
+ * caller's.
1305
+ *
1306
+ * @param props - The props of a `div`.
1307
+ * @returns The `div` element.
1308
+ */
1309
+ function Viewport(props) {
1310
+ const $ = c(5);
1311
+ const api = useNavigationMenu();
1312
+ let t0;
1313
+ if ($[0] !== api.open) {
1314
+ t0 = { present: api.open };
1315
+ $[0] = api.open;
1316
+ $[1] = t0;
1317
+ } else t0 = $[1];
1318
+ const { props: presented, setNode } = usePresence(t0);
1319
+ const t1 = mergeProps(api.getViewportProps(omitUndefined({ align: useAlign() })), presented, props);
1320
+ let t2;
1321
+ if ($[2] !== setNode || $[3] !== t1) {
1322
+ t2 = /* @__PURE__ */ jsx(Shown, {
1323
+ ...t1,
1324
+ ref: setNode
1325
+ });
1326
+ $[2] = setNode;
1327
+ $[3] = t1;
1328
+ $[4] = t2;
1329
+ } else t2 = $[4];
1330
+ return t2;
1331
+ }
1332
+ //#endregion
1333
+ //#region src/navigation-menu/index.ts
1334
+ var navigation_menu_exports = /* @__PURE__ */ __exportAll({
1335
+ Content: () => Content,
1336
+ Indicator: () => Indicator$1,
1337
+ Item: () => Item$2,
1338
+ Link: () => Link$2,
1339
+ List: () => List$1,
1340
+ Root: () => Root$2,
1341
+ Trigger: () => Trigger,
1342
+ Viewport: () => Viewport,
1343
+ ViewportPositioner: () => ViewportPositioner
1344
+ });
1345
+ //#endregion
1346
+ //#region src/pagination/context.ts
1347
+ /**
1348
+ * Binds the pagination's recipe to its parts.
1349
+ *
1350
+ * @remarks
1351
+ * The binding is apart from the recipe, because a compiler reads the recipe at build time and the
1352
+ * binding imports the runtime. It is apart from the machine, because the recipe styles a part and
1353
+ * the machine sets its behaviour.
1354
+ */
1355
+ /**
1356
+ * Binds the recipe once. The root provides the variants and every other part reads them.
1357
+ */
1358
+ const { withContext: withContext$1, withProvider: withProvider$1 } = createSlotRecipeContext(recipe$4);
1359
+ //#endregion
1360
+ //#region src/pagination/machine.ts
1361
+ /**
1362
+ * Connects the pagination machine and provides its api to the parts.
1363
+ *
1364
+ * @remarks
1365
+ * The root starts one machine and every part reads its api from context, so the pages, the
1366
+ * triggers and the page text report the same page. The machine counts pages from one.
1367
+ */
1368
+ /**
1369
+ * Creates the context through which the root provides the running machine to its parts.
1370
+ *
1371
+ * @remarks
1372
+ * `usePagination` throws when no `Pagination.Root` is mounted above the calling part.
1373
+ */
1374
+ const [MachineProvider, usePagination] = createRequiredContext("Pagination");
1375
+ /**
1376
+ * Starts the pagination machine and returns its connected api and the kind of its pages.
1377
+ *
1378
+ * @param options - Machine settings split from the root's props. React generates `id` when the
1379
+ * caller states none.
1380
+ */
1381
+ function usePaginationMachine(options) {
1382
+ const $ = c(10);
1383
+ const generated = useId();
1384
+ let t0;
1385
+ if ($[0] !== options) {
1386
+ t0 = omitUndefined(options);
1387
+ $[0] = options;
1388
+ $[1] = t0;
1389
+ } else t0 = $[1];
1390
+ const t1 = options.id ?? generated;
1391
+ let t2;
1392
+ if ($[2] !== t0 || $[3] !== t1) {
1393
+ t2 = {
1394
+ ...t0,
1395
+ id: t1
1396
+ };
1397
+ $[2] = t0;
1398
+ $[3] = t1;
1399
+ $[4] = t2;
1400
+ } else t2 = $[4];
1401
+ const service = useMachine(pagination.machine, t2);
1402
+ let t3;
1403
+ if ($[5] !== service) {
1404
+ t3 = pagination.connect(service, normalizeProps);
1405
+ $[5] = service;
1406
+ $[6] = t3;
1407
+ } else t3 = $[6];
1408
+ const t4 = options.type ?? "button";
1409
+ let t5;
1410
+ if ($[7] !== t3 || $[8] !== t4) {
1411
+ t5 = {
1412
+ api: t3,
1413
+ type: t4
1414
+ };
1415
+ $[7] = t3;
1416
+ $[8] = t4;
1417
+ $[9] = t5;
1418
+ } else t5 = $[9];
1419
+ return t5;
1420
+ }
1421
+ /**
1422
+ * Splits the root's props into machine settings and element props, without `translations`.
1423
+ *
1424
+ * @remarks
1425
+ * The key list comes from the machine's own `splitProps`, so it follows the installed version.
1426
+ * @typeParam Props - Type of the root's props.
1427
+ * @param props - The root's props.
1428
+ * @returns The machine settings and the element props.
1429
+ */
1430
+ function splitPaginationProps(props) {
1431
+ const [options, rest] = splitEnumerable(pagination.splitProps)(props);
1432
+ const { translations: _translations, ...kept } = options;
1433
+ return [kept, rest];
1434
+ }
1435
+ //#endregion
1436
+ //#region src/pagination/ellipsis.tsx
1437
+ /**
1438
+ * Renders the `span` with the pagination's ellipsis class.
1439
+ */
1440
+ const Gap = withContext$1("span", "ellipsis");
1441
+ /**
1442
+ * Renders the ellipsis with the machine's props merged over the caller's.
1443
+ *
1444
+ * @param props - The mark's index and the props of a `span`.
1445
+ * @returns The `span` element.
1446
+ */
1447
+ function Ellipsis(t0) {
1448
+ const $ = c(4);
1449
+ const { children, index, ...rest } = t0;
1450
+ const { api } = usePagination();
1451
+ const T0 = Gap;
1452
+ const t1 = mergeProps(api.getEllipsisProps({ index }), { "aria-hidden": true }, rest);
1453
+ const t2 = children ?? "…";
1454
+ let t3;
1455
+ if ($[0] !== T0 || $[1] !== t1 || $[2] !== t2) {
1456
+ t3 = /* @__PURE__ */ jsx(T0, {
1457
+ ...t1,
1458
+ children: t2
1459
+ });
1460
+ $[0] = T0;
1461
+ $[1] = t1;
1462
+ $[2] = t2;
1463
+ $[3] = t3;
1464
+ } else t3 = $[3];
1465
+ return t3;
1466
+ }
1467
+ //#endregion
1468
+ //#region src/pagination/anchor.tsx
1469
+ /**
1470
+ * Renders the button as an `a` without a `type`.
1471
+ *
1472
+ * @param props - The props of a `Button` and the address the link opens.
1473
+ * @returns The `a` element with the button's classes.
1474
+ */
1475
+ function Anchor(props) {
1476
+ const $ = c(2);
1477
+ let t0;
1478
+ if ($[0] !== props) {
1479
+ t0 = /* @__PURE__ */ jsx(Button, {
1480
+ ...props,
1481
+ as: "a"
1482
+ });
1483
+ $[0] = props;
1484
+ $[1] = t0;
1485
+ } else t0 = $[1];
1486
+ return t0;
1487
+ }
1488
+ //#endregion
1489
+ //#region src/pagination/bound.ts
1490
+ /**
1491
+ * Renders a page as the library's `Button` with the pagination's item class.
1492
+ */
1493
+ const PageButton = withContext$1(Button, "item");
1494
+ /**
1495
+ * Renders a page as the button's `a` with the pagination's item class.
1496
+ */
1497
+ const PageLink = withContext$1(Anchor, "item");
1498
+ /**
1499
+ * Renders a trigger as the library's `Button` with the pagination's trigger class.
1500
+ */
1501
+ const TriggerButton = withContext$1(Button, "trigger");
1502
+ /**
1503
+ * Renders a trigger as the button's `a` with the pagination's trigger class.
1504
+ */
1505
+ const TriggerLink = withContext$1(Anchor, "trigger");
1506
+ //#endregion
1507
+ //#region src/pagination/linked.ts
1508
+ /**
1509
+ * Returns a part's props as a link, without the machine's click handler.
1510
+ *
1511
+ * @remarks
1512
+ * A trigger at an end opens no page, so it keeps no address. It takes the link role and a tab
1513
+ * stop, because an `a` without `href` has neither, and the browser moves focus from an element it
1514
+ * cannot focus to the page's body.
1515
+ * @param props - The props the machine gives the part.
1516
+ * @param end - Whether the part is a trigger with no page to open.
1517
+ * @returns The part's props.
1518
+ */
1519
+ function linked({ href, onClick: _onClick, ...props }, end = false) {
1520
+ return end ? {
1521
+ ...props,
1522
+ role: "link",
1523
+ tabIndex: 0
1524
+ } : {
1525
+ ...props,
1526
+ href
1527
+ };
1528
+ }
1529
+ //#endregion
1530
+ //#region src/pagination/ended.ts
1531
+ /**
1532
+ * Returns a trigger's props with `aria-disabled` in place of `disabled` at an end, as a link when
1533
+ * the machine's pages are links.
1534
+ *
1535
+ * @param props - The props the machine gives the trigger.
1536
+ * @param end - Whether the trigger has no page to move to.
1537
+ * @param type - Whether the machine's pages are buttons or links.
1538
+ * @returns The trigger's props.
1539
+ */
1540
+ function ended(props, end, type) {
1541
+ const marked = {
1542
+ ...props,
1543
+ "aria-disabled": end ? true : void 0,
1544
+ disabled: void 0
1545
+ };
1546
+ return type === "link" ? linked(marked, end) : marked;
1547
+ }
1548
+ //#endregion
1549
+ //#region src/pagination/first-trigger.tsx
1550
+ /**
1551
+ * Renders the first trigger with the machine's props merged over the caller's.
1552
+ *
1553
+ * @param props - The trigger's name and the props of a `Button`.
1554
+ * @returns The `button` element, or an `a` for links.
1555
+ */
1556
+ function FirstTrigger(t0) {
1557
+ const $ = c(4);
1558
+ const { label: t1, ...rest } = t0;
1559
+ const label = t1 === void 0 ? "First page" : t1;
1560
+ const { api, type } = usePagination();
1561
+ const Pressed = type === "link" ? TriggerLink : TriggerButton;
1562
+ const props = ended(api.getFirstTriggerProps(), api.page <= 1, type);
1563
+ const t2 = mergeProps(props, rest);
1564
+ let t3;
1565
+ if ($[0] !== Pressed || $[1] !== label || $[2] !== t2) {
1566
+ t3 = /* @__PURE__ */ jsx(Pressed, {
1567
+ ...t2,
1568
+ "aria-label": label,
1569
+ shape: "square"
1570
+ });
1571
+ $[0] = Pressed;
1572
+ $[1] = label;
1573
+ $[2] = t2;
1574
+ $[3] = t3;
1575
+ } else t3 = $[3];
1576
+ return t3;
1577
+ }
1578
+ //#endregion
1579
+ //#region src/pagination/item.tsx
1580
+ /**
1581
+ * Renders a page with the machine's item props merged over the caller's.
1582
+ *
1583
+ * @param props - The page's number and name and the props of a `Button`.
1584
+ * @returns The `button` element, or an `a` for links.
1585
+ */
1586
+ function Item$1(t0) {
1587
+ const $ = c(5);
1588
+ const { children, label, value, ...rest } = t0;
1589
+ const { api, type } = usePagination();
1590
+ const Paged = type === "link" ? PageLink : PageButton;
1591
+ const item = api.getItemProps({
1592
+ type: "page",
1593
+ value
1594
+ });
1595
+ const t1 = mergeProps(type === "link" ? linked(item) : item, rest);
1596
+ const t2 = label ?? `Page ${value}`;
1597
+ const t3 = children ?? value;
1598
+ let t4;
1599
+ if ($[0] !== Paged || $[1] !== t1 || $[2] !== t2 || $[3] !== t3) {
1600
+ t4 = /* @__PURE__ */ jsx(Paged, {
1601
+ ...t1,
1602
+ "aria-label": t2,
1603
+ shape: "square",
1604
+ children: t3
1605
+ });
1606
+ $[0] = Paged;
1607
+ $[1] = t1;
1608
+ $[2] = t2;
1609
+ $[3] = t3;
1610
+ $[4] = t4;
1611
+ } else t4 = $[4];
1612
+ return t4;
1613
+ }
1614
+ //#endregion
1615
+ //#region src/pagination/wording.ts
1616
+ /**
1617
+ * Returns the text for the current page in the format given.
1618
+ *
1619
+ * @remarks
1620
+ * `compact` gives "Page 12 of 24", `short` "12 / 24" and `long` the range of items, "111–120 of
1621
+ * 240". A count of zero has no pages, which the formats word as "Page 0 of 0", "0 / 0" and "0–0
1622
+ * of 0". A function receives the four details alone, whatever else the object passed in contains,
1623
+ * and returns the words in any language.
1624
+ * @param details - Where the reader is among the pages, such as the machine's api.
1625
+ * @param format - The format, or the function that words the details.
1626
+ * @returns The text.
1627
+ */
1628
+ function worded({ count, page, pageRange, totalPages }, format) {
1629
+ if (typeof format === "function") return format({
1630
+ count,
1631
+ page,
1632
+ pageRange,
1633
+ totalPages
1634
+ });
1635
+ const shown = Math.min(page, totalPages);
1636
+ const first = count === 0 ? 0 : pageRange.start + 1;
1637
+ return {
1638
+ compact: `Page ${shown} of ${totalPages}`,
1639
+ long: `${first}–${pageRange.end} of ${count}`,
1640
+ short: `${shown} / ${totalPages}`
1641
+ }[format];
1642
+ }
1643
+ //#endregion
1644
+ //#region src/pagination/items.tsx
1645
+ /**
1646
+ * Renders the `output` with the pagination's summary class.
1647
+ */
1648
+ const Summary = withContext$1("output", "summary");
1649
+ /**
1650
+ * Pairs every entry of the machine's list with a key: the page's number, or for a mark the number
1651
+ * of the page before it, because the list always opens on a page.
1652
+ *
1653
+ * @param pages - The machine's list of pages and marks.
1654
+ * @returns Each entry with its key, in order.
1655
+ */
1656
+ function keyed(pages) {
1657
+ let before = 0;
1658
+ return pages.map((page) => {
1659
+ if (page.type === "ellipsis") return [`after-${before}`, page];
1660
+ before = page.value;
1661
+ return [`page-${page.value}`, page];
1662
+ });
1663
+ }
1664
+ /**
1665
+ * Renders the pages, the marks between them and the summary.
1666
+ *
1667
+ * @param props - The function that names a page and the summary's format.
1668
+ * @returns The items in the machine's order, then the summary.
1669
+ */
1670
+ function Items(t0) {
1671
+ const $ = c(13);
1672
+ const { label, summary: t1 } = t0;
1673
+ const summary = t1 === void 0 ? "compact" : t1;
1674
+ const { api } = usePagination();
1675
+ let t2;
1676
+ if ($[0] !== api.pages || $[1] !== label) {
1677
+ let t3;
1678
+ if ($[3] !== label) {
1679
+ t3 = (t4, index) => {
1680
+ const [key, page] = t4;
1681
+ return page.type === "page" ? /* @__PURE__ */ jsx(Item$1, {
1682
+ label: label?.(page.value),
1683
+ value: page.value
1684
+ }, key) : /* @__PURE__ */ jsx(Ellipsis, { index }, key);
1685
+ };
1686
+ $[3] = label;
1687
+ $[4] = t3;
1688
+ } else t3 = $[4];
1689
+ t2 = keyed(api.pages).map(t3);
1690
+ $[0] = api.pages;
1691
+ $[1] = label;
1692
+ $[2] = t2;
1693
+ } else t2 = $[2];
1694
+ let t3;
1695
+ if ($[5] !== api || $[6] !== summary) {
1696
+ t3 = worded(api, summary);
1697
+ $[5] = api;
1698
+ $[6] = summary;
1699
+ $[7] = t3;
1700
+ } else t3 = $[7];
1701
+ let t4;
1702
+ if ($[8] !== t3) {
1703
+ t4 = /* @__PURE__ */ jsx(Summary, { children: t3 });
1704
+ $[8] = t3;
1705
+ $[9] = t4;
1706
+ } else t4 = $[9];
1707
+ let t5;
1708
+ if ($[10] !== t2 || $[11] !== t4) {
1709
+ t5 = /* @__PURE__ */ jsxs(Fragment, { children: [t2, t4] });
1710
+ $[10] = t2;
1711
+ $[11] = t4;
1712
+ $[12] = t5;
1713
+ } else t5 = $[12];
1714
+ return t5;
1715
+ }
1716
+ //#endregion
1717
+ //#region src/pagination/last-trigger.tsx
1718
+ /**
1719
+ * Renders the last trigger with the machine's props merged over the caller's.
1720
+ *
1721
+ * @param props - The trigger's name and the props of a `Button`.
1722
+ * @returns The `button` element, or an `a` for links.
1723
+ */
1724
+ function LastTrigger(t0) {
1725
+ const $ = c(4);
1726
+ const { label: t1, ...rest } = t0;
1727
+ const label = t1 === void 0 ? "Last page" : t1;
1728
+ const { api, type } = usePagination();
1729
+ const Pressed = type === "link" ? TriggerLink : TriggerButton;
1730
+ const props = ended(api.getLastTriggerProps(), api.page >= api.totalPages, type);
1731
+ const t2 = mergeProps(props, rest);
1732
+ let t3;
1733
+ if ($[0] !== Pressed || $[1] !== label || $[2] !== t2) {
1734
+ t3 = /* @__PURE__ */ jsx(Pressed, {
1735
+ ...t2,
1736
+ "aria-label": label,
1737
+ shape: "square"
1738
+ });
1739
+ $[0] = Pressed;
1740
+ $[1] = label;
1741
+ $[2] = t2;
1742
+ $[3] = t3;
1743
+ } else t3 = $[3];
1744
+ return t3;
1745
+ }
1746
+ //#endregion
1747
+ //#region src/pagination/next-trigger.tsx
1748
+ /**
1749
+ * Renders the next trigger with the machine's props merged over the caller's.
1750
+ *
1751
+ * @param props - The trigger's name and the props of a `Button`.
1752
+ * @returns The `button` element, or an `a` for links.
1753
+ */
1754
+ function NextTrigger(t0) {
1755
+ const $ = c(4);
1756
+ const { label: t1, ...rest } = t0;
1757
+ const label = t1 === void 0 ? "Next page" : t1;
1758
+ const { api, type } = usePagination();
1759
+ const Pressed = type === "link" ? TriggerLink : TriggerButton;
1760
+ const props = ended(api.getNextTriggerProps(), api.page >= api.totalPages, type);
1761
+ const t2 = mergeProps(props, rest);
1762
+ let t3;
1763
+ if ($[0] !== Pressed || $[1] !== label || $[2] !== t2) {
1764
+ t3 = /* @__PURE__ */ jsx(Pressed, {
1765
+ ...t2,
1766
+ "aria-label": label,
1767
+ shape: "square"
1768
+ });
1769
+ $[0] = Pressed;
1770
+ $[1] = label;
1771
+ $[2] = t2;
1772
+ $[3] = t3;
1773
+ } else t3 = $[3];
1774
+ return t3;
1775
+ }
1776
+ //#endregion
1777
+ //#region src/pagination/page-text.tsx
1778
+ /**
1779
+ * Renders the `output` with the pagination's page text class.
1780
+ */
1781
+ const Stated = withContext$1("output", "pageText");
1782
+ /**
1783
+ * Renders the text for the current page.
1784
+ *
1785
+ * @param props - The format and the props of an `output`.
1786
+ * @returns The `output` element.
1787
+ */
1788
+ function PageText(t0) {
1789
+ const $ = c(9);
1790
+ let rest;
1791
+ let t1;
1792
+ if ($[0] !== t0) {
1793
+ ({format: t1, ...rest} = t0);
1794
+ $[0] = t0;
1795
+ $[1] = rest;
1796
+ $[2] = t1;
1797
+ } else {
1798
+ rest = $[1];
1799
+ t1 = $[2];
1800
+ }
1801
+ const format = t1 === void 0 ? "compact" : t1;
1802
+ const { api } = usePagination();
1803
+ let t2;
1804
+ if ($[3] !== api || $[4] !== format) {
1805
+ t2 = worded(api, format);
1806
+ $[3] = api;
1807
+ $[4] = format;
1808
+ $[5] = t2;
1809
+ } else t2 = $[5];
1810
+ let t3;
1811
+ if ($[6] !== rest || $[7] !== t2) {
1812
+ t3 = /* @__PURE__ */ jsx(Stated, {
1813
+ ...rest,
1814
+ children: t2
1815
+ });
1816
+ $[6] = rest;
1817
+ $[7] = t2;
1818
+ $[8] = t3;
1819
+ } else t3 = $[8];
1820
+ return t3;
1821
+ }
1822
+ //#endregion
1823
+ //#region src/pagination/prev-trigger.tsx
1824
+ /**
1825
+ * Renders the previous trigger with the machine's props merged over the caller's.
1826
+ *
1827
+ * @param props - The trigger's name and the props of a `Button`.
1828
+ * @returns The `button` element, or an `a` for links.
1829
+ */
1830
+ function PrevTrigger(t0) {
1831
+ const $ = c(4);
1832
+ const { label: t1, ...rest } = t0;
1833
+ const label = t1 === void 0 ? "Previous page" : t1;
1834
+ const { api, type } = usePagination();
1835
+ const Pressed = type === "link" ? TriggerLink : TriggerButton;
1836
+ const props = ended(api.getPrevTriggerProps(), api.page <= 1, type);
1837
+ const t2 = mergeProps(props, rest);
1838
+ let t3;
1839
+ if ($[0] !== Pressed || $[1] !== label || $[2] !== t2) {
1840
+ t3 = /* @__PURE__ */ jsx(Pressed, {
1841
+ ...t2,
1842
+ "aria-label": label,
1843
+ shape: "square"
1844
+ });
1845
+ $[0] = Pressed;
1846
+ $[1] = label;
1847
+ $[2] = t2;
1848
+ $[3] = t3;
1849
+ } else t3 = $[3];
1850
+ return t3;
1851
+ }
1852
+ //#endregion
1853
+ //#region src/pagination/root.tsx
1854
+ /**
1855
+ * Renders the `nav` that provides the recipe's variants.
1856
+ */
1857
+ const Framed = withProvider$1("nav", "root");
1858
+ /**
1859
+ * Renders the root, passes the buttons' variants down, and provides the running machine to the
1860
+ * parts.
1861
+ *
1862
+ * @param props - The machine's options, the buttons' look and palette, the recipe's variants and
1863
+ * the props of a `nav`.
1864
+ * @returns The `nav` element inside the providers.
1865
+ */
1866
+ function Root$1(t0) {
1867
+ const $ = c(21);
1868
+ const { "aria-label": t1, palette, size, variant: t2, ...props } = t0;
1869
+ const label = t1 === void 0 ? "Pagination" : t1;
1870
+ const variant = t2 === void 0 ? "ghost" : t2;
1871
+ const [options, rest] = splitPaginationProps(props);
1872
+ const machine = usePaginationMachine(options);
1873
+ const [crowded, ref] = useCrowded();
1874
+ const T0 = MachineProvider;
1875
+ const T1 = ButtonPropsProvider;
1876
+ let t3;
1877
+ if ($[0] !== palette || $[1] !== size || $[2] !== variant) {
1878
+ t3 = omitUndefined({
1879
+ palette,
1880
+ size,
1881
+ variant
1882
+ });
1883
+ $[0] = palette;
1884
+ $[1] = size;
1885
+ $[2] = variant;
1886
+ $[3] = t3;
1887
+ } else t3 = $[3];
1888
+ const T2 = Framed;
1889
+ const t4 = mergeProps(machine.api.getRootProps(), rest);
1890
+ const t5 = crowded ? "" : void 0;
1891
+ let t6;
1892
+ if ($[4] !== size) {
1893
+ t6 = omitUndefined({ size });
1894
+ $[4] = size;
1895
+ $[5] = t6;
1896
+ } else t6 = $[5];
1897
+ let t7;
1898
+ if ($[6] !== T2 || $[7] !== label || $[8] !== ref || $[9] !== t4 || $[10] !== t5 || $[11] !== t6) {
1899
+ t7 = /* @__PURE__ */ jsx(T2, {
1900
+ ...t4,
1901
+ "aria-label": label,
1902
+ "data-crowded": t5,
1903
+ ref,
1904
+ ...t6
1905
+ });
1906
+ $[6] = T2;
1907
+ $[7] = label;
1908
+ $[8] = ref;
1909
+ $[9] = t4;
1910
+ $[10] = t5;
1911
+ $[11] = t6;
1912
+ $[12] = t7;
1913
+ } else t7 = $[12];
1914
+ let t8;
1915
+ if ($[13] !== T1 || $[14] !== t3 || $[15] !== t7) {
1916
+ t8 = /* @__PURE__ */ jsx(T1, {
1917
+ value: t3,
1918
+ children: t7
1919
+ });
1920
+ $[13] = T1;
1921
+ $[14] = t3;
1922
+ $[15] = t7;
1923
+ $[16] = t8;
1924
+ } else t8 = $[16];
1925
+ let t9;
1926
+ if ($[17] !== T0 || $[18] !== machine || $[19] !== t8) {
1927
+ t9 = /* @__PURE__ */ jsx(T0, {
1928
+ value: machine,
1929
+ children: t8
1930
+ });
1931
+ $[17] = T0;
1932
+ $[18] = machine;
1933
+ $[19] = t8;
1934
+ $[20] = t9;
1935
+ } else t9 = $[20];
1936
+ return t9;
1937
+ }
1938
+ //#endregion
1939
+ //#region src/pagination/index.ts
1940
+ var pagination_exports = /* @__PURE__ */ __exportAll({
1941
+ Ellipsis: () => Ellipsis,
1942
+ FirstTrigger: () => FirstTrigger,
1943
+ Item: () => Item$1,
1944
+ Items: () => Items,
1945
+ LastTrigger: () => LastTrigger,
1946
+ NextTrigger: () => NextTrigger,
1947
+ PageText: () => PageText,
1948
+ PrevTrigger: () => PrevTrigger,
1949
+ Root: () => Root$1
1950
+ });
1951
+ //#endregion
1952
+ //#region src/toc/context.ts
1953
+ /**
1954
+ * Binds the table of contents slot recipe to React.
1955
+ *
1956
+ * @remarks
1957
+ * The binding is a separate module from the recipe, because an application's compiler imports the
1958
+ * recipe at build time and the binding needs the React runtime. It is separate from the machine,
1959
+ * because the recipe sets the styles and the machine sets the state.
1960
+ */
1961
+ /**
1962
+ * Factories for the parts. The root resolves the variants once and the other parts read them.
1963
+ */
1964
+ const { withContext, withProvider } = createSlotRecipeContext(recipe$5);
1965
+ //#endregion
1966
+ //#region src/toc/reveal.ts
1967
+ /**
1968
+ * Scrolls the scroller a table of contents is in until its active row is in view, and leaves the
1969
+ * page that contains the headings where the reader put it.
1970
+ */
1971
+ /**
1972
+ * Lists the values of `overflow-y` under which an element scrolls.
1973
+ */
1974
+ const SCROLLING = /* @__PURE__ */ new Set(["auto", "scroll"]);
1975
+ /**
1976
+ * Returns the nearest ancestor of an element that scrolls vertically, or null where none does.
1977
+ *
1978
+ * @param element - The element inside the scroller.
1979
+ */
1980
+ function scrollerOf(element) {
1981
+ for (let at = element.parentElement; at !== null; at = at.parentElement) if (at.scrollHeight > at.clientHeight && SCROLLING.has(getComputedStyle(at).overflowY)) return at;
1982
+ return null;
1983
+ }
1984
+ /**
1985
+ * Scrolls the nearest scroller around a row until the row is inside it, by the least distance.
1986
+ *
1987
+ * @remarks
1988
+ * A scroller that also contains the heading the row names is the page's, which the reader moves,
1989
+ * and the function leaves it alone. A list under the page's body would otherwise pull the page
1990
+ * down to itself whenever the reader passed a heading. A list in a sticky aside scrolls on its
1991
+ * own, and the row is revealed there. The row's own `scrollIntoView` scrolls every scroller
1992
+ * around it, the page's included.
1993
+ * @param row - The active row.
1994
+ * @param heading - The heading the row names, or null where the document has none.
1995
+ * @param behavior - How the scroller moves, as `scrollBehavior` states it. The browser's default
1996
+ * where it is left out.
1997
+ */
1998
+ function revealRow(row, heading, behavior) {
1999
+ const view = scrollerOf(row);
2000
+ if (view === null || view.contains(heading)) return;
2001
+ const at = row.getBoundingClientRect();
2002
+ const box = view.getBoundingClientRect();
2003
+ view.scrollBy({
2004
+ ...omitUndefined({ behavior }),
2005
+ top: Math.max(0, at.bottom - box.bottom) - Math.max(0, box.top - at.top)
2006
+ });
2007
+ }
2008
+ //#endregion
2009
+ //#region src/toc/machine.ts
2010
+ /**
2011
+ * Connects the table of contents machine and provides its api to the parts.
2012
+ *
2013
+ * @remarks
2014
+ * The machine observes the listed headings with an `IntersectionObserver`, tracks the ids of the
2015
+ * visible ones, and measures their items to position the indicator. The root starts one machine
2016
+ * and every part reads its api from context. The machine derives the title's id from `id`, and
2017
+ * the landmark references that id.
2018
+ */
2019
+ /**
2020
+ * Creates the context through which the root provides the connected api to its parts.
2021
+ *
2022
+ * @remarks
2023
+ * `useToc` throws when no `Toc.Root` is mounted above the calling part.
2024
+ */
2025
+ const [ApiProvider, useToc] = createRequiredContext("Toc");
2026
+ /**
2027
+ * Splits the root's props into machine settings and element props.
2028
+ *
2029
+ * @remarks
2030
+ * The key list comes from the machine's own `splitProps`, so it follows the installed version.
2031
+ */
2032
+ const splitTocProps = splitEnumerable(toc.splitProps);
2033
+ /**
2034
+ * Runs the table of contents machine with a reveal that scrolls the list's own scroller alone.
2035
+ *
2036
+ * @remarks
2037
+ * The machine reveals the active row with the row's own `scrollIntoView`, which also scrolls the
2038
+ * page, and a list stacked under the page's body would pull the page down to itself whenever a
2039
+ * heading becomes active. The override finds the row by the id the machine gives it, the
2040
+ * caller's `ids.item` or `toc:<id>:item-<value>`, and `revealRow` scrolls the nearest scroller
2041
+ * that does not also contain the headings.
2042
+ */
2043
+ const MACHINE = {
2044
+ ...toc.machine,
2045
+ implementations: {
2046
+ ...toc.machine.implementations,
2047
+ actions: {
2048
+ ...toc.machine.implementations?.actions,
2049
+ autoScrollToc: ({ context, prop, scope }) => {
2050
+ const [active] = context.get("activeIds");
2051
+ if (active === void 0 || !prop("autoScroll")) return;
2052
+ const row = scope.getById(prop("ids")?.item?.(active) ?? `toc:${prop("id")}:item-${active}`);
2053
+ if (row !== null) revealRow(row, scope.getById(active), prop("scrollBehavior"));
2054
+ }
2055
+ }
2056
+ }
2057
+ };
2058
+ /**
2059
+ * Starts the table of contents machine and returns its connected api.
2060
+ *
2061
+ * @param options - Machine settings split from the root's props. A generated id is used when `id`
2062
+ * is absent.
2063
+ */
2064
+ function useTocMachine(options) {
2065
+ const $ = c(5);
2066
+ const generated = useId();
2067
+ let t0;
2068
+ if ($[0] !== options) {
2069
+ t0 = omitUndefined(options);
2070
+ $[0] = options;
2071
+ $[1] = t0;
2072
+ } else t0 = $[1];
2073
+ const t1 = options.id ?? generated;
2074
+ let t2;
2075
+ if ($[2] !== t0 || $[3] !== t1) {
2076
+ t2 = {
2077
+ ...t0,
2078
+ id: t1
2079
+ };
2080
+ $[2] = t0;
2081
+ $[3] = t1;
2082
+ $[4] = t2;
2083
+ } else t2 = $[4];
2084
+ return toc.connect(useMachine(MACHINE, t2), normalizeProps);
2085
+ }
2086
+ //#endregion
2087
+ //#region src/toc/indicator.tsx
2088
+ /**
2089
+ * List item with the indicator slot classes.
2090
+ */
2091
+ const Styled$4 = withContext("li", "indicator");
2092
+ /**
2093
+ * Renders a list item positioned over the active rows, hidden from the accessibility tree.
2094
+ */
2095
+ function Indicator(props) {
2096
+ const $ = c(5);
2097
+ const api = useToc();
2098
+ let t0;
2099
+ if ($[0] !== api || $[1] !== props) {
2100
+ t0 = mergeProps({ "aria-hidden": true }, api.getIndicatorProps(), props);
2101
+ $[0] = api;
2102
+ $[1] = props;
2103
+ $[2] = t0;
2104
+ } else t0 = $[2];
2105
+ let t1;
2106
+ if ($[3] !== t0) {
2107
+ t1 = /* @__PURE__ */ jsx(Styled$4, { ...t0 });
2108
+ $[3] = t0;
2109
+ $[4] = t1;
2110
+ } else t1 = $[4];
2111
+ return t1;
2112
+ }
2113
+ //#endregion
2114
+ //#region src/toc/item.tsx
2115
+ /**
2116
+ * List item with the item slot classes.
2117
+ */
2118
+ const Styled$3 = withContext("li", "item");
2119
+ /**
2120
+ * Renders a list item with the depth and active state of its heading.
2121
+ */
2122
+ function Item(t0) {
2123
+ const $ = c(3);
2124
+ const { item, ...rest } = t0;
2125
+ const api = useToc();
2126
+ const T0 = Styled$3;
2127
+ const t1 = mergeProps(api.getItemProps({ item }), rest);
2128
+ let t2;
2129
+ if ($[0] !== T0 || $[1] !== t1) {
2130
+ t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
2131
+ $[0] = T0;
2132
+ $[1] = t1;
2133
+ $[2] = t2;
2134
+ } else t2 = $[2];
2135
+ return t2;
2136
+ }
2137
+ //#endregion
2138
+ //#region src/toc/link.tsx
2139
+ /**
2140
+ * Anchor with the link slot classes.
2141
+ */
2142
+ const Styled$2 = withContext("a", "link");
2143
+ /**
2144
+ * Renders an anchor that sets `aria-current` while its heading is visible.
2145
+ */
2146
+ function Link$1(t0) {
2147
+ const $ = c(3);
2148
+ const { item, ...rest } = t0;
2149
+ const api = useToc();
2150
+ const T0 = Styled$2;
2151
+ const t1 = mergeProps(api.getLinkProps({ item }), rest);
2152
+ let t2;
2153
+ if ($[0] !== T0 || $[1] !== t1) {
2154
+ t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
2155
+ $[0] = T0;
2156
+ $[1] = t1;
2157
+ $[2] = t2;
2158
+ } else t2 = $[2];
2159
+ return t2;
2160
+ }
2161
+ //#endregion
2162
+ //#region src/toc/list.tsx
2163
+ /**
2164
+ * Unordered list with the list slot classes.
2165
+ */
2166
+ const Styled$1 = withContext("ul", "list");
2167
+ /**
2168
+ * Renders an unordered list with the ID the machine measures the rows against.
2169
+ */
2170
+ function List(props) {
2171
+ const $ = c(5);
2172
+ const api = useToc();
2173
+ let t0;
2174
+ if ($[0] !== api || $[1] !== props) {
2175
+ t0 = mergeProps(api.getListProps(), props);
2176
+ $[0] = api;
2177
+ $[1] = props;
2178
+ $[2] = t0;
2179
+ } else t0 = $[2];
2180
+ let t1;
2181
+ if ($[3] !== t0) {
2182
+ t1 = /* @__PURE__ */ jsx(Styled$1, { ...t0 });
2183
+ $[3] = t0;
2184
+ $[4] = t1;
2185
+ } else t1 = $[4];
2186
+ return t1;
2187
+ }
2188
+ //#endregion
2189
+ //#region src/toc/root.tsx
2190
+ /**
2191
+ * Nav element that provides the recipe's variants to the parts.
2192
+ */
2193
+ const Landmark = withProvider("nav", "root");
2194
+ /**
2195
+ * Renders the scroll area's root with the recipe's class, which leaves the focus ring room.
2196
+ */
2197
+ const Scroller = withContext(ScrollArea.Root, "scroller");
2198
+ /**
2199
+ * Renders the scroll area's content with the recipe's class, a padded column of the children.
2200
+ */
2201
+ const Column = withContext(ScrollArea.Content, "content");
2202
+ /**
2203
+ * Renders a `nav` that runs the machine and provides its api to the parts, around a scroll area
2204
+ * in the aside placement.
2205
+ */
2206
+ function Root(props) {
2207
+ const $ = c(17);
2208
+ let t0;
2209
+ if ($[0] !== props) {
2210
+ t0 = splitTocProps(props);
2211
+ $[0] = props;
2212
+ $[1] = t0;
2213
+ } else t0 = $[1];
2214
+ const [options, t1] = t0;
2215
+ let children;
2216
+ let rest;
2217
+ if ($[2] !== t1) {
2218
+ ({children, ...rest} = t1);
2219
+ $[2] = t1;
2220
+ $[3] = children;
2221
+ $[4] = rest;
2222
+ } else {
2223
+ children = $[3];
2224
+ rest = $[4];
2225
+ }
2226
+ const api = useTocMachine(options);
2227
+ let t2;
2228
+ if ($[5] !== api) {
2229
+ t2 = api.getRootProps();
2230
+ $[5] = api;
2231
+ $[6] = t2;
2232
+ } else t2 = $[6];
2233
+ let t3;
2234
+ if ($[7] !== children || $[8] !== rest.placement) {
2235
+ t3 = rest.placement === "aside" ? /* @__PURE__ */ jsxs(Scroller, { children: [/* @__PURE__ */ jsx(ScrollArea.Viewport, {
2236
+ focusable: false,
2237
+ children: /* @__PURE__ */ jsx(Column, { children })
2238
+ }), /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {})] }) : children;
2239
+ $[7] = children;
2240
+ $[8] = rest.placement;
2241
+ $[9] = t3;
2242
+ } else t3 = $[9];
2243
+ let t4;
2244
+ if ($[10] !== rest || $[11] !== t2 || $[12] !== t3) {
2245
+ t4 = /* @__PURE__ */ jsx(Landmark, {
2246
+ ...rest,
2247
+ ...t2,
2248
+ children: t3
2249
+ });
2250
+ $[10] = rest;
2251
+ $[11] = t2;
2252
+ $[12] = t3;
2253
+ $[13] = t4;
2254
+ } else t4 = $[13];
2255
+ let t5;
2256
+ if ($[14] !== api || $[15] !== t4) {
2257
+ t5 = /* @__PURE__ */ jsx(ApiProvider, {
2258
+ value: api,
2259
+ children: t4
2260
+ });
2261
+ $[14] = api;
2262
+ $[15] = t4;
2263
+ $[16] = t5;
2264
+ } else t5 = $[16];
2265
+ return t5;
2266
+ }
2267
+ //#endregion
2268
+ //#region src/toc/title.tsx
2269
+ /**
2270
+ * Div with the title slot classes.
2271
+ */
2272
+ const Styled = withContext("div", "title");
2273
+ /**
2274
+ * Renders a div with the ID the root's `aria-labelledby` references.
2275
+ */
2276
+ function Title(props) {
2277
+ const $ = c(5);
2278
+ const api = useToc();
2279
+ let t0;
2280
+ if ($[0] !== api || $[1] !== props) {
2281
+ t0 = mergeProps(api.getTitleProps(), props);
2282
+ $[0] = api;
2283
+ $[1] = props;
2284
+ $[2] = t0;
2285
+ } else t0 = $[2];
2286
+ let t1;
2287
+ if ($[3] !== t0) {
2288
+ t1 = /* @__PURE__ */ jsx(Styled, { ...t0 });
2289
+ $[3] = t0;
2290
+ $[4] = t1;
2291
+ } else t1 = $[4];
2292
+ return t1;
2293
+ }
2294
+ //#endregion
2295
+ //#region src/toc/index.ts
2296
+ var toc_exports = /* @__PURE__ */ __exportAll({
2297
+ Indicator: () => Indicator,
2298
+ Item: () => Item,
2299
+ Link: () => Link$1,
2300
+ List: () => List,
2301
+ Root: () => Root,
2302
+ Title: () => Title
2303
+ });
86
2304
  //#endregion
87
- export { breadcrumb_exports as Breadcrumb, Link, PropsProvider as LinkPropsProvider };
2305
+ export { breadcrumb_exports as Breadcrumb, Link, PropsProvider as LinkPropsProvider, nav_list_exports as NavList, navigation_menu_exports as NavigationMenu, pagination_exports as Pagination, toc_exports as Toc };