@staqforce.studio/staqui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1486 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/shared.ts
5
+ import { useState } from "react";
6
+ var cx = (...values) => values.filter(Boolean).join(" ");
7
+ function useControllable(value, defaultValue, onChange, controlled = value !== void 0) {
8
+ const [internal, setInternal] = useState(defaultValue);
9
+ return [
10
+ controlled ? value : internal,
11
+ (next) => {
12
+ if (!controlled) setInternal(next);
13
+ onChange?.(next);
14
+ }
15
+ ];
16
+ }
17
+
18
+ // src/foundations.tsx
19
+ import {
20
+ createContext,
21
+ useContext,
22
+ createElement,
23
+ useId,
24
+ useState as useState2
25
+ } from "react";
26
+ import {
27
+ Check,
28
+ X,
29
+ Search,
30
+ Plus,
31
+ ChevronDown,
32
+ ChevronLeft,
33
+ ChevronRight,
34
+ Info,
35
+ CircleAlert,
36
+ Settings,
37
+ Copy,
38
+ ArrowUpRight,
39
+ Package,
40
+ Upload,
41
+ Moon,
42
+ Sun,
43
+ SlidersHorizontal,
44
+ Code,
45
+ Layers,
46
+ CheckCheck
47
+ } from "lucide-react";
48
+ import { jsx, jsxs } from "react/jsx-runtime";
49
+ var StaqContext = createContext({ theme: "light", density: "compact" });
50
+ var useStaq = () => useContext(StaqContext);
51
+ function StaqProvider({
52
+ theme = "light",
53
+ density = "compact",
54
+ className,
55
+ ...props
56
+ }) {
57
+ return /* @__PURE__ */ jsx(StaqContext.Provider, { value: { theme, density }, children: /* @__PURE__ */ jsx(
58
+ "div",
59
+ {
60
+ "data-staq-theme": theme,
61
+ "data-staq-density": density,
62
+ className: cx("sq-root", className),
63
+ ...props
64
+ }
65
+ ) });
66
+ }
67
+ var icons = {
68
+ check: Check,
69
+ close: X,
70
+ search: Search,
71
+ plus: Plus,
72
+ chevronDown: ChevronDown,
73
+ chevronLeft: ChevronLeft,
74
+ chevronRight: ChevronRight,
75
+ info: Info,
76
+ warning: CircleAlert,
77
+ settings: Settings,
78
+ copy: Copy,
79
+ arrowUpRight: ArrowUpRight,
80
+ package: Package,
81
+ upload: Upload,
82
+ moon: Moon,
83
+ sun: Sun,
84
+ sliders: SlidersHorizontal,
85
+ code: Code,
86
+ layers: Layers,
87
+ complete: CheckCheck
88
+ };
89
+ function Icon({
90
+ name = "info",
91
+ source,
92
+ size = 18,
93
+ label,
94
+ className
95
+ }) {
96
+ const Component = source ?? icons[name];
97
+ return /* @__PURE__ */ jsx(
98
+ Component,
99
+ {
100
+ size,
101
+ strokeWidth: 1.7,
102
+ role: label ? "img" : void 0,
103
+ "aria-label": label,
104
+ "aria-hidden": label ? void 0 : true,
105
+ className
106
+ }
107
+ );
108
+ }
109
+ function Box({
110
+ padding = "4",
111
+ background = "transparent",
112
+ border = false,
113
+ radius = "medium",
114
+ className,
115
+ style,
116
+ ...props
117
+ }) {
118
+ return /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ className: cx("sq-box", className),
122
+ "data-background": background,
123
+ "data-border": border,
124
+ "data-radius": radius,
125
+ style: { padding: `var(--sq-space-${padding})`, ...style },
126
+ ...props
127
+ }
128
+ );
129
+ }
130
+ function Stack({
131
+ direction = "column",
132
+ gap = "4",
133
+ align,
134
+ justify,
135
+ wrap = true,
136
+ className,
137
+ style,
138
+ ...props
139
+ }) {
140
+ return /* @__PURE__ */ jsx(
141
+ "div",
142
+ {
143
+ className: cx("sq-stack", className),
144
+ style: {
145
+ flexDirection: direction,
146
+ gap: `var(--sq-space-${gap})`,
147
+ alignItems: align,
148
+ justifyContent: justify,
149
+ flexWrap: wrap ? "wrap" : "nowrap",
150
+ ...style
151
+ },
152
+ ...props
153
+ }
154
+ );
155
+ }
156
+ function Grid({
157
+ columns = 2,
158
+ minColumnWidth = "14rem",
159
+ gap = "4",
160
+ style,
161
+ className,
162
+ ...props
163
+ }) {
164
+ return /* @__PURE__ */ jsx(
165
+ "div",
166
+ {
167
+ className: cx("sq-grid", className),
168
+ style: {
169
+ "--sq-columns": columns,
170
+ "--sq-grid-min": minColumnWidth,
171
+ gap: `var(--sq-space-${gap})`,
172
+ ...style
173
+ },
174
+ ...props
175
+ }
176
+ );
177
+ }
178
+ function QueryContainer({
179
+ name = "staq",
180
+ style,
181
+ ...props
182
+ }) {
183
+ return /* @__PURE__ */ jsx(
184
+ "div",
185
+ {
186
+ style: { containerType: "inline-size", containerName: name, ...style },
187
+ ...props
188
+ }
189
+ );
190
+ }
191
+ function Divider({
192
+ vertical = false,
193
+ className,
194
+ ...props
195
+ }) {
196
+ return /* @__PURE__ */ jsx(
197
+ "hr",
198
+ {
199
+ className: cx("sq-divider", className),
200
+ "data-vertical": vertical,
201
+ "aria-orientation": vertical ? "vertical" : "horizontal",
202
+ ...props
203
+ }
204
+ );
205
+ }
206
+ function Heading({
207
+ level = 2,
208
+ size = "medium",
209
+ className,
210
+ ...props
211
+ }) {
212
+ return createElement(`h${level}`, {
213
+ className: cx("sq-heading", `sq-heading-${size}`, className),
214
+ ...props
215
+ });
216
+ }
217
+ function Text({
218
+ tone = "neutral",
219
+ weight = "regular",
220
+ size = "medium",
221
+ className,
222
+ ...props
223
+ }) {
224
+ return /* @__PURE__ */ jsx(
225
+ "span",
226
+ {
227
+ className: cx("sq-text", className),
228
+ "data-tone": tone,
229
+ "data-weight": weight,
230
+ "data-size": size,
231
+ ...props
232
+ }
233
+ );
234
+ }
235
+ function Paragraph({
236
+ tone = "neutral",
237
+ className,
238
+ ...props
239
+ }) {
240
+ return /* @__PURE__ */ jsx("p", { className: cx("sq-paragraph", className), "data-tone": tone, ...props });
241
+ }
242
+ function Number({
243
+ value,
244
+ locale = "en-US",
245
+ format,
246
+ className,
247
+ ...props
248
+ }) {
249
+ return /* @__PURE__ */ jsx(Text, { className: cx("sq-number", className), ...props, children: new Intl.NumberFormat(locale, format).format(value) });
250
+ }
251
+ function OrderedList(props) {
252
+ return /* @__PURE__ */ jsx("ol", { className: "sq-list", ...props });
253
+ }
254
+ function UnorderedList(props) {
255
+ return /* @__PURE__ */ jsx("ul", { className: "sq-list", ...props });
256
+ }
257
+ function ListItem(props) {
258
+ return /* @__PURE__ */ jsx("li", { ...props });
259
+ }
260
+ function Section({
261
+ heading,
262
+ description,
263
+ action,
264
+ children,
265
+ className,
266
+ ...props
267
+ }) {
268
+ const id = useId();
269
+ return /* @__PURE__ */ jsxs(
270
+ "section",
271
+ {
272
+ "aria-labelledby": heading ? id : void 0,
273
+ className: cx("sq-section", className),
274
+ ...props,
275
+ children: [
276
+ (heading || action) && /* @__PURE__ */ jsxs("header", { className: "sq-section-header", children: [
277
+ /* @__PURE__ */ jsxs("div", { children: [
278
+ heading && /* @__PURE__ */ jsx(Heading, { id, children: heading }),
279
+ description && /* @__PURE__ */ jsx(Paragraph, { tone: "muted", children: description })
280
+ ] }),
281
+ action
282
+ ] }),
283
+ children
284
+ ]
285
+ }
286
+ );
287
+ }
288
+ function Page({
289
+ heading,
290
+ description,
291
+ action,
292
+ aside,
293
+ breadcrumbs,
294
+ width = "default",
295
+ className,
296
+ children,
297
+ ...props
298
+ }) {
299
+ return /* @__PURE__ */ jsxs("div", { className: cx("sq-page", className), "data-width": width, ...props, children: [
300
+ breadcrumbs,
301
+ /* @__PURE__ */ jsxs("header", { className: "sq-section-header", children: [
302
+ /* @__PURE__ */ jsxs("div", { children: [
303
+ heading && /* @__PURE__ */ jsx(Heading, { level: 1, size: "large", children: heading }),
304
+ description && /* @__PURE__ */ jsx(Paragraph, { tone: "muted", children: description })
305
+ ] }),
306
+ action
307
+ ] }),
308
+ /* @__PURE__ */ jsxs("div", { className: aside ? "sq-page-layout" : void 0, children: [
309
+ /* @__PURE__ */ jsx("div", { children }),
310
+ aside && /* @__PURE__ */ jsx("aside", { children: aside })
311
+ ] })
312
+ ] });
313
+ }
314
+ function Image({
315
+ alt,
316
+ fit = "cover",
317
+ aspectRatio,
318
+ style,
319
+ className,
320
+ ...props
321
+ }) {
322
+ return /* @__PURE__ */ jsx(
323
+ "img",
324
+ {
325
+ alt,
326
+ className: cx("sq-image", className),
327
+ style: { objectFit: fit, aspectRatio, ...style },
328
+ ...props
329
+ }
330
+ );
331
+ }
332
+ function Thumbnail({
333
+ size = "medium",
334
+ className,
335
+ ...props
336
+ }) {
337
+ return /* @__PURE__ */ jsx(
338
+ Image,
339
+ {
340
+ className: cx("sq-thumbnail", className),
341
+ "data-size": size,
342
+ ...props
343
+ }
344
+ );
345
+ }
346
+ function Avatar({ name, src, size = "medium", className }) {
347
+ const [failed, setFailed] = useState2(false);
348
+ const initials = name.trim().split(/\s+/).slice(0, 2).map((x) => x[0]).join("");
349
+ return /* @__PURE__ */ jsx(
350
+ "span",
351
+ {
352
+ className: cx("sq-avatar", className),
353
+ "data-size": size,
354
+ role: "img",
355
+ "aria-label": name,
356
+ children: src && !failed ? /* @__PURE__ */ jsx("img", { src, alt: "", onError: () => setFailed(true) }) : initials
357
+ }
358
+ );
359
+ }
360
+
361
+ // src/actions.tsx
362
+ import {
363
+ forwardRef,
364
+ useState as useState3
365
+ } from "react";
366
+ import { Slot } from "@radix-ui/react-slot";
367
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
368
+ var Button = forwardRef(
369
+ function Button2({
370
+ variant = "secondary",
371
+ tone = "neutral",
372
+ size = "medium",
373
+ loading,
374
+ disabled,
375
+ icon,
376
+ fullWidth,
377
+ asChild,
378
+ children,
379
+ className,
380
+ type = "button",
381
+ ...props
382
+ }, ref) {
383
+ const Comp = asChild ? Slot : "button";
384
+ return /* @__PURE__ */ jsx2(
385
+ Comp,
386
+ {
387
+ ref,
388
+ type: asChild ? void 0 : type,
389
+ className: cx("sq-button", className),
390
+ "data-variant": variant,
391
+ "data-tone": tone,
392
+ "data-size": size,
393
+ "data-full-width": fullWidth,
394
+ disabled: asChild ? void 0 : disabled || loading,
395
+ "aria-busy": loading || void 0,
396
+ ...props,
397
+ children: asChild ? children : /* @__PURE__ */ jsxs2(Fragment, { children: [
398
+ loading ? /* @__PURE__ */ jsx2("span", { className: "sq-spinner", "aria-hidden": "true" }) : icon,
399
+ children,
400
+ loading && /* @__PURE__ */ jsx2("span", { className: "sq-sr-only", children: "Loading" })
401
+ ] })
402
+ }
403
+ );
404
+ }
405
+ );
406
+ function ButtonGroup({
407
+ label,
408
+ className,
409
+ ...props
410
+ }) {
411
+ return /* @__PURE__ */ jsx2(
412
+ "div",
413
+ {
414
+ role: "group",
415
+ "aria-label": label,
416
+ className: cx("sq-button-group", className),
417
+ ...props
418
+ }
419
+ );
420
+ }
421
+ var Clickable = forwardRef(function Clickable2({ className, type = "button", ...props }, ref) {
422
+ return /* @__PURE__ */ jsx2(
423
+ "button",
424
+ {
425
+ ref,
426
+ type,
427
+ className: cx("sq-clickable", className),
428
+ ...props
429
+ }
430
+ );
431
+ });
432
+ var Link = forwardRef(function Link2({ tone = "neutral", variant = "text", className, target, rel, ...props }, ref) {
433
+ return /* @__PURE__ */ jsx2(
434
+ "a",
435
+ {
436
+ ref,
437
+ className: cx(variant === "button" ? "sq-button" : "sq-link", className),
438
+ "data-tone": tone,
439
+ target,
440
+ rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
441
+ ...props
442
+ }
443
+ );
444
+ });
445
+ function Chip({
446
+ onRemove,
447
+ removeLabel = "Remove tag",
448
+ tone = "neutral",
449
+ className,
450
+ children,
451
+ ...props
452
+ }) {
453
+ return /* @__PURE__ */ jsxs2("span", { className: cx("sq-chip", className), "data-tone": tone, ...props, children: [
454
+ children,
455
+ onRemove && /* @__PURE__ */ jsx2(
456
+ "button",
457
+ {
458
+ className: "sq-chip-remove",
459
+ type: "button",
460
+ "aria-label": removeLabel,
461
+ onClick: onRemove,
462
+ children: /* @__PURE__ */ jsx2(Icon, { name: "close", size: 12 })
463
+ }
464
+ )
465
+ ] });
466
+ }
467
+ function ClickableChip({
468
+ selected = false,
469
+ onRemove,
470
+ removeLabel = "Remove filter",
471
+ className,
472
+ children,
473
+ ...props
474
+ }) {
475
+ return /* @__PURE__ */ jsxs2("span", { className: "sq-chip-wrapper", children: [
476
+ /* @__PURE__ */ jsxs2(
477
+ "button",
478
+ {
479
+ type: "button",
480
+ className: cx("sq-chip", "sq-clickable-chip", className),
481
+ "aria-pressed": selected,
482
+ ...props,
483
+ children: [
484
+ selected && /* @__PURE__ */ jsx2(Icon, { name: "check", size: 14 }),
485
+ " ",
486
+ children
487
+ ]
488
+ }
489
+ ),
490
+ onRemove && /* @__PURE__ */ jsx2(
491
+ "button",
492
+ {
493
+ type: "button",
494
+ className: "sq-chip-remove",
495
+ disabled: props.disabled,
496
+ "aria-label": removeLabel,
497
+ onClick: onRemove,
498
+ children: /* @__PURE__ */ jsx2(Icon, { name: "close", size: 12 })
499
+ }
500
+ )
501
+ ] });
502
+ }
503
+ function Badge({
504
+ tone = "neutral",
505
+ size = "medium",
506
+ icon,
507
+ className,
508
+ children,
509
+ ...props
510
+ }) {
511
+ return /* @__PURE__ */ jsxs2(
512
+ "span",
513
+ {
514
+ className: cx("sq-badge", className),
515
+ "data-tone": tone,
516
+ "data-size": size,
517
+ ...props,
518
+ children: [
519
+ icon,
520
+ children
521
+ ]
522
+ }
523
+ );
524
+ }
525
+ function Banner({
526
+ title,
527
+ tone = "info",
528
+ dismissible,
529
+ onDismiss,
530
+ action,
531
+ className,
532
+ children,
533
+ ...props
534
+ }) {
535
+ const [dismissed, setDismissed] = useState3(false);
536
+ if (dismissed) return null;
537
+ return /* @__PURE__ */ jsxs2(
538
+ "div",
539
+ {
540
+ role: tone === "critical" ? "alert" : "status",
541
+ className: cx("sq-banner", className),
542
+ "data-tone": tone,
543
+ ...props,
544
+ children: [
545
+ /* @__PURE__ */ jsx2(
546
+ Icon,
547
+ {
548
+ name: tone === "critical" || tone === "warning" ? "warning" : "info"
549
+ }
550
+ ),
551
+ /* @__PURE__ */ jsxs2("div", { className: "sq-grow", children: [
552
+ /* @__PURE__ */ jsx2("strong", { children: title }),
553
+ children && /* @__PURE__ */ jsx2("div", { children }),
554
+ action
555
+ ] }),
556
+ dismissible && /* @__PURE__ */ jsx2(
557
+ Button,
558
+ {
559
+ variant: "tertiary",
560
+ size: "small",
561
+ "aria-label": "Dismiss notification",
562
+ onClick: () => {
563
+ setDismissed(true);
564
+ onDismiss?.();
565
+ },
566
+ children: /* @__PURE__ */ jsx2(Icon, { name: "close" })
567
+ }
568
+ )
569
+ ]
570
+ }
571
+ );
572
+ }
573
+ function EmptyState({
574
+ title,
575
+ children,
576
+ action,
577
+ graphic
578
+ }) {
579
+ return /* @__PURE__ */ jsxs2("div", { className: "sq-empty", children: [
580
+ graphic ?? /* @__PURE__ */ jsx2(Icon, { name: "package", size: 36 }),
581
+ /* @__PURE__ */ jsx2("h3", { children: title }),
582
+ children && /* @__PURE__ */ jsx2("div", { className: "sq-muted", children }),
583
+ action
584
+ ] });
585
+ }
586
+ function Progress({
587
+ value,
588
+ max = 100,
589
+ label,
590
+ showValue = true
591
+ }) {
592
+ const safeMax = Math.max(1, max);
593
+ const safeValue = value === void 0 ? void 0 : Math.min(safeMax, Math.max(0, value));
594
+ return /* @__PURE__ */ jsxs2("div", { className: "sq-progress", children: [
595
+ /* @__PURE__ */ jsxs2("div", { children: [
596
+ /* @__PURE__ */ jsx2("span", { children: label }),
597
+ showValue && safeValue !== void 0 && /* @__PURE__ */ jsxs2("span", { children: [
598
+ Math.round(safeValue / safeMax * 100),
599
+ "%"
600
+ ] })
601
+ ] }),
602
+ /* @__PURE__ */ jsx2("progress", { "aria-label": label, max: safeMax, value: safeValue })
603
+ ] });
604
+ }
605
+ function Spinner({
606
+ label = "Loading",
607
+ size = "medium"
608
+ }) {
609
+ return /* @__PURE__ */ jsxs2("span", { role: "status", className: "sq-spinner-wrap", children: [
610
+ /* @__PURE__ */ jsx2("span", { className: "sq-spinner", "data-size": size, "aria-hidden": "true" }),
611
+ /* @__PURE__ */ jsx2("span", { className: "sq-sr-only", children: label })
612
+ ] });
613
+ }
614
+
615
+ // src/forms.tsx
616
+ import {
617
+ forwardRef as forwardRef2,
618
+ useId as useId2,
619
+ useRef,
620
+ useEffect,
621
+ useState as useState4
622
+ } from "react";
623
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
624
+ function FieldShell({
625
+ id,
626
+ label,
627
+ description,
628
+ error,
629
+ hideLabel,
630
+ required,
631
+ children
632
+ }) {
633
+ return /* @__PURE__ */ jsxs3("div", { className: "sq-field", children: [
634
+ /* @__PURE__ */ jsxs3("label", { htmlFor: id, className: hideLabel ? "sq-sr-only" : "sq-label", children: [
635
+ label,
636
+ required && /* @__PURE__ */ jsx3("span", { "aria-hidden": "true", children: " *" })
637
+ ] }),
638
+ children,
639
+ description && /* @__PURE__ */ jsx3("div", { id: `${id}-help`, className: "sq-field-help", children: description }),
640
+ error && /* @__PURE__ */ jsxs3("div", { id: `${id}-error`, className: "sq-field-error", children: [
641
+ /* @__PURE__ */ jsx3(Icon, { name: "warning", size: 14 }),
642
+ error
643
+ ] })
644
+ ] });
645
+ }
646
+ var TextField = forwardRef2(
647
+ function TextField2({
648
+ label,
649
+ description,
650
+ error,
651
+ hideLabel,
652
+ id: givenId,
653
+ prefix,
654
+ suffix,
655
+ className,
656
+ onValueChange,
657
+ onChange,
658
+ required,
659
+ ...props
660
+ }, ref) {
661
+ const uid = useId2();
662
+ const id = givenId ?? uid;
663
+ const describedBy = [
664
+ description && `${id}-help`,
665
+ error && `${id}-error`,
666
+ props["aria-describedby"]
667
+ ].filter(Boolean).join(" ") || void 0;
668
+ return /* @__PURE__ */ jsx3(FieldShell, { ...{ id, label, description, error, hideLabel, required }, children: /* @__PURE__ */ jsxs3(
669
+ "div",
670
+ {
671
+ className: "sq-input-wrap",
672
+ "data-error": !!error,
673
+ "data-disabled": !!props.disabled,
674
+ children: [
675
+ prefix && /* @__PURE__ */ jsx3("span", { className: "sq-input-affix", children: prefix }),
676
+ /* @__PURE__ */ jsx3(
677
+ "input",
678
+ {
679
+ ref,
680
+ id,
681
+ className: cx("sq-input", className),
682
+ required,
683
+ ...props,
684
+ "aria-invalid": error ? true : props["aria-invalid"],
685
+ "aria-describedby": describedBy,
686
+ onChange: (e) => {
687
+ onChange?.(e);
688
+ onValueChange?.(e.target.value);
689
+ }
690
+ }
691
+ ),
692
+ suffix && /* @__PURE__ */ jsx3("span", { className: "sq-input-affix", children: suffix })
693
+ ]
694
+ }
695
+ ) });
696
+ }
697
+ );
698
+ function EmailField(props) {
699
+ return /* @__PURE__ */ jsx3(TextField, { autoComplete: "email", ...props, type: "email" });
700
+ }
701
+ function URLField(props) {
702
+ return /* @__PURE__ */ jsx3(TextField, { autoComplete: "url", ...props, type: "url" });
703
+ }
704
+ function SearchField(props) {
705
+ return /* @__PURE__ */ jsx3(TextField, { prefix: /* @__PURE__ */ jsx3(Icon, { name: "search" }), ...props, type: "search" });
706
+ }
707
+ function NumberField(props) {
708
+ return /* @__PURE__ */ jsx3(TextField, { inputMode: "decimal", ...props, type: "number" });
709
+ }
710
+ function MoneyField({
711
+ currency = "USD",
712
+ locale = "en-US",
713
+ ...props
714
+ }) {
715
+ const symbol = new Intl.NumberFormat(locale, { style: "currency", currency }).formatToParts(0).find((p) => p.type === "currency")?.value ?? currency;
716
+ return /* @__PURE__ */ jsx3(NumberField, { step: "0.01", prefix: symbol, suffix: currency, ...props });
717
+ }
718
+ function PasswordField(props) {
719
+ const [visible, setVisible] = useState4(false);
720
+ return /* @__PURE__ */ jsx3(
721
+ TextField,
722
+ {
723
+ autoComplete: "current-password",
724
+ ...props,
725
+ type: visible ? "text" : "password",
726
+ suffix: /* @__PURE__ */ jsx3(
727
+ Button,
728
+ {
729
+ variant: "tertiary",
730
+ size: "small",
731
+ disabled: props.disabled,
732
+ "aria-label": visible ? "Hide password" : "Show password",
733
+ "aria-pressed": visible,
734
+ onClick: () => setVisible(!visible),
735
+ children: visible ? "Hide" : "Show"
736
+ }
737
+ )
738
+ }
739
+ );
740
+ }
741
+ function DateField(props) {
742
+ return /* @__PURE__ */ jsx3(TextField, { ...props, className: cx("sq-date-field", props.className), type: "date" });
743
+ }
744
+ var TextArea = forwardRef2(
745
+ function TextArea2({
746
+ label,
747
+ description,
748
+ error,
749
+ hideLabel,
750
+ id: givenId,
751
+ onValueChange,
752
+ onChange,
753
+ className,
754
+ required,
755
+ ...props
756
+ }, ref) {
757
+ const uid = useId2();
758
+ const id = givenId ?? uid;
759
+ return /* @__PURE__ */ jsx3(FieldShell, { ...{ id, label, description, error, hideLabel, required }, children: /* @__PURE__ */ jsx3(
760
+ "textarea",
761
+ {
762
+ ref,
763
+ id,
764
+ rows: 4,
765
+ className: cx("sq-input", "sq-textarea", className),
766
+ required,
767
+ ...props,
768
+ "aria-invalid": error ? true : props["aria-invalid"],
769
+ "aria-describedby": [
770
+ description && `${id}-help`,
771
+ error && `${id}-error`,
772
+ props["aria-describedby"]
773
+ ].filter(Boolean).join(" ") || void 0,
774
+ onChange: (e) => {
775
+ onChange?.(e);
776
+ onValueChange?.(e.target.value);
777
+ }
778
+ }
779
+ ) });
780
+ }
781
+ );
782
+ var Select = forwardRef2(
783
+ function Select2({
784
+ label,
785
+ description,
786
+ error,
787
+ hideLabel,
788
+ id: givenId,
789
+ options,
790
+ placeholder,
791
+ onValueChange,
792
+ onChange,
793
+ className,
794
+ required,
795
+ ...props
796
+ }, ref) {
797
+ const uid = useId2();
798
+ const id = givenId ?? uid;
799
+ const groups = [...new Set(options.map((o) => o.group))];
800
+ const option = (o) => /* @__PURE__ */ jsx3("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value);
801
+ return /* @__PURE__ */ jsx3(FieldShell, { ...{ id, label, description, error, hideLabel, required }, children: /* @__PURE__ */ jsxs3(
802
+ "select",
803
+ {
804
+ ref,
805
+ id,
806
+ className: cx("sq-input", "sq-select", className),
807
+ required,
808
+ defaultValue: placeholder && props.value === void 0 ? props.defaultValue ?? "" : void 0,
809
+ ...props,
810
+ "aria-invalid": error ? true : props["aria-invalid"],
811
+ "aria-describedby": [
812
+ description && `${id}-help`,
813
+ error && `${id}-error`,
814
+ props["aria-describedby"]
815
+ ].filter(Boolean).join(" ") || void 0,
816
+ onChange: (e) => {
817
+ onChange?.(e);
818
+ onValueChange?.(e.target.value);
819
+ },
820
+ children: [
821
+ placeholder && /* @__PURE__ */ jsx3("option", { value: "", disabled: true, children: placeholder }),
822
+ groups.map(
823
+ (group) => group ? /* @__PURE__ */ jsx3("optgroup", { label: group, children: options.filter((o) => o.group === group).map(option) }, group) : options.filter((o) => !o.group).map(option)
824
+ )
825
+ ]
826
+ }
827
+ ) });
828
+ }
829
+ );
830
+ function Checkbox({
831
+ label,
832
+ description,
833
+ error,
834
+ hideLabel,
835
+ id: givenId,
836
+ indeterminate,
837
+ onCheckedChange,
838
+ onChange,
839
+ className,
840
+ ...props
841
+ }) {
842
+ const uid = useId2();
843
+ const id = givenId ?? uid;
844
+ const ref = useRef(null);
845
+ useEffect(() => {
846
+ if (ref.current) ref.current.indeterminate = !!indeterminate;
847
+ }, [indeterminate]);
848
+ return /* @__PURE__ */ jsxs3("div", { className: "sq-check-field", children: [
849
+ /* @__PURE__ */ jsxs3("label", { htmlFor: id, className: cx("sq-check-label", className), children: [
850
+ /* @__PURE__ */ jsx3(
851
+ "input",
852
+ {
853
+ ref,
854
+ id,
855
+ type: "checkbox",
856
+ className: "sq-checkbox",
857
+ ...props,
858
+ "aria-invalid": error ? true : props["aria-invalid"],
859
+ "aria-describedby": [
860
+ description && `${id}-help`,
861
+ error && `${id}-error`,
862
+ props["aria-describedby"]
863
+ ].filter(Boolean).join(" ") || void 0,
864
+ onChange: (e) => {
865
+ onChange?.(e);
866
+ onCheckedChange?.(e.target.checked);
867
+ }
868
+ }
869
+ ),
870
+ /* @__PURE__ */ jsx3("span", { className: hideLabel ? "sq-sr-only" : void 0, children: label })
871
+ ] }),
872
+ description && /* @__PURE__ */ jsx3("div", { id: `${id}-help`, className: "sq-field-help", children: description }),
873
+ error && /* @__PURE__ */ jsx3("div", { id: `${id}-error`, className: "sq-field-error", children: error })
874
+ ] });
875
+ }
876
+ function Switch(props) {
877
+ return /* @__PURE__ */ jsx3(
878
+ Checkbox,
879
+ {
880
+ ...props,
881
+ role: "switch",
882
+ className: cx("sq-switch", props.className)
883
+ }
884
+ );
885
+ }
886
+ function ChoiceList({
887
+ label,
888
+ options,
889
+ value,
890
+ defaultValue = [],
891
+ onValueChange,
892
+ multiple,
893
+ disabled,
894
+ name,
895
+ required,
896
+ description,
897
+ error,
898
+ hideLabel
899
+ }) {
900
+ const id = useId2();
901
+ const [selected, setSelected] = useControllable(
902
+ value,
903
+ defaultValue,
904
+ onValueChange
905
+ );
906
+ return /* @__PURE__ */ jsxs3(
907
+ "fieldset",
908
+ {
909
+ className: "sq-choice-list",
910
+ disabled,
911
+ "aria-invalid": !!error,
912
+ "aria-describedby": [description && `${id}-help`, error && `${id}-error`].filter(Boolean).join(" ") || void 0,
913
+ children: [
914
+ /* @__PURE__ */ jsx3("legend", { className: hideLabel ? "sq-sr-only" : "sq-label", children: label }),
915
+ options.map((o) => /* @__PURE__ */ jsxs3("label", { className: "sq-check-label", children: [
916
+ /* @__PURE__ */ jsx3(
917
+ "input",
918
+ {
919
+ className: "sq-checkbox",
920
+ type: multiple ? "checkbox" : "radio",
921
+ name: name ?? id,
922
+ value: o.value,
923
+ required: required && (!multiple || selected.length === 0),
924
+ disabled: o.disabled,
925
+ checked: selected.includes(o.value),
926
+ onChange: (e) => setSelected(
927
+ multiple ? e.target.checked ? [...selected, o.value] : selected.filter((v) => v !== o.value) : [o.value]
928
+ )
929
+ }
930
+ ),
931
+ o.label
932
+ ] }, o.value)),
933
+ description && /* @__PURE__ */ jsx3("div", { id: `${id}-help`, className: "sq-field-help", children: description }),
934
+ error && /* @__PURE__ */ jsx3("div", { id: `${id}-error`, className: "sq-field-error", children: error })
935
+ ]
936
+ }
937
+ );
938
+ }
939
+ function ColorPicker({
940
+ label = "Color",
941
+ value,
942
+ defaultValue = "#0a2eb5",
943
+ onValueChange,
944
+ ...props
945
+ }) {
946
+ return /* @__PURE__ */ jsxs3("label", { className: "sq-color-picker", children: [
947
+ /* @__PURE__ */ jsx3("span", { children: label }),
948
+ /* @__PURE__ */ jsx3(
949
+ "input",
950
+ {
951
+ type: "color",
952
+ value,
953
+ defaultValue: value === void 0 ? defaultValue : void 0,
954
+ onChange: (e) => onValueChange?.(e.target.value),
955
+ ...props
956
+ }
957
+ )
958
+ ] });
959
+ }
960
+ function ColorField({
961
+ value,
962
+ defaultValue = "#0a2eb5",
963
+ onValueChange,
964
+ onChange,
965
+ ...props
966
+ }) {
967
+ const [color, setColor] = useControllable(
968
+ value === void 0 ? void 0 : String(value),
969
+ String(defaultValue),
970
+ onValueChange
971
+ );
972
+ return /* @__PURE__ */ jsx3(
973
+ TextField,
974
+ {
975
+ ...props,
976
+ value: color,
977
+ pattern: "#[0-9a-fA-F]{6}",
978
+ onChange,
979
+ onValueChange: setColor,
980
+ prefix: /* @__PURE__ */ jsx3(
981
+ "input",
982
+ {
983
+ "aria-label": `${props.label} picker`,
984
+ className: "sq-color-input",
985
+ type: "color",
986
+ disabled: props.disabled || props.readOnly,
987
+ value: /^#[0-9a-f]{6}$/i.test(color) ? color : "#000000",
988
+ onChange: (e) => setColor(e.target.value)
989
+ }
990
+ )
991
+ }
992
+ );
993
+ }
994
+ function DropZone({
995
+ label,
996
+ description,
997
+ error,
998
+ accept,
999
+ multiple,
1000
+ disabled,
1001
+ maxSize = 10 * 1024 * 1024,
1002
+ name,
1003
+ required,
1004
+ onFilesChange,
1005
+ onReject
1006
+ }) {
1007
+ const id = useId2();
1008
+ const ref = useRef(null);
1009
+ const [files, setFiles] = useState4([]);
1010
+ const [rejection, setRejection] = useState4("");
1011
+ const [dragging, setDragging] = useState4(false);
1012
+ function receive(incoming) {
1013
+ if (disabled) return false;
1014
+ const patterns = accept?.split(",").map((x) => x.trim().toLowerCase()).filter(Boolean) ?? [];
1015
+ const invalid = !multiple && incoming.length > 1 || incoming.some(
1016
+ (f) => f.size > maxSize || patterns.length > 0 && !patterns.some(
1017
+ (p) => p.startsWith(".") ? f.name.toLowerCase().endsWith(p) : p.endsWith("/*") ? f.type.startsWith(p.slice(0, -1)) : f.type === p
1018
+ )
1019
+ );
1020
+ if (invalid) {
1021
+ const message = "File rejected. Check the file type, size, and number of files.";
1022
+ setRejection(message);
1023
+ onReject?.(message);
1024
+ if (ref.current) ref.current.value = "";
1025
+ return false;
1026
+ }
1027
+ setRejection("");
1028
+ setFiles(incoming);
1029
+ onFilesChange?.(incoming);
1030
+ return true;
1031
+ }
1032
+ return /* @__PURE__ */ jsxs3("div", { className: "sq-field", children: [
1033
+ /* @__PURE__ */ jsx3("label", { htmlFor: id, className: "sq-label", children: label }),
1034
+ /* @__PURE__ */ jsxs3(
1035
+ "div",
1036
+ {
1037
+ className: "sq-drop-zone",
1038
+ "data-dragging": dragging,
1039
+ "data-disabled": disabled,
1040
+ onDragOver: (e) => {
1041
+ e.preventDefault();
1042
+ if (!disabled) setDragging(true);
1043
+ },
1044
+ onDragLeave: () => setDragging(false),
1045
+ onDrop: (e) => {
1046
+ e.preventDefault();
1047
+ setDragging(false);
1048
+ const dropped = Array.from(e.dataTransfer.files);
1049
+ if (receive(dropped) && ref.current) {
1050
+ try {
1051
+ const transfer = new DataTransfer();
1052
+ dropped.forEach((f) => transfer.items.add(f));
1053
+ ref.current.files = transfer.files;
1054
+ } catch {
1055
+ }
1056
+ }
1057
+ },
1058
+ children: [
1059
+ /* @__PURE__ */ jsx3(Icon, { name: "upload", size: 24 }),
1060
+ /* @__PURE__ */ jsx3("span", { children: "Drop files here or choose files" }),
1061
+ /* @__PURE__ */ jsx3(
1062
+ "input",
1063
+ {
1064
+ ref,
1065
+ id,
1066
+ type: "file",
1067
+ name,
1068
+ required,
1069
+ accept,
1070
+ multiple,
1071
+ disabled,
1072
+ "aria-invalid": !!(error || rejection),
1073
+ "aria-describedby": `${id}-help ${id}-status`,
1074
+ onChange: (e) => receive(Array.from(e.target.files ?? []))
1075
+ }
1076
+ )
1077
+ ]
1078
+ }
1079
+ ),
1080
+ /* @__PURE__ */ jsx3("div", { id: `${id}-help`, className: "sq-field-help", children: description ?? `Maximum ${Math.round(maxSize / 1024 / 1024)} MB per file` }),
1081
+ /* @__PURE__ */ jsx3(
1082
+ "div",
1083
+ {
1084
+ id: `${id}-status`,
1085
+ "aria-live": "polite",
1086
+ className: error || rejection ? "sq-field-error" : "sq-field-help",
1087
+ children: error || rejection || files.map((f) => f.name).join(", ")
1088
+ }
1089
+ )
1090
+ ] });
1091
+ }
1092
+
1093
+ // src/overlays.tsx
1094
+ import * as Dialog from "@radix-ui/react-dialog";
1095
+ import * as Pop from "@radix-ui/react-popover";
1096
+ import * as Dropdown from "@radix-ui/react-dropdown-menu";
1097
+ import * as Tip from "@radix-ui/react-tooltip";
1098
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1099
+ function Modal({
1100
+ title,
1101
+ description,
1102
+ trigger,
1103
+ children,
1104
+ footer,
1105
+ size = "medium",
1106
+ ...props
1107
+ }) {
1108
+ const { theme, density } = useStaq();
1109
+ return /* @__PURE__ */ jsxs4(Dialog.Root, { ...props, children: [
1110
+ trigger && /* @__PURE__ */ jsx4(Dialog.Trigger, { asChild: true, children: trigger }),
1111
+ /* @__PURE__ */ jsxs4(Dialog.Portal, { children: [
1112
+ /* @__PURE__ */ jsx4(Dialog.Overlay, { className: "sq-overlay" }),
1113
+ /* @__PURE__ */ jsxs4(
1114
+ Dialog.Content,
1115
+ {
1116
+ "data-staq-theme": theme,
1117
+ "data-staq-density": density,
1118
+ className: "sq-modal",
1119
+ "data-size": size,
1120
+ children: [
1121
+ /* @__PURE__ */ jsxs4("div", { className: "sq-section-header", children: [
1122
+ /* @__PURE__ */ jsx4(Dialog.Title, { className: "sq-heading", children: title }),
1123
+ /* @__PURE__ */ jsx4(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx4(Button, { variant: "tertiary", size: "small", "aria-label": "Close dialog", children: /* @__PURE__ */ jsx4(Icon, { name: "close" }) }) })
1124
+ ] }),
1125
+ /* @__PURE__ */ jsx4(Dialog.Description, { className: "sq-muted", children: description }),
1126
+ /* @__PURE__ */ jsx4("div", { className: "sq-modal-body", children }),
1127
+ footer && /* @__PURE__ */ jsx4("footer", { className: "sq-modal-footer", children: footer })
1128
+ ]
1129
+ }
1130
+ )
1131
+ ] })
1132
+ ] });
1133
+ }
1134
+ function Popover({
1135
+ trigger,
1136
+ label,
1137
+ children,
1138
+ align = "start",
1139
+ side = "bottom",
1140
+ ...props
1141
+ }) {
1142
+ const { theme, density } = useStaq();
1143
+ return /* @__PURE__ */ jsxs4(Pop.Root, { ...props, children: [
1144
+ /* @__PURE__ */ jsx4(Pop.Trigger, { asChild: true, children: trigger }),
1145
+ /* @__PURE__ */ jsx4(Pop.Portal, { children: /* @__PURE__ */ jsxs4(
1146
+ Pop.Content,
1147
+ {
1148
+ "aria-label": label,
1149
+ "data-staq-theme": theme,
1150
+ "data-staq-density": density,
1151
+ className: "sq-popover",
1152
+ align,
1153
+ side,
1154
+ sideOffset: 8,
1155
+ collisionPadding: 16,
1156
+ children: [
1157
+ children,
1158
+ /* @__PURE__ */ jsx4(Pop.Close, { asChild: true, children: /* @__PURE__ */ jsx4(Button, { variant: "tertiary", size: "small", "aria-label": "Close popover", children: /* @__PURE__ */ jsx4(Icon, { name: "close" }) }) })
1159
+ ]
1160
+ }
1161
+ ) })
1162
+ ] });
1163
+ }
1164
+ function Menu({
1165
+ trigger,
1166
+ label,
1167
+ items,
1168
+ align = "end",
1169
+ onOpenChange
1170
+ }) {
1171
+ const { theme, density } = useStaq();
1172
+ const groups = [...new Set(items.map((x) => x.group))];
1173
+ const item = (i) => /* @__PURE__ */ jsx4(
1174
+ Dropdown.Item,
1175
+ {
1176
+ className: "sq-menu-item",
1177
+ disabled: i.disabled,
1178
+ onSelect: i.onSelect,
1179
+ "data-tone": i.tone,
1180
+ asChild: !!i.href && !i.disabled,
1181
+ children: i.href && !i.disabled ? /* @__PURE__ */ jsxs4("a", { href: i.href, children: [
1182
+ i.icon,
1183
+ i.label
1184
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
1185
+ i.icon,
1186
+ i.label
1187
+ ] })
1188
+ },
1189
+ i.id
1190
+ );
1191
+ return /* @__PURE__ */ jsxs4(Dropdown.Root, { onOpenChange, children: [
1192
+ /* @__PURE__ */ jsx4(Dropdown.Trigger, { asChild: true, children: trigger }),
1193
+ /* @__PURE__ */ jsx4(Dropdown.Portal, { children: /* @__PURE__ */ jsx4(
1194
+ Dropdown.Content,
1195
+ {
1196
+ "aria-label": label,
1197
+ "data-staq-theme": theme,
1198
+ "data-staq-density": density,
1199
+ className: "sq-menu",
1200
+ sideOffset: 6,
1201
+ align,
1202
+ collisionPadding: 12,
1203
+ children: groups.map((group, index) => /* @__PURE__ */ jsxs4(Dropdown.Group, { children: [
1204
+ index > 0 && /* @__PURE__ */ jsx4(Dropdown.Separator, { className: "sq-divider" }),
1205
+ group && /* @__PURE__ */ jsx4(Dropdown.Label, { className: "sq-menu-label", children: group }),
1206
+ items.filter((i) => i.group === group).map(item)
1207
+ ] }, group ?? "default"))
1208
+ }
1209
+ ) })
1210
+ ] });
1211
+ }
1212
+ function Tooltip({ content, children, side = "top" }) {
1213
+ const { theme, density } = useStaq();
1214
+ return /* @__PURE__ */ jsx4(Tip.Provider, { delayDuration: 800, children: /* @__PURE__ */ jsxs4(Tip.Root, { children: [
1215
+ /* @__PURE__ */ jsx4(Tip.Trigger, { asChild: true, children }),
1216
+ /* @__PURE__ */ jsx4(Tip.Portal, { children: /* @__PURE__ */ jsxs4(
1217
+ Tip.Content,
1218
+ {
1219
+ "data-staq-theme": theme,
1220
+ "data-staq-density": density,
1221
+ className: "sq-tooltip",
1222
+ side,
1223
+ sideOffset: 8,
1224
+ collisionPadding: 12,
1225
+ children: [
1226
+ content,
1227
+ /* @__PURE__ */ jsx4(Tip.Arrow, { className: "sq-tooltip-arrow" })
1228
+ ]
1229
+ }
1230
+ ) })
1231
+ ] }) });
1232
+ }
1233
+
1234
+ // src/complex.tsx
1235
+ import { useId as useId3 } from "react";
1236
+ import {
1237
+ DayPicker,
1238
+ labelDayButton,
1239
+ formatDay
1240
+ } from "react-day-picker";
1241
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1242
+ var iso = (d) => d ? `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}` : "";
1243
+ function DatePicker(props) {
1244
+ const { label = "Choose a date", name, ...calendar } = props;
1245
+ const [selected, setSelected] = useControllable(
1246
+ props.value,
1247
+ props.defaultValue,
1248
+ (next) => {
1249
+ if (props.mode === "range")
1250
+ props.onValueChange?.(next);
1251
+ else props.onValueChange?.(next);
1252
+ },
1253
+ "value" in props
1254
+ );
1255
+ const common = {
1256
+ month: calendar.month,
1257
+ defaultMonth: calendar.defaultMonth,
1258
+ onMonthChange: calendar.onMonthChange,
1259
+ disabled: calendar.disabled,
1260
+ numberOfMonths: calendar.numberOfMonths,
1261
+ locale: calendar.locale,
1262
+ startMonth: calendar.startMonth,
1263
+ endMonth: calendar.endMonth,
1264
+ showOutsideDays: true,
1265
+ labels: {
1266
+ labelDayButton: ((date, modifiers, options, dateLib) => `${formatDay(date, options, dateLib)}: ${labelDayButton(date, modifiers, options, dateLib)}`)
1267
+ }
1268
+ };
1269
+ return /* @__PURE__ */ jsxs5("div", { className: "sq-calendar", role: "group", "aria-label": label, children: [
1270
+ props.mode === "range" ? /* @__PURE__ */ jsx5(
1271
+ DayPicker,
1272
+ {
1273
+ ...common,
1274
+ mode: "range",
1275
+ selected,
1276
+ onSelect: setSelected,
1277
+ excludeDisabled: true
1278
+ }
1279
+ ) : /* @__PURE__ */ jsx5(
1280
+ DayPicker,
1281
+ {
1282
+ ...common,
1283
+ mode: "single",
1284
+ selected,
1285
+ onSelect: setSelected
1286
+ }
1287
+ ),
1288
+ /* @__PURE__ */ jsx5("div", { className: "sq-sr-only", "aria-live": "polite", children: selected instanceof Date ? iso(selected) : selected?.from ? `${iso(selected.from)} to ${iso(selected.to) || "select end date"}` : "No date selected" }),
1289
+ name && /* @__PURE__ */ jsx5(
1290
+ "input",
1291
+ {
1292
+ type: "hidden",
1293
+ name,
1294
+ value: selected instanceof Date ? iso(selected) : selected ? `${iso(selected.from)}/${iso(selected.to)}` : ""
1295
+ }
1296
+ )
1297
+ ] });
1298
+ }
1299
+ function Table({
1300
+ label,
1301
+ columns,
1302
+ rows,
1303
+ rowKey,
1304
+ loading,
1305
+ emptyMessage = "No results found.",
1306
+ sort,
1307
+ onSortChange,
1308
+ selected = [],
1309
+ onSelectionChange,
1310
+ pagination,
1311
+ filters
1312
+ }) {
1313
+ const id = useId3();
1314
+ const [sorting, setSorting] = useControllable(
1315
+ sort,
1316
+ void 0,
1317
+ (next) => {
1318
+ if (next) onSortChange?.(next);
1319
+ }
1320
+ );
1321
+ const column = columns.find((c) => c.id === sorting?.column);
1322
+ const displayed = column?.sortValue ? [...rows].sort((a, b) => {
1323
+ const av = column.sortValue(a);
1324
+ const bv = column.sortValue(b);
1325
+ return (typeof av === "number" && typeof bv === "number" ? av - bv : String(av).localeCompare(String(bv))) * (sorting?.direction === "descending" ? -1 : 1);
1326
+ }) : rows;
1327
+ const all = rows.length > 0 && rows.every((r) => selected.includes(rowKey(r)));
1328
+ return /* @__PURE__ */ jsxs5("div", { className: "sq-table-container", "aria-busy": loading, children: [
1329
+ filters && /* @__PURE__ */ jsx5("div", { className: "sq-table-filters", children: filters }),
1330
+ /* @__PURE__ */ jsx5(
1331
+ "div",
1332
+ {
1333
+ className: "sq-table-scroll",
1334
+ role: "region",
1335
+ "aria-label": `${label} table`,
1336
+ tabIndex: 0,
1337
+ children: /* @__PURE__ */ jsxs5("table", { className: "sq-table", children: [
1338
+ /* @__PURE__ */ jsx5("caption", { id, children: label }),
1339
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1340
+ onSelectionChange && /* @__PURE__ */ jsx5("th", { scope: "col", children: /* @__PURE__ */ jsx5(
1341
+ "input",
1342
+ {
1343
+ "aria-label": "Select all visible rows",
1344
+ type: "checkbox",
1345
+ className: "sq-checkbox",
1346
+ checked: all,
1347
+ onChange: (e) => {
1348
+ const keys = rows.map(rowKey);
1349
+ onSelectionChange(
1350
+ e.target.checked ? [.../* @__PURE__ */ new Set([...selected, ...keys])] : selected.filter((k) => !keys.includes(k))
1351
+ );
1352
+ }
1353
+ }
1354
+ ) }),
1355
+ columns.map((c) => /* @__PURE__ */ jsx5(
1356
+ "th",
1357
+ {
1358
+ scope: "col",
1359
+ "data-align": c.align,
1360
+ "aria-sort": sorting?.column === c.id ? sorting.direction : void 0,
1361
+ children: c.sortValue ? /* @__PURE__ */ jsxs5(
1362
+ "button",
1363
+ {
1364
+ className: "sq-table-sort",
1365
+ type: "button",
1366
+ onClick: () => setSorting({
1367
+ column: c.id,
1368
+ direction: sorting?.column === c.id && sorting.direction === "ascending" ? "descending" : "ascending"
1369
+ }),
1370
+ children: [
1371
+ c.header,
1372
+ /* @__PURE__ */ jsx5(Icon, { name: "chevronDown", size: 14 })
1373
+ ]
1374
+ }
1375
+ ) : c.header
1376
+ },
1377
+ c.id
1378
+ ))
1379
+ ] }) }),
1380
+ /* @__PURE__ */ jsxs5("tbody", { children: [
1381
+ displayed.map((r) => /* @__PURE__ */ jsxs5("tr", { "data-selected": selected.includes(rowKey(r)), children: [
1382
+ onSelectionChange && /* @__PURE__ */ jsx5("td", { children: /* @__PURE__ */ jsx5(
1383
+ "input",
1384
+ {
1385
+ type: "checkbox",
1386
+ className: "sq-checkbox",
1387
+ "aria-label": `Select row ${rowKey(r)}`,
1388
+ checked: selected.includes(rowKey(r)),
1389
+ onChange: (e) => onSelectionChange(
1390
+ e.target.checked ? [.../* @__PURE__ */ new Set([...selected, rowKey(r)])] : selected.filter((k) => k !== rowKey(r))
1391
+ )
1392
+ }
1393
+ ) }),
1394
+ columns.map((c) => /* @__PURE__ */ jsx5("td", { "data-align": c.align, children: c.cell(r) }, c.id))
1395
+ ] }, rowKey(r))),
1396
+ !rows.length && /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: columns.length + (onSelectionChange ? 1 : 0), children: loading ? "Loading\u2026" : emptyMessage }) })
1397
+ ] })
1398
+ ] })
1399
+ }
1400
+ ),
1401
+ pagination && /* @__PURE__ */ jsxs5("div", { className: "sq-pagination", children: [
1402
+ /* @__PURE__ */ jsx5("span", { children: pagination.label }),
1403
+ /* @__PURE__ */ jsxs5("div", { children: [
1404
+ /* @__PURE__ */ jsx5(
1405
+ Button,
1406
+ {
1407
+ size: "small",
1408
+ disabled: !pagination.hasPrevious || loading,
1409
+ "aria-label": "Previous page",
1410
+ onClick: pagination.onPrevious,
1411
+ children: /* @__PURE__ */ jsx5(Icon, { name: "chevronLeft" })
1412
+ }
1413
+ ),
1414
+ /* @__PURE__ */ jsx5(
1415
+ Button,
1416
+ {
1417
+ size: "small",
1418
+ disabled: !pagination.hasNext || loading,
1419
+ "aria-label": "Next page",
1420
+ onClick: pagination.onNext,
1421
+ children: /* @__PURE__ */ jsx5(Icon, { name: "chevronRight" })
1422
+ }
1423
+ )
1424
+ ] })
1425
+ ] })
1426
+ ] });
1427
+ }
1428
+ export {
1429
+ Avatar,
1430
+ Badge,
1431
+ Banner,
1432
+ Box,
1433
+ Button,
1434
+ ButtonGroup,
1435
+ Checkbox,
1436
+ Chip,
1437
+ ChoiceList,
1438
+ Clickable,
1439
+ ClickableChip,
1440
+ ColorField,
1441
+ ColorPicker,
1442
+ DateField,
1443
+ DatePicker,
1444
+ Divider,
1445
+ DropZone,
1446
+ EmailField,
1447
+ EmptyState,
1448
+ Grid,
1449
+ Heading,
1450
+ Icon,
1451
+ Image,
1452
+ Link,
1453
+ ListItem,
1454
+ Menu,
1455
+ Modal,
1456
+ MoneyField,
1457
+ Number,
1458
+ NumberField,
1459
+ OrderedList,
1460
+ Page,
1461
+ Paragraph,
1462
+ PasswordField,
1463
+ Popover,
1464
+ Progress,
1465
+ QueryContainer,
1466
+ SearchField,
1467
+ Section,
1468
+ Select,
1469
+ Spinner,
1470
+ Stack,
1471
+ StaqContext,
1472
+ StaqProvider,
1473
+ Switch,
1474
+ Table,
1475
+ Text,
1476
+ TextArea,
1477
+ TextField,
1478
+ Thumbnail,
1479
+ Tooltip,
1480
+ URLField,
1481
+ UnorderedList,
1482
+ cx,
1483
+ icons,
1484
+ useControllable,
1485
+ useStaq
1486
+ };