@dev-dga/react 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/components/Button/Button.tsx
2
2
  import "react";
3
+ import { Slot as SlotPrimitive } from "radix-ui";
3
4
  import { cva } from "class-variance-authority";
4
5
 
5
6
  // src/utils/cn.ts
@@ -9,7 +10,7 @@ function cn(...inputs) {
9
10
  }
10
11
 
11
12
  // src/internal/icons/index.tsx
12
- import { jsx } from "react/jsx-runtime";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
13
14
  function Spinner(props) {
14
15
  return /* @__PURE__ */ jsx(
15
16
  "svg",
@@ -65,9 +66,114 @@ function Minus(props) {
65
66
  }
66
67
  );
67
68
  }
69
+ function Info(props) {
70
+ return /* @__PURE__ */ jsxs(
71
+ "svg",
72
+ {
73
+ xmlns: "http://www.w3.org/2000/svg",
74
+ width: "1em",
75
+ height: "1em",
76
+ viewBox: "0 0 24 24",
77
+ fill: "none",
78
+ stroke: "currentColor",
79
+ strokeWidth: "2",
80
+ strokeLinecap: "round",
81
+ strokeLinejoin: "round",
82
+ ...props,
83
+ children: [
84
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
85
+ /* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
86
+ /* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
87
+ ]
88
+ }
89
+ );
90
+ }
91
+ function AlertTriangle(props) {
92
+ return /* @__PURE__ */ jsxs(
93
+ "svg",
94
+ {
95
+ xmlns: "http://www.w3.org/2000/svg",
96
+ width: "1em",
97
+ height: "1em",
98
+ viewBox: "0 0 24 24",
99
+ fill: "none",
100
+ stroke: "currentColor",
101
+ strokeWidth: "2",
102
+ strokeLinecap: "round",
103
+ strokeLinejoin: "round",
104
+ ...props,
105
+ children: [
106
+ /* @__PURE__ */ jsx("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" }),
107
+ /* @__PURE__ */ jsx("path", { d: "M12 9v4" }),
108
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
109
+ ]
110
+ }
111
+ );
112
+ }
113
+ function AlertCircle(props) {
114
+ return /* @__PURE__ */ jsxs(
115
+ "svg",
116
+ {
117
+ xmlns: "http://www.w3.org/2000/svg",
118
+ width: "1em",
119
+ height: "1em",
120
+ viewBox: "0 0 24 24",
121
+ fill: "none",
122
+ stroke: "currentColor",
123
+ strokeWidth: "2",
124
+ strokeLinecap: "round",
125
+ strokeLinejoin: "round",
126
+ ...props,
127
+ children: [
128
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
129
+ /* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "8", y2: "12" }),
130
+ /* @__PURE__ */ jsx("line", { x1: "12", x2: "12.01", y1: "16", y2: "16" })
131
+ ]
132
+ }
133
+ );
134
+ }
135
+ function Close(props) {
136
+ return /* @__PURE__ */ jsxs(
137
+ "svg",
138
+ {
139
+ xmlns: "http://www.w3.org/2000/svg",
140
+ width: "1em",
141
+ height: "1em",
142
+ viewBox: "0 0 24 24",
143
+ fill: "none",
144
+ stroke: "currentColor",
145
+ strokeWidth: "2",
146
+ strokeLinecap: "round",
147
+ strokeLinejoin: "round",
148
+ ...props,
149
+ children: [
150
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
151
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ function ChevronDown(props) {
157
+ return /* @__PURE__ */ jsx(
158
+ "svg",
159
+ {
160
+ xmlns: "http://www.w3.org/2000/svg",
161
+ width: "1em",
162
+ height: "1em",
163
+ viewBox: "0 0 24 24",
164
+ fill: "none",
165
+ stroke: "currentColor",
166
+ strokeWidth: "2",
167
+ strokeLinecap: "round",
168
+ strokeLinejoin: "round",
169
+ ...props,
170
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
171
+ }
172
+ );
173
+ }
68
174
 
69
175
  // src/components/Button/Button.tsx
70
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
176
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
71
177
  var buttonVariants = cva("ddga-button", {
72
178
  variants: {
73
179
  variant: {
@@ -103,6 +209,7 @@ function Button({
103
209
  startIcon,
104
210
  endIcon,
105
211
  iconFlip,
212
+ asChild,
106
213
  className,
107
214
  children,
108
215
  type = "button",
@@ -116,11 +223,12 @@ function Button({
116
223
  }
117
224
  }
118
225
  const isDisabled = disabled || loading;
119
- return /* @__PURE__ */ jsxs(
120
- "button",
226
+ const Comp = asChild ? SlotPrimitive.Slot : "button";
227
+ return /* @__PURE__ */ jsxs2(
228
+ Comp,
121
229
  {
122
- type,
123
- disabled: isDisabled,
230
+ ...asChild ? {} : { type, disabled: isDisabled },
231
+ ...asChild && isDisabled ? { tabIndex: -1 } : {},
124
232
  "aria-disabled": isDisabled || void 0,
125
233
  "aria-busy": loading || void 0,
126
234
  "data-slot": "button",
@@ -133,7 +241,12 @@ function Button({
133
241
  children: [
134
242
  loading && /* @__PURE__ */ jsx2(Spinner, { "aria-hidden": "true" }),
135
243
  !loading && startIcon && /* @__PURE__ */ jsx2("span", { className: cn("ddga-button__icon", iconFlip && "ddga-icon-flip"), "aria-hidden": "true", children: startIcon }),
136
- children != null && children !== "" && /* @__PURE__ */ jsx2("span", { className: "ddga-button__text", children }),
244
+ asChild ? (
245
+ // children IS the consumer's single element (e.g. <Link>). Slottable
246
+ // marks where THAT element's original children should land , without
247
+ // it the icons would replace the link text entirely.
248
+ /* @__PURE__ */ jsx2(SlotPrimitive.Slottable, { children })
249
+ ) : children != null && children !== "" && /* @__PURE__ */ jsx2("span", { className: "ddga-button__text", children }),
137
250
  !loading && endIcon && /* @__PURE__ */ jsx2("span", { className: cn("ddga-button__icon", iconFlip && "ddga-icon-flip"), "aria-hidden": "true", children: endIcon })
138
251
  ]
139
252
  }
@@ -143,7 +256,7 @@ function Button({
143
256
  // src/components/Input/Input.tsx
144
257
  import { cva as cva2 } from "class-variance-authority";
145
258
 
146
- // src/internal/field/use-field-a11y.ts
259
+ // src/field/use-field-a11y.ts
147
260
  import { useId } from "react";
148
261
  function isPresent(value) {
149
262
  return value != null && value !== "";
@@ -153,7 +266,7 @@ function useFieldA11y(options) {
153
266
  const fieldId = options.id ?? generatedId;
154
267
  const helperId = `${fieldId}-helper`;
155
268
  const errorId = `${fieldId}-error`;
156
- const hasError = !!options.error;
269
+ const hasError = !!options.error || isPresent(options.errorMessage);
157
270
  const hasErrorMessage = hasError && isPresent(options.errorMessage);
158
271
  const hasHelper = !hasErrorMessage && isPresent(options.helperText);
159
272
  if (process.env.NODE_ENV === "development" && !options.label) {
@@ -178,7 +291,7 @@ function useFieldA11y(options) {
178
291
  };
179
292
  }
180
293
 
181
- // src/internal/field/FieldMessage.tsx
294
+ // src/field/FieldMessage.tsx
182
295
  import { jsx as jsx3 } from "react/jsx-runtime";
183
296
  function FieldMessage({ id, variant, children }) {
184
297
  return /* @__PURE__ */ jsx3(
@@ -194,7 +307,7 @@ function FieldMessage({ id, variant, children }) {
194
307
  }
195
308
 
196
309
  // src/components/Input/Input.tsx
197
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
310
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
198
311
  var inputVariants = cva2("ddga-input", {
199
312
  variants: {
200
313
  size: {
@@ -233,12 +346,12 @@ function Input({
233
346
  "aria-label": props["aria-label"],
234
347
  "aria-labelledby": props["aria-labelledby"]
235
348
  });
236
- return /* @__PURE__ */ jsxs2("div", { "data-slot": "input-field", className: "ddga-field", children: [
237
- label && /* @__PURE__ */ jsxs2("label", { htmlFor: fieldId, className: "ddga-input__label", children: [
349
+ return /* @__PURE__ */ jsxs3("div", { "data-slot": "input-field", className: "ddga-field", children: [
350
+ label && /* @__PURE__ */ jsxs3("label", { htmlFor: fieldId, className: "ddga-input__label", children: [
238
351
  label,
239
352
  required && /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", className: "ddga-input__required", children: "*" })
240
353
  ] }),
241
- /* @__PURE__ */ jsxs2(
354
+ /* @__PURE__ */ jsxs3(
242
355
  "div",
243
356
  {
244
357
  "data-slot": "input-control",
@@ -280,7 +393,7 @@ function Input({
280
393
 
281
394
  // src/components/Textarea/Textarea.tsx
282
395
  import { cva as cva3 } from "class-variance-authority";
283
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
396
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
284
397
  var textareaVariants = cva3("ddga-textarea", {
285
398
  variants: {
286
399
  size: {
@@ -326,8 +439,8 @@ function Textarea({
326
439
  "aria-label": props["aria-label"],
327
440
  "aria-labelledby": props["aria-labelledby"]
328
441
  });
329
- return /* @__PURE__ */ jsxs3("div", { "data-slot": "textarea-field", className: "ddga-field", children: [
330
- label && /* @__PURE__ */ jsxs3("label", { htmlFor: fieldId, className: "ddga-textarea__label", children: [
442
+ return /* @__PURE__ */ jsxs4("div", { "data-slot": "textarea-field", className: "ddga-field", children: [
443
+ label && /* @__PURE__ */ jsxs4("label", { htmlFor: fieldId, className: "ddga-textarea__label", children: [
331
444
  label,
332
445
  required && /* @__PURE__ */ jsx5("span", { "aria-hidden": "true", className: "ddga-textarea__required", children: "*" })
333
446
  ] }),
@@ -350,7 +463,7 @@ function Textarea({
350
463
  // src/components/Checkbox/Checkbox.tsx
351
464
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
352
465
  import { cva as cva4 } from "class-variance-authority";
353
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
466
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
354
467
  var checkboxVariants = cva4("ddga-checkbox", {
355
468
  variants: {
356
469
  size: {
@@ -386,8 +499,8 @@ function Checkbox({
386
499
  "aria-label": props["aria-label"],
387
500
  "aria-labelledby": props["aria-labelledby"]
388
501
  });
389
- return /* @__PURE__ */ jsxs4("div", { "data-slot": "checkbox-field", className: "ddga-field", children: [
390
- /* @__PURE__ */ jsxs4("div", { className: "ddga-checkbox-row", children: [
502
+ return /* @__PURE__ */ jsxs5("div", { "data-slot": "checkbox-field", className: "ddga-field", children: [
503
+ /* @__PURE__ */ jsxs5("div", { className: "ddga-checkbox-row", children: [
391
504
  /* @__PURE__ */ jsx6(
392
505
  CheckboxPrimitive.Root,
393
506
  {
@@ -396,7 +509,7 @@ function Checkbox({
396
509
  "data-slot": "checkbox",
397
510
  required,
398
511
  className: cn(checkboxVariants({ size, error: hasError }), className),
399
- children: /* @__PURE__ */ jsxs4(
512
+ children: /* @__PURE__ */ jsxs5(
400
513
  CheckboxPrimitive.Indicator,
401
514
  {
402
515
  "data-slot": "checkbox-indicator",
@@ -409,7 +522,7 @@ function Checkbox({
409
522
  )
410
523
  }
411
524
  ),
412
- label && /* @__PURE__ */ jsxs4("label", { htmlFor: fieldId, className: "ddga-checkbox__label", children: [
525
+ label && /* @__PURE__ */ jsxs5("label", { htmlFor: fieldId, className: "ddga-checkbox__label", children: [
413
526
  label,
414
527
  required && /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", className: "ddga-checkbox__required", children: "*" })
415
528
  ] })
@@ -419,9 +532,169 @@ function Checkbox({
419
532
  ] });
420
533
  }
421
534
 
422
- // src/providers/DgaProvider.tsx
423
- import { useRef, useMemo, useContext as useContext2 } from "react";
424
- import { Direction as DirectionPrimitive, Tooltip as TooltipPrimitive } from "radix-ui";
535
+ // src/components/Radio/Radio.tsx
536
+ import { useId as useId2 } from "react";
537
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
538
+ import { cva as cva5 } from "class-variance-authority";
539
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
540
+ var radioGroupVariants = cva5("ddga-radio-group", {
541
+ variants: {
542
+ size: {
543
+ sm: "ddga-radio-group--sm",
544
+ md: "ddga-radio-group--md"
545
+ },
546
+ orientation: {
547
+ vertical: "ddga-radio-group--vertical",
548
+ horizontal: "ddga-radio-group--horizontal"
549
+ },
550
+ error: {
551
+ true: "ddga-radio-group--error"
552
+ }
553
+ },
554
+ defaultVariants: {
555
+ size: "md",
556
+ orientation: "vertical"
557
+ }
558
+ });
559
+ var radioVariants = cva5("ddga-radio");
560
+ function RadioGroup({
561
+ id: externalId,
562
+ label,
563
+ helperText,
564
+ errorMessage,
565
+ error,
566
+ size,
567
+ orientation,
568
+ required,
569
+ className,
570
+ children,
571
+ ...props
572
+ }) {
573
+ const { errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps, fieldId } = useFieldA11y({
574
+ name: "RadioGroup",
575
+ id: externalId,
576
+ label,
577
+ error,
578
+ errorMessage,
579
+ helperText,
580
+ "aria-label": props["aria-label"],
581
+ "aria-labelledby": props["aria-labelledby"]
582
+ });
583
+ const labelId = `${fieldId}-label`;
584
+ return /* @__PURE__ */ jsxs6("div", { "data-slot": "radio-group-field", className: "ddga-field", children: [
585
+ label && /* @__PURE__ */ jsxs6("span", { id: labelId, className: "ddga-radio-group__label", children: [
586
+ label,
587
+ required && /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", className: "ddga-radio-group__required", children: "*" })
588
+ ] }),
589
+ /* @__PURE__ */ jsx7(
590
+ RadioGroupPrimitive.Root,
591
+ {
592
+ ...props,
593
+ "aria-invalid": controlProps["aria-invalid"],
594
+ "aria-describedby": controlProps["aria-describedby"],
595
+ "aria-labelledby": label ? labelId : props["aria-labelledby"],
596
+ orientation: orientation === "horizontal" ? "horizontal" : "vertical",
597
+ required,
598
+ "data-slot": "radio-group",
599
+ className: cn(radioGroupVariants({ size, orientation, error: hasError }), className),
600
+ children
601
+ }
602
+ ),
603
+ hasErrorMessage && /* @__PURE__ */ jsx7(FieldMessage, { id: errorId, variant: "error", children: errorMessage }),
604
+ hasHelper && /* @__PURE__ */ jsx7(FieldMessage, { id: helperId, variant: "helper", children: helperText })
605
+ ] });
606
+ }
607
+ function Radio({ id: externalId, label, className, ...props }) {
608
+ const generatedId = useId2();
609
+ const itemId = externalId ?? generatedId;
610
+ return /* @__PURE__ */ jsxs6("div", { className: "ddga-radio-row", children: [
611
+ /* @__PURE__ */ jsx7(
612
+ RadioGroupPrimitive.Item,
613
+ {
614
+ ...props,
615
+ id: itemId,
616
+ "data-slot": "radio",
617
+ className: cn(radioVariants(), className),
618
+ children: /* @__PURE__ */ jsx7(
619
+ RadioGroupPrimitive.Indicator,
620
+ {
621
+ "data-slot": "radio-indicator",
622
+ className: "ddga-radio__indicator",
623
+ children: /* @__PURE__ */ jsx7("span", { className: "ddga-radio__dot", "aria-hidden": "true" })
624
+ }
625
+ )
626
+ }
627
+ ),
628
+ label && /* @__PURE__ */ jsx7("label", { htmlFor: itemId, className: "ddga-radio__label", children: label })
629
+ ] });
630
+ }
631
+
632
+ // src/components/Switch/Switch.tsx
633
+ import { Switch as SwitchPrimitive } from "radix-ui";
634
+ import { cva as cva6 } from "class-variance-authority";
635
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
636
+ var switchVariants = cva6("ddga-switch", {
637
+ variants: {
638
+ size: {
639
+ sm: "ddga-switch--sm",
640
+ md: "ddga-switch--md"
641
+ },
642
+ error: {
643
+ true: "ddga-switch--error"
644
+ }
645
+ },
646
+ defaultVariants: {
647
+ size: "md"
648
+ }
649
+ });
650
+ function Switch({
651
+ id: externalId,
652
+ label,
653
+ helperText,
654
+ errorMessage,
655
+ error,
656
+ size,
657
+ required,
658
+ className,
659
+ ...props
660
+ }) {
661
+ const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } = useFieldA11y({
662
+ name: "Switch",
663
+ id: externalId,
664
+ label,
665
+ error,
666
+ errorMessage,
667
+ helperText,
668
+ "aria-label": props["aria-label"],
669
+ "aria-labelledby": props["aria-labelledby"]
670
+ });
671
+ return /* @__PURE__ */ jsxs7("div", { "data-slot": "switch-field", className: "ddga-field", children: [
672
+ /* @__PURE__ */ jsxs7("div", { className: "ddga-switch-row", children: [
673
+ /* @__PURE__ */ jsx8(
674
+ SwitchPrimitive.Root,
675
+ {
676
+ ...props,
677
+ ...controlProps,
678
+ "data-slot": "switch",
679
+ required,
680
+ className: cn(switchVariants({ size, error: hasError }), className),
681
+ children: /* @__PURE__ */ jsx8(SwitchPrimitive.Thumb, { "data-slot": "switch-thumb", className: "ddga-switch__thumb" })
682
+ }
683
+ ),
684
+ label && /* @__PURE__ */ jsxs7("label", { htmlFor: fieldId, className: "ddga-switch__label", children: [
685
+ label,
686
+ required && /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "ddga-switch__required", children: "*" })
687
+ ] })
688
+ ] }),
689
+ hasErrorMessage && /* @__PURE__ */ jsx8(FieldMessage, { id: errorId, variant: "error", children: errorMessage }),
690
+ hasHelper && /* @__PURE__ */ jsx8(FieldMessage, { id: helperId, variant: "helper", children: helperText })
691
+ ] });
692
+ }
693
+
694
+ // src/components/Select/Select.tsx
695
+ import { useContext as useContext2 } from "react";
696
+ import { Select as SelectPrimitive } from "radix-ui";
697
+ import { cva as cva7 } from "class-variance-authority";
425
698
 
426
699
  // src/providers/DgaContext.ts
427
700
  import { createContext, useContext } from "react";
@@ -434,37 +707,571 @@ function useDga() {
434
707
  return ctx;
435
708
  }
436
709
 
710
+ // src/components/Select/Select.tsx
711
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
712
+ var selectTriggerVariants = cva7("ddga-select-trigger", {
713
+ variants: {
714
+ size: {
715
+ sm: "ddga-select-trigger--sm",
716
+ md: "ddga-select-trigger--md"
717
+ },
718
+ error: {
719
+ true: "ddga-select-trigger--error"
720
+ }
721
+ },
722
+ defaultVariants: {
723
+ size: "md"
724
+ }
725
+ });
726
+ function Select({
727
+ id: externalId,
728
+ label,
729
+ helperText,
730
+ errorMessage,
731
+ error,
732
+ size,
733
+ required,
734
+ placeholder,
735
+ className,
736
+ children,
737
+ ...rootProps
738
+ }) {
739
+ const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } = useFieldA11y({
740
+ name: "Select",
741
+ id: externalId,
742
+ label,
743
+ error,
744
+ errorMessage,
745
+ helperText,
746
+ "aria-label": rootProps["aria-label"],
747
+ "aria-labelledby": rootProps["aria-labelledby"]
748
+ });
749
+ const ctx = useContext2(DgaContext);
750
+ const portalContainer = ctx?.rootEl ?? void 0;
751
+ return /* @__PURE__ */ jsxs8("div", { "data-slot": "select-field", className: "ddga-field", children: [
752
+ label && /* @__PURE__ */ jsxs8("label", { htmlFor: fieldId, className: "ddga-select__label", children: [
753
+ label,
754
+ required && /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", className: "ddga-select__required", children: "*" })
755
+ ] }),
756
+ /* @__PURE__ */ jsxs8(SelectPrimitive.Root, { required, ...rootProps, children: [
757
+ /* @__PURE__ */ jsxs8(
758
+ SelectPrimitive.Trigger,
759
+ {
760
+ ...controlProps,
761
+ "data-slot": "select-trigger",
762
+ className: cn(selectTriggerVariants({ size, error: hasError }), className),
763
+ children: [
764
+ /* @__PURE__ */ jsx9(SelectPrimitive.Value, { placeholder }),
765
+ /* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, className: "ddga-select__icon", children: /* @__PURE__ */ jsx9(ChevronDown, { "aria-hidden": "true" }) })
766
+ ]
767
+ }
768
+ ),
769
+ /* @__PURE__ */ jsx9(SelectPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx9(
770
+ SelectPrimitive.Content,
771
+ {
772
+ "data-slot": "select-content",
773
+ className: "ddga-select-content",
774
+ position: "popper",
775
+ sideOffset: 4,
776
+ children: /* @__PURE__ */ jsx9(SelectPrimitive.Viewport, { className: "ddga-select-viewport", children })
777
+ }
778
+ ) })
779
+ ] }),
780
+ hasErrorMessage && /* @__PURE__ */ jsx9(FieldMessage, { id: errorId, variant: "error", children: errorMessage }),
781
+ hasHelper && /* @__PURE__ */ jsx9(FieldMessage, { id: helperId, variant: "helper", children: helperText })
782
+ ] });
783
+ }
784
+ function SelectItem({ className, children, ...props }) {
785
+ return /* @__PURE__ */ jsxs8(
786
+ SelectPrimitive.Item,
787
+ {
788
+ ...props,
789
+ "data-slot": "select-item",
790
+ className: cn("ddga-select-item", className),
791
+ children: [
792
+ /* @__PURE__ */ jsx9(SelectPrimitive.ItemText, { children }),
793
+ /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { className: "ddga-select-item__indicator", children: /* @__PURE__ */ jsx9(Check, { className: "ddga-select-item__check", "aria-hidden": "true" }) })
794
+ ]
795
+ }
796
+ );
797
+ }
798
+
799
+ // src/components/Tooltip/Tooltip.tsx
800
+ import { useContext as useContext3 } from "react";
801
+ import { Tooltip as TooltipPrimitive } from "radix-ui";
802
+ import { cva as cva8 } from "class-variance-authority";
803
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
804
+ var tooltipContentVariants = cva8("ddga-tooltip", {
805
+ variants: {
806
+ size: {
807
+ sm: "ddga-tooltip--sm",
808
+ md: "ddga-tooltip--md"
809
+ }
810
+ },
811
+ defaultVariants: {
812
+ size: "md"
813
+ }
814
+ });
815
+ function Tooltip(props) {
816
+ return /* @__PURE__ */ jsx10(TooltipPrimitive.Root, { ...props });
817
+ }
818
+ function TooltipTrigger({ className, ...props }) {
819
+ return /* @__PURE__ */ jsx10(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", className, ...props });
820
+ }
821
+ function TooltipContent({
822
+ size,
823
+ arrow = true,
824
+ sideOffset = 6,
825
+ className,
826
+ children,
827
+ ...props
828
+ }) {
829
+ const ctx = useContext3(DgaContext);
830
+ const portalContainer = ctx?.rootEl ?? void 0;
831
+ return /* @__PURE__ */ jsx10(TooltipPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs9(
832
+ TooltipPrimitive.Content,
833
+ {
834
+ "data-slot": "tooltip-content",
835
+ sideOffset,
836
+ className: cn(tooltipContentVariants({ size }), className),
837
+ ...props,
838
+ children: [
839
+ children,
840
+ arrow ? /* @__PURE__ */ jsx10(TooltipPrimitive.Arrow, { className: "ddga-tooltip__arrow" }) : null
841
+ ]
842
+ }
843
+ ) });
844
+ }
845
+
846
+ // src/components/Alert/Alert.tsx
847
+ import { useState } from "react";
848
+ import { Slot as SlotPrimitive2 } from "radix-ui";
849
+ import { cva as cva9 } from "class-variance-authority";
850
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
851
+ var alertVariants = cva9("ddga-alert", {
852
+ variants: {
853
+ variant: {
854
+ info: "ddga-alert--info",
855
+ success: "ddga-alert--success",
856
+ warning: "ddga-alert--warning",
857
+ destructive: "ddga-alert--destructive"
858
+ }
859
+ },
860
+ defaultVariants: {
861
+ variant: "info"
862
+ }
863
+ });
864
+ var DEFAULT_ICONS = {
865
+ info: /* @__PURE__ */ jsx11(Info, { "aria-hidden": "true" }),
866
+ success: /* @__PURE__ */ jsx11(Check, { "aria-hidden": "true" }),
867
+ warning: /* @__PURE__ */ jsx11(AlertTriangle, { "aria-hidden": "true" }),
868
+ destructive: /* @__PURE__ */ jsx11(AlertCircle, { "aria-hidden": "true" })
869
+ };
870
+ function Alert({
871
+ variant,
872
+ asChild,
873
+ icon,
874
+ dismissible,
875
+ open: controlledOpen,
876
+ onDismiss,
877
+ live,
878
+ closeLabel = "Dismiss",
879
+ className,
880
+ children,
881
+ ...props
882
+ }) {
883
+ const [internalOpen, setInternalOpen] = useState(true);
884
+ const isControlled = controlledOpen !== void 0;
885
+ const open = isControlled ? controlledOpen : internalOpen;
886
+ if (!open) return null;
887
+ const Comp = asChild ? SlotPrimitive2.Slot : "div";
888
+ const resolvedIcon = icon === false ? null : icon !== void 0 ? icon : DEFAULT_ICONS[variant ?? "info"];
889
+ const liveProps = live === "assertive" ? { role: "alert", "aria-live": "assertive" } : live === "polite" ? { role: "status", "aria-live": "polite" } : {};
890
+ function handleDismiss() {
891
+ if (!isControlled) setInternalOpen(false);
892
+ onDismiss?.();
893
+ }
894
+ return /* @__PURE__ */ jsxs10(
895
+ Comp,
896
+ {
897
+ "data-slot": "alert",
898
+ "data-variant": variant ?? "info",
899
+ className: cn(alertVariants({ variant }), className),
900
+ ...liveProps,
901
+ ...props,
902
+ children: [
903
+ resolvedIcon ? /* @__PURE__ */ jsx11("span", { className: "ddga-alert__icon", children: resolvedIcon }) : null,
904
+ asChild ? (
905
+ // Slot mode: the consumer's element receives the children body.
906
+ // Title/description are nested by the consumer.
907
+ /* @__PURE__ */ jsx11(SlotPrimitive2.Slottable, { children })
908
+ ) : /* @__PURE__ */ jsx11("div", { className: "ddga-alert__body", children }),
909
+ dismissible ? /* @__PURE__ */ jsx11(
910
+ "button",
911
+ {
912
+ type: "button",
913
+ className: "ddga-alert__close",
914
+ "aria-label": closeLabel,
915
+ onClick: handleDismiss,
916
+ children: /* @__PURE__ */ jsx11(Close, { "aria-hidden": "true" })
917
+ }
918
+ ) : null
919
+ ]
920
+ }
921
+ );
922
+ }
923
+ function AlertTitle({ asChild, className, ...props }) {
924
+ const Comp = asChild ? SlotPrimitive2.Slot : "h5";
925
+ return /* @__PURE__ */ jsx11(Comp, { "data-slot": "alert-title", className: cn("ddga-alert__title", className), ...props });
926
+ }
927
+ function AlertDescription({ asChild, className, ...props }) {
928
+ const Comp = asChild ? SlotPrimitive2.Slot : "p";
929
+ return /* @__PURE__ */ jsx11(
930
+ Comp,
931
+ {
932
+ "data-slot": "alert-description",
933
+ className: cn("ddga-alert__description", className),
934
+ ...props
935
+ }
936
+ );
937
+ }
938
+
939
+ // src/components/Modal/Modal.tsx
940
+ import { useContext as useContext4 } from "react";
941
+ import { Dialog as DialogPrimitive, Slot as SlotPrimitive3 } from "radix-ui";
942
+ import { cva as cva10 } from "class-variance-authority";
943
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
944
+ var modalContentVariants = cva10("ddga-modal", {
945
+ variants: {
946
+ size: {
947
+ sm: "ddga-modal--sm",
948
+ md: "ddga-modal--md",
949
+ lg: "ddga-modal--lg",
950
+ xl: "ddga-modal--xl",
951
+ full: "ddga-modal--full"
952
+ }
953
+ },
954
+ defaultVariants: {
955
+ size: "md"
956
+ }
957
+ });
958
+ function Modal(props) {
959
+ return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { ...props });
960
+ }
961
+ function ModalTrigger({ className, ...props }) {
962
+ return /* @__PURE__ */ jsx12(DialogPrimitive.Trigger, { "data-slot": "modal-trigger", className, ...props });
963
+ }
964
+ function ModalContent({
965
+ size,
966
+ showCloseButton = true,
967
+ closeLabel = "Close",
968
+ className,
969
+ children,
970
+ ...props
971
+ }) {
972
+ const ctx = useContext4(DgaContext);
973
+ const portalContainer = ctx?.rootEl ?? void 0;
974
+ return /* @__PURE__ */ jsxs11(DialogPrimitive.Portal, { container: portalContainer, children: [
975
+ /* @__PURE__ */ jsx12(DialogPrimitive.Overlay, { className: "ddga-modal__overlay", "data-slot": "modal-overlay" }),
976
+ /* @__PURE__ */ jsxs11(
977
+ DialogPrimitive.Content,
978
+ {
979
+ "data-slot": "modal-content",
980
+ className: cn(modalContentVariants({ size }), className),
981
+ ...props,
982
+ children: [
983
+ children,
984
+ showCloseButton ? /* @__PURE__ */ jsx12(
985
+ DialogPrimitive.Close,
986
+ {
987
+ className: "ddga-modal__close",
988
+ "aria-label": closeLabel,
989
+ "data-slot": "modal-close-x",
990
+ children: /* @__PURE__ */ jsx12(Close, { "aria-hidden": "true" })
991
+ }
992
+ ) : null
993
+ ]
994
+ }
995
+ )
996
+ ] });
997
+ }
998
+ function ModalHeader({ asChild, className, ...props }) {
999
+ const Comp = asChild ? SlotPrimitive3.Slot : "div";
1000
+ return /* @__PURE__ */ jsx12(Comp, { "data-slot": "modal-header", className: cn("ddga-modal__header", className), ...props });
1001
+ }
1002
+ function ModalTitle({ asChild, className, ...props }) {
1003
+ return /* @__PURE__ */ jsx12(
1004
+ DialogPrimitive.Title,
1005
+ {
1006
+ asChild,
1007
+ "data-slot": "modal-title",
1008
+ className: cn("ddga-modal__title", className),
1009
+ ...props
1010
+ }
1011
+ );
1012
+ }
1013
+ function ModalDescription({ asChild, className, ...props }) {
1014
+ return /* @__PURE__ */ jsx12(
1015
+ DialogPrimitive.Description,
1016
+ {
1017
+ asChild,
1018
+ "data-slot": "modal-description",
1019
+ className: cn("ddga-modal__description", className),
1020
+ ...props
1021
+ }
1022
+ );
1023
+ }
1024
+ function ModalFooter({ asChild, className, ...props }) {
1025
+ const Comp = asChild ? SlotPrimitive3.Slot : "div";
1026
+ return /* @__PURE__ */ jsx12(Comp, { "data-slot": "modal-footer", className: cn("ddga-modal__footer", className), ...props });
1027
+ }
1028
+ function ModalClose({ className, ...props }) {
1029
+ return /* @__PURE__ */ jsx12(DialogPrimitive.Close, { "data-slot": "modal-close", className, ...props });
1030
+ }
1031
+
1032
+ // src/components/Toast/Toast.tsx
1033
+ import { useSyncExternalStore } from "react";
1034
+ import { Toast as ToastPrimitive } from "radix-ui";
1035
+ import { cva as cva11 } from "class-variance-authority";
1036
+
1037
+ // src/components/Toast/toast-store.ts
1038
+ import "react";
1039
+ var EXIT_ANIM_MS = 200;
1040
+ function createToastStore() {
1041
+ let toasts = [];
1042
+ const listeners = /* @__PURE__ */ new Set();
1043
+ let counter = 0;
1044
+ function emit() {
1045
+ for (const l of listeners) l();
1046
+ }
1047
+ function subscribe(listener) {
1048
+ listeners.add(listener);
1049
+ return () => {
1050
+ listeners.delete(listener);
1051
+ };
1052
+ }
1053
+ function getSnapshot() {
1054
+ return toasts;
1055
+ }
1056
+ function nextId() {
1057
+ counter += 1;
1058
+ return `t${counter}`;
1059
+ }
1060
+ function add(variant, message, options = {}) {
1061
+ const id = options.id ?? nextId();
1062
+ const existing = toasts.findIndex((t) => t.id === id);
1063
+ const data = {
1064
+ id,
1065
+ variant,
1066
+ open: true,
1067
+ title: message,
1068
+ description: options.description,
1069
+ duration: options.duration,
1070
+ action: options.action,
1071
+ onDismiss: options.onDismiss
1072
+ };
1073
+ if (existing >= 0) {
1074
+ toasts = toasts.map((t, i) => i === existing ? data : t);
1075
+ } else {
1076
+ toasts = [...toasts, data];
1077
+ }
1078
+ emit();
1079
+ return id;
1080
+ }
1081
+ function dismiss(id) {
1082
+ if (id === void 0) {
1083
+ const ids = toasts.map((t) => t.id);
1084
+ toasts = toasts.map((t) => ({ ...t, open: false }));
1085
+ emit();
1086
+ setTimeout(() => {
1087
+ ids.forEach((id2) => remove(id2));
1088
+ }, EXIT_ANIM_MS);
1089
+ } else {
1090
+ toasts = toasts.map((t) => t.id === id ? { ...t, open: false } : t);
1091
+ emit();
1092
+ setTimeout(() => remove(id), EXIT_ANIM_MS);
1093
+ }
1094
+ }
1095
+ function remove(id) {
1096
+ const target = toasts.find((t) => t.id === id);
1097
+ toasts = toasts.filter((t) => t.id !== id);
1098
+ emit();
1099
+ target?.onDismiss?.();
1100
+ }
1101
+ function __reset() {
1102
+ toasts = [];
1103
+ counter = 0;
1104
+ emit();
1105
+ }
1106
+ return { subscribe, getSnapshot, add, dismiss, remove, __reset };
1107
+ }
1108
+ var toastStore = createToastStore();
1109
+ function createToast(store) {
1110
+ const fn = ((message, options) => store.add("default", message, options));
1111
+ fn.default = (message, options) => store.add("default", message, options);
1112
+ fn.info = (message, options) => store.add("info", message, options);
1113
+ fn.success = (message, options) => store.add("success", message, options);
1114
+ fn.warning = (message, options) => store.add("warning", message, options);
1115
+ fn.error = (message, options) => store.add("destructive", message, options);
1116
+ fn.destructive = fn.error;
1117
+ fn.dismiss = (id) => store.dismiss(id);
1118
+ return fn;
1119
+ }
1120
+ var toast = createToast(toastStore);
1121
+
1122
+ // src/components/Toast/Toast.tsx
1123
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1124
+ var toastVariants = cva11("ddga-toast", {
1125
+ variants: {
1126
+ variant: {
1127
+ default: "ddga-toast--default",
1128
+ info: "ddga-toast--info",
1129
+ success: "ddga-toast--success",
1130
+ warning: "ddga-toast--warning",
1131
+ destructive: "ddga-toast--destructive"
1132
+ }
1133
+ },
1134
+ defaultVariants: {
1135
+ variant: "default"
1136
+ }
1137
+ });
1138
+ var toastViewportVariants = cva11("ddga-toast-viewport", {
1139
+ variants: {
1140
+ position: {
1141
+ "top-start": "ddga-toast-viewport--top-start",
1142
+ "top-center": "ddga-toast-viewport--top-center",
1143
+ "top-end": "ddga-toast-viewport--top-end",
1144
+ "bottom-start": "ddga-toast-viewport--bottom-start",
1145
+ "bottom-center": "ddga-toast-viewport--bottom-center",
1146
+ "bottom-end": "ddga-toast-viewport--bottom-end"
1147
+ },
1148
+ containerized: {
1149
+ true: "ddga-toast-viewport--containerized"
1150
+ }
1151
+ },
1152
+ defaultVariants: {
1153
+ position: "bottom-end"
1154
+ }
1155
+ });
1156
+ var DEFAULT_ICONS2 = {
1157
+ default: null,
1158
+ info: /* @__PURE__ */ jsx13(Info, { "aria-hidden": "true" }),
1159
+ success: /* @__PURE__ */ jsx13(Check, { "aria-hidden": "true" }),
1160
+ warning: /* @__PURE__ */ jsx13(AlertTriangle, { "aria-hidden": "true" }),
1161
+ destructive: /* @__PURE__ */ jsx13(AlertCircle, { "aria-hidden": "true" })
1162
+ };
1163
+ function Toaster({
1164
+ position = "bottom-end",
1165
+ containerized = false,
1166
+ duration = 4e3,
1167
+ closeButton = true,
1168
+ closeLabel = "Dismiss",
1169
+ hideIcon = false,
1170
+ className,
1171
+ swipeDirection,
1172
+ store = toastStore
1173
+ }) {
1174
+ const toasts = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
1175
+ const resolvedSwipe = swipeDirection ?? (position.startsWith("top") ? "up" : "down");
1176
+ return /* @__PURE__ */ jsxs12(ToastPrimitive.Provider, { duration, swipeDirection: resolvedSwipe, children: [
1177
+ toasts.map((t) => /* @__PURE__ */ jsx13(
1178
+ ToastItem,
1179
+ {
1180
+ toast: t,
1181
+ store,
1182
+ closeButton,
1183
+ closeLabel,
1184
+ hideIcon
1185
+ },
1186
+ t.id
1187
+ )),
1188
+ /* @__PURE__ */ jsx13(
1189
+ ToastPrimitive.Viewport,
1190
+ {
1191
+ "data-slot": "toast-viewport",
1192
+ "data-position": position,
1193
+ className: cn(toastViewportVariants({ position, containerized }), className)
1194
+ }
1195
+ )
1196
+ ] });
1197
+ }
1198
+ function ToastItem({ toast: t, store, closeButton, closeLabel, hideIcon }) {
1199
+ const radixType = t.variant === "destructive" ? "foreground" : "background";
1200
+ const icon = hideIcon ? null : DEFAULT_ICONS2[t.variant];
1201
+ return /* @__PURE__ */ jsxs12(
1202
+ ToastPrimitive.Root,
1203
+ {
1204
+ "data-slot": "toast",
1205
+ "data-variant": t.variant,
1206
+ className: toastVariants({ variant: t.variant }),
1207
+ open: t.open,
1208
+ type: radixType,
1209
+ duration: t.duration,
1210
+ onOpenChange: (open) => {
1211
+ if (!open) {
1212
+ store.dismiss(t.id);
1213
+ }
1214
+ },
1215
+ children: [
1216
+ icon ? /* @__PURE__ */ jsx13("span", { className: "ddga-toast__icon", children: icon }) : null,
1217
+ /* @__PURE__ */ jsxs12("div", { className: "ddga-toast__body", children: [
1218
+ t.title ? /* @__PURE__ */ jsx13(ToastPrimitive.Title, { className: "ddga-toast__title", children: t.title }) : null,
1219
+ t.description ? /* @__PURE__ */ jsx13(ToastPrimitive.Description, { className: "ddga-toast__description", children: t.description }) : null,
1220
+ t.action ? /* @__PURE__ */ jsx13(
1221
+ ToastPrimitive.Action,
1222
+ {
1223
+ className: "ddga-toast__action",
1224
+ altText: t.action.altText ?? (typeof t.action.label === "string" ? t.action.label : "Action"),
1225
+ onClick: () => {
1226
+ t.action?.onClick();
1227
+ store.dismiss(t.id);
1228
+ },
1229
+ children: t.action.label
1230
+ }
1231
+ ) : null
1232
+ ] }),
1233
+ closeButton ? /* @__PURE__ */ jsx13(ToastPrimitive.Close, { className: "ddga-toast__close", "aria-label": closeLabel, children: /* @__PURE__ */ jsx13(Close, { "aria-hidden": "true" }) }) : null
1234
+ ]
1235
+ }
1236
+ );
1237
+ }
1238
+
437
1239
  // src/providers/DgaProvider.tsx
438
- import { jsx as jsx7 } from "react/jsx-runtime";
1240
+ import { useState as useState2, useMemo, useContext as useContext5 } from "react";
1241
+ import { Direction as DirectionPrimitive, Tooltip as TooltipPrimitive2 } from "radix-ui";
1242
+ import { buildTheme } from "@dev-dga/tokens";
1243
+ import { jsx as jsx14 } from "react/jsx-runtime";
439
1244
  function DgaProvider({
440
1245
  dir = "ltr",
441
1246
  locale,
442
1247
  mode = "light",
1248
+ theme,
443
1249
  as: Component = "div",
444
1250
  className,
445
1251
  style: consumerStyle,
446
1252
  children
447
1253
  }) {
448
- const parentCtx = useContext2(DgaContext);
1254
+ const parentCtx = useContext5(DgaContext);
449
1255
  const isNested = parentCtx !== null;
450
- const rootRef = useRef(null);
1256
+ const [rootEl, setRootEl] = useState2(null);
451
1257
  const resolvedLocale = locale ?? (dir === "rtl" ? "ar" : "en");
452
1258
  const ctxValue = useMemo(
453
- () => ({ dir, locale: resolvedLocale, mode, rootRef }),
454
- [dir, resolvedLocale, mode]
1259
+ () => ({ dir, locale: resolvedLocale, mode, rootEl }),
1260
+ [dir, resolvedLocale, mode, rootEl]
455
1261
  );
456
- const inner = /* @__PURE__ */ jsx7(DirectionPrimitive.Provider, { dir, children });
457
- return /* @__PURE__ */ jsx7(DgaContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsx7(
1262
+ const themeVars = useMemo(() => theme ? buildTheme(theme) : null, [theme]);
1263
+ const inner = /* @__PURE__ */ jsx14(DirectionPrimitive.Provider, { dir, children });
1264
+ return /* @__PURE__ */ jsx14(DgaContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsx14(
458
1265
  Component,
459
1266
  {
460
- ref: rootRef,
1267
+ ref: setRootEl,
461
1268
  dir,
462
1269
  lang: resolvedLocale,
463
1270
  "data-slot": "dga-root",
464
1271
  "data-theme": mode,
465
1272
  className,
466
- style: { colorScheme: mode, ...consumerStyle },
467
- children: isNested ? inner : /* @__PURE__ */ jsx7(TooltipPrimitive.Provider, { delayDuration: 300, skipDelayDuration: 100, children: inner })
1273
+ style: { colorScheme: mode, ...themeVars ?? {}, ...consumerStyle },
1274
+ children: isNested ? inner : /* @__PURE__ */ jsx14(TooltipPrimitive2.Provider, { delayDuration: 300, skipDelayDuration: 100, children: inner })
468
1275
  }
469
1276
  ) });
470
1277
  }
@@ -474,17 +1281,52 @@ function useDir() {
474
1281
  return useDga().dir;
475
1282
  }
476
1283
  export {
1284
+ Alert,
1285
+ AlertDescription,
1286
+ AlertTitle,
477
1287
  Button,
478
1288
  Checkbox,
479
1289
  DgaProvider,
1290
+ FieldMessage,
480
1291
  Input,
1292
+ Modal,
1293
+ ModalClose,
1294
+ ModalContent,
1295
+ ModalDescription,
1296
+ ModalFooter,
1297
+ ModalHeader,
1298
+ ModalTitle,
1299
+ ModalTrigger,
1300
+ Radio,
1301
+ RadioGroup,
1302
+ Select,
1303
+ SelectItem,
1304
+ Switch,
481
1305
  Textarea,
1306
+ Toaster,
1307
+ Tooltip,
1308
+ TooltipContent,
1309
+ TooltipTrigger,
1310
+ alertVariants,
482
1311
  buttonVariants,
483
1312
  checkboxVariants,
484
1313
  cn,
1314
+ createToast,
1315
+ createToastStore,
485
1316
  inputVariants,
1317
+ modalContentVariants,
1318
+ radioGroupVariants,
1319
+ radioVariants,
1320
+ selectTriggerVariants,
1321
+ switchVariants,
486
1322
  textareaVariants,
1323
+ toast,
1324
+ toastStore,
1325
+ toastVariants,
1326
+ toastViewportVariants,
1327
+ tooltipContentVariants,
487
1328
  useDga,
488
- useDir
1329
+ useDir,
1330
+ useFieldA11y
489
1331
  };
490
1332
  //# sourceMappingURL=index.js.map