@open-mercato/ui 0.5.1-develop.2949.009dcdd2d5 → 0.5.1-develop.2954.610bab2d08

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.
Files changed (96) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +8 -0
  3. package/dist/backend/CrudForm.js +57 -29
  4. package/dist/backend/CrudForm.js.map +2 -2
  5. package/dist/backend/DataTable.js +32 -14
  6. package/dist/backend/DataTable.js.map +2 -2
  7. package/dist/backend/FilterOverlay.js +23 -17
  8. package/dist/backend/FilterOverlay.js.map +2 -2
  9. package/dist/backend/JsonBuilder.js +32 -18
  10. package/dist/backend/JsonBuilder.js.map +2 -2
  11. package/dist/backend/columns/ColumnChooserPanel.js +12 -13
  12. package/dist/backend/columns/ColumnChooserPanel.js.map +2 -2
  13. package/dist/backend/custom-fields/FieldDefinitionsEditor.js +71 -62
  14. package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +2 -2
  15. package/dist/backend/date-range/DateRangeSelect.js +11 -10
  16. package/dist/backend/date-range/DateRangeSelect.js.map +2 -2
  17. package/dist/backend/date-range/InlineDateRangeSelect.js +10 -22
  18. package/dist/backend/date-range/InlineDateRangeSelect.js.map +2 -2
  19. package/dist/backend/detail/ActivitiesSection.js +20 -12
  20. package/dist/backend/detail/ActivitiesSection.js.map +2 -2
  21. package/dist/backend/detail/AddressEditor.js +24 -7
  22. package/dist/backend/detail/AddressEditor.js.map +2 -2
  23. package/dist/backend/detail/InlineEditors.js +12 -6
  24. package/dist/backend/detail/InlineEditors.js.map +2 -2
  25. package/dist/backend/detail/NotesSection.js +20 -14
  26. package/dist/backend/detail/NotesSection.js.map +2 -2
  27. package/dist/backend/filters/AdvancedFilterBuilder.js +52 -24
  28. package/dist/backend/filters/AdvancedFilterBuilder.js.map +2 -2
  29. package/dist/backend/injection/InjectedField.js +12 -7
  30. package/dist/backend/injection/InjectedField.js.map +2 -2
  31. package/dist/backend/inputs/ComboboxInput.js.map +2 -2
  32. package/dist/backend/inputs/EventSelect.js +22 -6
  33. package/dist/backend/inputs/EventSelect.js.map +2 -2
  34. package/dist/backend/inputs/PhoneNumberField.js +2 -2
  35. package/dist/backend/inputs/PhoneNumberField.js.map +2 -2
  36. package/dist/backend/inputs/TimeInput.js +9 -10
  37. package/dist/backend/inputs/TimeInput.js.map +2 -2
  38. package/dist/backend/messages/message-compose-form-groups.js +12 -7
  39. package/dist/backend/messages/message-compose-form-groups.js.map +2 -2
  40. package/dist/backend/messages/useMessageCompose.js +7 -1
  41. package/dist/backend/messages/useMessageCompose.js.map +2 -2
  42. package/dist/frontend/LanguageSwitcher.js +19 -14
  43. package/dist/frontend/LanguageSwitcher.js.map +2 -2
  44. package/dist/index.js +5 -0
  45. package/dist/index.js.map +2 -2
  46. package/dist/primitives/checkbox-field.js +17 -5
  47. package/dist/primitives/checkbox-field.js.map +2 -2
  48. package/dist/primitives/input.js +71 -14
  49. package/dist/primitives/input.js.map +2 -2
  50. package/dist/primitives/radio-field.js +74 -0
  51. package/dist/primitives/radio-field.js.map +7 -0
  52. package/dist/primitives/radio.js +37 -0
  53. package/dist/primitives/radio.js.map +7 -0
  54. package/dist/primitives/select.js +155 -0
  55. package/dist/primitives/select.js.map +7 -0
  56. package/dist/primitives/switch-field.js +76 -0
  57. package/dist/primitives/switch-field.js.map +7 -0
  58. package/dist/primitives/switch.js +17 -3
  59. package/dist/primitives/switch.js.map +2 -2
  60. package/dist/primitives/textarea.js +48 -12
  61. package/dist/primitives/textarea.js.map +2 -2
  62. package/dist/primitives/tooltip.js +44 -15
  63. package/dist/primitives/tooltip.js.map +2 -2
  64. package/package.json +5 -3
  65. package/src/backend/CrudForm.tsx +104 -37
  66. package/src/backend/DataTable.tsx +38 -20
  67. package/src/backend/FilterOverlay.tsx +35 -21
  68. package/src/backend/JsonBuilder.tsx +38 -20
  69. package/src/backend/__tests__/FieldDefinitionsEditor.test.tsx +23 -6
  70. package/src/backend/columns/ColumnChooserPanel.tsx +9 -10
  71. package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +120 -87
  72. package/src/backend/date-range/DateRangeSelect.tsx +19 -12
  73. package/src/backend/date-range/InlineDateRangeSelect.tsx +16 -20
  74. package/src/backend/detail/ActivitiesSection.tsx +35 -23
  75. package/src/backend/detail/AddressEditor.tsx +30 -16
  76. package/src/backend/detail/InlineEditors.tsx +21 -11
  77. package/src/backend/detail/NotesSection.tsx +35 -25
  78. package/src/backend/filters/AdvancedFilterBuilder.tsx +60 -34
  79. package/src/backend/injection/InjectedField.tsx +21 -12
  80. package/src/backend/inputs/ComboboxInput.tsx +4 -0
  81. package/src/backend/inputs/EventSelect.tsx +30 -17
  82. package/src/backend/inputs/PhoneNumberField.tsx +2 -2
  83. package/src/backend/inputs/TimeInput.tsx +9 -10
  84. package/src/backend/messages/message-compose-form-groups.tsx +21 -12
  85. package/src/backend/messages/useMessageCompose.ts +20 -1
  86. package/src/frontend/LanguageSwitcher.tsx +20 -17
  87. package/src/index.ts +5 -0
  88. package/src/primitives/checkbox-field.tsx +10 -2
  89. package/src/primitives/input.tsx +73 -12
  90. package/src/primitives/radio-field.tsx +92 -0
  91. package/src/primitives/radio.tsx +42 -0
  92. package/src/primitives/select.tsx +200 -0
  93. package/src/primitives/switch-field.tsx +100 -0
  94. package/src/primitives/switch.tsx +17 -4
  95. package/src/primitives/textarea.tsx +67 -11
  96. package/src/primitives/tooltip.tsx +68 -24
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/primitives/input.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype InputProps = React.ComponentPropsWithoutRef<'input'>\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type = 'text', ...props }, ref) => (\n <input\n ref={ref}\n type={type}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n {...props}\n />\n )\n)\n\nInput.displayName = 'Input'\n"],
5
- "mappings": "AAOI;AAPJ,YAAY,WAAW;AACvB,SAAS,UAAU;AAIZ,MAAM,QAAQ,MAAM;AAAA,EACzB,CAAC,EAAE,WAAW,OAAO,QAAQ,GAAG,MAAM,GAAG,QACvC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,MAAM,cAAc;",
4
+ "sourcesContent": ["import * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nconst inputWrapperVariants = cva(\n 'inline-flex w-full items-center gap-2 rounded-md border border-input bg-background shadow-xs transition-colors focus-within:outline-none focus-within:shadow-focus focus-within:border-foreground hover:bg-muted/40 has-[input:disabled]:bg-bg-disabled has-[input:disabled]:border-border-disabled has-[input:disabled]:shadow-none has-[input:disabled]:hover:bg-bg-disabled has-[input[aria-invalid=true]]:border-destructive has-[input[aria-invalid=true]]:focus-within:border-destructive',\n {\n variants: {\n size: {\n sm: 'h-8 px-2.5',\n default: 'h-9 px-3',\n lg: 'h-10 px-3',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\nconst inputElementVariants = cva(\n 'flex-1 min-w-0 bg-transparent border-0 outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-transparent',\n {\n variants: {\n size: {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-sm',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\nexport type InputProps = Omit<React.ComponentPropsWithoutRef<'input'>, 'size'> &\n VariantProps<typeof inputWrapperVariants> & {\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n /** Optional className on the inner <input> element. */\n inputClassName?: string\n }\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, inputClassName, type = 'text', size, leftIcon, rightIcon, ...props }, ref) => {\n return (\n <div\n className={cn(inputWrapperVariants({ size }), className)}\n data-slot=\"input-wrapper\"\n >\n {leftIcon ? (\n <span\n className=\"flex shrink-0 items-center text-muted-foreground [&_svg]:size-4\"\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n ) : null}\n <input\n ref={ref}\n type={type}\n className={cn(inputElementVariants({ size }), inputClassName)}\n {...props}\n />\n {rightIcon ? (\n <span\n className=\"flex shrink-0 items-center text-muted-foreground [&_svg]:size-4\"\n aria-hidden=\"true\"\n >\n {rightIcon}\n </span>\n ) : null}\n </div>\n )\n }\n)\n\nInput.displayName = 'Input'\n\nexport { inputWrapperVariants, inputElementVariants }\n"],
5
+ "mappings": "AA+CM,SAKI,KALJ;AA/CN,YAAY,WAAW;AACvB,SAAS,WAA8B;AACvC,SAAS,UAAU;AAEnB,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAUO,MAAM,QAAQ,MAAM;AAAA,EACzB,CAAC,EAAE,WAAW,gBAAgB,OAAO,QAAQ,MAAM,UAAU,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC1F,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,qBAAqB,EAAE,KAAK,CAAC,GAAG,SAAS;AAAA,QACvD,aAAU;AAAA,QAET;AAAA,qBACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA,cAEX;AAAA;AAAA,UACH,IACE;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA,WAAW,GAAG,qBAAqB,EAAE,KAAK,CAAC,GAAG,cAAc;AAAA,cAC3D,GAAG;AAAA;AAAA,UACN;AAAA,UACC,YACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA,cAEX;AAAA;AAAA,UACH,IACE;AAAA;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,MAAM,cAAc;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "@open-mercato/shared/lib/utils";
5
+ import { Radio } from "./radio.js";
6
+ const RadioField = React.forwardRef(({
7
+ id: idProp,
8
+ label,
9
+ sublabel,
10
+ description,
11
+ badge,
12
+ link,
13
+ flip = false,
14
+ containerClassName,
15
+ contentClassName,
16
+ className,
17
+ disabled,
18
+ ...radioProps
19
+ }, ref) => {
20
+ const fallbackId = React.useId();
21
+ const id = idProp ?? fallbackId;
22
+ const hasMultiLine = Boolean(description || sublabel || link);
23
+ const radio = /* @__PURE__ */ jsx(
24
+ Radio,
25
+ {
26
+ ref,
27
+ id,
28
+ disabled,
29
+ className: cn(hasMultiLine && "mt-0.5", className),
30
+ ...radioProps
31
+ }
32
+ );
33
+ const content = /* @__PURE__ */ jsxs("div", { className: cn("flex flex-1 min-w-0 flex-col gap-2.5", contentClassName), children: [
34
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
36
+ /* @__PURE__ */ jsx(
37
+ "label",
38
+ {
39
+ htmlFor: id,
40
+ className: cn(
41
+ "text-sm font-medium leading-5 text-foreground select-none",
42
+ disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"
43
+ ),
44
+ children: label
45
+ }
46
+ ),
47
+ sublabel ? /* @__PURE__ */ jsx("span", { className: "text-xs leading-4 text-muted-foreground select-none", children: sublabel }) : null,
48
+ badge ? /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0", children: badge }) : null
49
+ ] }),
50
+ description ? /* @__PURE__ */ jsx("p", { className: "text-xs leading-4 text-muted-foreground", children: description }) : null
51
+ ] }),
52
+ link ? /* @__PURE__ */ jsx("div", { className: "flex", children: link }) : null
53
+ ] });
54
+ return /* @__PURE__ */ jsxs(
55
+ "div",
56
+ {
57
+ className: cn(
58
+ "flex gap-2",
59
+ hasMultiLine ? "items-start" : "items-center",
60
+ flip && "flex-row-reverse",
61
+ containerClassName
62
+ ),
63
+ children: [
64
+ flip ? content : radio,
65
+ flip ? radio : content
66
+ ]
67
+ }
68
+ );
69
+ });
70
+ RadioField.displayName = "RadioField";
71
+ export {
72
+ RadioField
73
+ };
74
+ //# sourceMappingURL=radio-field.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/primitives/radio-field.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Radio } from './radio'\n\nexport type RadioFieldProps = Omit<React.ComponentProps<typeof Radio>, 'id'> & {\n id?: string\n label: React.ReactNode\n sublabel?: React.ReactNode\n description?: React.ReactNode\n badge?: React.ReactNode\n link?: React.ReactNode\n /** When true, renders the radio on the right of the label content. */\n flip?: boolean\n containerClassName?: string\n contentClassName?: string\n}\n\nexport const RadioField = React.forwardRef<\n React.ElementRef<typeof Radio>,\n RadioFieldProps\n>(({\n id: idProp,\n label,\n sublabel,\n description,\n badge,\n link,\n flip = false,\n containerClassName,\n contentClassName,\n className,\n disabled,\n ...radioProps\n}, ref) => {\n // useId is SSR/HMR-stable; counter-based fallbacks drift on hydration.\n const fallbackId = React.useId()\n const id = idProp ?? fallbackId\n\n const hasMultiLine = Boolean(description || sublabel || link)\n const radio = (\n <Radio\n ref={ref}\n id={id}\n disabled={disabled}\n className={cn(hasMultiLine && 'mt-0.5', className)}\n {...radioProps}\n />\n )\n\n const content = (\n <div className={cn('flex flex-1 min-w-0 flex-col gap-2.5', contentClassName)}>\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <label\n htmlFor={id}\n className={cn(\n 'text-sm font-medium leading-5 text-foreground select-none',\n disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'\n )}\n >\n {label}\n </label>\n {sublabel ? (\n <span className=\"text-xs leading-4 text-muted-foreground select-none\">{sublabel}</span>\n ) : null}\n {badge ? <span className=\"inline-flex shrink-0\">{badge}</span> : null}\n </div>\n {description ? (\n <p className=\"text-xs leading-4 text-muted-foreground\">{description}</p>\n ) : null}\n </div>\n {link ? <div className=\"flex\">{link}</div> : null}\n </div>\n )\n\n return (\n <div\n className={cn(\n 'flex gap-2',\n hasMultiLine ? 'items-start' : 'items-center',\n flip && 'flex-row-reverse',\n containerClassName\n )}\n >\n {flip ? content : radio}\n {flip ? radio : content}\n </div>\n )\n})\nRadioField.displayName = 'RadioField'\n"],
5
+ "mappings": ";AA0CI,cAYI,YAZJ;AAxCJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,aAAa;AAef,MAAM,aAAa,MAAM,WAG9B,CAAC;AAAA,EACD,IAAI;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAG,QAAQ;AAET,QAAM,aAAa,MAAM,MAAM;AAC/B,QAAM,KAAK,UAAU;AAErB,QAAM,eAAe,QAAQ,eAAe,YAAY,IAAI;AAC5D,QAAM,QACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,GAAG,gBAAgB,UAAU,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAGF,QAAM,UACJ,qBAAC,SAAI,WAAW,GAAG,wCAAwC,gBAAgB,GACzE;AAAA,yBAAC,SAAI,WAAU,uBACb;AAAA,2BAAC,SAAI,WAAU,qCACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,WAAW;AAAA,cACT;AAAA,cACA,WAAW,kCAAkC;AAAA,YAC/C;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACC,WACC,oBAAC,UAAK,WAAU,uDAAuD,oBAAS,IAC9E;AAAA,QACH,QAAQ,oBAAC,UAAK,WAAU,wBAAwB,iBAAM,IAAU;AAAA,SACnE;AAAA,MACC,cACC,oBAAC,OAAE,WAAU,2CAA2C,uBAAY,IAClE;AAAA,OACN;AAAA,IACC,OAAO,oBAAC,SAAI,WAAU,QAAQ,gBAAK,IAAS;AAAA,KAC/C;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,eAAe,gBAAgB;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,MAEC;AAAA,eAAO,UAAU;AAAA,QACjB,OAAO,QAAQ;AAAA;AAAA;AAAA,EAClB;AAEJ,CAAC;AACD,WAAW,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5
+ import { cn } from "@open-mercato/shared/lib/utils";
6
+ const RadioGroup = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7
+ RadioGroupPrimitive.Root,
8
+ {
9
+ ref,
10
+ className: cn("flex flex-col gap-2", className),
11
+ ...props
12
+ }
13
+ ));
14
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
15
+ const Radio = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16
+ RadioGroupPrimitive.Item,
17
+ {
18
+ ref,
19
+ className: cn(
20
+ "aspect-square size-5 shrink-0 rounded-full border border-input bg-background",
21
+ "flex items-center justify-center transition-colors",
22
+ "hover:border-muted-foreground/40",
23
+ "data-[state=checked]:border-accent-indigo data-[state=checked]:bg-accent-indigo",
24
+ "focus-visible:outline-none focus-visible:shadow-focus",
25
+ "disabled:cursor-not-allowed disabled:opacity-60",
26
+ className
27
+ ),
28
+ ...props,
29
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "block size-2 rounded-full bg-white" }) })
30
+ }
31
+ ));
32
+ Radio.displayName = RadioGroupPrimitive.Item.displayName;
33
+ export {
34
+ Radio,
35
+ RadioGroup
36
+ };
37
+ //# sourceMappingURL=radio.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/primitives/radio.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nexport const RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn('flex flex-col gap-2', className)}\n {...props}\n />\n))\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName\n\nexport const Radio = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n 'aspect-square size-5 shrink-0 rounded-full border border-input bg-background',\n 'flex items-center justify-center transition-colors',\n 'hover:border-muted-foreground/40',\n 'data-[state=checked]:border-accent-indigo data-[state=checked]:bg-accent-indigo',\n 'focus-visible:outline-none focus-visible:shadow-focus',\n 'disabled:cursor-not-allowed disabled:opacity-60',\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <span aria-hidden=\"true\" className=\"block size-2 rounded-full bg-white\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n))\nRadio.displayName = RadioGroupPrimitive.Item.displayName\n"],
5
+ "mappings": ";AAWE;AATF,YAAY,WAAW;AACvB,YAAY,yBAAyB;AAErC,SAAS,UAAU;AAEZ,MAAM,aAAa,MAAM,WAG9B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,oBAAoB;AAAA,EAApB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,uBAAuB,SAAS;AAAA,IAC7C,GAAG;AAAA;AACN,CACD;AACD,WAAW,cAAc,oBAAoB,KAAK;AAE3C,MAAM,QAAQ,MAAM,WAGzB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,oBAAoB;AAAA,EAApB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEJ,8BAAC,oBAAoB,WAApB,EAA8B,WAAU,oCACvC,8BAAC,UAAK,eAAY,QAAO,WAAU,sCAAqC,GAC1E;AAAA;AACF,CACD;AACD,MAAM,cAAc,oBAAoB,KAAK;",
6
+ "names": []
7
+ }
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import * as SelectPrimitive from "@radix-ui/react-select";
5
+ import { Check, ChevronDown, ChevronUp } from "lucide-react";
6
+ import { cva } from "class-variance-authority";
7
+ import { cn } from "@open-mercato/shared/lib/utils";
8
+ const selectTriggerVariants = cva(
9
+ "inline-flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background shadow-xs transition-colors outline-none placeholder:text-muted-foreground hover:bg-muted/40 focus:outline-none focus-visible:outline-none focus-visible:shadow-focus focus-visible:border-foreground disabled:cursor-not-allowed disabled:bg-bg-disabled disabled:border-border-disabled disabled:shadow-none disabled:hover:bg-bg-disabled disabled:[&_svg]:opacity-60 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive data-[placeholder]:text-muted-foreground [&>span]:line-clamp-1 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0",
10
+ {
11
+ variants: {
12
+ size: {
13
+ sm: "h-8 px-2.5 text-xs",
14
+ default: "h-9 px-3 text-sm",
15
+ lg: "h-10 px-3 text-sm"
16
+ }
17
+ },
18
+ defaultVariants: {
19
+ size: "default"
20
+ }
21
+ }
22
+ );
23
+ const SelectTrigger = React.forwardRef(({ className, size, children, ...props }, ref) => /* @__PURE__ */ jsxs(
24
+ SelectPrimitive.Trigger,
25
+ {
26
+ ref,
27
+ className: cn(selectTriggerVariants({ size }), className),
28
+ "data-slot": "select-trigger",
29
+ ...props,
30
+ children: [
31
+ children,
32
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "text-muted-foreground", "aria-hidden": "true" }) })
33
+ ]
34
+ }
35
+ ));
36
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
37
+ const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38
+ SelectPrimitive.ScrollUpButton,
39
+ {
40
+ ref,
41
+ className: cn("flex cursor-default items-center justify-center py-1 text-muted-foreground", className),
42
+ ...props,
43
+ children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4", "aria-hidden": "true" })
44
+ }
45
+ ));
46
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
47
+ const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
48
+ SelectPrimitive.ScrollDownButton,
49
+ {
50
+ ref,
51
+ className: cn("flex cursor-default items-center justify-center py-1 text-muted-foreground", className),
52
+ ...props,
53
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4", "aria-hidden": "true" })
54
+ }
55
+ ));
56
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
57
+ const SelectContent = React.forwardRef(({ className, children, position = "popper", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
58
+ SelectPrimitive.Content,
59
+ {
60
+ ref,
61
+ position,
62
+ sideOffset,
63
+ className: cn(
64
+ "relative z-dropdown min-w-[8rem] overflow-hidden rounded-md border border-input bg-popover text-popover-foreground shadow-md outline-none",
65
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
66
+ position === "popper" && "w-full min-w-[var(--radix-select-trigger-width)]",
67
+ className
68
+ ),
69
+ ...props,
70
+ children: [
71
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
72
+ /* @__PURE__ */ jsx(
73
+ SelectPrimitive.Viewport,
74
+ {
75
+ className: cn(
76
+ "p-1 max-h-[var(--radix-select-content-available-height)] overflow-y-auto",
77
+ position === "popper" && "w-full min-w-[var(--radix-select-trigger-width)]"
78
+ ),
79
+ children
80
+ }
81
+ ),
82
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
83
+ ]
84
+ }
85
+ ) }));
86
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
87
+ const SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
88
+ SelectPrimitive.Label,
89
+ {
90
+ ref,
91
+ className: cn("px-2 py-1.5 text-overline uppercase text-muted-foreground", className),
92
+ ...props
93
+ }
94
+ ));
95
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
96
+ const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
97
+ SelectPrimitive.Item,
98
+ {
99
+ ref,
100
+ className: cn(
101
+ "relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none transition-colors",
102
+ "focus:bg-muted focus:text-foreground",
103
+ "data-[state=checked]:bg-muted/70 data-[state=checked]:text-foreground",
104
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
105
+ "[&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0",
106
+ className
107
+ ),
108
+ ...props,
109
+ children: [
110
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children }) }),
111
+ /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4 text-foreground", "aria-hidden": "true" }) }) })
112
+ ]
113
+ }
114
+ ));
115
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
116
+ const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
117
+ SelectPrimitive.Separator,
118
+ {
119
+ ref,
120
+ className: cn("-mx-1 my-1 h-px bg-border", className),
121
+ ...props
122
+ }
123
+ ));
124
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
125
+ const Select = React.forwardRef(({ value, defaultValue, onValueChange, ...props }, _ref) => {
126
+ const isControlled = value !== void 0 || onValueChange !== void 0;
127
+ if (!isControlled) {
128
+ return /* @__PURE__ */ jsx(SelectPrimitive.Root, { defaultValue, ...props });
129
+ }
130
+ return /* @__PURE__ */ jsx(
131
+ SelectPrimitive.Root,
132
+ {
133
+ value: value ?? "",
134
+ onValueChange,
135
+ ...props
136
+ }
137
+ );
138
+ });
139
+ Select.displayName = "Select";
140
+ const SelectGroup = SelectPrimitive.Group;
141
+ const SelectValue = SelectPrimitive.Value;
142
+ export {
143
+ Select,
144
+ SelectContent,
145
+ SelectGroup,
146
+ SelectItem,
147
+ SelectLabel,
148
+ SelectScrollDownButton,
149
+ SelectScrollUpButton,
150
+ SelectSeparator,
151
+ SelectTrigger,
152
+ SelectValue,
153
+ selectTriggerVariants
154
+ };
155
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/primitives/select.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport * as SelectPrimitive from '@radix-ui/react-select'\nimport { Check, ChevronDown, ChevronUp } from 'lucide-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nconst selectTriggerVariants = cva(\n 'inline-flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background shadow-xs transition-colors outline-none placeholder:text-muted-foreground hover:bg-muted/40 focus:outline-none focus-visible:outline-none focus-visible:shadow-focus focus-visible:border-foreground disabled:cursor-not-allowed disabled:bg-bg-disabled disabled:border-border-disabled disabled:shadow-none disabled:hover:bg-bg-disabled disabled:[&_svg]:opacity-60 aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive data-[placeholder]:text-muted-foreground [&>span]:line-clamp-1 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n size: {\n sm: 'h-8 px-2.5 text-xs',\n default: 'h-9 px-3 text-sm',\n lg: 'h-10 px-3 text-sm',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\nexport type SelectTriggerProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> &\n VariantProps<typeof selectTriggerVariants>\n\nconst SelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n SelectTriggerProps\n>(({ className, size, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(selectTriggerVariants({ size }), className)}\n data-slot=\"select-trigger\"\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"text-muted-foreground\" aria-hidden=\"true\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn('flex cursor-default items-center justify-center py-1 text-muted-foreground', className)}\n {...props}\n >\n <ChevronUp className=\"size-4\" aria-hidden=\"true\" />\n </SelectPrimitive.ScrollUpButton>\n))\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn('flex cursor-default items-center justify-center py-1 text-muted-foreground', className)}\n {...props}\n >\n <ChevronDown className=\"size-4\" aria-hidden=\"true\" />\n </SelectPrimitive.ScrollDownButton>\n))\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName\n\nconst SelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = 'popper', sideOffset = 4, ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n position={position}\n sideOffset={sideOffset}\n className={cn(\n 'relative z-dropdown min-w-[8rem] overflow-hidden rounded-md border border-input bg-popover text-popover-foreground shadow-md outline-none',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n position === 'popper' && 'w-full min-w-[var(--radix-select-trigger-width)]',\n className\n )}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n 'p-1 max-h-[var(--radix-select-content-available-height)] overflow-y-auto',\n position === 'popper' && 'w-full min-w-[var(--radix-select-trigger-width)]'\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn('px-2 py-1.5 text-overline uppercase text-muted-foreground', className)}\n {...props}\n />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none transition-colors',\n 'focus:bg-muted focus:text-foreground',\n 'data-[state=checked]:bg-muted/70 data-[state=checked]:text-foreground',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n '[&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0',\n className\n )}\n {...props}\n >\n <span className=\"flex-1 truncate\">\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </span>\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"size-4 text-foreground\" aria-hidden=\"true\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\n/**\n * Wraps Radix `Select.Root` to absorb the controlled/uncontrolled transition\n * many call sites trigger by passing `value={x || undefined}`. React fires\n * \"Select is changing from uncontrolled to controlled\" the moment value flips\n * from undefined to a defined string, and Radix's internal state ends up in\n * an inconsistent shape (dropdown flashes, selections no-op). Coercing\n * `undefined` \u2192 `''` keeps Radix in stable controlled mode for the lifetime\n * of the component while preserving \"no selection\" semantics \u2014 Radix simply\n * matches no SelectItem and `SelectValue` falls back to the placeholder.\n */\nconst Select = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>\n>(({ value, defaultValue, onValueChange, ...props }, _ref) => {\n const isControlled = value !== undefined || onValueChange !== undefined\n if (!isControlled) {\n return <SelectPrimitive.Root defaultValue={defaultValue} {...props} />\n }\n return (\n <SelectPrimitive.Root\n value={value ?? ''}\n onValueChange={onValueChange}\n {...props}\n />\n )\n}) as unknown as typeof SelectPrimitive.Root\n;(Select as React.ComponentType).displayName = 'Select'\nconst SelectGroup = SelectPrimitive.Group\nconst SelectValue = SelectPrimitive.Value\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n selectTriggerVariants,\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "@open-mercato/shared/lib/utils";
5
+ import { Switch } from "./switch.js";
6
+ const SwitchField = React.forwardRef(({
7
+ id: idProp,
8
+ label,
9
+ sublabel,
10
+ description,
11
+ badge,
12
+ link,
13
+ flip = false,
14
+ containerClassName,
15
+ contentClassName,
16
+ className,
17
+ disabled,
18
+ ...switchProps
19
+ }, ref) => {
20
+ const fallbackId = React.useId();
21
+ const id = idProp ?? fallbackId;
22
+ const hasMultiLine = Boolean(description || sublabel || link);
23
+ const switchEl = /* @__PURE__ */ jsx(
24
+ Switch,
25
+ {
26
+ ref,
27
+ id,
28
+ disabled,
29
+ className: cn(hasMultiLine && "mt-0.5", className),
30
+ ...switchProps
31
+ }
32
+ );
33
+ const content = /* @__PURE__ */ jsxs("div", { className: cn("flex flex-1 min-w-0 flex-col gap-2.5", contentClassName), children: [
34
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", children: [
36
+ /* @__PURE__ */ jsx(
37
+ "label",
38
+ {
39
+ htmlFor: id,
40
+ className: cn(
41
+ "text-sm font-medium leading-5 text-foreground select-none",
42
+ disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"
43
+ ),
44
+ children: label
45
+ }
46
+ ),
47
+ sublabel ? /* @__PURE__ */ jsx("span", { className: "text-xs leading-4 text-muted-foreground select-none", children: sublabel }) : null,
48
+ badge ? /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0", children: badge }) : null
49
+ ] }),
50
+ description ? /* @__PURE__ */ jsx("p", { className: "text-xs leading-4 text-muted-foreground", children: description }) : null
51
+ ] }),
52
+ link ? /* @__PURE__ */ jsx("div", { className: "flex", children: link }) : null
53
+ ] });
54
+ return /* @__PURE__ */ jsx(
55
+ "div",
56
+ {
57
+ className: cn(
58
+ "flex gap-3",
59
+ hasMultiLine ? "items-start" : "items-center",
60
+ containerClassName
61
+ ),
62
+ children: flip ? /* @__PURE__ */ jsxs(Fragment, { children: [
63
+ switchEl,
64
+ content
65
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
66
+ content,
67
+ switchEl
68
+ ] })
69
+ }
70
+ );
71
+ });
72
+ SwitchField.displayName = "SwitchField";
73
+ export {
74
+ SwitchField
75
+ };
76
+ //# sourceMappingURL=switch-field.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/primitives/switch-field.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { Switch } from './switch'\n\nexport type SwitchFieldProps = Omit<React.ComponentProps<typeof Switch>, 'id'> & {\n id?: string\n label: React.ReactNode\n sublabel?: React.ReactNode\n description?: React.ReactNode\n badge?: React.ReactNode\n link?: React.ReactNode\n /** When true, renders the switch on the left of the label content. */\n flip?: boolean\n containerClassName?: string\n contentClassName?: string\n}\n\nexport const SwitchField = React.forwardRef<\n React.ElementRef<typeof Switch>,\n SwitchFieldProps\n>(({\n id: idProp,\n label,\n sublabel,\n description,\n badge,\n link,\n flip = false,\n containerClassName,\n contentClassName,\n className,\n disabled,\n ...switchProps\n}, ref) => {\n // useId is SSR/HMR-stable; counter-based fallbacks drift on hydration.\n const fallbackId = React.useId()\n const id = idProp ?? fallbackId\n\n const hasMultiLine = Boolean(description || sublabel || link)\n const switchEl = (\n <Switch\n ref={ref}\n id={id}\n disabled={disabled}\n className={cn(hasMultiLine && 'mt-0.5', className)}\n {...switchProps}\n />\n )\n\n const content = (\n <div className={cn('flex flex-1 min-w-0 flex-col gap-2.5', contentClassName)}>\n <div className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <label\n htmlFor={id}\n className={cn(\n 'text-sm font-medium leading-5 text-foreground select-none',\n disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer'\n )}\n >\n {label}\n </label>\n {sublabel ? (\n <span className=\"text-xs leading-4 text-muted-foreground select-none\">{sublabel}</span>\n ) : null}\n {badge ? <span className=\"inline-flex shrink-0\">{badge}</span> : null}\n </div>\n {description ? (\n <p className=\"text-xs leading-4 text-muted-foreground\">{description}</p>\n ) : null}\n </div>\n {link ? <div className=\"flex\">{link}</div> : null}\n </div>\n )\n\n return (\n <div\n className={cn(\n 'flex gap-3',\n hasMultiLine ? 'items-start' : 'items-center',\n containerClassName\n )}\n >\n {flip ? (\n <>\n {switchEl}\n {content}\n </>\n ) : (\n <>\n {content}\n {switchEl}\n </>\n )}\n </div>\n )\n})\nSwitchField.displayName = 'SwitchField'\n"],
5
+ "mappings": ";AA0CI,SA4CI,UA5CJ,KAYI,YAZJ;AAxCJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,cAAc;AAehB,MAAM,cAAc,MAAM,WAG/B,CAAC;AAAA,EACD,IAAI;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAG,QAAQ;AAET,QAAM,aAAa,MAAM,MAAM;AAC/B,QAAM,KAAK,UAAU;AAErB,QAAM,eAAe,QAAQ,eAAe,YAAY,IAAI;AAC5D,QAAM,WACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,GAAG,gBAAgB,UAAU,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAGF,QAAM,UACJ,qBAAC,SAAI,WAAW,GAAG,wCAAwC,gBAAgB,GACzE;AAAA,yBAAC,SAAI,WAAU,uBACb;AAAA,2BAAC,SAAI,WAAU,qCACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,WAAW;AAAA,cACT;AAAA,cACA,WAAW,kCAAkC;AAAA,YAC/C;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACC,WACC,oBAAC,UAAK,WAAU,uDAAuD,oBAAS,IAC9E;AAAA,QACH,QAAQ,oBAAC,UAAK,WAAU,wBAAwB,iBAAM,IAAU;AAAA,SACnE;AAAA,MACC,cACC,oBAAC,OAAE,WAAU,2CAA2C,uBAAY,IAClE;AAAA,OACN;AAAA,IACC,OAAO,oBAAC,SAAI,WAAU,QAAQ,gBAAK,IAAS;AAAA,KAC/C;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,eAAe,gBAAgB;AAAA,QAC/B;AAAA,MACF;AAAA,MAEC,iBACC,iCACG;AAAA;AAAA,QACA;AAAA,SACH,IAEA,iCACG;AAAA;AAAA,QACA;AAAA,SACH;AAAA;AAAA,EAEJ;AAEJ,CAAC;AACD,YAAY,cAAc;",
6
+ "names": []
7
+ }
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { cn } from "@open-mercato/shared/lib/utils";
@@ -55,7 +56,9 @@ const Switch = React.forwardRef(
55
56
  onKeyDown: handleKeyDown,
56
57
  disabled,
57
58
  className: cn(
58
- "inline-flex h-6 w-11 items-center rounded-full border border-transparent bg-input/60 transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary",
59
+ "group relative inline-flex h-5 w-8 shrink-0 cursor-pointer items-center justify-center rounded-full bg-transparent p-0",
60
+ "focus-visible:outline-none focus-visible:shadow-focus",
61
+ "disabled:cursor-not-allowed disabled:opacity-60",
59
62
  className
60
63
  ),
61
64
  ...props,
@@ -64,8 +67,19 @@ const Switch = React.forwardRef(
64
67
  {
65
68
  "aria-hidden": true,
66
69
  className: cn(
67
- "inline-block size-5 translate-x-0 rounded-full bg-background shadow transition-transform duration-200",
68
- currentChecked ? "translate-x-5" : "translate-x-0"
70
+ "pointer-events-none flex h-4 w-7 items-center rounded-full px-0.5 transition-colors duration-150",
71
+ "bg-border group-hover:bg-muted-foreground/30",
72
+ "group-data-[state=checked]:bg-accent-indigo group-data-[state=checked]:group-hover:bg-accent-indigo/85"
73
+ ),
74
+ children: /* @__PURE__ */ jsx(
75
+ "span",
76
+ {
77
+ className: cn(
78
+ "block size-3 rounded-full bg-white transition-transform duration-200",
79
+ "shadow-[0_1px_2px_rgba(10,13,20,0.10),0_0_0_0.5px_rgba(10,13,20,0.04)]",
80
+ currentChecked ? "translate-x-3" : "translate-x-0"
81
+ )
82
+ }
69
83
  )
70
84
  }
71
85
  )
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/primitives/switch.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype SwitchProps = {\n checked?: boolean\n defaultChecked?: boolean\n onCheckedChange?: (checked: boolean) => void\n} & Omit<React.ComponentProps<'button'>, 'onChange'>\n\nexport const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(\n ({ checked, defaultChecked, onCheckedChange, disabled, className, onClick, onKeyDown, ...props }, ref) => {\n const isControlled = typeof checked === 'boolean'\n const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultChecked ?? false)\n\n const currentChecked = isControlled ? checked : uncontrolledValue\n\n const toggle = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => {\n event.preventDefault()\n if (disabled) {\n return\n }\n const next = !currentChecked\n if (!isControlled) {\n setUncontrolledValue(next)\n }\n onCheckedChange?.(next)\n },\n [currentChecked, disabled, isControlled, onCheckedChange]\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n toggle(event)\n }\n },\n [onClick, toggle]\n )\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) {\n return\n }\n if (event.key === ' ' || event.key === 'Enter') {\n toggle(event)\n }\n },\n [onKeyDown, toggle]\n )\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n data-state={currentChecked ? 'checked' : 'unchecked'}\n data-disabled={disabled ? '' : undefined}\n ref={ref}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n className={cn(\n 'inline-flex h-6 w-11 items-center rounded-full border border-transparent bg-input/60 transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary',\n className\n )}\n {...props}\n >\n <span\n aria-hidden\n className={cn(\n 'inline-block size-5 translate-x-0 rounded-full bg-background shadow transition-transform duration-200',\n currentChecked ? 'translate-x-5' : 'translate-x-0'\n )}\n />\n </button>\n )\n }\n)\n\nSwitch.displayName = 'Switch'\n"],
5
- "mappings": "AAyEQ;AAzER,YAAY,WAAW;AAEvB,SAAS,UAAU;AAQZ,MAAM,SAAS,MAAM;AAAA,EAC1B,CAAC,EAAE,SAAS,gBAAgB,iBAAiB,UAAU,WAAW,SAAS,WAAW,GAAG,MAAM,GAAG,QAAQ;AACxG,UAAM,eAAe,OAAO,YAAY;AACxC,UAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAS,kBAAkB,KAAK;AAExF,UAAM,iBAAiB,eAAe,UAAU;AAEhD,UAAM,SAAS,MAAM;AAAA,MACnB,CAAC,UAAwF;AACvF,cAAM,eAAe;AACrB,YAAI,UAAU;AACZ;AAAA,QACF;AACA,cAAM,OAAO,CAAC;AACd,YAAI,CAAC,cAAc;AACjB,+BAAqB,IAAI;AAAA,QAC3B;AACA,0BAAkB,IAAI;AAAA,MACxB;AAAA,MACA,CAAC,gBAAgB,UAAU,cAAc,eAAe;AAAA,IAC1D;AAEA,UAAM,cAAc,MAAM;AAAA,MACxB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,CAAC,MAAM,kBAAkB;AAC3B,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,CAAC,SAAS,MAAM;AAAA,IAClB;AAEA,UAAM,gBAAgB,MAAM;AAAA,MAC1B,CAAC,UAAkD;AACjD,oBAAY,KAAK;AACjB,YAAI,MAAM,kBAAkB;AAC1B;AAAA,QACF;AACA,YAAI,MAAM,QAAQ,OAAO,MAAM,QAAQ,SAAS;AAC9C,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,IACpB;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,gBAAc;AAAA,QACd,iBAAe;AAAA,QACf,cAAY,iBAAiB,YAAY;AAAA,QACzC,iBAAe,WAAW,KAAK;AAAA,QAC/B;AAAA,QACA,SAAS;AAAA,QACT,WAAW;AAAA,QACX;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,WAAW;AAAA,cACT;AAAA,cACA,iBAAiB,kBAAkB;AAAA,YACrC;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype SwitchProps = {\n checked?: boolean\n defaultChecked?: boolean\n onCheckedChange?: (checked: boolean) => void\n} & Omit<React.ComponentProps<'button'>, 'onChange'>\n\nexport const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(\n ({ checked, defaultChecked, onCheckedChange, disabled, className, onClick, onKeyDown, ...props }, ref) => {\n const isControlled = typeof checked === 'boolean'\n const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultChecked ?? false)\n\n const currentChecked = isControlled ? checked : uncontrolledValue\n\n const toggle = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => {\n event.preventDefault()\n if (disabled) {\n return\n }\n const next = !currentChecked\n if (!isControlled) {\n setUncontrolledValue(next)\n }\n onCheckedChange?.(next)\n },\n [currentChecked, disabled, isControlled, onCheckedChange]\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n toggle(event)\n }\n },\n [onClick, toggle]\n )\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented) {\n return\n }\n if (event.key === ' ' || event.key === 'Enter') {\n toggle(event)\n }\n },\n [onKeyDown, toggle]\n )\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={currentChecked}\n aria-disabled={disabled}\n data-state={currentChecked ? 'checked' : 'unchecked'}\n data-disabled={disabled ? '' : undefined}\n ref={ref}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n className={cn(\n 'group relative inline-flex h-5 w-8 shrink-0 cursor-pointer items-center justify-center rounded-full bg-transparent p-0',\n 'focus-visible:outline-none focus-visible:shadow-focus',\n 'disabled:cursor-not-allowed disabled:opacity-60',\n className\n )}\n {...props}\n >\n <span\n aria-hidden\n className={cn(\n 'pointer-events-none flex h-4 w-7 items-center rounded-full px-0.5 transition-colors duration-150',\n 'bg-border group-hover:bg-muted-foreground/30',\n 'group-data-[state=checked]:bg-accent-indigo group-data-[state=checked]:group-hover:bg-accent-indigo/85'\n )}\n >\n <span\n className={cn(\n 'block size-3 rounded-full bg-white transition-transform duration-200',\n 'shadow-[0_1px_2px_rgba(10,13,20,0.10),0_0_0_0.5px_rgba(10,13,20,0.04)]',\n currentChecked ? 'translate-x-3' : 'translate-x-0'\n )}\n />\n </span>\n </button>\n )\n }\n)\n\nSwitch.displayName = 'Switch'\n"],
5
+ "mappings": ";AAqFU;AAnFV,YAAY,WAAW;AAEvB,SAAS,UAAU;AAQZ,MAAM,SAAS,MAAM;AAAA,EAC1B,CAAC,EAAE,SAAS,gBAAgB,iBAAiB,UAAU,WAAW,SAAS,WAAW,GAAG,MAAM,GAAG,QAAQ;AACxG,UAAM,eAAe,OAAO,YAAY;AACxC,UAAM,CAAC,mBAAmB,oBAAoB,IAAI,MAAM,SAAS,kBAAkB,KAAK;AAExF,UAAM,iBAAiB,eAAe,UAAU;AAEhD,UAAM,SAAS,MAAM;AAAA,MACnB,CAAC,UAAwF;AACvF,cAAM,eAAe;AACrB,YAAI,UAAU;AACZ;AAAA,QACF;AACA,cAAM,OAAO,CAAC;AACd,YAAI,CAAC,cAAc;AACjB,+BAAqB,IAAI;AAAA,QAC3B;AACA,0BAAkB,IAAI;AAAA,MACxB;AAAA,MACA,CAAC,gBAAgB,UAAU,cAAc,eAAe;AAAA,IAC1D;AAEA,UAAM,cAAc,MAAM;AAAA,MACxB,CAAC,UAA+C;AAC9C,kBAAU,KAAK;AACf,YAAI,CAAC,MAAM,kBAAkB;AAC3B,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,CAAC,SAAS,MAAM;AAAA,IAClB;AAEA,UAAM,gBAAgB,MAAM;AAAA,MAC1B,CAAC,UAAkD;AACjD,oBAAY,KAAK;AACjB,YAAI,MAAM,kBAAkB;AAC1B;AAAA,QACF;AACA,YAAI,MAAM,QAAQ,OAAO,MAAM,QAAQ,SAAS;AAC9C,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,IACpB;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,gBAAc;AAAA,QACd,iBAAe;AAAA,QACf,cAAY,iBAAiB,YAAY;AAAA,QACzC,iBAAe,WAAW,KAAK;AAAA,QAC/B;AAAA,QACA,SAAS;AAAA,QACT,WAAW;AAAA,QACX;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW;AAAA,kBACT;AAAA,kBACA;AAAA,kBACA,iBAAiB,kBAAkB;AAAA,gBACrC;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;",
6
6
  "names": []
