trc-ui 0.1.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,34 +22,76 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  var src_exports = {};
23
23
  __export(src_exports, {
24
24
  AccentText: () => AccentText,
25
+ Accordion: () => Accordion,
26
+ Alert: () => Alert,
25
27
  ArrowLeft: () => ArrowLeft,
26
28
  ArrowRight: () => ArrowRight,
27
29
  ArrowUp: () => ArrowUp,
30
+ Avatar: () => Avatar,
31
+ AvatarGroup: () => AvatarGroup,
28
32
  BackToTop: () => BackToTop,
33
+ Breadcrumbs: () => Breadcrumbs,
34
+ Calendar: () => Calendar,
29
35
  Card: () => Card,
30
36
  Check: () => Check,
31
37
  Checkbox: () => Checkbox,
32
38
  ChevronDown: () => ChevronDown,
39
+ ChevronLeft: () => ChevronLeft,
40
+ ChevronRight: () => ChevronRight,
33
41
  Close: () => Close,
42
+ CodeBlock: () => CodeBlock,
43
+ Combobox: () => Combobox,
34
44
  Container: () => Container,
45
+ DatePicker: () => DatePicker,
46
+ Dialog: () => Dialog,
47
+ Divider: () => Divider,
48
+ Drawer: () => Drawer,
49
+ DropdownMenu: () => DropdownMenu,
50
+ Dropzone: () => Dropzone,
35
51
  Field: () => Field,
52
+ FileInput: () => FileInput,
36
53
  Heading: () => Heading,
37
54
  HeroVideo: () => HeroVideo,
38
55
  Input: () => Input,
56
+ Kbd: () => Kbd,
57
+ LanguageSwitcher: () => LanguageSwitcher,
39
58
  Menu: () => Menu,
40
59
  PageHero: () => PageHero,
60
+ Pagination: () => Pagination,
61
+ PasswordInput: () => PasswordInput,
41
62
  PillButton: () => PillButton,
42
63
  PillLink: () => PillLink,
64
+ PinInput: () => PinInput,
65
+ Popover: () => Popover,
66
+ Progress: () => Progress,
67
+ RadioGroup: () => RadioGroup,
43
68
  Section: () => Section,
69
+ SegmentedControl: () => SegmentedControl,
44
70
  Select: () => Select,
45
71
  SiteFooter: () => SiteFooter,
46
72
  SiteHeader: () => SiteHeader,
73
+ Skeleton: () => Skeleton,
74
+ Slider: () => Slider,
75
+ Spinner: () => Spinner2,
76
+ Stat: () => Stat,
47
77
  StepNumber: () => StepNumber,
78
+ Steps: () => Steps,
48
79
  Switch: () => Switch,
80
+ Table: () => Table,
81
+ Tabs: () => Tabs,
82
+ Tag: () => Tag,
49
83
  Text: () => Text,
50
84
  Textarea: () => Textarea,
85
+ Toaster: () => Toaster,
86
+ Tooltip: () => Tooltip,
87
+ acceptsFile: () => acceptsFile,
51
88
  cx: () => cx,
52
- plainText: () => plainText
89
+ formatBytes: () => formatBytes,
90
+ initials: () => initials,
91
+ paginationRange: () => paginationRange,
92
+ plainText: () => plainText,
93
+ toast: () => toast,
94
+ validateFiles: () => validateFiles
53
95
  });
54
96
  module.exports = __toCommonJS(src_exports);
55
97
 
@@ -76,15 +118,21 @@ function AccentText({ text, accentLast = 0 }) {
76
118
  ] });
77
119
  }
78
120
  var plainText = (text) => text.replaceAll("*", "");
79
- function Heading({ as: Tag = "h2", size = "xl", accentLast, className, children, ...props }) {
80
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, { className: cx("trc-display", `trc-heading--${size}`, className), ...props, children: typeof children === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccentText, { text: children, accentLast }) : children });
121
+ function Heading({ as: Tag2 = "h2", size: size2 = "xl", accentLast, className, children, ...props }) {
122
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag2, { className: cx("trc-display", `trc-heading--${size2}`, className), ...props, children: typeof children === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccentText, { text: children, accentLast }) : children });
81
123
  }
82
- function Text({ as, size = "md", tone = "muted", className, ...props }) {
83
- const Tag = as ?? "p";
84
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, { className: cx("trc-text", `trc-text--${size}`, `trc-text--${tone}`, className), ...props });
124
+ function Text({
125
+ as,
126
+ size: size2 = "md",
127
+ tone = "muted",
128
+ className,
129
+ ...props
130
+ }) {
131
+ const Tag2 = as ?? "p";
132
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag2, { className: cx("trc-text", `trc-text--${size2}`, `trc-text--${tone}`, className), ...props });
85
133
  }
86
- function StepNumber({ n, size = "md", className }) {
87
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: cx("trc-step-number", size === "sm" && "trc-step-number--sm", className), children: String(n).padStart(2, "0") });
134
+ function StepNumber({ n, size: size2 = "md", className }) {
135
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, className: cx("trc-step-number", size2 === "sm" && "trc-step-number--sm", className), children: String(n).padStart(2, "0") });
88
136
  }
89
137
 
90
138
  // src/components/pill.tsx
@@ -110,10 +158,16 @@ var Check = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...
110
158
  var Menu = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...base, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 7h16M4 12h16M4 17h16" }) });
111
159
  var Close = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...base, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) });
112
160
  var ArrowUp = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...base, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 19V5M6 11l6-6 6 6" }) });
161
+ var Calendar = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { ...base, ...props, children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "5", width: "18", height: "16", rx: "3" }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 10h18M8 3v4M16 3v4" })
164
+ ] });
165
+ var ChevronLeft = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...base, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 6-6 6 6 6" }) });
166
+ var ChevronRight = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { ...base, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 6 6 6-6 6" }) });
113
167
 
114
168
  // src/components/pill.tsx
115
169
  var import_jsx_runtime3 = require("react/jsx-runtime");
116
- var pillClass = ({ solid, size }, className) => cx("trc-pill", size === "sm" && "trc-pill--sm", solid && "trc-pill--solid", className);
170
+ var pillClass = ({ solid, size: size2 }, className) => cx("trc-pill", size2 === "sm" && "trc-pill--sm", solid && "trc-pill--solid", className);
117
171
  function PillInner({ icon, children }) {
118
172
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
119
173
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, className: "trc-pill__fill" }),
@@ -121,7 +175,7 @@ function PillInner({ icon, children }) {
121
175
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "trc-pill__label", children })
122
176
  ] });
123
177
  }
124
- var PillButton = (0, import_react.forwardRef)(function PillButton2({ solid, size = "md", icon, loading = false, disabled, type = "button", className, children, ...props }, ref) {
178
+ var PillButton = (0, import_react.forwardRef)(function PillButton2({ solid, size: size2 = "md", icon, loading = false, disabled, type = "button", className, children, ...props }, ref) {
125
179
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
126
180
  "button",
127
181
  {
@@ -129,22 +183,27 @@ var PillButton = (0, import_react.forwardRef)(function PillButton2({ solid, size
129
183
  type,
130
184
  disabled: disabled || loading,
131
185
  "aria-busy": loading || void 0,
132
- className: pillClass({ solid, size }, className),
186
+ className: pillClass({ solid, size: size2 }, className),
133
187
  ...props,
134
188
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PillInner, { icon: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { className: "trc-spin" }) : icon, children })
135
189
  }
136
190
  );
137
191
  });
138
- var PillLink = (0, import_react.forwardRef)(function PillLink2({ as, solid, size = "md", icon, className, children, ...props }, ref) {
139
- const Tag = as ?? "a";
140
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Tag, { ref, className: pillClass({ solid, size }, className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PillInner, { icon, children }) });
192
+ var PillLink = (0, import_react.forwardRef)(function PillLink2({ as, solid, size: size2 = "md", icon, className, children, ...props }, ref) {
193
+ const Tag2 = as ?? "a";
194
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Tag2, { ref, className: pillClass({ solid, size: size2 }, className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PillInner, { icon, children }) });
141
195
  });
142
196
 
143
197
  // src/components/surfaces.tsx
144
198
  var import_jsx_runtime4 = require("react/jsx-runtime");
145
- function Container({ as, size = "default", className, ...props }) {
146
- const Tag = as ?? "div";
147
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag, { className: cx("trc-container", size !== "default" && `trc-container--${size}`, className), ...props });
199
+ function Container({
200
+ as,
201
+ size: size2 = "default",
202
+ className,
203
+ ...props
204
+ }) {
205
+ const Tag2 = as ?? "div";
206
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag2, { className: cx("trc-container", size2 !== "default" && `trc-container--${size2}`, className), ...props });
148
207
  }
149
208
  function Section({
150
209
  as,
@@ -154,11 +213,11 @@ function Section({
154
213
  children,
155
214
  ...props
156
215
  }) {
157
- const Tag = as ?? "section";
216
+ const Tag2 = as ?? "section";
158
217
  if (inset) {
159
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag, { className: cx("trc-section-inset", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cx("trc-section-inset__card", spacing !== "none" && `trc-section--${spacing}`), children }) });
218
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag2, { className: cx("trc-section-inset", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cx("trc-section-inset__card", spacing !== "none" && `trc-section--${spacing}`), children }) });
160
219
  }
161
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag, { className: cx(spacing !== "none" && `trc-section--${spacing}`, className), ...props, children });
220
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tag2, { className: cx(spacing !== "none" && `trc-section--${spacing}`, className), ...props, children });
162
221
  }
163
222
  function Card({
164
223
  as,
@@ -170,9 +229,9 @@ function Card({
170
229
  children,
171
230
  ...props
172
231
  }) {
173
- const Tag = as ?? "div";
232
+ const Tag2 = as ?? "div";
174
233
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
175
- Tag,
234
+ Tag2,
176
235
  {
177
236
  className: cx(
178
237
  "trc-card",
@@ -289,8 +348,10 @@ var Switch = (0, import_react3.forwardRef)(function Switch2({ label, description
289
348
  });
290
349
 
291
350
  // src/components/site-header.tsx
292
- var import_react5 = require("react");
293
- var import_react_dom = require("react-dom");
351
+ var import_react7 = require("react");
352
+
353
+ // src/components/layer.tsx
354
+ var import_react6 = require("react");
294
355
 
295
356
  // src/hooks/use-modal.ts
296
357
  var import_react4 = require("react");
@@ -312,9 +373,9 @@ function useModal(open, panelRef, onClose) {
312
373
  return;
313
374
  }
314
375
  if (e.key !== "Tab") return;
315
- const items = [...panel.querySelectorAll(FOCUSABLE)].filter((el) => el.offsetParent !== null);
316
- const first = items[0];
317
- const last = items[items.length - 1];
376
+ const items2 = [...panel.querySelectorAll(FOCUSABLE)].filter((el) => el.offsetParent !== null);
377
+ const first = items2[0];
378
+ const last = items2[items2.length - 1];
318
379
  if (!first || !last) {
319
380
  e.preventDefault();
320
381
  return;
@@ -336,8 +397,88 @@ function useModal(open, panelRef, onClose) {
336
397
  }, [open, panelRef]);
337
398
  }
338
399
 
339
- // src/components/site-header.tsx
400
+ // src/utils/portal.tsx
401
+ var import_react5 = require("react");
402
+ var import_react_dom = require("react-dom");
403
+ var noop = () => () => {
404
+ };
405
+ var useIsClient = () => (0, import_react5.useSyncExternalStore)(
406
+ noop,
407
+ () => true,
408
+ () => false
409
+ );
410
+ function Portal({ children }) {
411
+ return useIsClient() ? (0, import_react_dom.createPortal)(children, document.body) : null;
412
+ }
413
+
414
+ // src/components/layer.tsx
340
415
  var import_jsx_runtime7 = require("react/jsx-runtime");
416
+ function ModalLayer({
417
+ open,
418
+ onClose,
419
+ title,
420
+ description,
421
+ children,
422
+ footer,
423
+ closeLabel,
424
+ closeOnOverlay,
425
+ rootClassName,
426
+ panelClassName
427
+ }) {
428
+ const titleId = (0, import_react6.useId)();
429
+ const descriptionId = (0, import_react6.useId)();
430
+ const panel = (0, import_react6.useRef)(null);
431
+ useModal(open, panel, onClose);
432
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cx("trc-layer", rootClassName, open && "trc-layer--open"), "aria-hidden": !open, children: [
433
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-layer__overlay", onClick: closeOnOverlay ? onClose : void 0 }),
434
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
435
+ "div",
436
+ {
437
+ ref: panel,
438
+ role: "dialog",
439
+ "aria-modal": "true",
440
+ "aria-labelledby": titleId,
441
+ "aria-describedby": description != null ? descriptionId : void 0,
442
+ tabIndex: -1,
443
+ className: panelClassName,
444
+ children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "trc-layer__head", children: [
446
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { id: titleId, className: "trc-layer__title", children: title }),
447
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "trc-layer__close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Close, {}) })
448
+ ] }),
449
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { id: descriptionId, className: "trc-layer__description", children: description }),
450
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-layer__body", children }),
451
+ footer != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-layer__footer", children: footer })
452
+ ]
453
+ }
454
+ )
455
+ ] }) });
456
+ }
457
+
458
+ // src/components/drawer.tsx
459
+ var import_jsx_runtime8 = require("react/jsx-runtime");
460
+ function Drawer({
461
+ side = "right",
462
+ size: size2 = "sm",
463
+ closeLabel = "Close",
464
+ closeOnOverlay = true,
465
+ className,
466
+ ...props
467
+ }) {
468
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
469
+ ModalLayer,
470
+ {
471
+ ...props,
472
+ closeLabel,
473
+ closeOnOverlay,
474
+ rootClassName: `trc-layer--drawer trc-layer--${side}`,
475
+ panelClassName: cx("trc-drawer", `trc-drawer--${size2}`, className)
476
+ }
477
+ );
478
+ }
479
+
480
+ // src/components/site-header.tsx
481
+ var import_jsx_runtime9 = require("react/jsx-runtime");
341
482
  var isMenu = (item) => "items" in item;
