@stealthscale/component-media 0.1.0 → 0.2.2

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,1890 +1,2 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { a as recipe$3, c as recipe, n as recipe$5, o as recipe$2, r as recipe$4, s as recipe$1, t as recipe$6 } from "./recipe-m4bX2c06.js";
3
- import { c } from "react/compiler-runtime";
4
- import { createRecipeContext, createSlotRecipeContext } from "@stealthscale/theme";
5
- import { Fragment, jsx } from "react/jsx-runtime";
6
- import { createContext, use, useEffect, useId, useState, useSyncExternalStore } from "react";
7
- import { createRequiredContext, omitUndefined, splitEnumerable, useSafeLayoutEffect } from "@stealthscale/hooks";
8
- import { mergeProps, normalizeProps, useMachine } from "@zag-js/react";
9
- import * as avatar from "@zag-js/avatar";
10
- import { createSplitProps, noop } from "@zag-js/utils";
11
- import * as carousel from "@zag-js/carousel";
12
- import { Button } from "@stealthscale/component-actions";
13
- import { getEventKey } from "@zag-js/dom-query";
14
- import * as imageCropper from "@zag-js/image-cropper";
15
- import { handles } from "@zag-js/image-cropper";
16
- //#region src/audio/context.ts
17
- /**
18
- * Binds the audio recipe to the element that renders it.
19
- *
20
- * @remarks
21
- * The binding is kept out of `recipe.ts` because an application's style compiler imports the
22
- * recipe at build time, and a binding there would pull the React runtime into that import.
23
- */
24
- /**
25
- * Supplies the element factory the audio component is built from.
26
- */
27
- const { withContext: withContext$5 } = createRecipeContext(recipe);
28
- //#endregion
29
- //#region src/audio/audio.tsx
30
- /**
31
- * Renders the `audio` element with the recipe's class.
32
- */
33
- const Drawn$13 = withContext$5("audio");
34
- /**
35
- * Renders the element with the browser's controls unless the caller turns them off.
36
- *
37
- * @param props - The props of an `audio` element.
38
- * @returns The `audio` element.
39
- */
40
- function Audio(t0) {
41
- const $ = c(6);
42
- let rest;
43
- let t1;
44
- if ($[0] !== t0) {
45
- ({controls: t1, ...rest} = t0);
46
- $[0] = t0;
47
- $[1] = rest;
48
- $[2] = t1;
49
- } else {
50
- rest = $[1];
51
- t1 = $[2];
52
- }
53
- const controls = t1 === void 0 ? true : t1;
54
- let t2;
55
- if ($[3] !== controls || $[4] !== rest) {
56
- t2 = /* @__PURE__ */ jsx(Drawn$13, {
57
- ...rest,
58
- controls
59
- });
60
- $[3] = controls;
61
- $[4] = rest;
62
- $[5] = t2;
63
- } else t2 = $[5];
64
- return t2;
65
- }
66
- //#endregion
67
- //#region src/avatar/context.ts
68
- /**
69
- * Binds the avatar slot recipe and the badge recipe to the elements that render them.
70
- *
71
- * @remarks
72
- * The bindings are kept out of the recipe modules because an application's style compiler
73
- * imports the recipes at build time, and a binding there would pull the React runtime into that
74
- * import.
75
- */
76
- /**
77
- * Factories that bind an element to a slot: `withProvider` for the root and the group, which take
78
- * the variants, and `withContext` for the image and the fallback, which read them.
79
- */
80
- const { withContext: withContext$4, withProvider: withProvider$2 } = createSlotRecipeContext(recipe$1);
81
- /**
82
- * Binds the badge's element, which takes the badge recipe's variants as props.
83
- */
84
- const { withContext: withBadgeContext } = createRecipeContext(recipe$2);
85
- //#endregion
86
- //#region src/avatar/state.ts
87
- /**
88
- * Provides the name an avatar's fallback reads, the variants a group gives its avatars, and the
89
- * setter through which a badge describes its avatar.
90
- */
91
- /**
92
- * Context through which the root provides its `name` to the fallback.
93
- */
94
- const NameContext = createContext(void 0);
95
- /**
96
- * Context through which a group provides its variants to the avatars in it.
97
- */
98
- const DefaultsContext = createContext(void 0);
99
- /**
100
- * Context through which the root provides the setter of the IDs that describe it.
101
- */
102
- const DescribeContext = createContext(void 0);
103
- /**
104
- * Returns the name of the avatar around the caller.
105
- *
106
- * @returns The root's `name`, or undefined when the root has none.
107
- */
108
- function useAvatarName() {
109
- return use(NameContext);
110
- }
111
- /**
112
- * Returns the variants of the group around the caller.
113
- *
114
- * @returns The group's variants, or an empty object outside a group.
115
- */
116
- function useDefaults() {
117
- return use(DefaultsContext) ?? {};
118
- }
119
- /**
120
- * Returns the setter of the IDs that describe the avatar around the caller.
121
- *
122
- * @returns The root's setter, or undefined outside a root.
123
- */
124
- function useDescribe() {
125
- return use(DescribeContext);
126
- }
127
- //#endregion
128
- //#region src/avatar/badge.tsx
129
- /**
130
- * Renders a mark pinned to a corner of the avatar: a status dot, a count, an emoji or an icon.
131
- *
132
- * @remarks
133
- * The badge goes inside `Avatar.Root`, which it is positioned against. Without children it is a
134
- * dot. With `label` it is an image named by the label, and its ID joins the root's
135
- * `aria-describedby`, because a root named by `name` is an image whose children are not read.
136
- * Without `label` it is hidden from screen readers, for a state already written beside the
137
- * avatar. `palette`, `placement` and `variant` are the badge's own, apart from the avatar's.
138
- */
139
- /**
140
- * Renders the badge `span` with the badge recipe's variants.
141
- */
142
- const Marked = withBadgeContext("span");
143
- /**
144
- * Renders the badge, named by `label` and describing the avatar around it.
145
- *
146
- * @param props - The label, the variants and the `span` element's props.
147
- * @returns The `span` element.
148
- */
149
- function Badge(t0) {
150
- const $ = c(14);
151
- let label;
152
- let rest;
153
- if ($[0] !== t0) {
154
- ({label, ...rest} = t0);
155
- $[0] = t0;
156
- $[1] = label;
157
- $[2] = rest;
158
- } else {
159
- label = $[1];
160
- rest = $[2];
161
- }
162
- const id = useId();
163
- const describe = useDescribe();
164
- let t1;
165
- let t2;
166
- if ($[3] !== describe || $[4] !== id || $[5] !== label) {
167
- t1 = () => {
168
- const described = label === void 0 ? void 0 : describe;
169
- described?.((ids) => [...ids, id]);
170
- return () => {
171
- described?.((ids_0) => ids_0.filter((each) => each !== id));
172
- };
173
- };
174
- t2 = [
175
- describe,
176
- id,
177
- label
178
- ];
179
- $[3] = describe;
180
- $[4] = id;
181
- $[5] = label;
182
- $[6] = t1;
183
- $[7] = t2;
184
- } else {
185
- t1 = $[6];
186
- t2 = $[7];
187
- }
188
- useSafeLayoutEffect(t1, t2);
189
- let t3;
190
- if ($[8] !== id || $[9] !== label) {
191
- t3 = label === void 0 ? { "aria-hidden": true } : {
192
- "aria-label": label,
193
- id,
194
- role: "img"
195
- };
196
- $[8] = id;
197
- $[9] = label;
198
- $[10] = t3;
199
- } else t3 = $[10];
200
- let t4;
201
- if ($[11] !== rest || $[12] !== t3) {
202
- t4 = /* @__PURE__ */ jsx(Marked, {
203
- ...t3,
204
- ...rest
205
- });
206
- $[11] = rest;
207
- $[12] = t3;
208
- $[13] = t4;
209
- } else t4 = $[13];
210
- return t4;
211
- }
212
- //#endregion
213
- //#region src/avatar/initials.ts
214
- /**
215
- * Derives the initials an avatar's fallback shows from a name.
216
- */
217
- /**
218
- * Splits a word into its user-perceived characters.
219
- */
220
- const LETTERS = new Intl.Segmenter(void 0, { granularity: "grapheme" });
221
- /**
222
- * Returns the first user-perceived character of a word.
223
- */
224
- function firstLetter(word) {
225
- return Array.from(LETTERS.segment(word), (part) => part.segment).slice(0, 1).join("");
226
- }
227
- /**
228
- * Returns the initials of a name: the first letter of its first word and of its last word.
229
- *
230
- * @remarks
231
- * A letter is a grapheme cluster, so a name that opens on a composed or accented letter keeps it
232
- * whole. A name of one word returns one letter, and a blank name returns an empty string. The
233
- * recipe sets the initials in capitals.
234
- * @param name - The name, as the root received it.
235
- * @returns Zero, one or two letters.
236
- */
237
- function initialsOf(name) {
238
- const words = name.split(/\s+/u).filter((word) => word !== "");
239
- return [...words.slice(0, 1), ...words.slice(1).slice(-1)].map((word) => firstLetter(word)).join("");
240
- }
241
- //#endregion
242
- //#region src/avatar/machine.ts
243
- /**
244
- * Connects the Zag avatar machine and provides its API to the image and the fallback.
245
- *
246
- * @remarks
247
- * The machine starts in `loading` and moves to `loaded` when the image loads or to `error` when
248
- * it fails. The image is hidden until it loads, and the fallback is hidden only once it has, so
249
- * an avatar without an image shows its fallback.
250
- */
251
- /**
252
- * Context through which the root provides the connected API to its parts.
253
- *
254
- * @remarks
255
- * `useAvatar` throws when no `Avatar.Root` is mounted above the calling part.
256
- */
257
- const [ApiProvider$1, useAvatar] = createRequiredContext("Avatar");
258
- /**
259
- * Starts the avatar machine and returns its connected API.
260
- *
261
- * @param options - Machine settings split from the root's props. A generated ID is used when `id`
262
- * is absent.
263
- */
264
- function useAvatarMachine(options) {
265
- const $ = c(5);
266
- const generated = useId();
267
- let t0;
268
- if ($[0] !== options) {
269
- t0 = omitUndefined(options);
270
- $[0] = options;
271
- $[1] = t0;
272
- } else t0 = $[1];
273
- const t1 = options.id ?? generated;
274
- let t2;
275
- if ($[2] !== t0 || $[3] !== t1) {
276
- t2 = {
277
- ...t0,
278
- id: t1
279
- };
280
- $[2] = t0;
281
- $[3] = t1;
282
- $[4] = t2;
283
- } else t2 = $[4];
284
- return avatar.connect(useMachine(avatar.machine, t2), normalizeProps);
285
- }
286
- /**
287
- * Splits the root's props into machine settings and element props.
288
- *
289
- * @remarks
290
- * The machine's own splitter types `id` as required, and the root generates the ID after
291
- * splitting, so the splitter is rebuilt over `AvatarOptions` from the machine's key list.
292
- */
293
- const splitAvatarProps = splitEnumerable(createSplitProps(avatar.props));
294
- //#endregion
295
- //#region src/avatar/fallback.tsx
296
- /**
297
- * Renders the fallback `span`.
298
- */
299
- const Lettered = withContext$4("span", "fallback");
300
- /**
301
- * Renders the children, or the initials of the root's name.
302
- *
303
- * @param props - The `span` element's props.
304
- * @returns The `span` element, hidden once the picture loads.
305
- */
306
- function Fallback(t0) {
307
- const $ = c(7);
308
- const { children, ...rest } = t0;
309
- const api = useAvatar();
310
- const name = useAvatarName();
311
- const T0 = Lettered;
312
- const t1 = mergeProps(api.getFallbackProps(), rest);
313
- let t2;
314
- if ($[0] !== children || $[1] !== name) {
315
- t2 = children ?? initialsOf(name ?? "");
316
- $[0] = children;
317
- $[1] = name;
318
- $[2] = t2;
319
- } else t2 = $[2];
320
- let t3;
321
- if ($[3] !== T0 || $[4] !== t1 || $[5] !== t2) {
322
- t3 = /* @__PURE__ */ jsx(T0, {
323
- ...t1,
324
- children: t2
325
- });
326
- $[3] = T0;
327
- $[4] = t1;
328
- $[5] = t2;
329
- $[6] = t3;
330
- } else t3 = $[6];
331
- return t3;
332
- }
333
- //#endregion
334
- //#region src/avatar/group.tsx
335
- /**
336
- * Renders the group `span`.
337
- */
338
- const Grouped = withProvider$2("span", "group");
339
- /**
340
- * Renders the row and provides its variants to the avatars in it.
341
- *
342
- * @param props - The variants and the `span` element's props.
343
- * @returns The `span` element.
344
- */
345
- function Group(t0) {
346
- const $ = c(16);
347
- let palette;
348
- let rest;
349
- let shape;
350
- let size;
351
- let variant;
352
- if ($[0] !== t0) {
353
- ({palette, shape, size, variant, ...rest} = t0);
354
- $[0] = t0;
355
- $[1] = palette;
356
- $[2] = rest;
357
- $[3] = shape;
358
- $[4] = size;
359
- $[5] = variant;
360
- } else {
361
- palette = $[1];
362
- rest = $[2];
363
- shape = $[3];
364
- size = $[4];
365
- variant = $[5];
366
- }
367
- let t1;
368
- if ($[6] !== palette || $[7] !== shape || $[8] !== size || $[9] !== variant) {
369
- t1 = omitUndefined({
370
- palette,
371
- shape,
372
- size,
373
- variant
374
- });
375
- $[6] = palette;
376
- $[7] = shape;
377
- $[8] = size;
378
- $[9] = variant;
379
- $[10] = t1;
380
- } else t1 = $[10];
381
- let t2;
382
- if ($[11] !== rest) {
383
- t2 = /* @__PURE__ */ jsx(Grouped, { ...rest });
384
- $[11] = rest;
385
- $[12] = t2;
386
- } else t2 = $[12];
387
- let t3;
388
- if ($[13] !== t1 || $[14] !== t2) {
389
- t3 = /* @__PURE__ */ jsx(DefaultsContext, {
390
- value: t1,
391
- children: t2
392
- });
393
- $[13] = t1;
394
- $[14] = t2;
395
- $[15] = t3;
396
- } else t3 = $[15];
397
- return t3;
398
- }
399
- //#endregion
400
- //#region src/avatar/image.tsx
401
- /**
402
- * Renders the picture `img`.
403
- */
404
- const Pictured = withContext$4("img", "image");
405
- /**
406
- * Renders the picture with the machine's load handlers merged under the caller's.
407
- *
408
- * @param props - The `img` element's props.
409
- * @returns The `img` element, hidden until it loads.
410
- */
411
- function Image$1(t0) {
412
- const $ = c(3);
413
- const { alt: t1, ...rest } = t0;
414
- const alt = t1 === void 0 ? "" : t1;
415
- const api = useAvatar();
416
- const T0 = Pictured;
417
- const t2 = mergeProps(api.getImageProps(), {
418
- alt,
419
- draggable: false,
420
- referrerPolicy: "no-referrer",
421
- ...rest
422
- });
423
- let t3;
424
- if ($[0] !== T0 || $[1] !== t2) {
425
- t3 = /* @__PURE__ */ jsx(T0, { ...t2 });
426
- $[0] = T0;
427
- $[1] = t2;
428
- $[2] = t3;
429
- } else t3 = $[2];
430
- return t3;
431
- }
432
- //#endregion
433
- //#region src/avatar/root.tsx
434
- /**
435
- * Renders the avatar's box and runs the machine that tracks its picture.
436
- *
437
- * @remarks
438
- * The element is a `span`, so an avatar fits in a line of text or a table cell. With `name`, the
439
- * root is an image named by that name, `role="img"` with `aria-label`, and the fallback shows its
440
- * initials. Without `name`, the root has no role, and the caller names the avatar through the
441
- * image's `alt`. Beside the same name in words, set `aria-hidden` on the root, so a screen reader
442
- * reads the name once. `palette`, `shape`, `size` and `variant` default to the nearest
443
- * `Avatar.Group`. A badge with a label adds its ID to the root's `aria-describedby`, because the
444
- * children of an image are not read.
445
- */
446
- /**
447
- * Renders the root `span` and provides the variants to the image and the fallback.
448
- */
449
- const Boxed = withProvider$2("span", "root");
450
- /**
451
- * Renders the box, named by `name` when one is passed.
452
- *
453
- * @param props - The machine settings, the name, the recipe's variants and the `span` props.
454
- * @returns The `span` element, with the connected API in context.
455
- */
456
- function Root$2(props) {
457
- const $ = c(33);
458
- let t0;
459
- if ($[0] !== props) {
460
- t0 = splitAvatarProps(props);
461
- $[0] = props;
462
- $[1] = t0;
463
- } else t0 = $[1];
464
- const [options, t1] = t0;
465
- let name;
466
- let palette;
467
- let rest;
468
- let shape;
469
- let size;
470
- let variant;
471
- if ($[2] !== t1) {
472
- ({name, palette, shape, size, variant, ...rest} = t1);
473
- $[2] = t1;
474
- $[3] = name;
475
- $[4] = palette;
476
- $[5] = rest;
477
- $[6] = shape;
478
- $[7] = size;
479
- $[8] = variant;
480
- } else {
481
- name = $[3];
482
- palette = $[4];
483
- rest = $[5];
484
- shape = $[6];
485
- size = $[7];
486
- variant = $[8];
487
- }
488
- const api = useAvatarMachine(options);
489
- const defaults = useDefaults();
490
- let t2;
491
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
492
- t2 = [];
493
- $[9] = t2;
494
- } else t2 = $[9];
495
- const [described, setDescribed] = useState(t2);
496
- let t3;
497
- if ($[10] !== name) {
498
- t3 = name === void 0 ? {} : {
499
- "aria-label": name,
500
- role: "img"
501
- };
502
- $[10] = name;
503
- $[11] = t3;
504
- } else t3 = $[11];
505
- let t4;
506
- if ($[12] !== described) {
507
- t4 = described.length === 0 ? {} : { "aria-describedby": described.join(" ") };
508
- $[12] = described;
509
- $[13] = t4;
510
- } else t4 = $[13];
511
- const t5 = palette ?? defaults.palette;
512
- const t6 = shape ?? defaults.shape;
513
- const t7 = size ?? defaults.size;
514
- const t8 = variant ?? defaults.variant;
515
- let t9;
516
- if ($[14] !== t5 || $[15] !== t6 || $[16] !== t7 || $[17] !== t8) {
517
- t9 = omitUndefined({
518
- palette: t5,
519
- shape: t6,
520
- size: t7,
521
- variant: t8
522
- });
523
- $[14] = t5;
524
- $[15] = t6;
525
- $[16] = t7;
526
- $[17] = t8;
527
- $[18] = t9;
528
- } else t9 = $[18];
529
- let t10;
530
- if ($[19] !== api) {
531
- t10 = api.getRootProps();
532
- $[19] = api;
533
- $[20] = t10;
534
- } else t10 = $[20];
535
- let t11;
536
- if ($[21] !== rest || $[22] !== t10 || $[23] !== t3 || $[24] !== t4 || $[25] !== t9) {
537
- t11 = /* @__PURE__ */ jsx(DescribeContext, {
538
- value: setDescribed,
539
- children: /* @__PURE__ */ jsx(Boxed, {
540
- ...t3,
541
- ...t4,
542
- ...rest,
543
- ...t9,
544
- ...t10
545
- })
546
- });
547
- $[21] = rest;
548
- $[22] = t10;
549
- $[23] = t3;
550
- $[24] = t4;
551
- $[25] = t9;
552
- $[26] = t11;
553
- } else t11 = $[26];
554
- let t12;
555
- if ($[27] !== name || $[28] !== t11) {
556
- t12 = /* @__PURE__ */ jsx(NameContext, {
557
- value: name,
558
- children: t11
559
- });
560
- $[27] = name;
561
- $[28] = t11;
562
- $[29] = t12;
563
- } else t12 = $[29];
564
- let t13;
565
- if ($[30] !== api || $[31] !== t12) {
566
- t13 = /* @__PURE__ */ jsx(ApiProvider$1, {
567
- value: api,
568
- children: t12
569
- });
570
- $[30] = api;
571
- $[31] = t12;
572
- $[32] = t13;
573
- } else t13 = $[32];
574
- return t13;
575
- }
576
- //#endregion
577
- //#region src/avatar/index.ts
578
- var avatar_exports = /* @__PURE__ */ __exportAll({
579
- Badge: () => Badge,
580
- Fallback: () => Fallback,
581
- Group: () => Group,
582
- Image: () => Image$1,
583
- Root: () => Root$2
584
- });
585
- //#endregion
586
- //#region src/carousel/machine.ts
587
- /**
588
- * Connects the carousel machine and provides it to the parts, with the rotation and the reader's
589
- * motion setting.
590
- *
591
- * @remarks
592
- * The root starts one machine and every part reads it from context. The machine's own keys on
593
- * the scroller are switched off: they page on Left and Right only, in a vertical carousel too,
594
- * ignore `dir`, and act while focus is on any element inside a slide. The scroller part pages
595
- * through `keys.ts` instead. The machine ignores a press that starts a drag while the scroller
596
- * has focus, so its focus state takes the drag as its idle state does. The machine starts and
597
- * stops its rotation only in its idle and rotating states, so a change that arrives while a drag
598
- * settles is sent again after the next render.
599
- */
600
- /**
601
- * Creates the context through which the root provides the running machine to its parts.
602
- *
603
- * @remarks
604
- * `useCarousel` throws when no `Carousel.Root` is mounted above the calling part.
605
- */
606
- const [MachineProvider, useCarousel] = createRequiredContext("Carousel");
607
- /**
608
- * Lists the states of Zag's carousel machine.
609
- */
610
- const STATES = carousel.machine.states;
611
- /**
612
- * Runs Zag's carousel machine without its keys on the scroller, and starts a drag while the
613
- * scroller has focus as it does while idle.
614
- */
615
- const MACHINE = {
616
- ...carousel.machine,
617
- implementations: {
618
- ...carousel.machine.implementations,
619
- effects: {
620
- ...carousel.machine.implementations?.effects,
621
- trackKeyboardScroll: noop
622
- }
623
- },
624
- states: {
625
- ...STATES,
626
- focus: {
627
- ...STATES.focus,
628
- on: {
629
- ...STATES.focus.on,
630
- "DRAGGING.START": {
631
- actions: ["invokeDragStart"],
632
- target: "dragging"
633
- }
634
- }
635
- }
636
- }
637
- };
638
- /**
639
- * Starts the carousel machine and returns its connected api and its `send`.
640
- *
641
- * @param options - Machine settings split from the root's props. React generates `id` when the
642
- * caller states none.
643
- * @returns The api and the function that sends the machine an event.
644
- */
645
- function useCarouselMachine(options) {
646
- const $ = c(14);
647
- const generated = useId();
648
- let t0;
649
- if ($[0] !== options) {
650
- t0 = omitUndefined(options);
651
- $[0] = options;
652
- $[1] = t0;
653
- } else t0 = $[1];
654
- const t1 = options.id ?? generated;
655
- let t2;
656
- if ($[2] !== t0 || $[3] !== t1) {
657
- t2 = {
658
- ...t0,
659
- id: t1
660
- };
661
- $[2] = t0;
662
- $[3] = t1;
663
- $[4] = t2;
664
- } else t2 = $[4];
665
- const service = useMachine(MACHINE, t2);
666
- let t3;
667
- if ($[5] !== service) {
668
- t3 = carousel.connect(service, normalizeProps);
669
- $[5] = service;
670
- $[6] = t3;
671
- } else t3 = $[6];
672
- const api = t3;
673
- const rotating = Boolean(options.autoplay);
674
- let t4;
675
- if ($[7] !== api.isPlaying || $[8] !== rotating || $[9] !== service) {
676
- t4 = () => {
677
- if (rotating !== api.isPlaying) service.send({ type: rotating ? "AUTOPLAY.START" : "AUTOPLAY.PAUSE" });
678
- };
679
- $[7] = api.isPlaying;
680
- $[8] = rotating;
681
- $[9] = service;
682
- $[10] = t4;
683
- } else t4 = $[10];
684
- useEffect(t4);
685
- let t5;
686
- if ($[11] !== api || $[12] !== service.send) {
687
- t5 = [api, service.send];
688
- $[11] = api;
689
- $[12] = service.send;
690
- $[13] = t5;
691
- } else t5 = $[13];
692
- return t5;
693
- }
694
- /**
695
- * Splits the root's props into machine settings and element props, without `translations`.
696
- *
697
- * @remarks
698
- * The key list comes from the machine's own `splitProps`, so it follows the installed version.
699
- * @typeParam Props - Type of the root's props.
700
- * @param props - The root's props.
701
- * @returns The machine settings and the element props.
702
- */
703
- function splitCarouselProps(props) {
704
- const [options, rest] = splitEnumerable(carousel.splitProps)(props);
705
- const { translations: _translations, ...kept } = options;
706
- return [kept, rest];
707
- }
708
- //#endregion
709
- //#region src/carousel/autoplay-indicator.ts
710
- /**
711
- * Renders the glyph of the rotation control's next action.
712
- *
713
- * @param props - The glyph of each action.
714
- * @returns The glyph for the rotation's state.
715
- */
716
- function AutoplayIndicator(t0) {
717
- const { pause, play } = t0;
718
- const { rotation } = useCarousel();
719
- return rotation.wanted ? pause : play;
720
- }
721
- //#endregion
722
- //#region src/carousel/context.ts
723
- /**
724
- * Binds the carousel recipe to React.
725
- *
726
- * @remarks
727
- * The binding is a separate module from the recipe, because the theme compiler imports the recipe
728
- * at build time and must not load the React runtime.
729
- */
730
- /**
731
- * Binds the recipe once. The root receives the variants and every other part reads them.
732
- */
733
- const { withContext: withContext$3, withProvider: withProvider$1 } = createSlotRecipeContext(recipe$3);
734
- //#endregion
735
- //#region src/carousel/bound.ts
736
- /**
737
- * Renders the previous trigger as the library's `Button` with the carousel's class.
738
- */
739
- const PrevButton = withContext$3(Button, "prevTrigger");
740
- /**
741
- * Renders the next trigger as the library's `Button` with the carousel's class.
742
- */
743
- const NextButton = withContext$3(Button, "nextTrigger");
744
- /**
745
- * Renders the rotation control as the library's `Button` with the carousel's class.
746
- */
747
- const AutoplayButton = withContext$3(Button, "autoplayTrigger");
748
- /**
749
- * Returns the look a trigger takes unless the caller sets another.
750
- *
751
- * @param controls - Where the controls go.
752
- * @returns `surface` over the slides, else `ghost`.
753
- */
754
- function lookOf(controls) {
755
- return controls === "overlay" ? "surface" : "ghost";
756
- }
757
- //#endregion
758
- //#region src/carousel/autoplay-trigger.tsx
759
- /**
760
- * Renders the rotation control with the machine's props merged under the caller's.
761
- *
762
- * @param props - The names of the two actions and the props of a `Button`.
763
- * @returns The `button` element.
764
- */
765
- function AutoplayTrigger(t0) {
766
- const $ = c(4);
767
- const { startLabel: t1, stopLabel: t2, ...rest } = t0;
768
- const startLabel = t1 === void 0 ? "Start slide rotation" : t1;
769
- const stopLabel = t2 === void 0 ? "Stop slide rotation" : t2;
770
- const { api, controls, rotation } = useCarousel();
771
- const pressed = {
772
- onClick(event) {
773
- if (event.defaultPrevented) return;
774
- event.preventDefault();
775
- rotation.toggle();
776
- },
777
- variant: lookOf(controls)
778
- };
779
- const T0 = AutoplayButton;
780
- const t3 = mergeProps(api.getAutoplayTriggerProps(), pressed, rest);
781
- const t4 = rotation.wanted ? stopLabel : startLabel;
782
- let t5;
783
- if ($[0] !== T0 || $[1] !== t3 || $[2] !== t4) {
784
- t5 = /* @__PURE__ */ jsx(T0, {
785
- ...t3,
786
- "aria-label": t4,
787
- "data-pressed": void 0,
788
- shape: "square"
789
- });
790
- $[0] = T0;
791
- $[1] = t3;
792
- $[2] = t4;
793
- $[3] = t5;
794
- } else t5 = $[3];
795
- return t5;
796
- }
797
- //#endregion
798
- //#region src/carousel/control.tsx
799
- /**
800
- * Renders the `div` with the carousel's control class.
801
- */
802
- const Drawn$12 = withContext$3("div", "control");
803
- /**
804
- * Renders the control row with the machine's props merged under the caller's.
805
- *
806
- * @param props - The props of a `div`, the controls among its children.
807
- * @returns The `div` element.
808
- */
809
- function Control(props) {
810
- const $ = c(5);
811
- const { api } = useCarousel();
812
- let t0;
813
- if ($[0] !== api || $[1] !== props) {
814
- t0 = mergeProps(api.getControlProps(), props);
815
- $[0] = api;
816
- $[1] = props;
817
- $[2] = t0;
818
- } else t0 = $[2];
819
- let t1;
820
- if ($[3] !== t0) {
821
- t1 = /* @__PURE__ */ jsx(Drawn$12, { ...t0 });
822
- $[3] = t0;
823
- $[4] = t1;
824
- } else t1 = $[4];
825
- return t1;
826
- }
827
- //#endregion
828
- //#region src/carousel/keys.ts
829
- /**
830
- * Maps the keys that move a carousel a page to the machine's page events.
831
- *
832
- * @remarks
833
- * The keys follow the carousel's orientation and direction: Left and Right page a horizontal
834
- * carousel, swapped under `dir="rtl"`, and Up and Down page a vertical one. Home and End move to
835
- * the first and the last page. The machine writes `dir` and `data-orientation` on the element
836
- * that receives the key, so the map reads both from it.
837
- */
838
- /**
839
- * Lists the arrow keys that step a page, per orientation, after the swap for a right-to-left
840
- * carousel.
841
- */
842
- const STEPS = {
843
- horizontal: {
844
- ArrowLeft: "PAGE.PREV",
845
- ArrowRight: "PAGE.NEXT"
846
- },
847
- vertical: {
848
- ArrowDown: "PAGE.NEXT",
849
- ArrowUp: "PAGE.PREV"
850
- }
851
- };
852
- /**
853
- * Returns the page event for a key, or undefined for a key that moves no page.
854
- *
855
- * @param key - The key's `key` value.
856
- * @param element - The part that received the key, with the machine's `dir` and
857
- * `data-orientation` on it.
858
- * @param last - The index of the last page.
859
- * @returns The page event.
860
- */
861
- function paged(key, element, last) {
862
- const orientation = element.dataset["orientation"] === "vertical" ? "vertical" : "horizontal";
863
- const pressed = getEventKey({ key }, {
864
- dir: element.dir === "rtl" ? "rtl" : "ltr",
865
- orientation
866
- });
867
- if (pressed === "Home") return {
868
- index: 0,
869
- type: "PAGE.SET"
870
- };
871
- if (pressed === "End") return {
872
- index: last,
873
- type: "PAGE.SET"
874
- };
875
- const type = STEPS[orientation][pressed];
876
- return type === void 0 ? void 0 : { type };
877
- }
878
- //#endregion
879
- //#region src/carousel/indicator-group.tsx
880
- /**
881
- * Renders the `div` with the carousel's dot group class.
882
- */
883
- const Drawn$11 = withContext$3("div", "indicatorGroup");
884
- /**
885
- * Renders the dot group with the machine's props merged under the caller's.
886
- *
887
- * @param props - The props of a `div`, the dots among its children.
888
- * @returns The `div` element.
889
- */
890
- function IndicatorGroup(props) {
891
- const $ = c(9);
892
- const { api, instant, send } = useCarousel();
893
- let T0;
894
- let t0;
895
- if ($[0] !== api || $[1] !== instant || $[2] !== props || $[3] !== send) {
896
- const keys = { onKeyDown(event) {
897
- if (event.defaultPrevented) return;
898
- const step = paged(event.key, event.currentTarget, api.pageSnapPoints.length - 1);
899
- if (step === void 0) return;
900
- event.preventDefault();
901
- send({
902
- ...step,
903
- instant,
904
- src: "indicator"
905
- });
906
- } };
907
- T0 = Drawn$11;
908
- t0 = mergeProps(api.getIndicatorGroupProps(), keys, props);
909
- $[0] = api;
910
- $[1] = instant;
911
- $[2] = props;
912
- $[3] = send;
913
- $[4] = T0;
914
- $[5] = t0;
915
- } else {
916
- T0 = $[4];
917
- t0 = $[5];
918
- }
919
- let t1;
920
- if ($[6] !== T0 || $[7] !== t0) {
921
- t1 = /* @__PURE__ */ jsx(T0, { ...t0 });
922
- $[6] = T0;
923
- $[7] = t0;
924
- $[8] = t1;
925
- } else t1 = $[8];
926
- return t1;
927
- }
928
- //#endregion
929
- //#region src/carousel/indicator.tsx
930
- /**
931
- * Renders the `button` with the carousel's dot class.
932
- */
933
- const Drawn$10 = withContext$3("button", "indicator");
934
- /**
935
- * Renders the dot with the machine's props merged under the caller's.
936
- *
937
- * @param props - The page, the name, the read-only flag and the props of a `button`.
938
- * @returns The `button` element.
939
- */
940
- function Indicator(t0) {
941
- const $ = c(6);
942
- const { index, label, readOnly, ...rest } = t0;
943
- const { api, instant, send } = useCarousel();
944
- const picked = {
945
- "aria-disabled": index === api.page || void 0,
946
- onClick(event) {
947
- if (event.defaultPrevented) return;
948
- event.preventDefault();
949
- if (readOnly !== true) send({
950
- index,
951
- instant,
952
- src: "indicator",
953
- type: "PAGE.SET"
954
- });
955
- }
956
- };
957
- const T0 = Drawn$10;
958
- const t1 = mergeProps(api.getIndicatorProps({
959
- index,
960
- readOnly
961
- }), picked, rest);
962
- let t2;
963
- if ($[0] !== label) {
964
- t2 = omitUndefined({ "aria-label": label });
965
- $[0] = label;
966
- $[1] = t2;
967
- } else t2 = $[1];
968
- let t3;
969
- if ($[2] !== T0 || $[3] !== t1 || $[4] !== t2) {
970
- t3 = /* @__PURE__ */ jsx(T0, {
971
- ...t1,
972
- ...t2
973
- });
974
- $[2] = T0;
975
- $[3] = t1;
976
- $[4] = t2;
977
- $[5] = t3;
978
- } else t3 = $[5];
979
- return t3;
980
- }
981
- //#endregion
982
- //#region src/carousel/indicators.tsx
983
- /**
984
- * Renders the dots.
985
- *
986
- * @param props - The function that returns a dot's accessible name.
987
- * @returns A dot per page, in order.
988
- */
989
- function Indicators(t0) {
990
- const $ = c(7);
991
- const { label } = t0;
992
- const { api } = useCarousel();
993
- let t1;
994
- if ($[0] !== api.pageSnapPoints || $[1] !== label) {
995
- let t2;
996
- if ($[3] !== label) {
997
- t2 = (point, index) => /* @__PURE__ */ jsx(Indicator, {
998
- index,
999
- label: label?.(index + 1)
1000
- }, point);
1001
- $[3] = label;
1002
- $[4] = t2;
1003
- } else t2 = $[4];
1004
- t1 = api.pageSnapPoints.map(t2);
1005
- $[0] = api.pageSnapPoints;
1006
- $[1] = label;
1007
- $[2] = t1;
1008
- } else t1 = $[2];
1009
- let t2;
1010
- if ($[5] !== t1) {
1011
- t2 = /* @__PURE__ */ jsx(Fragment, { children: t1 });
1012
- $[5] = t1;
1013
- $[6] = t2;
1014
- } else t2 = $[6];
1015
- return t2;
1016
- }
1017
- //#endregion
1018
- //#region src/carousel/item-group.tsx
1019
- /**
1020
- * Renders the `div` with the carousel's scroller class.
1021
- */
1022
- const Drawn$9 = withContext$3("div", "itemGroup");
1023
- /**
1024
- * Renders the scroller with the machine's props merged under the caller's.
1025
- *
1026
- * @param props - The props of a `div`, the slides among its children.
1027
- * @returns The `div` element.
1028
- */
1029
- function ItemGroup(props) {
1030
- const $ = c(9);
1031
- const { api, instant, send } = useCarousel();
1032
- let T0;
1033
- let t0;
1034
- if ($[0] !== api || $[1] !== instant || $[2] !== props || $[3] !== send) {
1035
- const keys = { onKeyDown(event) {
1036
- if (event.target !== event.currentTarget) return;
1037
- const step = paged(event.key, event.currentTarget, api.pageSnapPoints.length - 1);
1038
- if (step === void 0) return;
1039
- event.preventDefault();
1040
- send({
1041
- ...step,
1042
- instant
1043
- });
1044
- } };
1045
- T0 = Drawn$9;
1046
- t0 = mergeProps(api.getItemGroupProps(), keys, props);
1047
- $[0] = api;
1048
- $[1] = instant;
1049
- $[2] = props;
1050
- $[3] = send;
1051
- $[4] = T0;
1052
- $[5] = t0;
1053
- } else {
1054
- T0 = $[4];
1055
- t0 = $[5];
1056
- }
1057
- let t1;
1058
- if ($[6] !== T0 || $[7] !== t0) {
1059
- t1 = /* @__PURE__ */ jsx(T0, { ...t0 });
1060
- $[6] = T0;
1061
- $[7] = t0;
1062
- $[8] = t1;
1063
- } else t1 = $[8];
1064
- return t1;
1065
- }
1066
- //#endregion
1067
- //#region src/carousel/item.tsx
1068
- /**
1069
- * Renders the `div` with the carousel's slide class.
1070
- */
1071
- const Drawn$8 = withContext$3("div", "item");
1072
- /**
1073
- * Renders the slide with the machine's props merged under the caller's.
1074
- *
1075
- * @param props - The index, the snap edge and the props of a `div`.
1076
- * @returns The `div` element.
1077
- */
1078
- function Item(t0) {
1079
- const $ = c(7);
1080
- const { index, snapAlign, ...props } = t0;
1081
- const { api } = useCarousel();
1082
- const T0 = Drawn$8;
1083
- const t1 = mergeProps(api.getItemProps({
1084
- index,
1085
- snapAlign
1086
- }), props);
1087
- let t2;
1088
- if ($[0] !== api || $[1] !== index) {
1089
- t2 = !api.isInView(index) || void 0;
1090
- $[0] = api;
1091
- $[1] = index;
1092
- $[2] = t2;
1093
- } else t2 = $[2];
1094
- let t3;
1095
- if ($[3] !== T0 || $[4] !== t1 || $[5] !== t2) {
1096
- t3 = /* @__PURE__ */ jsx(T0, {
1097
- ...t1,
1098
- inert: t2
1099
- });
1100
- $[3] = T0;
1101
- $[4] = t1;
1102
- $[5] = t2;
1103
- $[6] = t3;
1104
- } else t3 = $[6];
1105
- return t3;
1106
- }
1107
- //#endregion
1108
- //#region src/carousel/stepping.ts
1109
- /**
1110
- * Returns a trigger's props with `aria-disabled` in place of `disabled` at an end, a press that
1111
- * sends the page event, and the look for where the controls go.
1112
- *
1113
- * @param machine - Where the controls go, whether pages move at once, and the machine's `send`.
1114
- * @param props - The props the machine gives the trigger.
1115
- * @param ended - Whether the trigger has no page to move to.
1116
- * @param type - The page event a press sends.
1117
- * @returns The trigger's props.
1118
- */
1119
- function stepping(machine, props, ended, type) {
1120
- const { controls, instant, send } = machine;
1121
- return mergeProps({
1122
- ...props,
1123
- disabled: void 0
1124
- }, {
1125
- "aria-disabled": ended || void 0,
1126
- /**
1127
- * Sends the page event unless the caller cancelled the press or the trigger has no page to
1128
- * move to, and stops the machine's own press handler.
1129
- */
1130
- onClick(event) {
1131
- if (event.defaultPrevented) return;
1132
- event.preventDefault();
1133
- if (!ended) send({
1134
- instant,
1135
- src: "trigger",
1136
- type
1137
- });
1138
- },
1139
- variant: lookOf(controls)
1140
- });
1141
- }
1142
- //#endregion
1143
- //#region src/carousel/next-trigger.tsx
1144
- /**
1145
- * Renders the next trigger with the machine's props merged under the caller's.
1146
- *
1147
- * @param props - The trigger's name and the props of a `Button`.
1148
- * @returns The `button` element.
1149
- */
1150
- function NextTrigger(t0) {
1151
- const $ = c(4);
1152
- const { label: t1, ...rest } = t0;
1153
- const label = t1 === void 0 ? "Next slide" : t1;
1154
- const machine = useCarousel();
1155
- const { api } = machine;
1156
- const props = stepping(machine, api.getNextTriggerProps(), !api.canScrollNext, "PAGE.NEXT");
1157
- const T0 = NextButton;
1158
- const t2 = mergeProps(props, rest);
1159
- let t3;
1160
- if ($[0] !== T0 || $[1] !== label || $[2] !== t2) {
1161
- t3 = /* @__PURE__ */ jsx(T0, {
1162
- ...t2,
1163
- "aria-label": label,
1164
- shape: "square"
1165
- });
1166
- $[0] = T0;
1167
- $[1] = label;
1168
- $[2] = t2;
1169
- $[3] = t3;
1170
- } else t3 = $[3];
1171
- return t3;
1172
- }
1173
- //#endregion
1174
- //#region src/carousel/prev-trigger.tsx
1175
- /**
1176
- * Renders the previous trigger with the machine's props merged under the caller's.
1177
- *
1178
- * @param props - The trigger's name and the props of a `Button`.
1179
- * @returns The `button` element.
1180
- */
1181
- function PrevTrigger(t0) {
1182
- const $ = c(4);
1183
- const { label: t1, ...rest } = t0;
1184
- const label = t1 === void 0 ? "Previous slide" : t1;
1185
- const machine = useCarousel();
1186
- const { api } = machine;
1187
- const props = stepping(machine, api.getPrevTriggerProps(), !api.canScrollPrev, "PAGE.PREV");
1188
- const T0 = PrevButton;
1189
- const t2 = mergeProps(props, rest);
1190
- let t3;
1191
- if ($[0] !== T0 || $[1] !== label || $[2] !== t2) {
1192
- t3 = /* @__PURE__ */ jsx(T0, {
1193
- ...t2,
1194
- "aria-label": label,
1195
- shape: "square"
1196
- });
1197
- $[0] = T0;
1198
- $[1] = label;
1199
- $[2] = t2;
1200
- $[3] = t3;
1201
- } else t3 = $[3];
1202
- return t3;
1203
- }
1204
- //#endregion
1205
- //#region src/carousel/progress-text.tsx
1206
- /**
1207
- * Renders the `span` with the carousel's progress text class.
1208
- */
1209
- const Drawn$7 = withContext$3("span", "progressText");
1210
- /**
1211
- * Renders the progress text.
1212
- *
1213
- * @param props - The words and the props of a `span`.
1214
- * @returns The `span` element.
1215
- */
1216
- function ProgressText(t0) {
1217
- const $ = c(4);
1218
- const { text, ...rest } = t0;
1219
- const { api } = useCarousel();
1220
- const details = {
1221
- page: api.page + 1,
1222
- totalPages: api.pageSnapPoints.length
1223
- };
1224
- const T0 = Drawn$7;
1225
- const t1 = mergeProps(api.getProgressTextProps(), rest);
1226
- const t2 = text?.(details) ?? api.getProgressText();
1227
- let t3;
1228
- if ($[0] !== T0 || $[1] !== t1 || $[2] !== t2) {
1229
- t3 = /* @__PURE__ */ jsx(T0, {
1230
- ...t1,
1231
- children: t2
1232
- });
1233
- $[0] = T0;
1234
- $[1] = t1;
1235
- $[2] = t2;
1236
- $[3] = t3;
1237
- } else t3 = $[3];
1238
- return t3;
1239
- }
1240
- //#endregion
1241
- //#region src/carousel/rotation.ts
1242
- /**
1243
- * Decides whether a carousel rotates, from the root's `autoplay`, the reader's motion setting, the
1244
- * rotation control, the pointer and the keyboard focus.
1245
- *
1246
- * @remarks
1247
- * The rules follow the APG carousel pattern. The reader's choice through the rotation control
1248
- * decides, and until the reader makes one the root's `autoplay` decides, unless the reader asks
1249
- * the system for reduced motion. Keyboard focus that enters the carousel from outside counts as a
1250
- * choice to stop, so the rotation does not restart until the reader starts it again. A pointer
1251
- * over the carousel pauses the rotation until it leaves, unless the reader started the rotation
1252
- * with the control. Focus that a pointer press moves into the carousel does not count, because
1253
- * the pointer already pauses the rotation.
1254
- */
1255
- /**
1256
- * Returns whether the carousel rotates and the handlers that pause and stop it.
1257
- *
1258
- * @param requested - The root's `autoplay`.
1259
- * @param reduced - Whether the reader asks the system for reduced motion.
1260
- * @returns The machine's setting, the handlers and the rotation control's state and press.
1261
- */
1262
- function useRotation(requested, reduced) {
1263
- const $ = c(4);
1264
- const [choice, setChoice] = useState();
1265
- const [hovered, setHovered] = useState(false);
1266
- const wanted = choice ?? (Boolean(requested) && !reduced);
1267
- const t0 = wanted && (choice === true || !hovered) && (typeof requested === "object" ? requested : true);
1268
- let t1;
1269
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
1270
- t1 = {
1271
- onFocus(event) {
1272
- if (event.currentTarget.contains(event.relatedTarget)) return;
1273
- if (event.target.matches(":focus-visible")) setChoice(false);
1274
- },
1275
- onPointerEnter() {
1276
- setHovered(true);
1277
- },
1278
- onPointerLeave() {
1279
- setHovered(false);
1280
- }
1281
- };
1282
- $[0] = t1;
1283
- } else t1 = $[0];
1284
- let t2;
1285
- if ($[1] !== t0 || $[2] !== wanted) {
1286
- t2 = {
1287
- autoplay: t0,
1288
- handlers: t1,
1289
- toggle() {
1290
- setChoice(!wanted);
1291
- },
1292
- wanted
1293
- };
1294
- $[1] = t0;
1295
- $[2] = wanted;
1296
- $[3] = t2;
1297
- } else t2 = $[3];
1298
- return t2;
1299
- }
1300
- //#endregion
1301
- //#region src/reduced-motion.ts
1302
- /**
1303
- * Reads whether the reader asks the system for reduced motion, correct from the first render.
1304
- *
1305
- * @remarks
1306
- * The read goes through `useSyncExternalStore`, so a client render reads the media query before
1307
- * the first paint, and a clip or a rotation that must not start by itself never mounts started. A
1308
- * server render has no window and reports reduced motion, so its markup starts nothing. A change
1309
- * of the setting renders again.
1310
- */
1311
- /**
1312
- * Media query a reader matches by asking the system for reduced motion.
1313
- */
1314
- const REDUCED_MOTION = "(prefers-reduced-motion: reduce)";
1315
- /**
1316
- * Listens for a change of the setting.
1317
- *
1318
- * @param change - The callback React runs to read the setting again.
1319
- * @returns The function that stops listening.
1320
- */
1321
- function subscribe(change) {
1322
- const query = globalThis.matchMedia(REDUCED_MOTION);
1323
- query.addEventListener("change", change);
1324
- return () => {
1325
- query.removeEventListener("change", change);
1326
- };
1327
- }
1328
- /**
1329
- * Returns whether the query matches in the window.
1330
- */
1331
- function clientSnapshot() {
1332
- return globalThis.matchMedia(REDUCED_MOTION).matches;
1333
- }
1334
- /**
1335
- * Returns true, because a server cannot read the setting and motion must not start unasked.
1336
- */
1337
- function serverSnapshot() {
1338
- return true;
1339
- }
1340
- /**
1341
- * Returns whether the reader asks for reduced motion.
1342
- *
1343
- * @returns `true` while `prefers-reduced-motion: reduce` matches, and on the server.
1344
- */
1345
- function useReducedMotion() {
1346
- return useSyncExternalStore(subscribe, clientSnapshot, serverSnapshot);
1347
- }
1348
- //#endregion
1349
- //#region src/carousel/root.tsx
1350
- /**
1351
- * Renders the `div` that provides the recipe's variants.
1352
- */
1353
- const Framed$1 = withProvider$1("div", "root");
1354
- /**
1355
- * Renders the root and provides the running machine, the rotation and the motion setting to the
1356
- * parts.
1357
- *
1358
- * @param props - The machine's options, the recipe's variants and the props of a `div`.
1359
- * @returns The `div` element inside the provider.
1360
- */
1361
- function Root$1(t0) {
1362
- const $ = c(14);
1363
- const { autoplay, controls: t1, loop, spacing, ...props } = t0;
1364
- const controls = t1 === void 0 ? "outside" : t1;
1365
- const [options, rest] = splitCarouselProps(props);
1366
- const instant = useReducedMotion();
1367
- const rotation = useRotation(autoplay, instant);
1368
- const [api, send] = useCarouselMachine({
1369
- ...options,
1370
- autoplay: rotation.autoplay,
1371
- loop: loop ?? Boolean(autoplay),
1372
- spacing: spacing ?? `var(--carousel-gap)`
1373
- });
1374
- const T0 = MachineProvider;
1375
- let t2;
1376
- if ($[0] !== api || $[1] !== controls || $[2] !== instant || $[3] !== rotation || $[4] !== send) {
1377
- t2 = {
1378
- api,
1379
- controls,
1380
- instant,
1381
- rotation,
1382
- send
1383
- };
1384
- $[0] = api;
1385
- $[1] = controls;
1386
- $[2] = instant;
1387
- $[3] = rotation;
1388
- $[4] = send;
1389
- $[5] = t2;
1390
- } else t2 = $[5];
1391
- const T1 = Framed$1;
1392
- const t3 = mergeProps(api.getRootProps(), rotation.handlers, rest);
1393
- let t4;
1394
- if ($[6] !== T1 || $[7] !== controls || $[8] !== t3) {
1395
- t4 = /* @__PURE__ */ jsx(T1, {
1396
- ...t3,
1397
- controls
1398
- });
1399
- $[6] = T1;
1400
- $[7] = controls;
1401
- $[8] = t3;
1402
- $[9] = t4;
1403
- } else t4 = $[9];
1404
- let t5;
1405
- if ($[10] !== T0 || $[11] !== t2 || $[12] !== t4) {
1406
- t5 = /* @__PURE__ */ jsx(T0, {
1407
- value: t2,
1408
- children: t4
1409
- });
1410
- $[10] = T0;
1411
- $[11] = t2;
1412
- $[12] = t4;
1413
- $[13] = t5;
1414
- } else t5 = $[13];
1415
- return t5;
1416
- }
1417
- //#endregion
1418
- //#region src/carousel/index.ts
1419
- var carousel_exports = /* @__PURE__ */ __exportAll({
1420
- AutoplayIndicator: () => AutoplayIndicator,
1421
- AutoplayTrigger: () => AutoplayTrigger,
1422
- Control: () => Control,
1423
- Indicator: () => Indicator,
1424
- IndicatorGroup: () => IndicatorGroup,
1425
- Indicators: () => Indicators,
1426
- Item: () => Item,
1427
- ItemGroup: () => ItemGroup,
1428
- NextTrigger: () => NextTrigger,
1429
- PrevTrigger: () => PrevTrigger,
1430
- ProgressText: () => ProgressText,
1431
- Root: () => Root$1
1432
- });
1433
- //#endregion
1434
- //#region src/iframe/context.ts
1435
- /**
1436
- * Binds the iframe recipe to the element that renders it.
1437
- *
1438
- * @remarks
1439
- * The binding is kept out of `recipe.ts` because an application's style compiler imports the
1440
- * recipe at build time, and a binding there would pull the React runtime into that import.
1441
- */
1442
- /**
1443
- * Supplies the element factory the iframe component is built from.
1444
- */
1445
- const { withContext: withContext$2 } = createRecipeContext(recipe$4);
1446
- //#endregion
1447
- //#region src/iframe/iframe.tsx
1448
- /**
1449
- * Renders the `iframe` element with the recipe's class.
1450
- */
1451
- const Drawn$6 = withContext$2("iframe");
1452
- /**
1453
- * Renders the frame with the sandbox, the referrer policy and the lazy loading it defaults to.
1454
- *
1455
- * @param props - The props of an `iframe` element, with `title` required.
1456
- * @returns The `iframe` element.
1457
- */
1458
- function Iframe(t0) {
1459
- const $ = c(10);
1460
- let rest;
1461
- let t1;
1462
- let t2;
1463
- let t3;
1464
- if ($[0] !== t0) {
1465
- ({loading: t1, referrerPolicy: t2, sandbox: t3, ...rest} = t0);
1466
- $[0] = t0;
1467
- $[1] = rest;
1468
- $[2] = t1;
1469
- $[3] = t2;
1470
- $[4] = t3;
1471
- } else {
1472
- rest = $[1];
1473
- t1 = $[2];
1474
- t2 = $[3];
1475
- t3 = $[4];
1476
- }
1477
- const loading = t1 === void 0 ? "lazy" : t1;
1478
- const referrerPolicy = t2 === void 0 ? "no-referrer" : t2;
1479
- const sandbox = t3 === void 0 ? "" : t3;
1480
- let t4;
1481
- if ($[5] !== loading || $[6] !== referrerPolicy || $[7] !== rest || $[8] !== sandbox) {
1482
- t4 = /* @__PURE__ */ jsx(Drawn$6, {
1483
- ...rest,
1484
- loading,
1485
- referrerPolicy,
1486
- sandbox
1487
- });
1488
- $[5] = loading;
1489
- $[6] = referrerPolicy;
1490
- $[7] = rest;
1491
- $[8] = sandbox;
1492
- $[9] = t4;
1493
- } else t4 = $[9];
1494
- return t4;
1495
- }
1496
- //#endregion
1497
- //#region src/image-cropper/context.ts
1498
- /**
1499
- * Binds the image cropper recipe to React.
1500
- *
1501
- * @remarks
1502
- * The binding is a separate module from the recipe, because the theme compiler imports the recipe
1503
- * at build time and must not load the React runtime.
1504
- */
1505
- /**
1506
- * Binds the recipe once. The root receives the variants and every other part reads them.
1507
- */
1508
- const { withContext: withContext$1, withProvider } = createSlotRecipeContext(recipe$5);
1509
- //#endregion
1510
- //#region src/image-cropper/machine.ts
1511
- /**
1512
- * Starts the image cropper machine in application code and provides its api to the parts.
1513
- *
1514
- * @remarks
1515
- * An application calls `useImageCropper` and passes the api to `ImageCropper.Root`, so a control
1516
- * outside the root, such as a zoom slider or a save button, reads the crop and calls
1517
- * `getCroppedImage`. The machine's `translations` are left out: the parts take their words as
1518
- * props.
1519
- */
1520
- /**
1521
- * Creates the context through which the root provides the api to its parts.
1522
- *
1523
- * @remarks
1524
- * `useImageCropperApi` throws when no `ImageCropper.Root` is mounted above the calling part.
1525
- */
1526
- const [ApiProvider, useImageCropperApi] = createRequiredContext("ImageCropper");
1527
- /**
1528
- * Starts the image cropper machine and returns its connected api.
1529
- *
1530
- * @param options - The machine settings. A generated id is used when `id` is absent.
1531
- * @returns The api the root provides to its parts.
1532
- */
1533
- function useImageCropper(t0) {
1534
- const $ = c(9);
1535
- let t1;
1536
- if ($[0] !== t0) {
1537
- t1 = t0 === void 0 ? {} : t0;
1538
- $[0] = t0;
1539
- $[1] = t1;
1540
- } else t1 = $[1];
1541
- const options = t1;
1542
- const generated = useId();
1543
- let t2;
1544
- if ($[2] !== options) {
1545
- t2 = omitUndefined(options);
1546
- $[2] = options;
1547
- $[3] = t2;
1548
- } else t2 = $[3];
1549
- const t3 = options.id ?? generated;
1550
- let t4;
1551
- if ($[4] !== t2 || $[5] !== t3) {
1552
- t4 = {
1553
- ...t2,
1554
- id: t3
1555
- };
1556
- $[4] = t2;
1557
- $[5] = t3;
1558
- $[6] = t4;
1559
- } else t4 = $[6];
1560
- const service = useMachine(imageCropper.machine, t4);
1561
- let t5;
1562
- if ($[7] !== service) {
1563
- t5 = imageCropper.connect(service, normalizeProps);
1564
- $[7] = service;
1565
- $[8] = t5;
1566
- } else t5 = $[8];
1567
- return t5;
1568
- }
1569
- //#endregion
1570
- //#region src/image-cropper/grid.tsx
1571
- /**
1572
- * Renders the `div` with the image cropper's grid class.
1573
- */
1574
- const Drawn$5 = withContext$1("div", "grid");
1575
- /**
1576
- * Renders the grid with the machine's grid props merged over the caller's.
1577
- *
1578
- * @param props - The axis and the props of a `div`.
1579
- * @returns The `div` element.
1580
- */
1581
- function Grid(t0) {
1582
- const $ = c(3);
1583
- const { axis, ...props } = t0;
1584
- const api = useImageCropperApi();
1585
- const T0 = Drawn$5;
1586
- const t1 = mergeProps(api.getGridProps({ axis }), props);
1587
- let t2;
1588
- if ($[0] !== T0 || $[1] !== t1) {
1589
- t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
1590
- $[0] = T0;
1591
- $[1] = t1;
1592
- $[2] = t2;
1593
- } else t2 = $[2];
1594
- return t2;
1595
- }
1596
- //#endregion
1597
- //#region src/image-cropper/handle.tsx
1598
- /**
1599
- * Renders the `div` with the image cropper's handle class.
1600
- */
1601
- const Drawn$4 = withContext$1("div", "handle");
1602
- /**
1603
- * Renders the handle with the machine's handle props merged over the caller's.
1604
- *
1605
- * @param props - The position and the props of a `div`.
1606
- * @returns The `div` element.
1607
- */
1608
- function Handle(t0) {
1609
- const $ = c(3);
1610
- const { position, ...props } = t0;
1611
- const api = useImageCropperApi();
1612
- const T0 = Drawn$4;
1613
- const t1 = mergeProps(api.getHandleProps({ position }), props);
1614
- let t2;
1615
- if ($[0] !== T0 || $[1] !== t1) {
1616
- t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
1617
- $[0] = T0;
1618
- $[1] = t1;
1619
- $[2] = t2;
1620
- } else t2 = $[2];
1621
- return t2;
1622
- }
1623
- //#endregion
1624
- //#region src/image-cropper/image.tsx
1625
- /**
1626
- * Renders the `img` with the image cropper's image class.
1627
- */
1628
- const Drawn$3 = withContext$1("img", "image");
1629
- /**
1630
- * Renders the picture with the machine's image props merged over the caller's.
1631
- *
1632
- * @param props - The props of an `img`, the source among them.
1633
- * @returns The `img` element.
1634
- */
1635
- function Image(props) {
1636
- const $ = c(5);
1637
- const api = useImageCropperApi();
1638
- let t0;
1639
- if ($[0] !== api || $[1] !== props) {
1640
- t0 = mergeProps(api.getImageProps(), props);
1641
- $[0] = api;
1642
- $[1] = props;
1643
- $[2] = t0;
1644
- } else t0 = $[2];
1645
- let t1;
1646
- if ($[3] !== t0) {
1647
- t1 = /* @__PURE__ */ jsx(Drawn$3, { ...t0 });
1648
- $[3] = t0;
1649
- $[4] = t1;
1650
- } else t1 = $[4];
1651
- return t1;
1652
- }
1653
- //#endregion
1654
- //#region src/image-cropper/rounded.ts
1655
- /**
1656
- * Returns the crop with each value rounded to a whole pixel.
1657
- *
1658
- * @param crop - The crop the machine reports.
1659
- * @returns The rounded crop.
1660
- */
1661
- function rounded(crop) {
1662
- return {
1663
- height: Math.round(crop.height),
1664
- width: Math.round(crop.width),
1665
- x: Math.round(crop.x),
1666
- y: Math.round(crop.y)
1667
- };
1668
- }
1669
- //#endregion
1670
- //#region src/image-cropper/root.tsx
1671
- /**
1672
- * Renders the `div` that provides the recipe's variants.
1673
- */
1674
- const Framed = withProvider("div", "root");
1675
- /**
1676
- * Renders the root with the machine's root props, and provides the api to the parts.
1677
- *
1678
- * @param props - The api, the description's words, the recipe's variants and the props of a
1679
- * `div`.
1680
- * @returns The `div` element inside the api provider.
1681
- */
1682
- function Root(t0) {
1683
- const $ = c(20);
1684
- let T0;
1685
- let T1;
1686
- let t1;
1687
- let t2;
1688
- if ($[0] !== t0) {
1689
- const { cropper, description, loadingDescription, ...props } = t0;
1690
- const { naturalSize, rotation, zoom } = cropper;
1691
- let t3;
1692
- if ($[5] !== cropper.crop || $[6] !== description || $[7] !== loadingDescription || $[8] !== naturalSize.height || $[9] !== naturalSize.width || $[10] !== rotation || $[11] !== zoom) {
1693
- t3 = naturalSize.width > 0 && naturalSize.height > 0 ? description?.({
1694
- crop: rounded(cropper.crop),
1695
- rotation,
1696
- zoom
1697
- }) : loadingDescription;
1698
- $[5] = cropper.crop;
1699
- $[6] = description;
1700
- $[7] = loadingDescription;
1701
- $[8] = naturalSize.height;
1702
- $[9] = naturalSize.width;
1703
- $[10] = rotation;
1704
- $[11] = zoom;
1705
- $[12] = t3;
1706
- } else t3 = $[12];
1707
- const described = t3;
1708
- T1 = ApiProvider;
1709
- t2 = cropper;
1710
- T0 = Framed;
1711
- t1 = mergeProps(cropper.getRootProps(), { "aria-description": described }, props);
1712
- $[0] = t0;
1713
- $[1] = T0;
1714
- $[2] = T1;
1715
- $[3] = t1;
1716
- $[4] = t2;
1717
- } else {
1718
- T0 = $[1];
1719
- T1 = $[2];
1720
- t1 = $[3];
1721
- t2 = $[4];
1722
- }
1723
- let t3;
1724
- if ($[13] !== T0 || $[14] !== t1) {
1725
- t3 = /* @__PURE__ */ jsx(T0, { ...t1 });
1726
- $[13] = T0;
1727
- $[14] = t1;
1728
- $[15] = t3;
1729
- } else t3 = $[15];
1730
- let t4;
1731
- if ($[16] !== T1 || $[17] !== t2 || $[18] !== t3) {
1732
- t4 = /* @__PURE__ */ jsx(T1, {
1733
- value: t2,
1734
- children: t3
1735
- });
1736
- $[16] = T1;
1737
- $[17] = t2;
1738
- $[18] = t3;
1739
- $[19] = t4;
1740
- } else t4 = $[19];
1741
- return t4;
1742
- }
1743
- //#endregion
1744
- //#region src/image-cropper/selection.tsx
1745
- /**
1746
- * Renders the `div` with the image cropper's selection class.
1747
- */
1748
- const Drawn$2 = withContext$1("div", "selection");
1749
- /**
1750
- * Renders the selection with the machine's selection props, the value text and the caller's props.
1751
- *
1752
- * @param props - The value text's words and the props of a `div`, the handles and grid among its
1753
- * children.
1754
- * @returns The `div` element.
1755
- */
1756
- function Selection(t0) {
1757
- const $ = c(3);
1758
- const { valueText, ...props } = t0;
1759
- const api = useImageCropperApi();
1760
- const T0 = Drawn$2;
1761
- const t1 = mergeProps(api.getSelectionProps(), { "aria-valuetext": valueText?.(rounded(api.crop)) }, props);
1762
- let t2;
1763
- if ($[0] !== T0 || $[1] !== t1) {
1764
- t2 = /* @__PURE__ */ jsx(T0, { ...t1 });
1765
- $[0] = T0;
1766
- $[1] = t1;
1767
- $[2] = t2;
1768
- } else t2 = $[2];
1769
- return t2;
1770
- }
1771
- //#endregion
1772
- //#region src/image-cropper/viewport.tsx
1773
- /**
1774
- * Renders the `div` with the image cropper's viewport class.
1775
- */
1776
- const Drawn$1 = withContext$1("div", "viewport");
1777
- /**
1778
- * Renders the viewport with the machine's viewport props merged over the caller's.
1779
- *
1780
- * @param props - The props of a `div`.
1781
- * @returns The `div` element.
1782
- */
1783
- function Viewport(props) {
1784
- const $ = c(5);
1785
- const api = useImageCropperApi();
1786
- let t0;
1787
- if ($[0] !== api || $[1] !== props) {
1788
- t0 = mergeProps(api.getViewportProps(), props);
1789
- $[0] = api;
1790
- $[1] = props;
1791
- $[2] = t0;
1792
- } else t0 = $[2];
1793
- let t1;
1794
- if ($[3] !== t0) {
1795
- t1 = /* @__PURE__ */ jsx(Drawn$1, { ...t0 });
1796
- $[3] = t0;
1797
- $[4] = t1;
1798
- } else t1 = $[4];
1799
- return t1;
1800
- }
1801
- //#endregion
1802
- //#region src/image-cropper/index.ts
1803
- var image_cropper_exports = /* @__PURE__ */ __exportAll({
1804
- Grid: () => Grid,
1805
- Handle: () => Handle,
1806
- Image: () => Image,
1807
- Root: () => Root,
1808
- Selection: () => Selection,
1809
- Viewport: () => Viewport,
1810
- handles: () => handles,
1811
- useImageCropper: () => useImageCropper
1812
- });
1813
- //#endregion
1814
- //#region src/video/context.ts
1815
- /**
1816
- * Binds the video recipe to React.
1817
- *
1818
- * @remarks
1819
- * The binding is a separate module from the recipe, because the theme compiler imports the recipe
1820
- * at build time and must not load the React runtime.
1821
- */
1822
- /**
1823
- * Creates the video recipe's `withContext` binding and its `PropsProvider`.
1824
- *
1825
- * @remarks
1826
- * `PropsProvider` sets variants on every video below it. The package exports it as
1827
- * `VideoPropsProvider`.
1828
- */
1829
- const { PropsProvider, withContext } = createRecipeContext(recipe$6);
1830
- //#endregion
1831
- //#region src/video/video.tsx
1832
- /**
1833
- * Renders a `video` element with the classes of the video recipe.
1834
- */
1835
- const Drawn = withContext("video");
1836
- /**
1837
- * Renders the video, starting it by itself only while the reader allows motion.
1838
- *
1839
- * @param props - The recipe's variants and the props of a `video` element.
1840
- * @returns The `video` element.
1841
- */
1842
- function Video(t0) {
1843
- const $ = c(12);
1844
- let controls;
1845
- let playsInline;
1846
- let rest;
1847
- let t1;
1848
- let t2;
1849
- if ($[0] !== t0) {
1850
- ({autoPlay: t1, controls, muted: t2, playsInline, ...rest} = t0);
1851
- $[0] = t0;
1852
- $[1] = controls;
1853
- $[2] = playsInline;
1854
- $[3] = rest;
1855
- $[4] = t1;
1856
- $[5] = t2;
1857
- } else {
1858
- controls = $[1];
1859
- playsInline = $[2];
1860
- rest = $[3];
1861
- t1 = $[4];
1862
- t2 = $[5];
1863
- }
1864
- const autoPlay = t1 === void 0 ? false : t1;
1865
- const muted = t2 === void 0 ? false : t2;
1866
- const reduced = useReducedMotion();
1867
- const plays = autoPlay && !reduced;
1868
- const t3 = controls ?? autoPlay;
1869
- const t4 = plays || muted;
1870
- const t5 = playsInline ?? plays;
1871
- let t6;
1872
- if ($[6] !== plays || $[7] !== rest || $[8] !== t3 || $[9] !== t4 || $[10] !== t5) {
1873
- t6 = /* @__PURE__ */ jsx(Drawn, {
1874
- ...rest,
1875
- autoPlay: plays,
1876
- controls: t3,
1877
- muted: t4,
1878
- playsInline: t5
1879
- });
1880
- $[6] = plays;
1881
- $[7] = rest;
1882
- $[8] = t3;
1883
- $[9] = t4;
1884
- $[10] = t5;
1885
- $[11] = t6;
1886
- } else t6 = $[11];
1887
- return t6;
1888
- }
1889
- //#endregion
1
+ import { T as avatar_exports, f as Iframe, i as image_cropper_exports, j as Audio, n as PropsProvider, p as carousel_exports, t as Video } from "./shared-DH0DrBx7.js";
1890
2
  export { Audio, avatar_exports as Avatar, carousel_exports as Carousel, Iframe, image_cropper_exports as ImageCropper, Video, PropsProvider as VideoPropsProvider };