7
7
  }
@@ -1,18 +1,54 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { cn } from "@open-mercato/shared/lib/utils";
5
+ const baseTextareaClass = "flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-colors placeholder:text-muted-foreground outline-none focus-visible:outline-none focus-visible:shadow-focus focus-visible:border-foreground hover:bg-muted/40 disabled:cursor-not-allowed disabled:bg-bg-disabled disabled:border-border-disabled disabled:shadow-none disabled:hover:bg-bg-disabled aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive resize-y min-h-[80px]";
4
6
  const Textarea = React.forwardRef(
5
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
6
- "textarea",
7
- {
8
- ref,
9
- className: cn(
10
- "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
11
- className
12
- ),
13
- ...props
14
- }
15
- )
7
+ ({ className, showCount, wrapperClassName, value, defaultValue, maxLength, onChange, ...props }, ref) => {
8
+ const [internalValue, setInternalValue] = React.useState(
9
+ typeof defaultValue === "string" ? defaultValue : typeof value === "string" ? value : ""
10
+ );
11
+ const isControlled = value !== void 0;
12
+ const currentValue = isControlled ? String(value ?? "") : internalValue;
13
+ const handleChange = React.useCallback(
14
+ (event) => {
15
+ if (!isControlled) setInternalValue(event.target.value);
16
+ onChange?.(event);
17
+ },
18
+ [isControlled, onChange]
19
+ );
20
+ const textarea = /* @__PURE__ */ jsx(
21
+ "textarea",
22
+ {
23
+ ref,
24
+ value,
25
+ defaultValue: isControlled ? void 0 : defaultValue,
26
+ maxLength,
27
+ onChange: handleChange,
28
+ className: cn(baseTextareaClass, className),
29
+ ...props
30
+ }
31
+ );
32
+ if (!showCount) return textarea;
33
+ const length = currentValue.length;
34
+ const max = typeof maxLength === "number" ? maxLength : void 0;
35
+ const isError = max != null && length > max;
36
+ const isDisabled = props.disabled;
37
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1", wrapperClassName), children: [
38
+ textarea,
39
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
40
+ "span",
41
+ {
42
+ className: cn(
43
+ "text-overline uppercase",
44
+ isDisabled ? "text-text-disabled" : isError ? "text-destructive" : "text-muted-foreground"
45
+ ),
46
+ "aria-live": "polite",
47
+ children: max != null ? `${length}/${max}` : `${length}`
48
+ }
49
+ ) })
50
+ ] });
51
+ }
16
52
  );