342
483
  function SiteHeader({
343
484
  logo,
@@ -353,19 +494,19 @@ function SiteHeader({
353
494
  closeLabel = "Close",
354
495
  className
355
496
  }) {
356
- const [scrolled, setScrolled] = (0, import_react5.useState)(false);
357
- const [open, setOpen] = (0, import_react5.useState)(false);
358
- (0, import_react5.useEffect)(() => {
497
+ const [scrolled, setScrolled] = (0, import_react7.useState)(false);
498
+ const [open, setOpen] = (0, import_react7.useState)(false);
499
+ (0, import_react7.useEffect)(() => {
359
500
  const update = () => setScrolled(window.scrollY > scrollThreshold);
360
501
  update();
361
502
  window.addEventListener("scroll", update, { passive: true });
362
503
  return () => window.removeEventListener("scroll", update);
363
504
  }, [scrollThreshold]);
364
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: cx("trc-header", className), children: [
365
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cx("trc-header__bar", scrolled && "trc-header__bar--scrolled"), children: [
366
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkTag, { href: homeHref, "aria-label": logoLabel, className: "trc-header__logo", children: logo }),
367
- nav.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { className: "trc-header__nav", children: nav.map(
368
- (item, i) => isMenu(item) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NavDropdown, { menu: item, linkAs: LinkTag }, i) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
505
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { className: cx("trc-header", className), children: [
506
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cx("trc-header__bar", scrolled && "trc-header__bar--scrolled"), children: [
507
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LinkTag, { href: homeHref, "aria-label": logoLabel, className: "trc-header__logo", children: logo }),
508
+ nav.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("nav", { className: "trc-header__nav", children: nav.map(
509
+ (item, i) => isMenu(item) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(NavDropdown, { menu: item, linkAs: LinkTag }, i) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
369
510
  LinkTag,
370
511
  {
371
512
  href: item.href,
@@ -376,10 +517,10 @@ function SiteHeader({
376
517
  i
377
518
  )
378
519
  ) }),
379
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "trc-header__end", children: [
380
- actions && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-header__actions", children: actions }),
381
- cta && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PillLink, { as: LinkTag, href: cta.href, size: "sm", className: "trc-header__cta", children: cta.label }),
382
- (nav.length > 0 || cta || mobileFooter) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
520
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-header__end", children: [
521
+ actions && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-header__actions", children: actions }),
522
+ cta && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PillLink, { as: LinkTag, href: cta.href, size: "sm", className: "trc-header__cta", children: cta.label }),
523
+ (nav.length > 0 || cta || mobileFooter) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
383
524
  "button",
384
525
  {
385
526
  type: "button",
@@ -387,12 +528,12 @@ function SiteHeader({
387
528
  "aria-label": menuLabel,
388
529
  "aria-expanded": open,
389
530
  onClick: () => setOpen(true),
390
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Menu, {})
531
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Menu, {})
391
532
  }
392
533
  )
393
534
  ] })
394
535
  ] }),
395
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
536
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
396
537
  MobileMenu,
397
538
  {
398
539
  open,
@@ -408,19 +549,21 @@ function SiteHeader({
408
549
  ] });
409
550
  }
410
551
  function NavDropdown({ menu, linkAs: LinkTag }) {
411
- const id = (0, import_react5.useId)();
412
- const [open, setOpen] = (0, import_react5.useState)(false);
413
- const closeTimer = (0, import_react5.useRef)(void 0);
414
- const button = (0, import_react5.useRef)(null);
552
+ const id = (0, import_react7.useId)();
553
+ const [open, setOpen] = (0, import_react7.useState)(false);
554
+ const closeTimer = (0, import_react7.useRef)(void 0);
555
+ const button = (0, import_react7.useRef)(null);
556
+ const openedByHover = (0, import_react7.useRef)(false);
415
557
  const show = () => {
416
558
  window.clearTimeout(closeTimer.current);
559
+ if (!open) openedByHover.current = true;
417
560
  setOpen(true);
418
561
  };
419
562
  const hide = () => {
420
563
  closeTimer.current = window.setTimeout(() => setOpen(false), 120);
421
564
  };
422
- (0, import_react5.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
423
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
565
+ (0, import_react7.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
566
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
424
567
  "div",
425
568
  {
426
569
  className: "trc-dropdown",
@@ -434,22 +577,25 @@ function NavDropdown({ menu, linkAs: LinkTag }) {
434
577
  },
435
578
  onBlur: (e) => !e.currentTarget.contains(e.relatedTarget) && setOpen(false),
436
579
  children: [
437
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
580
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
438
581
  "button",
439
582
  {
440
583
  ref: button,
441
584
  type: "button",
442
585
  "aria-expanded": open,
443
586
  "aria-controls": id,
444
- onClick: () => setOpen((o) => !o),
587
+ onClick: () => {
588
+ if (open && openedByHover.current) openedByHover.current = false;
589
+ else setOpen((o) => !o);
590
+ },
445
591
  className: cx("trc-header__link", "trc-dropdown__trigger", open && "trc-dropdown__trigger--open"),
446
592
  children: [
447
593
  menu.label,
448
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDown, { className: "trc-dropdown__chevron" })
594
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChevronDown, { className: "trc-dropdown__chevron" })
449
595
  ]
450
596
  }
451
597
  ),
452
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { id, className: cx("trc-dropdown__panel", open && "trc-dropdown__panel--open"), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "trc-dropdown__list", children: menu.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
598
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { id, className: cx("trc-dropdown__panel", open && "trc-dropdown__panel--open"), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "trc-dropdown__list", children: menu.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
453
599
  LinkTag,
454
600
  {
455
601
  href: item.href,
@@ -457,8 +603,8 @@ function NavDropdown({ menu, linkAs: LinkTag }) {
457
603
  onClick: () => setOpen(false),
458
604
  className: "trc-dropdown__item",
459
605
  children: [
460
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "trc-dropdown__label", children: item.label }),
461
- item.description != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "trc-dropdown__description", children: item.description })
606
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "trc-dropdown__label", children: item.label }),
607
+ item.description != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "trc-dropdown__description", children: item.description })
462
608
  ]
463
609
  }
464
610
  ) }, i)) }) })
@@ -476,66 +622,39 @@ function MobileMenu({
476
622
  title,
477
623
  closeLabel
478
624
  }) {
479
- const titleId = (0, import_react5.useId)();
480
- const panel = (0, import_react5.useRef)(null);
481
- const [mounted, setMounted] = (0, import_react5.useState)(false);
482
- (0, import_react5.useEffect)(() => setMounted(true), []);
483
- useModal(open, panel, onClose);
484
- if (!mounted) return null;
485
- return (0, import_react_dom.createPortal)(
486
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cx("trc-drawer", open && "trc-drawer--open"), "aria-hidden": !open, children: [
487
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-drawer__overlay", onClick: onClose }),
488
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
489
- "div",
625
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Drawer, { open, onClose, title, closeLabel, className: "trc-mobile-menu", children: [
626
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("nav", { className: "trc-mobile-nav", children: nav.map(
627
+ (item, i) => isMenu(item) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-mobile-nav__group", children: [
628
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "trc-mobile-nav__heading", children: item.label }),
629
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "trc-mobile-nav__sub", children: item.items.map((sub, j) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
630
+ LinkTag,
631
+ {
632
+ href: sub.href,
633
+ "aria-current": sub.active ? "page" : void 0,
634
+ onClick: onClose,
635
+ className: "trc-mobile-nav__sublink",
636
+ children: sub.label
637
+ }
638
+ ) }, j)) })
639
+ ] }, i) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
640
+ LinkTag,
490
641
  {
491
- ref: panel,
492
- role: "dialog",
493
- "aria-modal": "true",
494
- "aria-labelledby": titleId,
495
- tabIndex: -1,
496
- className: "trc-drawer__panel",
497
- children: [
498
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "trc-drawer__head", children: [
499
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { id: titleId, className: "trc-drawer__title", children: title }),
500
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "trc-drawer__close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Close, {}) })
501
- ] }),
502
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { className: "trc-mobile-nav", children: nav.map(
503
- (item, i) => isMenu(item) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "trc-mobile-nav__group", children: [
504
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "trc-mobile-nav__heading", children: item.label }),
505
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "trc-mobile-nav__sub", children: item.items.map((sub, j) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
506
- LinkTag,
507
- {
508
- href: sub.href,
509
- "aria-current": sub.active ? "page" : void 0,
510
- onClick: onClose,
511
- className: "trc-mobile-nav__sublink",
512
- children: sub.label
513
- }
514
- ) }, j)) })
515
- ] }, i) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
516
- LinkTag,
517
- {
518
- href: item.href,
519
- "aria-current": item.active ? "page" : void 0,
520
- onClick: onClose,
521
- className: cx("trc-mobile-nav__link", item.active && "trc-mobile-nav__link--active"),
522
- children: item.label
523
- },
524
- i
525
- )
526
- ) }),
527
- cta && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PillLink, { as: LinkTag, href: cta.href, onClick: onClose, className: "trc-drawer__cta", children: cta.label }),
528
- footer != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "trc-drawer__footer", children: footer })
529
- ]
530
- }
642
+ href: item.href,
643
+ "aria-current": item.active ? "page" : void 0,
644
+ onClick: onClose,
645
+ className: cx("trc-mobile-nav__link", item.active && "trc-mobile-nav__link--active"),
646
+ children: item.label
647
+ },
648
+ i
531
649
  )
532
- ] }),
533
- document.body
534
- );
650
+ ) }),
651
+ cta && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PillLink, { as: LinkTag, href: cta.href, onClick: onClose, className: "trc-mobile-menu__cta", children: cta.label }),
652
+ footer != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-mobile-menu__footer", children: footer })
653
+ ] });
535
654
  }
536
655
 
537
656
  // src/components/site-footer.tsx
538
- var import_jsx_runtime8 = require("react/jsx-runtime");
657
+ var import_jsx_runtime10 = require("react/jsx-runtime");
539
658
  function SiteFooter({
540
659
  logo,
541
660
  logoLabel,
@@ -550,28 +669,28 @@ function SiteFooter({
550
669
  linkAs: LinkTag = "a",
551
670
  className
552
671
  }) {
553
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { className: cx("trc-footer", className), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "trc-footer__card", children: [
554
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "trc-footer__main", children: [
555
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "trc-footer__brand", children: [
556
- logo != null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkTag, { href: homeHref, "aria-label": logoLabel, className: "trc-footer__logo", children: logo }),
557
- tagline != null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "trc-footer__tagline", children: tagline }),
558
- children != null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "trc-footer__extra", children })
672
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("footer", { className: cx("trc-footer", className), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "trc-footer__card", children: [
673
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "trc-footer__main", children: [
674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "trc-footer__brand", children: [
675
+ logo != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LinkTag, { href: homeHref, "aria-label": logoLabel, className: "trc-footer__logo", children: logo }),
676
+ tagline != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "trc-footer__tagline", children: tagline }),
677
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "trc-footer__extra", children })
559
678
  ] }),
560
- columns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("nav", { className: "trc-footer__columns", "aria-label": columnsLabel, children: columns.map((col, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
561
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "trc-footer__heading", children: col.title }),
562
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "trc-footer__list", children: col.links.map((link, j) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkTag, { href: link.href, className: "trc-footer__link", children: link.label }) }, j)) })
679
+ columns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("nav", { className: "trc-footer__columns", "aria-label": columnsLabel, children: columns.map((col, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
680
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "trc-footer__heading", children: col.title }),
681
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "trc-footer__list", children: col.links.map((link, j) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LinkTag, { href: link.href, className: "trc-footer__link", children: link.label }) }, j)) })
563
682
  ] }, i)) })
564
683
  ] }),
565
- (copyright != null || legal.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "trc-footer__bottom", children: [
566
- copyright != null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "trc-footer__copyright", children: copyright }),
567
- legal.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("nav", { "aria-label": legalLabel, className: "trc-footer__legal", children: legal.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkTag, { href: link.href, className: "trc-footer__legal-link", children: link.label }, i)) })
684
+ (copyright != null || legal.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "trc-footer__bottom", children: [
685
+ copyright != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "trc-footer__copyright", children: copyright }),
686
+ legal.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("nav", { "aria-label": legalLabel, className: "trc-footer__legal", children: legal.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LinkTag, { href: link.href, className: "trc-footer__legal-link", children: link.label }, i)) })
568
687
  ] })
569
688
  ] }) });
570
689
  }
571
690
 
572
691
  // src/components/hero.tsx
573
- var import_react6 = require("react");
574
- var import_jsx_runtime9 = require("react/jsx-runtime");
692
+ var import_react8 = require("react");
693
+ var import_jsx_runtime11 = require("react/jsx-runtime");
575
694
  var delay = (ms) => ({ "--trc-delay": `${ms}ms` });
576
695
  function PageHero({
577
696
  title,
@@ -584,24 +703,24 @@ function PageHero({
584
703
  className
585
704
  }) {
586
705
  const words = title.split(" ").length;
587
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("section", { className: cx("trc-hero-inset", className), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-page-hero", children: [
588
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "aria-hidden": true, className: "trc-hero__media", children: typeof image === "string" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: image, alt: "", className: "trc-hero__image", style: { objectPosition: imagePosition } }) : image != null ? image : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-page-hero__glow" }) }),
589
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "aria-hidden": true, className: "trc-page-hero__veil" }),
590
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-page-hero__content", children: [
591
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", { className: "trc-display trc-page-hero__title trc-enter", style: delay(150), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AccentText, { text: title, accentLast: accentLast ?? (words > 3 ? 2 : 1) }) }),
592
- description != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "trc-page-hero__description trc-enter", style: delay(250), children: description }),
593
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-page-hero__meta trc-enter", style: delay(350), children: meta }),
594
- children != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-page-hero__actions trc-enter", style: delay(450), children })
706
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { className: cx("trc-hero-inset", className), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "trc-page-hero", children: [
707
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { "aria-hidden": true, className: "trc-hero__media", children: typeof image === "string" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { src: image, alt: "", className: "trc-hero__image", style: { objectPosition: imagePosition } }) : image != null ? image : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "trc-page-hero__glow" }) }),
708
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { "aria-hidden": true, className: "trc-page-hero__veil" }),
709
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "trc-page-hero__content", children: [
710
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h1", { className: "trc-display trc-page-hero__title trc-enter", style: delay(150), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AccentText, { text: title, accentLast: accentLast ?? (words > 3 ? 2 : 1) }) }),
711
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "trc-page-hero__description trc-enter", style: delay(250), children: description }),
712
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "trc-page-hero__meta trc-enter", style: delay(350), children: meta }),
713
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "trc-page-hero__actions trc-enter", style: delay(450), children })
595
714
  ] })
596
715
  ] }) });
597
716
  }
598
717
  var prefersReducedMotion = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
599
718
  function HeroVideo({ clips, children, aside, fade = 1.2, parallax = true, className }) {
600
- const videos = (0, import_react6.useRef)([]);
601
- const section = (0, import_react6.useRef)(null);
602
- const media = (0, import_react6.useRef)(null);
603
- const [active, setActive] = (0, import_react6.useState)(-1);
604
- (0, import_react6.useEffect)(() => {
719
+ const videos = (0, import_react8.useRef)([]);
720
+ const section = (0, import_react8.useRef)(null);
721
+ const media = (0, import_react8.useRef)(null);
722
+ const [active, setActive] = (0, import_react8.useState)(-1);
723
+ (0, import_react8.useEffect)(() => {
605
724
  if (clips.length === 0) return;
606
725
  const start = Math.floor(Math.random() * clips.length);
607
726
  const video = videos.current[start];
@@ -613,7 +732,7 @@ function HeroVideo({ clips, children, aside, fade = 1.2, parallax = true, classN
613
732
  video?.pause();
614
733
  };
615
734
  }, [clips.length]);
616
- (0, import_react6.useEffect)(() => {
735
+ (0, import_react8.useEffect)(() => {
617
736
  const el = section.current;
618
737
  const layer = media.current;
619
738
  if (!parallax || !el || !layer || prefersReducedMotion()) return;
@@ -642,8 +761,8 @@ function HeroVideo({ clips, children, aside, fade = 1.2, parallax = true, classN
642
761
  });
643
762
  setActive((i + 1) % clips.length);
644
763
  };
645
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("section", { ref: section, className: cx("trc-hero-inset", className), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-hero-video", children: [
646
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: media, "aria-hidden": true, className: "trc-hero__media trc-hero-video__media", children: clips.map((clip, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
764
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { ref: section, className: cx("trc-hero-inset", className), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "trc-hero-video", children: [
765
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: media, "aria-hidden": true, className: "trc-hero__media trc-hero-video__media", children: clips.map((clip, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
647
766
  "video",
648
767
  {
649
768
  ref: (el) => {
@@ -661,32 +780,32 @@ function HeroVideo({ clips, children, aside, fade = 1.2, parallax = true, classN
661
780
  },
662
781
  onEnded: () => i === active && playNext(i),
663
782
  children: [
664
- clip.webm && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("source", { src: clip.webm, type: "video/webm" }),
665
- clip.mp4 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("source", { src: clip.mp4, type: "video/mp4" })
783
+ clip.webm && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("source", { src: clip.webm, type: "video/webm" }),
784
+ clip.mp4 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("source", { src: clip.mp4, type: "video/mp4" })
666
785
  ]
667
786
  },
668
787
  i
669
788
  )) }),
670
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "aria-hidden": true, className: "trc-hero-video__veil" }),
671
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "trc-hero-video__content", children: [
672
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-hero-video__main", children }),
673
- aside != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "trc-hero-video__aside", children: aside })
789
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { "aria-hidden": true, className: "trc-hero-video__veil" }),
790
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "trc-hero-video__content", children: [
791
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "trc-hero-video__main", children }),
792
+ aside != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "trc-hero-video__aside", children: aside })
674
793
  ] })
675
794
  ] }) });
676
795
  }
677
796
 
678
797
  // src/components/back-to-top.tsx