17
53
  Textarea.displayName = "Textarea";
18
54
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/primitives/textarea.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n className={cn(\n 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n {...props}\n />\n )\n)\n\nTextarea.displayName = 'Textarea'\n"],
5
- "mappings": "AAQI;AARJ,YAAY,WAAW;AAEvB,SAAS,UAAU;AAIZ,MAAM,WAAW,MAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QACxB;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,cAAc;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\n\nimport { cn } from '@open-mercato/shared/lib/utils'\n\nconst baseTextareaClass =\n 'flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-colors placeholder:text-muted-foreground outline-none focus-visible:outline-none focus-visible:shadow-focus focus-visible:border-foreground hover:bg-muted/40 disabled:cursor-not-allowed disabled:bg-bg-disabled disabled:border-border-disabled disabled:shadow-none disabled:hover:bg-bg-disabled aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive resize-y min-h-[80px]'\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n /** Show character counter (`current/max`) below the textarea. Requires `maxLength`. */\n showCount?: boolean\n /** Optional className applied to the outer wrapper (when counter is shown). */\n wrapperClassName?: string\n}\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, showCount, wrapperClassName, value, defaultValue, maxLength, onChange, ...props }, ref) => {\n const [internalValue, setInternalValue] = React.useState<string>(\n typeof defaultValue === 'string' ? defaultValue : typeof value === 'string' ? value : ''\n )\n\n const isControlled = value !== undefined\n const currentValue = isControlled ? String(value ?? '') : internalValue\n\n const handleChange = React.useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) setInternalValue(event.target.value)\n onChange?.(event)\n },\n [isControlled, onChange]\n )\n\n const textarea = (\n <textarea\n ref={ref}\n value={value}\n defaultValue={isControlled ? undefined : defaultValue}\n maxLength={maxLength}\n onChange={handleChange}\n className={cn(baseTextareaClass, className)}\n {...props}\n />\n )\n\n if (!showCount) return textarea\n\n const length = currentValue.length\n const max = typeof maxLength === 'number' ? maxLength : undefined\n const isError = max != null && length > max\n const isDisabled = props.disabled\n\n return (\n <div className={cn('flex flex-col gap-1', wrapperClassName)}>\n {textarea}\n <div className=\"flex justify-end\">\n <span\n className={cn(\n 'text-overline uppercase',\n isDisabled\n ? 'text-text-disabled'\n : isError\n ? 'text-destructive'\n : 'text-muted-foreground'\n )}\n aria-live=\"polite\"\n >\n {max != null ? `${length}/${max}` : `${length}`}\n </span>\n </div>\n </div>\n )\n }\n)\n\nTextarea.displayName = 'Textarea'\n"],
5
+ "mappings": ";AAkCM,cAmBA,YAnBA;AAhCN,YAAY,WAAW;AAEvB,SAAS,UAAU;AAEnB,MAAM,oBACJ;AASK,MAAM,WAAW,MAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,WAAW,kBAAkB,OAAO,cAAc,WAAW,UAAU,GAAG,MAAM,GAAG,QAAQ;AACvG,UAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM;AAAA,MAC9C,OAAO,iBAAiB,WAAW,eAAe,OAAO,UAAU,WAAW,QAAQ;AAAA,IACxF;AAEA,UAAM,eAAe,UAAU;AAC/B,UAAM,eAAe,eAAe,OAAO,SAAS,EAAE,IAAI;AAE1D,UAAM,eAAe,MAAM;AAAA,MACzB,CAAC,UAAkD;AACjD,YAAI,CAAC,aAAc,kBAAiB,MAAM,OAAO,KAAK;AACtD,mBAAW,KAAK;AAAA,MAClB;AAAA,MACA,CAAC,cAAc,QAAQ;AAAA,IACzB;AAEA,UAAM,WACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,cAAc,eAAe,SAAY;AAAA,QACzC;AAAA,QACA,UAAU;AAAA,QACV,WAAW,GAAG,mBAAmB,SAAS;AAAA,QACzC,GAAG;AAAA;AAAA,IACN;AAGF,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,SAAS,aAAa;AAC5B,UAAM,MAAM,OAAO,cAAc,WAAW,YAAY;AACxD,UAAM,UAAU,OAAO,QAAQ,SAAS;AACxC,UAAM,aAAa,MAAM;AAEzB,WACE,qBAAC,SAAI,WAAW,GAAG,uBAAuB,gBAAgB,GACvD;AAAA;AAAA,MACD,oBAAC,SAAI,WAAU,oBACb;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,aACI,uBACA,UACE,qBACA;AAAA,UACR;AAAA,UACA,aAAU;AAAA,UAET,iBAAO,OAAO,GAAG,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM;AAAA;AAAA,MAC/C,GACF;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;",
6
6
  "names": []
7
7
  }