679
- var import_react7 = require("react");
680
- var import_jsx_runtime10 = require("react/jsx-runtime");
798
+ var import_react9 = require("react");
799
+ var import_jsx_runtime12 = require("react/jsx-runtime");
681
800
  function BackToTop({ label = "Back to top", threshold = 0.8, className }) {
682
- const [visible, setVisible] = (0, import_react7.useState)(false);
683
- (0, import_react7.useEffect)(() => {
801
+ const [visible, setVisible] = (0, import_react9.useState)(false);
802
+ (0, import_react9.useEffect)(() => {
684
803
  const update = () => setVisible(window.scrollY > window.innerHeight * threshold);
685
804
  update();
686
805
  window.addEventListener("scroll", update, { passive: true });
687
806
  return () => window.removeEventListener("scroll", update);
688
807
  }, [threshold]);
689
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
808
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
690
809
  "button",
691
810
  {
692
811
  type: "button",
@@ -698,40 +817,1894 @@ function BackToTop({ label = "Back to top", threshold = 0.8, className }) {
698
817
  "aria-hidden": !visible,
699
818
  tabIndex: visible ? 0 : -1,
700
819
  className: cx("trc-back-to-top", visible && "trc-back-to-top--visible", className),
701
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ArrowUp, {})
820
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ArrowUp, {})
821
+ }
822
+ );
823
+ }
824
+
825
+ // src/components/dialog.tsx
826
+ var import_jsx_runtime13 = require("react/jsx-runtime");
827
+ function Dialog({ size: size2 = "md", closeLabel = "Close", closeOnOverlay = true, className, ...props }) {
828
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
829
+ ModalLayer,
830
+ {
831
+ ...props,
832
+ closeLabel,
833
+ closeOnOverlay,
834
+ rootClassName: "trc-layer--dialog",
835
+ panelClassName: cx("trc-dialog", `trc-dialog--${size2}`, className)
836
+ }
837
+ );
838
+ }
839
+
840
+ // src/components/dropdown-menu.tsx
841
+ var import_react12 = require("react");
842
+
843
+ // src/hooks/use-floating.ts
844
+ var import_react10 = require("react");
845
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? import_react10.useEffect : import_react10.useLayoutEffect;
846
+ var MARGIN = 8;
847
+ function useAnchoredPosition(open, anchorRef, floatingRef, { side = "bottom", align = "start", offset = 8 } = {}) {
848
+ useIsomorphicLayoutEffect(() => {
849
+ if (!open) return;
850
+ const update = () => {
851
+ const anchor = anchorRef.current;
852
+ const floating = floatingRef.current;
853
+ if (!anchor || !floating) return;
854
+ const a = anchor.getBoundingClientRect();
855
+ const f = floating.getBoundingClientRect();
856
+ const vw = window.innerWidth;
857
+ const vh = window.innerHeight;
858
+ const below = a.bottom + offset;
859
+ const above = a.top - offset - f.height;
860
+ const fitsBelow = below + f.height <= vh - MARGIN;
861
+ const fitsAbove = above >= MARGIN;
862
+ const resolved = side === "bottom" ? fitsBelow || !fitsAbove ? "bottom" : "top" : fitsAbove || !fitsBelow ? "top" : "bottom";
863
+ const top = resolved === "bottom" ? below : above;
864
+ let left = align === "start" ? a.left : align === "end" ? a.right - f.width : a.left + a.width / 2 - f.width / 2;
865
+ left = Math.min(Math.max(left, MARGIN), Math.max(MARGIN, vw - f.width - MARGIN));
866
+ floating.style.top = `${Math.round(top)}px`;
867
+ floating.style.left = `${Math.round(left)}px`;
868
+ floating.dataset.side = resolved;
869
+ };
870
+ update();
871
+ window.addEventListener("resize", update);
872
+ window.addEventListener("scroll", update, true);
873
+ return () => {
874
+ window.removeEventListener("resize", update);
875
+ window.removeEventListener("scroll", update, true);
876
+ };
877
+ }, [open, side, align, offset]);
878
+ }
879
+ function useDismiss(open, refs, onDismiss) {
880
+ const dismiss2 = (0, import_react10.useRef)(onDismiss);
881
+ dismiss2.current = onDismiss;
882
+ (0, import_react10.useEffect)(() => {
883
+ if (!open) return;
884
+ const onPointerDown = (e) => {
885
+ const target = e.target;
886
+ if (!refs.some((ref) => ref.current?.contains(target))) dismiss2.current("outside");
887
+ };
888
+ const onKeyDown = (e) => {
889
+ if (e.key === "Escape") dismiss2.current("escape");
890
+ };
891
+ document.addEventListener("pointerdown", onPointerDown);
892
+ document.addEventListener("keydown", onKeyDown);
893
+ return () => {
894
+ document.removeEventListener("pointerdown", onPointerDown);
895
+ document.removeEventListener("keydown", onKeyDown);
896
+ };
897
+ }, [open]);
898
+ }
899
+
900
+ // src/utils/compose.ts
901
+ var import_react11 = require("react");
902
+ function callAll(...fns) {
903
+ return (...args) => fns.forEach((fn) => fn?.(...args));
904
+ }
905
+ function mergeRefs(...refs) {
906
+ return (value) => {
907
+ for (const ref of refs) {
908
+ if (typeof ref === "function") ref(value);
909
+ else if (ref) ref.current = value;
910
+ }
911
+ };
912
+ }
913
+ function getElementRef(element) {
914
+ const fromProps = element.props.ref;
915
+ if (Number.parseInt(import_react11.version, 10) >= 19) return fromProps;
916
+ return element.ref;
917
+ }
918
+
919
+ // src/components/dropdown-menu.tsx
920
+ var import_jsx_runtime14 = require("react/jsx-runtime");
921
+ var isAction = (item) => item !== "separator";
922
+ var textOf = (item) => (item.textValue ?? (typeof item.label === "string" ? item.label : "")).toLowerCase();
923
+ function DropdownMenu({ trigger, items: items2, align = "start", linkAs: LinkTag = "a", className }) {
924
+ const [open, setOpen] = (0, import_react12.useState)(false);
925
+ const triggerRef = (0, import_react12.useRef)(null);
926
+ const menuRef = (0, import_react12.useRef)(null);
927
+ const itemRefs = (0, import_react12.useRef)([]);
928
+ const generatedId = (0, import_react12.useId)();
929
+ const triggerId = trigger.props.id ?? `${generatedId}-trigger`;
930
+ const menuId = `${generatedId}-menu`;
931
+ const enabled = items2.map((item, i) => isAction(item) && !item.disabled ? i : -1).filter((i) => i >= 0);
932
+ const focusItem = (index) => index !== void 0 && itemRefs.current[index]?.focus();
933
+ const openMenu = (focus) => {
934
+ setOpen(true);
935
+ requestAnimationFrame(() => focusItem(focus === "first" ? enabled[0] : enabled[enabled.length - 1]));
936
+ };
937
+ const close = (returnFocus = true) => {
938
+ setOpen(false);
939
+ if (returnFocus) triggerRef.current?.focus();
940
+ };
941
+ useAnchoredPosition(open, triggerRef, menuRef, { side: "bottom", align });
942
+ useDismiss(open, [triggerRef, menuRef], (reason) => close(reason === "escape"));
943
+ const select = (item) => {
944
+ item.onSelect?.();
945
+ close();
946
+ };
947
+ const onMenuKeyDown = (e) => {
948
+ const current = itemRefs.current.findIndex((el) => el === document.activeElement);
949
+ const position = enabled.indexOf(current);
950
+ const move = (to) => {
951
+ e.preventDefault();
952
+ focusItem(enabled[(to + enabled.length) % enabled.length]);
953
+ };
954
+ if (e.key === "ArrowDown") move(position + 1);
955
+ else if (e.key === "ArrowUp") move(position - 1);
956
+ else if (e.key === "Home") move(0);
957
+ else if (e.key === "End") move(enabled.length - 1);
958
+ else if (e.key === "Tab") close(false);
959
+ else if (e.key.length === 1 && /\S/.test(e.key)) {
960
+ const letter = e.key.toLowerCase();
961
+ const order = [...enabled.slice(position + 1), ...enabled.slice(0, position + 1)];
962
+ const match = order.find((i) => textOf(items2[i]).startsWith(letter));
963
+ if (match !== void 0) focusItem(match);
964
+ }
965
+ };
966
+ const triggerElement = (0, import_react12.cloneElement)(trigger, {
967
+ ref: mergeRefs(triggerRef, getElementRef(trigger)),
968
+ id: triggerId,
969
+ "aria-haspopup": "menu",
970
+ "aria-expanded": open,
971
+ "aria-controls": open ? menuId : void 0,
972
+ onClick: callAll(trigger.props.onClick, () => open ? close() : openMenu("first")),
973
+ onKeyDown: callAll(trigger.props.onKeyDown, (e) => {
974
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
975
+ e.preventDefault();
976
+ openMenu(e.key === "ArrowDown" ? "first" : "last");
977
+ }
978
+ })
979
+ });
980
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
981
+ triggerElement,
982
+ open && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
983
+ "div",
984
+ {
985
+ ref: menuRef,
986
+ id: menuId,
987
+ role: "menu",
988
+ "aria-labelledby": triggerId,
989
+ className: cx("trc-floating", "trc-menu", className),
990
+ onKeyDown: onMenuKeyDown,
991
+ children: items2.map((item, i) => {
992
+ if (!isAction(item)) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "separator", className: "trc-menu__separator" }, i);
993
+ const shared = {
994
+ ref: (el) => {
995
+ itemRefs.current[i] = el;
996
+ },
997
+ role: "menuitem",
998
+ tabIndex: -1,
999
+ "aria-disabled": item.disabled || void 0,
1000
+ className: cx("trc-menu__item", item.danger && "trc-menu__item--danger"),
1001
+ onMouseMove: (e) => !item.disabled && e.currentTarget.focus(),
1002
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1003
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "trc-menu__label", children: item.label }),
1004
+ item.hint != null && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "trc-menu__hint", children: item.hint })
1005
+ ] })
1006
+ };
1007
+ return item.href && !item.disabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LinkTag, { href: item.href, ...shared, onClick: () => select(item) }, i) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1008
+ "div",
1009
+ {
1010
+ ...shared,
1011
+ onClick: () => !item.disabled && select(item),
1012
+ onKeyDown: (e) => {
1013
+ if ((e.key === "Enter" || e.key === " ") && !item.disabled) {
1014
+ e.preventDefault();
1015
+ select(item);
1016
+ }
1017
+ }
1018
+ },
1019
+ i
1020
+ );
1021
+ })
1022
+ }
1023
+ ) })
1024
+ ] });
1025
+ }
1026
+
1027
+ // src/components/popover.tsx
1028
+ var import_react13 = require("react");
1029
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1030
+ function Popover({
1031
+ trigger,
1032
+ title,
1033
+ label,
1034
+ children,
1035
+ side = "bottom",
1036
+ align = "start",
1037
+ open: controlled,
1038
+ onOpenChange,
1039
+ className
1040
+ }) {
1041
+ const [uncontrolled, setUncontrolled] = (0, import_react13.useState)(false);
1042
+ const open = controlled ?? uncontrolled;
1043
+ const setOpen = (value) => {
1044
+ if (controlled === void 0) setUncontrolled(value);
1045
+ onOpenChange?.(value);
1046
+ };
1047
+ const triggerRef = (0, import_react13.useRef)(null);
1048
+ const panelRef = (0, import_react13.useRef)(null);
1049
+ const id = (0, import_react13.useId)();
1050
+ useAnchoredPosition(open, triggerRef, panelRef, { side, align });
1051
+ useDismiss(open, [triggerRef, panelRef], (reason) => {
1052
+ setOpen(false);
1053
+ if (reason === "escape") triggerRef.current?.focus();
1054
+ });
1055
+ (0, import_react13.useEffect)(() => {
1056
+ if (!open) return;
1057
+ const panel = panelRef.current;
1058
+ const first = panel?.querySelector(
1059
+ "[data-autofocus], input, select, textarea, button, a[href], [tabindex]:not([tabindex='-1'])"
1060
+ );
1061
+ (first ?? panel)?.focus();
1062
+ }, [open]);
1063
+ const triggerElement = (0, import_react13.cloneElement)(trigger, {
1064
+ ref: mergeRefs(triggerRef, getElementRef(trigger)),
1065
+ "aria-haspopup": "dialog",
1066
+ "aria-expanded": open,
1067
+ "aria-controls": open ? `${id}-panel` : void 0,
1068
+ onClick: callAll(trigger.props.onClick, () => setOpen(!open))
1069
+ });
1070
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
1071
+ triggerElement,
1072
+ open && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1073
+ "div",
1074
+ {
1075
+ ref: panelRef,
1076
+ id: `${id}-panel`,
1077
+ role: "dialog",
1078
+ "aria-labelledby": title != null ? `${id}-title` : void 0,
1079
+ "aria-label": title == null ? label : void 0,
1080
+ tabIndex: -1,
1081
+ className: cx("trc-floating", "trc-popover", className),
1082
+ children: [
1083
+ title != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { id: `${id}-title`, className: "trc-popover__title", children: title }),
1084
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "trc-popover__body", children })
1085
+ ]
1086
+ }
1087
+ ) })
1088
+ ] });
1089
+ }
1090
+
1091
+ // src/components/tooltip.tsx
1092
+ var import_react14 = require("react");
1093
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1094
+ function Tooltip({ label, children, side = "top", delay: delay2 = 300, className }) {
1095
+ const [open, setOpen] = (0, import_react14.useState)(false);
1096
+ const anchorRef = (0, import_react14.useRef)(null);
1097
+ const tipRef = (0, import_react14.useRef)(null);
1098
+ const timer = (0, import_react14.useRef)(void 0);
1099
+ const id = (0, import_react14.useId)();
1100
+ const show = (wait) => {
1101
+ window.clearTimeout(timer.current);
1102
+ timer.current = window.setTimeout(() => setOpen(true), wait);
1103
+ };
1104
+ const hide = () => {
1105
+ window.clearTimeout(timer.current);
1106
+ timer.current = window.setTimeout(() => setOpen(false), 100);
1107
+ };
1108
+ (0, import_react14.useEffect)(() => () => window.clearTimeout(timer.current), []);
1109
+ (0, import_react14.useEffect)(() => {
1110
+ if (!open) return;
1111
+ const onKeyDown = (e) => e.key === "Escape" && setOpen(false);
1112
+ document.addEventListener("keydown", onKeyDown);
1113
+ return () => document.removeEventListener("keydown", onKeyDown);
1114
+ }, [open]);
1115
+ useAnchoredPosition(open, anchorRef, tipRef, { side, align: "center", offset: 8 });
1116
+ const child = (0, import_react14.cloneElement)(children, {
1117
+ ref: mergeRefs(anchorRef, getElementRef(children)),
1118
+ "aria-describedby": [children.props["aria-describedby"], id].filter(Boolean).join(" "),
1119
+ onMouseEnter: callAll(children.props.onMouseEnter, () => show(delay2)),
1120
+ onMouseLeave: callAll(children.props.onMouseLeave, hide),
1121
+ onFocus: callAll(children.props.onFocus, () => show(0)),
1122
+ onBlur: callAll(children.props.onBlur, () => {
1123
+ window.clearTimeout(timer.current);
1124
+ setOpen(false);
1125
+ })
1126
+ });
1127
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1128
+ child,
1129
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1130
+ "div",
1131
+ {
1132
+ ref: tipRef,
1133
+ id,
1134
+ role: "tooltip",
1135
+ className: cx("trc-floating", "trc-tooltip", open && "trc-tooltip--open", className),
1136
+ onMouseEnter: () => window.clearTimeout(timer.current),
1137
+ onMouseLeave: hide,
1138
+ children: label
1139
+ }
1140
+ ) })
1141
+ ] });
1142
+ }
1143
+
1144
+ // src/components/toast.tsx
1145
+ var import_react15 = require("react");
1146
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1147
+ var items = [];
1148
+ var nextId = 1;
1149
+ var listeners = /* @__PURE__ */ new Set();
1150
+ var emit = () => listeners.forEach((listener) => listener());
1151
+ var subscribe = (listener) => {
1152
+ listeners.add(listener);
1153
+ return () => listeners.delete(listener);
1154
+ };
1155
+ var EMPTY = [];
1156
+ var LEAVE_MS = 200;
1157
+ function dismiss(id) {
1158
+ items = items.map((t) => id === void 0 || t.id === id ? { ...t, leaving: true } : t);
1159
+ emit();
1160
+ window.setTimeout(() => {
1161
+ items = items.filter((t) => !(t.leaving && (id === void 0 || t.id === id)));
1162
+ emit();
1163
+ }, LEAVE_MS);
1164
+ }
1165
+ function toast(title, options = {}) {
1166
+ const id = nextId++;
1167
+ items = [...items, { ...options, id, title, leaving: false }];
1168
+ emit();
1169
+ return id;
1170
+ }
1171
+ toast.success = (title, options = {}) => toast(title, { ...options, tone: "success" });
1172
+ toast.error = (title, options = {}) => toast(title, { ...options, tone: "error" });
1173
+ toast.dismiss = dismiss;
1174
+ function Toaster({
1175
+ position = "bottom-right",
1176
+ duration = 5e3,
1177
+ label = "Notifications",
1178
+ closeLabel = "Close"
1179
+ }) {
1180
+ const toasts = (0, import_react15.useSyncExternalStore)(
1181
+ subscribe,
1182
+ () => items,
1183
+ () => EMPTY
1184
+ );
1185
+ const [paused, setPaused] = (0, import_react15.useState)(false);
1186
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1187
+ "section",
1188
+ {
1189
+ "aria-label": label,
1190
+ className: cx("trc-toaster", `trc-toaster--${position}`),
1191
+ onMouseEnter: () => setPaused(true),
1192
+ onMouseLeave: () => setPaused(false),
1193
+ onFocus: () => setPaused(true),
1194
+ onBlur: (e) => !e.currentTarget.contains(e.relatedTarget) && setPaused(false),
1195
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ol", { "aria-live": "polite", "aria-relevant": "additions", className: "trc-toaster__list", children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ToastCard, { toast: t, duration: t.duration ?? duration, paused, closeLabel }, t.id)) })
1196
+ }
1197
+ ) });
1198
+ }
1199
+ function ToastCard({
1200
+ toast: t,
1201
+ duration,
1202
+ paused,
1203
+ closeLabel
1204
+ }) {
1205
+ const remaining = (0, import_react15.useRef)(duration);
1206
+ (0, import_react15.useEffect)(() => {
1207
+ if (paused || t.leaving || !Number.isFinite(remaining.current)) return;
1208
+ const started = Date.now();
1209
+ const timer = window.setTimeout(() => dismiss(t.id), remaining.current);
1210
+ return () => {
1211
+ window.clearTimeout(timer);
1212
+ remaining.current -= Date.now() - started;
1213
+ };
1214
+ }, [paused, t.leaving, t.id]);
1215
+ const tone = t.tone ?? "default";
1216
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("li", { className: cx("trc-toast", `trc-toast--${tone}`, t.leaving && "trc-toast--leaving"), children: [
1217
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "trc-toast__text", role: tone === "error" ? "alert" : void 0, children: [
1218
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "trc-toast__title", children: t.title }),
1219
+ t.description != null && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "trc-toast__description", children: t.description })
1220
+ ] }),
1221
+ t.action && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1222
+ "button",
1223
+ {
1224
+ type: "button",
1225
+ className: "trc-toast__action",
1226
+ onClick: () => {
1227
+ t.action?.onClick();
1228
+ dismiss(t.id);
1229
+ },
1230
+ children: t.action.label
1231
+ }
1232
+ ),
1233
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "trc-toast__close", "aria-label": closeLabel, onClick: () => dismiss(t.id), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Close, {}) })
1234
+ ] });
1235
+ }
1236
+
1237
+ // src/components/alert.tsx
1238
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1239
+ function Alert({ title, tone = "info", actions, className, children, ...props }) {
1240
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cx("trc-alert", `trc-alert--${tone}`, className), ...props, children: [
1241
+ title != null && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "trc-alert__title", children: title }),
1242
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "trc-alert__body", children }),
1243
+ actions != null && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "trc-alert__actions", children: actions })
1244
+ ] });
1245
+ }
1246
+
1247
+ // src/components/tabs.tsx
1248
+ var import_react17 = require("react");
1249
+
1250
+ // src/hooks/use-controllable.ts
1251
+ var import_react16 = require("react");
1252
+ function useControllable(value, defaultValue, onChange) {
1253
+ const [internal, setInternal] = (0, import_react16.useState)(defaultValue);
1254
+ const controlled = (0, import_react16.useRef)(value !== void 0).current;
1255
+ const current = controlled ? value : internal;
1256
+ const set = (next) => {
1257
+ if (!controlled) setInternal(next);
1258
+ onChange?.(next);
1259
+ };
1260
+ return [current, set];
1261
+ }
1262
+
1263
+ // src/components/tabs.tsx
1264
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1265
+ function Tabs({
1266
+ items: items2,
1267
+ value,
1268
+ defaultValue,
1269
+ onValueChange,
1270
+ label,
1271
+ activation = "automatic",
1272
+ className
1273
+ }) {
1274
+ const firstEnabled = items2.find((item) => !item.disabled)?.value ?? "";
1275
+ const [selected, setSelected] = useControllable(value, defaultValue ?? firstEnabled, onValueChange);
1276
+ const id = (0, import_react17.useId)();
1277
+ const tabRefs = (0, import_react17.useRef)([]);
1278
+ const enabled = items2.map((item, i) => item.disabled ? -1 : i).filter((i) => i >= 0);
1279
+ const onKeyDown = (e, index) => {
1280
+ const position = enabled.indexOf(index);
1281
+ let target;
1282
+ if (e.key === "ArrowRight") target = enabled[(position + 1) % enabled.length];
1283
+ else if (e.key === "ArrowLeft") target = enabled[(position - 1 + enabled.length) % enabled.length];
1284
+ else if (e.key === "Home") target = enabled[0];
1285
+ else if (e.key === "End") target = enabled[enabled.length - 1];
1286
+ if (target === void 0) return;
1287
+ e.preventDefault();
1288
+ tabRefs.current[target]?.focus();
1289
+ if (activation === "automatic") setSelected(items2[target].value);
1290
+ };
1291
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cx("trc-tabs", className), children: [
1292
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { role: "tablist", "aria-label": label, className: "trc-tabs__list", children: items2.map((item, i) => {
1293
+ const isSelected = item.value === selected;
1294
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1295
+ "button",
1296
+ {
1297
+ ref: (el) => {
1298
+ tabRefs.current[i] = el;
1299
+ },
1300
+ type: "button",
1301
+ role: "tab",
1302
+ id: `${id}-tab-${i}`,
1303
+ "aria-selected": isSelected,
1304
+ "aria-controls": `${id}-panel-${i}`,
1305
+ disabled: item.disabled,
1306
+ tabIndex: isSelected ? 0 : -1,
1307
+ className: "trc-tabs__tab",
1308
+ onClick: () => setSelected(item.value),
1309
+ onKeyDown: (e) => onKeyDown(e, i),
1310
+ children: item.label
1311
+ },
1312
+ item.value
1313
+ );
1314
+ }) }),
1315
+ items2.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1316
+ "div",
1317
+ {
1318
+ role: "tabpanel",
1319
+ id: `${id}-panel-${i}`,
1320
+ "aria-labelledby": `${id}-tab-${i}`,
1321
+ hidden: item.value !== selected,
1322
+ tabIndex: 0,
1323
+ className: "trc-tabs__panel",
1324
+ children: item.content
1325
+ },
1326
+ item.value
1327
+ ))
1328
+ ] });
1329
+ }
1330
+
1331
+ // src/components/segmented-control.tsx
1332
+ var import_react18 = require("react");
1333
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1334
+ function SegmentedControl({
1335
+ options,
1336
+ value,
1337
+ defaultValue,
1338
+ onValueChange,
1339
+ label,
1340
+ name,
1341
+ size: size2 = "md",
1342
+ className
1343
+ }) {
1344
+ const [selected, setSelected] = useControllable(value, defaultValue ?? options[0]?.value ?? "", onValueChange);
1345
+ const generated = (0, import_react18.useId)();
1346
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1347
+ "div",
1348
+ {
1349
+ role: "radiogroup",
1350
+ "aria-label": label,
1351
+ className: cx("trc-segmented", size2 === "sm" && "trc-segmented--sm", className),
1352
+ children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "trc-segmented__option", children: [
1353
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1354
+ "input",
1355
+ {
1356
+ type: "radio",
1357
+ name: name ?? generated,
1358
+ value: option.value,
1359
+ checked: option.value === selected,
1360
+ disabled: option.disabled,
1361
+ onChange: () => setSelected(option.value),
1362
+ className: "trc-segmented__input"
1363
+ }
1364
+ ),
1365
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "trc-segmented__label", children: option.label })
1366
+ ] }, option.value))
702
1367
  }
703
1368
  );
704
1369
  }
1370
+
1371
+ // src/components/accordion.tsx
1372
+ var import_react19 = require("react");
1373
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1374
+ function Accordion({
1375
+ items: items2,
1376
+ type = "single",
1377
+ value,
1378
+ defaultValue = [],
1379
+ onValueChange,
1380
+ headingLevel = 3,
1381
+ className
1382
+ }) {
1383
+ const [open, setOpen] = useControllable(value, defaultValue, onValueChange);
1384
+ const id = (0, import_react19.useId)();
1385
+ const buttons = (0, import_react19.useRef)([]);
1386
+ const Heading2 = `h${headingLevel}`;
1387
+ const enabled = items2.map((item, i) => item.disabled ? -1 : i).filter((i) => i >= 0);
1388
+ const toggle = (itemValue) => {
1389
+ const isOpen = open.includes(itemValue);
1390
+ if (type === "single") setOpen(isOpen ? [] : [itemValue]);
1391
+ else setOpen(isOpen ? open.filter((v) => v !== itemValue) : [...open, itemValue]);
1392
+ };
1393
+ const onKeyDown = (e, index) => {
1394
+ const position = enabled.indexOf(index);
1395
+ let target;
1396
+ if (e.key === "ArrowDown") target = enabled[(position + 1) % enabled.length];
1397
+ else if (e.key === "ArrowUp") target = enabled[(position - 1 + enabled.length) % enabled.length];
1398
+ else if (e.key === "Home") target = enabled[0];
1399
+ else if (e.key === "End") target = enabled[enabled.length - 1];
1400
+ if (target === void 0) return;
1401
+ e.preventDefault();
1402
+ buttons.current[target]?.focus();
1403
+ };
1404
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cx("trc-accordion", className), children: items2.map((item, i) => {
1405
+ const isOpen = open.includes(item.value);
1406
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cx("trc-accordion__item", isOpen && "trc-accordion__item--open"), children: [
1407
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Heading2, { className: "trc-accordion__heading", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1408
+ "button",
1409
+ {
1410
+ ref: (el) => {
1411
+ buttons.current[i] = el;
1412
+ },
1413
+ type: "button",
1414
+ id: `${id}-trigger-${i}`,
1415
+ "aria-expanded": isOpen,
1416
+ "aria-controls": `${id}-panel-${i}`,
1417
+ disabled: item.disabled,
1418
+ className: "trc-accordion__trigger",
1419
+ onClick: () => toggle(item.value),
1420
+ onKeyDown: (e) => onKeyDown(e, i),
1421
+ children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: item.title }),
1423
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ChevronDown, { className: "trc-accordion__chevron" })
1424
+ ]
1425
+ }
1426
+ ) }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1428
+ "div",
1429
+ {
1430
+ id: `${id}-panel-${i}`,
1431
+ role: "region",
1432
+ "aria-labelledby": `${id}-trigger-${i}`,
1433
+ className: "trc-accordion__panel",
1434
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "trc-accordion__inner", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "trc-accordion__content", children: item.content }) })
1435
+ }
1436
+ )
1437
+ ] }, item.value);
1438
+ }) });
1439
+ }
1440
+
1441
+ // src/components/steps.tsx
1442
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1443
+ function Steps({ items: items2, current, className }) {
1444
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: cx("trc-steps", className), children: items2.map((item, i) => {
1445
+ const state = current === void 0 ? "default" : i < current ? "complete" : i === current ? "current" : "upcoming";
1446
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1447
+ "li",
1448
+ {
1449
+ className: cx("trc-steps__item", `trc-steps__item--${state}`),
1450
+ "aria-current": state === "current" ? "step" : void 0,
1451
+ children: [
1452
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": true, className: "trc-steps__number", children: String(i + 1).padStart(2, "0") }),
1453
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "trc-steps__text", children: [
1454
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "trc-steps__title", children: item.title }),
1455
+ item.description != null && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "trc-steps__description", children: item.description })
1456
+ ] })
1457
+ ]
1458
+ },
1459
+ i
1460
+ );
1461
+ }) });
1462
+ }
1463
+
1464
+ // src/components/breadcrumbs.tsx
1465
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1466
+ function Breadcrumbs({ items: items2, label = "Breadcrumb", linkAs: LinkTag = "a", className }) {
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("nav", { "aria-label": label, className: cx("trc-breadcrumbs", className), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ol", { className: "trc-breadcrumbs__list", children: items2.map((item, i) => {
1468
+ const last = i === items2.length - 1;
1469
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "trc-breadcrumbs__item", children: [
1470
+ last || !item.href ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-current": last ? "page" : void 0, className: "trc-breadcrumbs__current", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LinkTag, { href: item.href, className: "trc-breadcrumbs__link", children: item.label }),
1471
+ !last && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, className: "trc-breadcrumbs__separator", children: "/" })
1472
+ ] }, i);
1473
+ }) }) });
1474
+ }
1475
+
1476
+ // src/utils/label.ts
1477
+ function fill(template, values) {
1478
+ return template.replace(/\{(\w+)\}/g, (match, key) => key in values ? String(values[key]) : match);
1479
+ }
1480
+
1481
+ // src/components/pagination.tsx
1482
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1483
+ function paginationRange(page, total, siblings = 1) {
1484
+ const slots = siblings * 2 + 5;
1485
+ if (total <= slots) return Array.from({ length: total }, (_, i) => i + 1);
1486
+ const range = (from, to) => Array.from({ length: to - from + 1 }, (_, i) => from + i);
1487
+ if (page <= siblings + 3) return [...range(1, slots - 2), "ellipsis", total];
1488
+ if (page >= total - siblings - 2) return [1, "ellipsis", ...range(total - slots + 3, total)];
1489
+ return [1, "ellipsis", ...range(page - siblings, page + siblings), "ellipsis", total];
1490
+ }
1491
+ function Pagination({
1492
+ page,
1493
+ total,
1494
+ onPageChange,
1495
+ href,
1496
+ siblings = 1,
1497
+ linkAs: LinkTag = "a",
1498
+ label = "Pagination",
1499
+ previousLabel = "Previous",
1500
+ nextLabel = "Next",
1501
+ pageLabel = "Page {page}",
1502
+ className
1503
+ }) {
1504
+ if (total <= 1) return null;
1505
+ const getHref = href === void 0 ? void 0 : typeof href === "string" ? (p) => href.replace("{page}", String(p)) : href;
1506
+ const control = (target, content, extra) => {
1507
+ const disabled = target < 1 || target > total;
1508
+ const common = {
1509
+ className: cx("trc-pagination__control", extra.className),
1510
+ "aria-label": extra.ariaLabel,
1511
+ "aria-current": extra.current ? "page" : void 0
1512
+ };
1513
+ if (getHref) {
1514
+ return disabled ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { ...common, "aria-disabled": "true", children: content }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LinkTag, { href: getHref(target), ...common, children: content });
1515
+ }
1516
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", ...common, disabled, onClick: () => !extra.current && onPageChange?.(target), children: content });
1517
+ };
1518
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("nav", { "aria-label": label, className: cx("trc-pagination", className), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("ul", { className: "trc-pagination__list", children: [
1519
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { children: control(page - 1, /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ArrowLeft, {}), { className: "trc-pagination__step", ariaLabel: previousLabel }) }),
1520
+ paginationRange(page, total, siblings).map(
1521
+ (entry, i) => entry === "ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { "aria-hidden": true, className: "trc-pagination__ellipsis", children: "\u2026" }, `e${i}`) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { children: control(entry, entry, {
1522
+ className: "trc-pagination__page",
1523
+ ariaLabel: typeof pageLabel === "string" ? fill(pageLabel, { page: entry }) : pageLabel(entry),
1524
+ current: entry === page
1525
+ }) }, entry)
1526
+ ),
1527
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { children: control(page + 1, /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ArrowRight, {}), { className: "trc-pagination__step", ariaLabel: nextLabel }) })
1528
+ ] }) });
1529
+ }
1530
+
1531
+ // src/components/language-switcher.tsx
1532
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1533
+ function LanguageSwitcher({
1534
+ languages,
1535
+ value,
1536
+ onChange,
1537
+ label = "Language",
1538
+ linkAs: LinkTag = "a",
1539
+ className
1540
+ }) {
1541
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { "aria-label": label, className: cx("trc-languages", className), children: languages.map((language) => {
1542
+ const common = {
1543
+ lang: language.code,
1544
+ "aria-label": language.name,
1545
+ "aria-current": language.code === value ? "true" : void 0,
1546
+ className: "trc-languages__item",
1547
+ children: language.code.toUpperCase()
1548
+ };
1549
+ return language.href ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LinkTag, { href: language.href, hrefLang: language.code, ...common }, language.code) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", onClick: () => onChange?.(language.code), ...common }, language.code);
1550
+ }) });
1551
+ }
1552
+
1553
+ // src/components/radio-group.tsx
1554
+ var import_react20 = require("react");
1555
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1556
+ function RadioGroup({
1557
+ label,
1558
+ options,
1559
+ value,
1560
+ defaultValue,
1561
+ onValueChange,
1562
+ name,
1563
+ hint,
1564
+ error,
1565
+ required = false,
1566
+ orientation = "vertical",
1567
+ className
1568
+ }) {
1569
+ const [selected, setSelected] = useControllable(
1570
+ value,
1571
+ defaultValue,
1572
+ (v) => v && onValueChange?.(v)
1573
+ );
1574
+ const id = (0, import_react20.useId)();
1575
+ const message = error ?? hint;
1576
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1577
+ "fieldset",
1578
+ {
1579
+ className: cx("trc-radio-group", className),
1580
+ "aria-describedby": message != null ? `${id}-message` : void 0,
1581
+ "aria-invalid": error != null || void 0,
1582
+ "aria-required": required || void 0,
1583
+ children: [
1584
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("legend", { className: "trc-field__label", children: [
1585
+ label,
1586
+ required && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { "aria-hidden": true, className: "trc-field__required", children: [
1587
+ " ",
1588
+ "*"
1589
+ ] })
1590
+ ] }),
1591
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cx("trc-radio-group__options", orientation === "horizontal" && "trc-radio-group__options--row"), children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "trc-toggle trc-toggle--radio", children: [
1592
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "trc-radio", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1593
+ "input",
1594
+ {
1595
+ type: "radio",
1596
+ name: name ?? id,
1597
+ value: option.value,
1598
+ checked: selected === option.value,
1599
+ disabled: option.disabled,
1600
+ required,
1601
+ onChange: () => setSelected(option.value),
1602
+ className: "trc-radio__input"
1603
+ }
1604
+ ) }),
1605
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "trc-toggle__text", children: [
1606
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "trc-toggle__label", children: option.label }),
1607
+ option.description != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "trc-toggle__description", children: option.description })
1608
+ ] })
1609
+ ] }, option.value)) }),
1610
+ message != null && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { id: `${id}-message`, className: cx("trc-field__message", error != null && "trc-field__message--error"), children: message })
1611
+ ]
1612
+ }
1613
+ );
1614
+ }
1615
+
1616
+ // src/components/password-input.tsx
1617
+ var import_react21 = require("react");
1618
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1619
+ var PasswordInput = (0, import_react21.forwardRef)(function PasswordInput2({ showLabel = "Show", hideLabel = "Hide", noun = "password", className, autoComplete = "current-password", ...props }, ref) {
1620
+ const [visible, setVisible] = (0, import_react21.useState)(false);
1621
+ const { id } = useFieldProps(props);
1622
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: cx("trc-password", className), children: [
1623
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Input, { ref, ...props, id, type: visible ? "text" : "password", autoComplete }),
1624
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("button", { type: "button", className: "trc-password__toggle", "aria-controls": id, onClick: () => setVisible((v) => !v), children: [
1625
+ visible ? hideLabel : showLabel,
1626
+ " ",
1627
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "trc-visually-hidden", children: noun })
1628
+ ] })
1629
+ ] });
1630
+ });
1631
+
1632
+ // src/components/pin-input.tsx
1633
+ var import_react22 = require("react");
1634
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1635
+ function PinInput({
1636
+ length = 6,
1637
+ value,
1638
+ defaultValue = "",
1639
+ onChange,
1640
+ onComplete,
1641
+ type = "numeric",
1642
+ mask = false,
1643
+ label = "Verification code",
1644
+ charLabel = "Character {index} of {length}",
1645
+ invalid,
1646
+ disabled,
1647
+ id,
1648
+ name,
1649
+ className
1650
+ }) {
1651
+ const [code, setCode] = useControllable(value, defaultValue, onChange);
1652
+ const inputs = (0, import_react22.useRef)([]);
1653
+ const field = useFieldProps({ id, invalid });
1654
+ const accepted = type === "numeric" ? /[0-9]/ : /[0-9a-z]/i;
1655
+ const clean = (text) => [...text].filter((c) => accepted.test(c)).join("");
1656
+ const update = (next) => {
1657
+ const trimmed = next.slice(0, length);
1658
+ setCode(trimmed);
1659
+ if (trimmed.length === length && !trimmed.includes(" ")) onComplete?.(trimmed);
1660
+ };
1661
+ const focus = (index) => {
1662
+ const target = inputs.current[Math.max(0, Math.min(index, length - 1))];
1663
+ target?.focus();
1664
+ target?.select();
1665
+ };
1666
+ const charAt = (i) => code[i] && code[i] !== " " ? code[i] : "";
1667
+ const setCharAt = (i, char) => {
1668
+ const chars = Array.from({ length }, (_, k) => code[k] ?? " ");
1669
+ chars[i] = char || " ";
1670
+ return chars.join("").replace(/\s+$/, "");
1671
+ };
1672
+ const onInput = (i, raw) => {
1673
+ const typed = clean(raw);
1674
+ if (!typed) return;
1675
+ if (typed.length > 1) {
1676
+ const merged = (code.slice(0, i).padEnd(i, " ") + typed).slice(0, length);
1677
+ update(merged);
1678
+ focus(Math.min(i + typed.length, length - 1));
1679
+ return;
1680
+ }
1681
+ update(setCharAt(i, typed.slice(-1)));
1682
+ focus(i + 1);
1683
+ };
1684
+ const onKeyDown = (i, e) => {
1685
+ if (e.key === "Backspace") {
1686
+ e.preventDefault();
1687
+ if (charAt(i)) update(setCharAt(i, ""));
1688
+ else if (i > 0) {
1689
+ update(setCharAt(i - 1, ""));
1690
+ focus(i - 1);
1691
+ }
1692
+ } else if (e.key === "ArrowLeft") {
1693
+ e.preventDefault();
1694
+ focus(i - 1);
1695
+ } else if (e.key === "ArrowRight") {
1696
+ e.preventDefault();
1697
+ focus(i + 1);
1698
+ } else if (e.key === "Home") {
1699
+ e.preventDefault();
1700
+ focus(0);
1701
+ } else if (e.key === "End") {
1702
+ e.preventDefault();
1703
+ focus(length - 1);
1704
+ }
1705
+ };
1706
+ const onPaste = (i, e) => {
1707
+ e.preventDefault();
1708
+ onInput(i, e.clipboardData.getData("text"));
1709
+ };
1710
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1711
+ "div",
1712
+ {
1713
+ role: "group",
1714
+ "aria-label": label,
1715
+ "aria-describedby": field["aria-describedby"],
1716
+ className: cx("trc-pin", className),
1717
+ children: [
1718
+ Array.from({ length }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1719
+ "input",
1720
+ {
1721
+ ref: (el) => {
1722
+ inputs.current[i] = el;
1723
+ },
1724
+ id: i === 0 ? field.id : void 0,
1725
+ type: mask ? "password" : "text",
1726
+ inputMode: type === "numeric" ? "numeric" : "text",
1727
+ autoComplete: i === 0 ? "one-time-code" : "off",
1728
+ maxLength: length,
1729
+ "aria-label": typeof charLabel === "string" ? fill(charLabel, { index: i + 1, length }) : charLabel(i, length),
1730
+ "aria-invalid": field["aria-invalid"],
1731
+ disabled,
1732
+ value: charAt(i),
1733
+ onChange: (e) => onInput(i, e.target.value.replace(charAt(i), "") || e.target.value),
1734
+ onKeyDown: (e) => onKeyDown(i, e),
1735
+ onPaste: (e) => onPaste(i, e),
1736
+ onFocus: (e) => e.target.select(),
1737
+ className: "trc-control trc-pin__box"
1738
+ },
1739
+ i
1740
+ )),
1741
+ name && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "hidden", name, value: code.replace(/\s/g, "") })
1742
+ ]
1743
+ }
1744
+ );
1745
+ }
1746
+
1747
+ // src/components/combobox.tsx
1748
+ var import_react23 = require("react");
1749
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1750
+ var normalize = (text) => text.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
1751
+ function Combobox({
1752
+ options,
1753
+ value,
1754
+ defaultValue = null,
1755
+ onValueChange,
1756
+ placeholder,
1757
+ emptyText = "No results",
1758
+ invalid,
1759
+ disabled,
1760
+ required,
1761
+ id,
1762
+ name,
1763
+ className
1764
+ }) {
1765
+ const [selected, setSelected] = useControllable(value, defaultValue, onValueChange);
1766
+ const selectedOption = options.find((o) => o.value === selected) ?? null;
1767
+ const [query, setQuery] = (0, import_react23.useState)(selectedOption?.label ?? "");
1768
+ const [open, setOpen] = (0, import_react23.useState)(false);
1769
+ const [active, setActive] = (0, import_react23.useState)(-1);
1770
+ const wrapperRef = (0, import_react23.useRef)(null);
1771
+ const inputRef = (0, import_react23.useRef)(null);
1772
+ const listRef = (0, import_react23.useRef)(null);
1773
+ const listId = (0, import_react23.useId)();
1774
+ const a11y = useFieldProps({ id, invalid, required });
1775
+ const searching = query !== (selectedOption?.label ?? "");
1776
+ const visible = searching ? options.filter((o) => normalize(o.label).includes(normalize(query))) : options;
1777
+ const enabled = visible.map((o, i) => o.disabled ? -1 : i).filter((i) => i >= 0);
1778
+ (0, import_react23.useEffect)(() => {
1779
+ if (!open) setQuery(selectedOption?.label ?? "");
1780
+ }, [selectedOption?.label, open]);
1781
+ useAnchoredPosition(open, wrapperRef, listRef, { side: "bottom", align: "start", offset: 6 });
1782
+ useIsomorphicLayoutEffect(() => {
1783
+ if (open && listRef.current && wrapperRef.current)
1784
+ listRef.current.style.width = `${wrapperRef.current.offsetWidth}px`;
1785
+ }, [open]);
1786
+ useDismiss(open, [wrapperRef, listRef], () => close());
1787
+ (0, import_react23.useEffect)(() => {
1788
+ if (open && active >= 0)
1789
+ listRef.current?.querySelector(`[data-index="${active}"]`)?.scrollIntoView({ block: "nearest" });
1790
+ }, [open, active]);
1791
+ const openList = (index) => {
1792
+ setOpen(true);
1793
+ const current = visible.findIndex((o) => o.value === selected);
1794
+ setActive(index ?? (current >= 0 ? current : enabled[0] ?? -1));
1795
+ };
1796
+ const close = () => {
1797
+ setOpen(false);
1798
+ setActive(-1);
1799
+ setQuery(selectedOption?.label ?? "");
1800
+ };
1801
+ const choose = (option) => {
1802
+ if (option.disabled) return;
1803
+ setSelected(option.value);
1804
+ setQuery(option.label);
1805
+ setOpen(false);
1806
+ setActive(-1);
1807
+ };
1808
+ const onKeyDown = (e) => {
1809
+ const position = enabled.indexOf(active);
1810
+ if (e.key === "ArrowDown") {
1811
+ e.preventDefault();
1812
+ if (!open) openList();
1813
+ else setActive(enabled[(position + 1) % enabled.length] ?? -1);
1814
+ } else if (e.key === "ArrowUp") {
1815
+ e.preventDefault();
1816
+ if (!open) openList(enabled[enabled.length - 1]);
1817
+ else setActive(enabled[(position - 1 + enabled.length) % enabled.length] ?? -1);
1818
+ } else if (e.key === "Enter" && open) {
1819
+ e.preventDefault();
1820
+ const option = visible[active];
1821
+ if (option) choose(option);
1822
+ } else if (e.key === "Escape") {
1823
+ if (open) {
1824
+ e.preventDefault();
1825
+ close();
1826
+ } else if (query) {
1827
+ setQuery(selectedOption?.label ?? "");
1828
+ }
1829
+ } else if (e.key === "Tab" && open) {
1830
+ close();
1831
+ }
1832
+ };
1833
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { ref: wrapperRef, className: cx("trc-combobox", className), children: [
1834
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1835
+ "input",
1836
+ {
1837
+ ref: inputRef,
1838
+ type: "text",
1839
+ role: "combobox",
1840
+ "aria-expanded": open,
1841
+ "aria-controls": listId,
1842
+ "aria-autocomplete": "list",
1843
+ "aria-activedescendant": open && active >= 0 ? `${listId}-${active}` : void 0,
1844
+ autoComplete: "off",
1845
+ placeholder,
1846
+ disabled,
1847
+ value: query,
1848
+ onChange: (e) => {
1849
+ setQuery(e.target.value);
1850
+ setOpen(true);
1851
+ setActive(0);
1852
+ },
1853
+ onClick: () => open ? close() : openList(),
1854
+ onKeyDown,
1855
+ className: "trc-control trc-combobox__input",
1856
+ ...a11y
1857
+ }
1858
+ ),
1859
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChevronDown, { "aria-hidden": true, className: "trc-combobox__chevron" }),
1860
+ name && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("input", { type: "hidden", name, value: selected ?? "" }),
1861
+ open && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("ul", { ref: listRef, id: listId, role: "listbox", className: "trc-floating trc-listbox", children: [
1862
+ visible.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("li", { role: "presentation", className: "trc-listbox__empty", children: emptyText }),
1863
+ visible.map((option, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1864
+ "li",
1865
+ {
1866
+ id: `${listId}-${i}`,
1867
+ "data-index": i,
1868
+ role: "option",
1869
+ "aria-selected": option.value === selected,
1870
+ "aria-disabled": option.disabled || void 0,
1871
+ className: cx("trc-listbox__option", i === active && "trc-listbox__option--active"),
1872
+ onMouseDown: (e) => e.preventDefault(),
1873
+ onMouseMove: () => !option.disabled && setActive(i),
1874
+ onClick: () => choose(option),
1875
+ children: [
1876
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "trc-listbox__label", children: option.label }),
1877
+ option.description != null && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "trc-listbox__description", children: option.description })
1878
+ ]
1879
+ },
1880
+ option.value
1881
+ ))
1882
+ ] }) })
1883
+ ] });
1884
+ }
1885
+
1886
+ // src/components/file-input.tsx
1887
+ var import_react24 = require("react");
1888
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1889
+ function formatBytes(bytes) {
1890
+ if (bytes < 1024) return `${bytes} B`;
1891
+ const units = ["KB", "MB", "GB"];
1892
+ let value = bytes / 1024;
1893
+ let unit = 0;
1894
+ while (value >= 1024 && unit < units.length - 1) {
1895
+ value /= 1024;
1896
+ unit++;
1897
+ }
1898
+ return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;
1899
+ }
1900
+ function acceptsFile(file, accept) {
1901
+ if (!accept) return true;
1902
+ const name = file.name.toLowerCase();
1903
+ const type = file.type.toLowerCase();
1904
+ return accept.split(",").map((rule) => rule.trim().toLowerCase()).filter(Boolean).some(
1905
+ (rule) => rule.startsWith(".") ? name.endsWith(rule) : rule.endsWith("/*") ? type.startsWith(rule.slice(0, -1)) : type === rule
1906
+ );
1907
+ }
1908
+ function validateFiles(files, { accept, maxSize, maxFiles }, alreadyAccepted = 0) {
1909
+ const accepted = [];
1910
+ const rejected = [];
1911
+ for (const file of files) {
1912
+ if (!acceptsFile(file, accept)) rejected.push({ file, reason: "type" });
1913
+ else if (maxSize !== void 0 && file.size > maxSize) rejected.push({ file, reason: "size" });
1914
+ else if (maxFiles !== void 0 && alreadyAccepted + accepted.length >= maxFiles)
1915
+ rejected.push({ file, reason: "count" });
1916
+ else accepted.push(file);
1917
+ }
1918
+ return { accepted, rejected };
1919
+ }
1920
+ var FileInput = (0, import_react24.forwardRef)(function FileInput2({
1921
+ onFilesChange,
1922
+ buttonLabel = "Choose a file",
1923
+ placeholder = "No file chosen",
1924
+ countLabel = "{count} files",
1925
+ disabled,
1926
+ invalid,
1927
+ className,
1928
+ ...props
1929
+ }, ref) {
1930
+ const [files, setFiles] = (0, import_react24.useState)([]);
1931
+ const a11y = useFieldProps({ ...props, invalid });
1932
+ const summary = files.length === 0 ? placeholder : files.length === 1 ? files[0].name : typeof countLabel === "string" ? fill(countLabel, { count: files.length }) : countLabel(files.length);
1933
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: cx("trc-file-input", disabled && "trc-file-input--disabled", className), children: [
1934
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1935
+ "input",
1936
+ {
1937
+ ref,
1938
+ ...props,
1939
+ ...a11y,
1940
+ type: "file",
1941
+ disabled,
1942
+ className: "trc-visually-hidden",
1943
+ onChange: (e) => {
1944
+ const chosen = [...e.target.files ?? []];
1945
+ setFiles(chosen);
1946
+ onFilesChange?.(chosen);
1947
+ }
1948
+ }
1949
+ ),
1950
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, className: "trc-file-input__button", children: buttonLabel }),
1951
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: cx("trc-file-input__name", files.length === 0 && "trc-file-input__name--empty"), children: summary })
1952
+ ] });
1953
+ });
1954
+ var DEFAULT_REJECTIONS = {
1955
+ type: "{name}: this type of file is not accepted",
1956
+ size: "{name}: the file is too large",
1957
+ count: "{name}: too many files"
1958
+ };
1959
+ function Dropzone({
1960
+ accept,
1961
+ maxSize,
1962
+ maxFiles,
1963
+ multiple = true,
1964
+ onFilesChange,
1965
+ title = "Drop files here or",
1966
+ browseLabel = "browse",
1967
+ hint,
1968
+ removeLabel = "Remove {name}",
1969
+ rejectionLabel = DEFAULT_REJECTIONS,
1970
+ name,
1971
+ disabled,
1972
+ id,
1973
+ className
1974
+ }) {
1975
+ const [files, setFiles] = (0, import_react24.useState)([]);
1976
+ const [rejections, setRejections] = (0, import_react24.useState)([]);
1977
+ const rejectionText = (rejection) => typeof rejectionLabel === "function" ? rejectionLabel(rejection) : fill(rejectionLabel[rejection.reason] ?? DEFAULT_REJECTIONS[rejection.reason], { name: rejection.file.name });
1978
+ const [dragging, setDragging] = (0, import_react24.useState)(false);
1979
+ const hintId = (0, import_react24.useId)();
1980
+ const a11y = useFieldProps({ id });
1981
+ const add = (incoming) => {
1982
+ const base2 = multiple ? files : [];
1983
+ const { accepted, rejected } = validateFiles(
1984
+ multiple ? incoming : incoming.slice(0, 1),
1985
+ { accept, maxSize, maxFiles },
1986
+ base2.length
1987
+ );
1988
+ const next = [...base2, ...accepted];
1989
+ setFiles(next);
1990
+ setRejections(rejected);
1991
+ onFilesChange?.(next);
1992
+ };
1993
+ const remove = (index) => {
1994
+ const next = files.filter((_, i) => i !== index);
1995
+ setFiles(next);
1996
+ setRejections([]);
1997
+ onFilesChange?.(next);
1998
+ };
1999
+ const onDrop = (e) => {
2000
+ e.preventDefault();
2001
+ setDragging(false);
2002
+ if (!disabled) add([...e.dataTransfer.files]);
2003
+ };
2004
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cx("trc-dropzone", className), children: [
2005
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2006
+ "label",
2007
+ {
2008
+ className: cx(
2009
+ "trc-dropzone__area",
2010
+ dragging && "trc-dropzone__area--dragging",
2011
+ disabled && "trc-dropzone__area--disabled"
2012
+ ),
2013
+ onDragEnter: (e) => {
2014
+ e.preventDefault();
2015
+ if (!disabled) setDragging(true);
2016
+ },
2017
+ onDragOver: (e) => e.preventDefault(),
2018
+ onDragLeave: (e) => {
2019
+ if (!e.currentTarget.contains(e.relatedTarget)) setDragging(false);
2020
+ },
2021
+ onDrop,
2022
+ children: [
2023
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2024
+ "input",
2025
+ {
2026
+ type: "file",
2027
+ accept,
2028
+ multiple,
2029
+ name,
2030
+ disabled,
2031
+ className: "trc-visually-hidden",
2032
+ onChange: (e) => {
2033
+ add([...e.target.files ?? []]);
2034
+ e.target.value = "";
2035
+ },
2036
+ ...a11y,
2037
+ "aria-describedby": cx(a11y["aria-describedby"], hint != null && hintId) || void 0
2038
+ }
2039
+ ),
2040
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "trc-dropzone__title", children: [
2041
+ title,
2042
+ " ",
2043
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "trc-dropzone__browse", children: browseLabel })
2044
+ ] }),
2045
+ hint != null && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { id: hintId, "aria-hidden": true, className: "trc-dropzone__hint", children: hint })
2046
+ ]
2047
+ }
2048
+ ),
2049
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { "aria-live": "polite", children: rejections.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "trc-dropzone__rejections", children: rejections.map((rejection, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("li", { children: rejectionText(rejection) }, i)) }) }),
2050
+ files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "trc-dropzone__files", children: files.map((file, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("li", { className: "trc-dropzone__file", children: [
2051
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "trc-dropzone__file-name", children: file.name }),
2052
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "trc-dropzone__file-size", children: formatBytes(file.size) }),
2053
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2054
+ "button",
2055
+ {
2056
+ type: "button",
2057
+ className: "trc-dropzone__remove",
2058
+ "aria-label": typeof removeLabel === "string" ? fill(removeLabel, { name: file.name }) : removeLabel(file),
2059
+ onClick: () => remove(i),
2060
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Close, {})
2061
+ }
2062
+ )
2063
+ ] }, `${file.name}-${i}`)) })
2064
+ ] });
2065
+ }
2066
+
2067
+ // src/components/slider.tsx
2068
+ var import_react25 = require("react");
2069
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2070
+ var Slider = (0, import_react25.forwardRef)(function Slider2({
2071
+ value,
2072
+ defaultValue,
2073
+ onValueChange,
2074
+ min = 0,
2075
+ max = 100,
2076
+ step = 1,
2077
+ showValue = false,
2078
+ formatValue = (v) => v,
2079
+ invalid,
2080
+ className,
2081
+ style,
2082
+ ...props
2083
+ }, ref) {
2084
+ const [current, setCurrent] = useControllable(value, defaultValue ?? min, onValueChange);
2085
+ const a11y = useFieldProps({ ...props, invalid });
2086
+ const progress = max > min ? (current - min) / (max - min) * 100 : 0;
2087
+ const formatted = formatValue(current);
2088
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cx("trc-slider", className), children: [
2089
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2090
+ "input",
2091
+ {
2092
+ ref,
2093
+ ...props,
2094
+ ...a11y,
2095
+ type: "range",
2096
+ min,
2097
+ max,
2098
+ step,
2099
+ value: current,
2100
+ "aria-valuetext": typeof formatted === "string" ? formatted : void 0,
2101
+ onChange: (e) => setCurrent(Number(e.target.value)),
2102
+ className: "trc-slider__input",
2103
+ style: { ...style, "--trc-slider-progress": `${progress}%` }
2104
+ }
2105
+ ),
2106
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("output", { htmlFor: a11y.id, className: "trc-slider__value", "aria-hidden": true, children: formatted })
2107
+ ] });
2108
+ });
2109
+
2110
+ // src/components/date-picker.tsx
2111
+ var import_react26 = require("react");
2112
+
2113
+ // src/utils/dates.ts
2114
+ var startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
2115
+ var addDays = (date, days) => new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
2116
+ function addMonths(date, months) {
2117
+ const target = new Date(date.getFullYear(), date.getMonth() + months, 1);
2118
+ const lastDay = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();
2119
+ return new Date(target.getFullYear(), target.getMonth(), Math.min(date.getDate(), lastDay));
2120
+ }
2121
+ var sameDay = (a, b) => !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2122
+ var toISODate = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
2123
+ function gridStart(month, weekStartsOn) {
2124
+ const first = new Date(month.getFullYear(), month.getMonth(), 1);
2125
+ const offset = (first.getDay() - weekStartsOn + 7) % 7;
2126
+ return addDays(first, -offset);
2127
+ }
2128
+ var isBefore = (a, b) => startOfDay(a).getTime() < startOfDay(b).getTime();
2129
+
2130
+ // src/components/date-picker.tsx
2131
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2132
+ function DatePicker({
2133
+ value,
2134
+ defaultValue = null,
2135
+ onValueChange,
2136
+ min,
2137
+ max,
2138
+ locale,
2139
+ weekStartsOn = 1,
2140
+ placeholder = "Choose a date",
2141
+ formatDate,
2142
+ name,
2143
+ label = "Choose a date",
2144
+ previousMonthLabel = "Previous month",
2145
+ nextMonthLabel = "Next month",
2146
+ invalid,
2147
+ disabled,
2148
+ required,
2149
+ id,
2150
+ className
2151
+ }) {
2152
+ const [selected, setSelected] = useControllable(value, defaultValue, onValueChange);
2153
+ const [open, setOpen] = (0, import_react26.useState)(false);
2154
+ const [focused, setFocused] = (0, import_react26.useState)(() => startOfDay(selected ?? /* @__PURE__ */ new Date()));
2155
+ const triggerRef = (0, import_react26.useRef)(null);
2156
+ const panelRef = (0, import_react26.useRef)(null);
2157
+ const uid = (0, import_react26.useId)();
2158
+ const a11y = useFieldProps({ id, invalid, required });
2159
+ const display = new Intl.DateTimeFormat(locale, { dateStyle: "medium" });
2160
+ const full = new Intl.DateTimeFormat(locale, { dateStyle: "full" });
2161
+ const monthTitle = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" });
2162
+ const weekdayShort = new Intl.DateTimeFormat(locale, { weekday: "short" });
2163
+ const weekdayLong = new Intl.DateTimeFormat(locale, { weekday: "long" });
2164
+ const format = formatDate ?? ((d) => display.format(d));
2165
+ const outOfRange = (date) => !!min && isBefore(date, min) || !!max && isBefore(max, date);
2166
+ const clamp = (date) => min && isBefore(date, min) ? startOfDay(min) : max && isBefore(max, date) ? startOfDay(max) : date;
2167
+ const openCalendar = () => {
2168
+ setFocused(clamp(startOfDay(selected ?? /* @__PURE__ */ new Date())));
2169
+ setOpen(true);
2170
+ };
2171
+ const close = (returnFocus = true) => {
2172
+ setOpen(false);
2173
+ if (returnFocus) triggerRef.current?.focus();
2174
+ };
2175
+ const choose = (date) => {
2176
+ if (outOfRange(date)) return;
2177
+ setSelected(date);
2178
+ close();
2179
+ };
2180
+ useAnchoredPosition(open, triggerRef, panelRef, { side: "bottom", align: "start" });
2181
+ useDismiss(open, [triggerRef, panelRef], (reason) => close(reason === "escape"));
2182
+ (0, import_react26.useEffect)(() => {
2183
+ if (open) panelRef.current?.querySelector(`[data-date="${toISODate(focused)}"]`)?.focus();
2184
+ }, [open, focused]);
2185
+ const onGridKeyDown = (e) => {
2186
+ const moves = {
2187
+ ArrowLeft: () => addDays(focused, -1),
2188
+ ArrowRight: () => addDays(focused, 1),
2189
+ ArrowUp: () => addDays(focused, -7),
2190
+ ArrowDown: () => addDays(focused, 7),
2191
+ Home: () => addDays(focused, -((focused.getDay() - weekStartsOn + 7) % 7)),
2192
+ End: () => addDays(focused, 6 - (focused.getDay() - weekStartsOn + 7) % 7),
2193
+ PageUp: () => addMonths(focused, e.shiftKey ? -12 : -1),
2194
+ PageDown: () => addMonths(focused, e.shiftKey ? 12 : 1)
2195
+ };
2196
+ const move = moves[e.key];
2197
+ if (move) {
2198
+ e.preventDefault();
2199
+ setFocused(clamp(move()));
2200
+ }
2201
+ };
2202
+ const onPanelKeyDown = (e) => {
2203
+ if (e.key !== "Tab") return;
2204
+ const items2 = [
2205
+ ...panelRef.current?.querySelectorAll("button:not([disabled]):not([tabindex='-1'])") ?? []
2206
+ ];
2207
+ const first = items2[0];
2208
+ const last = items2[items2.length - 1];
2209
+ if (e.shiftKey && document.activeElement === first) {
2210
+ e.preventDefault();
2211
+ last?.focus();
2212
+ } else if (!e.shiftKey && document.activeElement === last) {
2213
+ e.preventDefault();
2214
+ first?.focus();
2215
+ }
2216
+ };
2217
+ const start = gridStart(focused, weekStartsOn);
2218
+ const days = Array.from({ length: 42 }, (_, i) => addDays(start, i));
2219
+ const weeks = Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7));
2220
+ const today = startOfDay(/* @__PURE__ */ new Date());
2221
+ const valueId = `${uid}-value`;
2222
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cx("trc-date-picker", className), children: [
2223
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2224
+ "button",
2225
+ {
2226
+ ref: triggerRef,
2227
+ type: "button",
2228
+ id: a11y.id,
2229
+ "aria-haspopup": "dialog",
2230
+ "aria-expanded": open,
2231
+ "aria-invalid": a11y["aria-invalid"],
2232
+ "aria-describedby": cx(valueId, a11y["aria-describedby"]) || void 0,
2233
+ disabled,
2234
+ onClick: () => open ? close() : openCalendar(),
2235
+ className: cx("trc-control", "trc-date-picker__trigger", !selected && "trc-date-picker__trigger--empty"),
2236
+ children: [
2237
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { id: valueId, children: selected ? format(selected) : placeholder }),
2238
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Calendar, { className: "trc-date-picker__icon" })
2239
+ ]
2240
+ }
2241
+ ),
2242
+ name && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("input", { type: "hidden", name, value: selected ? toISODate(selected) : "", required }),
2243
+ open && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2244
+ "div",
2245
+ {
2246
+ ref: panelRef,
2247
+ role: "dialog",
2248
+ "aria-modal": "true",
2249
+ "aria-label": label,
2250
+ className: "trc-floating trc-calendar",
2251
+ onKeyDown: onPanelKeyDown,
2252
+ children: [
2253
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "trc-calendar__head", children: [
2254
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2255
+ "button",
2256
+ {
2257
+ type: "button",
2258
+ className: "trc-calendar__nav",
2259
+ "aria-label": previousMonthLabel,
2260
+ onClick: () => setFocused(clamp(addMonths(focused, -1))),
2261
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronLeft, {})
2262
+ }
2263
+ ),
2264
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { id: `${uid}-title`, className: "trc-calendar__title", "aria-live": "polite", children: monthTitle.format(focused) }),
2265
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2266
+ "button",
2267
+ {
2268
+ type: "button",
2269
+ className: "trc-calendar__nav",
2270
+ "aria-label": nextMonthLabel,
2271
+ onClick: () => setFocused(clamp(addMonths(focused, 1))),
2272
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronRight, {})
2273
+ }
2274
+ )
2275
+ ] }),
2276
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2277
+ "table",
2278
+ {
2279
+ role: "grid",
2280
+ "aria-labelledby": `${uid}-title`,
2281
+ className: "trc-calendar__grid",
2282
+ onKeyDown: onGridKeyDown,
2283
+ children: [
2284
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { children: weeks[0].map((day) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", abbr: weekdayLong.format(day), className: "trc-calendar__weekday", children: weekdayShort.format(day).replace(".", "").slice(0, 3) }, day.getDay())) }) }),
2285
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { children: weeks.map((week, w) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { children: week.map((day) => {
2286
+ const isSelected = sameDay(day, selected);
2287
+ const disabledDay = outOfRange(day);
2288
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { role: "gridcell", "aria-selected": isSelected || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2289
+ "button",
2290
+ {
2291
+ type: "button",
2292
+ "data-date": toISODate(day),
2293
+ tabIndex: sameDay(day, focused) ? 0 : -1,
2294
+ "aria-label": full.format(day),
2295
+ "aria-current": sameDay(day, today) ? "date" : void 0,
2296
+ disabled: disabledDay,
2297
+ onClick: () => choose(day),
2298
+ onKeyDown: (e) => {
2299
+ if (e.key === "Enter" || e.key === " ") {
2300
+ e.preventDefault();
2301
+ choose(day);
2302
+ }
2303
+ },
2304
+ className: cx(
2305
+ "trc-calendar__day",
2306
+ day.getMonth() !== focused.getMonth() && "trc-calendar__day--outside",
2307
+ isSelected && "trc-calendar__day--selected"
2308
+ ),
2309
+ children: day.getDate()
2310
+ }
2311
+ ) }, toISODate(day));
2312
+ }) }, w)) })
2313
+ ]
2314
+ }
2315
+ )
2316
+ ]
2317
+ }
2318
+ ) })
2319
+ ] });
2320
+ }
2321
+
2322
+ // src/components/avatar.tsx
2323
+ var import_react27 = require("react");
2324
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2325
+ function initials(name) {
2326
+ const words = name.trim().split(/\s+/).filter(Boolean);
2327
+ const letters = words.length > 1 ? [words[0][0], words[words.length - 1][0]] : [words[0]?.[0]];
2328
+ return letters.filter(Boolean).join("").toUpperCase();
2329
+ }
2330
+ function Avatar({ name, src, size: size2 = "md", className }) {
2331
+ const [failed, setFailed] = (0, import_react27.useState)(false);
2332
+ const showImage = src && !failed;
2333
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cx("trc-avatar", `trc-avatar--${size2}`, className), children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("img", { src, alt: name, className: "trc-avatar__image", onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { role: "img", "aria-label": name, className: "trc-avatar__initials", children: initials(name) }) });
2334
+ }
2335
+ function AvatarGroup({
2336
+ children,
2337
+ max = 4,
2338
+ moreLabel = "{count} more",
2339
+ size: size2 = "md",
2340
+ className
2341
+ }) {
2342
+ const items2 = import_react27.Children.toArray(children);
2343
+ const hidden = items2.length - max;
2344
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: cx("trc-avatar-group", className), children: [
2345
+ items2.slice(0, max),
2346
+ hidden > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: cx("trc-avatar", `trc-avatar--${size2}`, "trc-avatar--more"), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
2347
+ "span",
2348
+ {
2349
+ role: "img",
2350
+ "aria-label": typeof moreLabel === "string" ? fill(moreLabel, { count: hidden }) : moreLabel(hidden),
2351
+ className: "trc-avatar__initials",
2352
+ children: [
2353
+ "+",
2354
+ hidden
2355
+ ]
2356
+ }
2357
+ ) })
2358
+ ] });
2359
+ }
2360
+
2361
+ // src/components/tag.tsx
2362
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2363
+ function Tag({ tone = "default", onRemove, removeLabel = "Remove", className, children, ...props }) {
2364
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: cx("trc-tag", tone === "accent" && "trc-tag--accent", className), ...props, children: [
2365
+ children,
2366
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2367
+ "button",
2368
+ {
2369
+ type: "button",
2370
+ className: "trc-tag__remove",
2371
+ "aria-label": `${removeLabel} ${typeof children === "string" ? children : ""}`.trim(),
2372
+ onClick: onRemove,
2373
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Close, {})
2374
+ }
2375
+ )
2376
+ ] });
2377
+ }
2378
+
2379
+ // src/components/stat.tsx
2380
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2381
+ function Stat({ label, value, change, changeTone = "neutral", description, className }) {
2382
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("dl", { className: cx("trc-stat", className), children: [
2383
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("dt", { className: "trc-stat__label", children: label }),
2384
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("dd", { className: "trc-stat__value", children: value }),
2385
+ (change != null || description != null) && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("dd", { className: "trc-stat__meta", children: [
2386
+ change != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cx("trc-stat__change", `trc-stat__change--${changeTone}`), children: change }),
2387
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "trc-stat__description", children: description })
2388
+ ] })
2389
+ ] });
2390
+ }
2391
+
2392
+ // src/components/table.tsx
2393
+ var import_react28 = require("react");
2394
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2395
+ var compare = (a, b) => {
2396
+ if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
2397
+ if (typeof a === "number" && typeof b === "number") return a - b;
2398
+ return String(a ?? "").localeCompare(String(b ?? ""), void 0, { numeric: true, sensitivity: "base" });
2399
+ };
2400
+ function Table({
2401
+ columns,
2402
+ rows,
2403
+ rowKey,
2404
+ caption,
2405
+ hideCaption = false,
2406
+ defaultSort,
2407
+ dense = false,
2408
+ emptyText = "No data",
2409
+ className
2410
+ }) {
2411
+ const [sort, setSort] = (0, import_react28.useState)(defaultSort);
2412
+ const field = (row, key) => row[key];
2413
+ const sorted = (() => {
2414
+ const column = columns.find((c) => c.key === sort?.key);
2415
+ if (!sort || !column) return rows;
2416
+ const value = (row) => column.sortValue ? column.sortValue(row) : field(row, column.key);
2417
+ const ordered = [...rows].sort((a, b) => compare(value(a), value(b)));
2418
+ return sort.direction === "ascending" ? ordered : ordered.reverse();
2419
+ })();
2420
+ const toggle = (key) => setSort(
2421
+ (current) => current?.key === key && current.direction === "ascending" ? { key, direction: "descending" } : { key, direction: "ascending" }
2422
+ );
2423
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2424
+ "div",
2425
+ {
2426
+ className: cx("trc-table", dense && "trc-table--dense", className),
2427
+ role: "region",
2428
+ "aria-label": typeof caption === "string" ? caption : void 0,
2429
+ tabIndex: 0,
2430
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("table", { className: "trc-table__table", children: [
2431
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("caption", { className: cx("trc-table__caption", hideCaption && "trc-visually-hidden"), children: caption }),
2432
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { children: columns.map((column) => {
2433
+ const direction = sort?.key === column.key ? sort.direction : void 0;
2434
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2435
+ "th",
2436
+ {
2437
+ scope: "col",
2438
+ "aria-sort": column.sortable ? direction ?? "none" : void 0,
2439
+ className: cx("trc-table__head", column.align && `trc-table__cell--${column.align}`),
2440
+ children: column.sortable ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("button", { type: "button", className: "trc-table__sort", onClick: () => toggle(column.key), children: [
2441
+ column.header,
2442
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2443
+ ChevronDown,
2444
+ {
2445
+ className: cx(
2446
+ "trc-table__sort-icon",
2447
+ direction && "trc-table__sort-icon--active",
2448
+ direction === "ascending" && "trc-table__sort-icon--up"
2449
+ )
2450
+ }
2451
+ )
2452
+ ] }) : column.header
2453
+ },
2454
+ column.key
2455
+ );
2456
+ }) }) }),
2457
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tbody", { children: sorted.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("td", { colSpan: columns.length, className: "trc-table__empty", children: emptyText }) }) : sorted.map((row) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("tr", { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2458
+ "td",
2459
+ {
2460
+ className: cx("trc-table__cell", column.align && `trc-table__cell--${column.align}`),
2461
+ children: column.render ? column.render(row) : field(row, column.key)
2462
+ },
2463
+ column.key
2464
+ )) }, rowKey(row))) })
2465
+ ] })
2466
+ }
2467
+ );
2468
+ }
2469
+
2470
+ // src/components/loading.tsx
2471
+ var import_react29 = require("react");
2472
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2473
+ var size = (value) => typeof value === "number" ? `${value}px` : value;
2474
+ function Skeleton({ width, height, circle = false, lines, className }) {
2475
+ if (lines && lines > 1) {
2476
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "aria-hidden": true, className: cx("trc-skeleton-lines", className), style: { width: size(width) }, children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2477
+ "span",
2478
+ {
2479
+ className: "trc-skeleton trc-skeleton--text",
2480
+ style: { width: i === lines - 1 ? "60%" : "100%" }
2481
+ },
2482
+ i
2483
+ )) });
2484
+ }
2485
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2486
+ "span",
2487
+ {
2488
+ "aria-hidden": true,
2489
+ className: cx(
2490
+ "trc-skeleton",
2491
+ circle && "trc-skeleton--circle",
2492
+ !height && !circle && "trc-skeleton--text",
2493
+ className
2494
+ ),
2495
+ style: { width: size(width), height: size(height) ?? (circle ? size(width) : void 0) }
2496
+ }
2497
+ );
2498
+ }
2499
+ function Spinner2({ size: s = "md", label = "Loading", className }) {
2500
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { role: "status", className: cx("trc-spinner", `trc-spinner--${s}`, className), children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { viewBox: "0 0 24 24", "aria-hidden": true, className: "trc-spinner__svg", children: [
2502
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("circle", { cx: "12", cy: "12", r: "10", className: "trc-spinner__track" }),
2503
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: "M12 2a10 10 0 0 1 10 10", className: "trc-spinner__arc" })
2504
+ ] }),
2505
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "trc-visually-hidden", children: label })
2506
+ ] });
2507
+ }
2508
+ function Progress({
2509
+ value,
2510
+ max = 100,
2511
+ label,
2512
+ "aria-label": ariaLabel,
2513
+ showValue = false,
2514
+ formatValue = (v, m) => `${Math.round(v / m * 100)} %`,
2515
+ className
2516
+ }) {
2517
+ const id = (0, import_react29.useId)();
2518
+ const determinate = value !== void 0 && value !== null;
2519
+ const clamped = determinate ? Math.min(Math.max(value, 0), max) : 0;
2520
+ const text = determinate ? formatValue(clamped, max) : void 0;
2521
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cx("trc-progress", !determinate && "trc-progress--indeterminate", className), children: [
2522
+ (label != null || showValue && text) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "trc-progress__head", children: [
2523
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { id: `${id}-label`, className: "trc-progress__label", children: label }),
2524
+ showValue && text && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "aria-hidden": true, className: "trc-progress__value", children: text })
2525
+ ] }),
2526
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2527
+ "div",
2528
+ {
2529
+ role: "progressbar",
2530
+ "aria-labelledby": label != null ? `${id}-label` : void 0,
2531
+ "aria-label": label == null ? ariaLabel : void 0,
2532
+ "aria-valuemin": 0,
2533
+ "aria-valuemax": max,
2534
+ "aria-valuenow": determinate ? clamped : void 0,
2535
+ "aria-valuetext": text,
2536
+ className: "trc-progress__track",
2537
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2538
+ "div",
2539
+ {
2540
+ className: "trc-progress__fill",
2541
+ style: { "--trc-progress": `${clamped / max * 100}%` }
2542
+ }
2543
+ )
2544
+ }
2545
+ )
2546
+ ] });
2547
+ }
2548
+
2549
+ // src/components/kbd.tsx
2550
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2551
+ function Kbd({ className, ...props }) {
2552
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("kbd", { className: cx("trc-kbd", className), ...props });
2553
+ }
2554
+ function Divider({ label, orientation = "horizontal", className }) {
2555
+ if (orientation === "vertical") {
2556
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { role: "separator", "aria-orientation": "vertical", className: cx("trc-divider--vertical", className) });
2557
+ }
2558
+ if (label == null) return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("hr", { className: cx("trc-divider", className) });
2559
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { role: "separator", className: cx("trc-divider-label", className), children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "trc-divider-label__text", children: label }) });
2560
+ }
2561
+
2562
+ // src/components/code-block.tsx
2563
+ var import_react30 = require("react");
2564
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2565
+ var BADGES = {
2566
+ tsx: "TS",
2567
+ ts: "TS",
2568
+ jsx: "JS",
2569
+ js: "JS",
2570
+ css: "CSS",
2571
+ bash: "SH",
2572
+ sh: "SH",
2573
+ html: "HTML",
2574
+ json: "JSON"
2575
+ };
2576
+ var CopyIcon = () => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2577
+ "svg",
2578
+ {
2579
+ viewBox: "0 0 24 24",
2580
+ fill: "none",
2581
+ stroke: "currentColor",
2582
+ strokeWidth: 1.75,
2583
+ strokeLinecap: "round",
2584
+ strokeLinejoin: "round",
2585
+ "aria-hidden": true,
2586
+ children: [
2587
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("rect", { x: "9", y: "9", width: "12", height: "12", rx: "2.5" }),
2588
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("path", { d: "M5 15H4.5A1.5 1.5 0 0 1 3 13.5v-9A1.5 1.5 0 0 1 4.5 3h9A1.5 1.5 0 0 1 15 4.5V5" })
2589
+ ]
2590
+ }
2591
+ );
2592
+ function CodeBlock({
2593
+ code,
2594
+ title,
2595
+ language,
2596
+ children,
2597
+ copyLabel = "Copy code",
2598
+ copiedLabel = "Copied",
2599
+ className
2600
+ }) {
2601
+ const [copied, setCopied] = (0, import_react30.useState)(false);
2602
+ const timer = (0, import_react30.useRef)(void 0);
2603
+ (0, import_react30.useEffect)(() => () => window.clearTimeout(timer.current), []);
2604
+ const copy = async () => {
2605
+ await navigator.clipboard.writeText(code);
2606
+ setCopied(true);
2607
+ window.clearTimeout(timer.current);
2608
+ timer.current = window.setTimeout(() => setCopied(false), 1600);
2609
+ };
2610
+ const button = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2611
+ "button",
2612
+ {
2613
+ type: "button",
2614
+ onClick: copy,
2615
+ className: "trc-code__copy",
2616
+ "aria-label": copyLabel,
2617
+ title: copyLabel,
2618
+ "data-copied": copied,
2619
+ children: [
2620
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Check, {}) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CopyIcon, {}),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "trc-visually-hidden", "aria-live": "polite", children: copied ? copiedLabel : "" })
2622
+ ]
2623
+ }
2624
+ );
2625
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cx("trc-code", title == null && "trc-code--bare", className), children: [
2626
+ title != null ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "trc-code__bar", children: [
2627
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "trc-code__file", children: [
2628
+ language && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "trc-code__lang", children: BADGES[language] ?? language.toUpperCase() }),
2629
+ title
2630
+ ] }),
2631
+ button
2632
+ ] }) : button,
2633
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("pre", { className: "trc-code__pre", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: children ?? code }) })
2634
+ ] });
2635
+ }
705
2636
  // Annotate the CommonJS export names for ESM import in node:
706
2637
  0 && (module.exports = {
707
2638
  AccentText,
2639
+ Accordion,
2640
+ Alert,
708
2641
  ArrowLeft,
709
2642
  ArrowRight,
710
2643
  ArrowUp,
2644
+ Avatar,
2645
+ AvatarGroup,
711
2646
  BackToTop,
2647
+ Breadcrumbs,
2648
+ Calendar,
712
2649
  Card,
713
2650
  Check,
714
2651
  Checkbox,
715
2652
  ChevronDown,
2653
+ ChevronLeft,
2654
+ ChevronRight,
716
2655
  Close,
2656
+ CodeBlock,
2657
+ Combobox,
717
2658
  Container,
2659
+ DatePicker,
2660
+ Dialog,
2661
+ Divider,
2662
+ Drawer,
2663
+ DropdownMenu,
2664
+ Dropzone,
718
2665
  Field,
2666
+ FileInput,
719
2667
  Heading,
720
2668
  HeroVideo,
721
2669
  Input,
2670
+ Kbd,
2671
+ LanguageSwitcher,
722
2672
  Menu,
723
2673
  PageHero,
2674
+ Pagination,
2675
+ PasswordInput,
724
2676
  PillButton,
725
2677
  PillLink,
2678
+ PinInput,
2679
+ Popover,
2680
+ Progress,
2681
+ RadioGroup,
726
2682
  Section,
2683
+ SegmentedControl,
727
2684
  Select,
728
2685
  SiteFooter,
729
2686
  SiteHeader,
2687
+ Skeleton,
2688
+ Slider,
2689
+ Spinner,
2690
+ Stat,
730
2691
  StepNumber,
2692
+ Steps,
731
2693
  Switch,
2694
+ Table,
2695
+ Tabs,
2696
+ Tag,
732
2697
  Text,
733
2698
  Textarea,
2699
+ Toaster,
2700
+ Tooltip,
2701
+ acceptsFile,
734
2702
  cx,
735
- plainText
2703
+ formatBytes,
2704
+ initials,
2705
+ paginationRange,
2706
+ plainText,
2707
+ toast,
2708
+ validateFiles
736
2709
  });
737
2710
  //# sourceMappingURL=index.cjs.map