@7onic-ui/react 0.3.9 → 0.3.11

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 (170) hide show
  1. package/README.md +2 -2
  2. package/dist/chart.mjs +3 -9
  3. package/dist/chart.mjs.map +1 -1
  4. package/dist/chunk-2WIIXHOV.mjs +148 -0
  5. package/dist/chunk-2WIIXHOV.mjs.map +1 -0
  6. package/dist/chunk-53MIUPSY.mjs +13 -0
  7. package/dist/chunk-53MIUPSY.mjs.map +1 -0
  8. package/dist/chunk-BN5BEA3V.mjs +195 -0
  9. package/dist/chunk-BN5BEA3V.mjs.map +1 -0
  10. package/dist/chunk-C5D3VRNJ.mjs +504 -0
  11. package/dist/chunk-C5D3VRNJ.mjs.map +1 -0
  12. package/dist/chunk-COW3B62M.mjs +214 -0
  13. package/dist/chunk-COW3B62M.mjs.map +1 -0
  14. package/dist/chunk-CTH6SN5Y.mjs +114 -0
  15. package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
  16. package/dist/chunk-D3NTQNDW.mjs +440 -0
  17. package/dist/chunk-D3NTQNDW.mjs.map +1 -0
  18. package/dist/chunk-DDRYEJBJ.mjs +164 -0
  19. package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
  20. package/dist/chunk-DJAEXCRU.mjs +190 -0
  21. package/dist/chunk-DJAEXCRU.mjs.map +1 -0
  22. package/dist/chunk-DYYQOHQR.mjs +214 -0
  23. package/dist/chunk-DYYQOHQR.mjs.map +1 -0
  24. package/dist/chunk-EG2GTK65.mjs +443 -0
  25. package/dist/chunk-EG2GTK65.mjs.map +1 -0
  26. package/dist/chunk-FHUAH6AJ.mjs +93 -0
  27. package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
  28. package/dist/chunk-GD4YE5AE.mjs +209 -0
  29. package/dist/chunk-GD4YE5AE.mjs.map +1 -0
  30. package/dist/chunk-HHX4GABH.mjs +129 -0
  31. package/dist/chunk-HHX4GABH.mjs.map +1 -0
  32. package/dist/chunk-HS2VRYSX.mjs +148 -0
  33. package/dist/chunk-HS2VRYSX.mjs.map +1 -0
  34. package/dist/chunk-IHHI3LIN.mjs +155 -0
  35. package/dist/chunk-IHHI3LIN.mjs.map +1 -0
  36. package/dist/chunk-IJ2FZ3L5.mjs +159 -0
  37. package/dist/chunk-IJ2FZ3L5.mjs.map +1 -0
  38. package/dist/chunk-IPCIC2BI.mjs +148 -0
  39. package/dist/chunk-IPCIC2BI.mjs.map +1 -0
  40. package/dist/chunk-JCJEVXER.mjs +170 -0
  41. package/dist/chunk-JCJEVXER.mjs.map +1 -0
  42. package/dist/chunk-KBPYAMGS.mjs +157 -0
  43. package/dist/chunk-KBPYAMGS.mjs.map +1 -0
  44. package/dist/chunk-L55ABE4H.mjs +283 -0
  45. package/dist/chunk-L55ABE4H.mjs.map +1 -0
  46. package/dist/chunk-LJJ6K4IU.mjs +318 -0
  47. package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
  48. package/dist/chunk-ND6TUVP2.mjs +148 -0
  49. package/dist/chunk-ND6TUVP2.mjs.map +1 -0
  50. package/dist/chunk-NWFMJWGX.mjs +165 -0
  51. package/dist/chunk-NWFMJWGX.mjs.map +1 -0
  52. package/dist/chunk-PTAPPOKU.mjs +117 -0
  53. package/dist/chunk-PTAPPOKU.mjs.map +1 -0
  54. package/dist/chunk-PVTBM7V7.mjs +316 -0
  55. package/dist/chunk-PVTBM7V7.mjs.map +1 -0
  56. package/dist/chunk-Q5WVLK2L.mjs +77 -0
  57. package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
  58. package/dist/chunk-R7FJEO4K.mjs +252 -0
  59. package/dist/chunk-R7FJEO4K.mjs.map +1 -0
  60. package/dist/chunk-RKSB2N5L.mjs +206 -0
  61. package/dist/chunk-RKSB2N5L.mjs.map +1 -0
  62. package/dist/chunk-S4DGVKBK.mjs +151 -0
  63. package/dist/chunk-S4DGVKBK.mjs.map +1 -0
  64. package/dist/chunk-S4T4PU7F.mjs +114 -0
  65. package/dist/chunk-S4T4PU7F.mjs.map +1 -0
  66. package/dist/chunk-SDDAGZWA.mjs +224 -0
  67. package/dist/chunk-SDDAGZWA.mjs.map +1 -0
  68. package/dist/chunk-SZPZOGPC.mjs +394 -0
  69. package/dist/chunk-SZPZOGPC.mjs.map +1 -0
  70. package/dist/chunk-T5A4APEL.mjs +140 -0
  71. package/dist/chunk-T5A4APEL.mjs.map +1 -0
  72. package/dist/chunk-V5UFWYFI.mjs +255 -0
  73. package/dist/chunk-V5UFWYFI.mjs.map +1 -0
  74. package/dist/chunk-W6YNEU53.mjs +175 -0
  75. package/dist/chunk-W6YNEU53.mjs.map +1 -0
  76. package/dist/chunk-XK52LYR4.mjs +182 -0
  77. package/dist/chunk-XK52LYR4.mjs.map +1 -0
  78. package/dist/chunk-YIAH6KHV.mjs +164 -0
  79. package/dist/chunk-YIAH6KHV.mjs.map +1 -0
  80. package/dist/chunk-YZ7HHFKA.mjs +375 -0
  81. package/dist/chunk-YZ7HHFKA.mjs.map +1 -0
  82. package/dist/chunk-ZDRUTJ4T.mjs +119 -0
  83. package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
  84. package/dist/components/accordion.mjs +19 -0
  85. package/dist/components/accordion.mjs.map +1 -0
  86. package/dist/components/alert.mjs +15 -0
  87. package/dist/components/alert.mjs.map +1 -0
  88. package/dist/components/avatar.mjs +23 -0
  89. package/dist/components/avatar.mjs.map +1 -0
  90. package/dist/components/badge.mjs +11 -0
  91. package/dist/components/badge.mjs.map +1 -0
  92. package/dist/components/breadcrumb.mjs +23 -0
  93. package/dist/components/breadcrumb.mjs.map +1 -0
  94. package/dist/components/button-group.mjs +11 -0
  95. package/dist/components/button-group.mjs.map +1 -0
  96. package/dist/components/button.mjs +12 -0
  97. package/dist/components/button.mjs.map +1 -0
  98. package/dist/components/card.mjs +25 -0
  99. package/dist/components/card.mjs.map +1 -0
  100. package/dist/components/chat-input.mjs +15 -0
  101. package/dist/components/chat-input.mjs.map +1 -0
  102. package/dist/components/chat-message.mjs +17 -0
  103. package/dist/components/chat-message.mjs.map +1 -0
  104. package/dist/components/checkbox.mjs +12 -0
  105. package/dist/components/checkbox.mjs.map +1 -0
  106. package/dist/components/divider.mjs +11 -0
  107. package/dist/components/divider.mjs.map +1 -0
  108. package/dist/components/drawer.mjs +33 -0
  109. package/dist/components/drawer.mjs.map +1 -0
  110. package/dist/components/dropdown.mjs +35 -0
  111. package/dist/components/dropdown.mjs.map +1 -0
  112. package/dist/components/field.mjs +19 -0
  113. package/dist/components/field.mjs.map +1 -0
  114. package/dist/components/icon-button.mjs +12 -0
  115. package/dist/components/icon-button.mjs.map +1 -0
  116. package/dist/components/input.mjs +12 -0
  117. package/dist/components/input.mjs.map +1 -0
  118. package/dist/components/metric-card.mjs +23 -0
  119. package/dist/components/metric-card.mjs.map +1 -0
  120. package/dist/components/modal.mjs +57 -0
  121. package/dist/components/modal.mjs.map +1 -0
  122. package/dist/components/navigation-menu.mjs +27 -0
  123. package/dist/components/navigation-menu.mjs.map +1 -0
  124. package/dist/components/pagination.mjs +33 -0
  125. package/dist/components/pagination.mjs.map +1 -0
  126. package/dist/components/popover.mjs +23 -0
  127. package/dist/components/popover.mjs.map +1 -0
  128. package/dist/components/progress.mjs +11 -0
  129. package/dist/components/progress.mjs.map +1 -0
  130. package/dist/components/quick-reply.mjs +15 -0
  131. package/dist/components/quick-reply.mjs.map +1 -0
  132. package/dist/components/radio-group.mjs +16 -0
  133. package/dist/components/radio-group.mjs.map +1 -0
  134. package/dist/components/segmented.mjs +15 -0
  135. package/dist/components/segmented.mjs.map +1 -0
  136. package/dist/components/select.mjs +24 -0
  137. package/dist/components/select.mjs.map +1 -0
  138. package/dist/components/skeleton.mjs +11 -0
  139. package/dist/components/skeleton.mjs.map +1 -0
  140. package/dist/components/slider.mjs +12 -0
  141. package/dist/components/slider.mjs.map +1 -0
  142. package/dist/components/spinner.mjs +11 -0
  143. package/dist/components/spinner.mjs.map +1 -0
  144. package/dist/components/switch.mjs +12 -0
  145. package/dist/components/switch.mjs.map +1 -0
  146. package/dist/components/table.mjs +23 -0
  147. package/dist/components/table.mjs.map +1 -0
  148. package/dist/components/tabs.mjs +19 -0
  149. package/dist/components/tabs.mjs.map +1 -0
  150. package/dist/components/textarea.mjs +12 -0
  151. package/dist/components/textarea.mjs.map +1 -0
  152. package/dist/components/toast.mjs +13 -0
  153. package/dist/components/toast.mjs.map +1 -0
  154. package/dist/components/toggle-group.mjs +15 -0
  155. package/dist/components/toggle-group.mjs.map +1 -0
  156. package/dist/components/toggle.mjs +11 -0
  157. package/dist/components/toggle.mjs.map +1 -0
  158. package/dist/components/tooltip.mjs +21 -0
  159. package/dist/components/tooltip.mjs.map +1 -0
  160. package/dist/components/typing-indicator.mjs +11 -0
  161. package/dist/components/typing-indicator.mjs.map +1 -0
  162. package/dist/index.d.ts +11 -2
  163. package/dist/index.js +95 -21
  164. package/dist/index.js.map +1 -1
  165. package/dist/index.mjs +296 -7536
  166. package/dist/index.mjs.map +1 -1
  167. package/llms.txt +50 -32
  168. package/package.json +14 -14
  169. package/dist/chart.d.mts +0 -147
  170. package/dist/index.d.mts +0 -1535
@@ -0,0 +1,151 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/toggle-group.tsx
7
+ import * as React from "react";
8
+ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
9
+ import { cva } from "class-variance-authority";
10
+ var toggleGroupVariants = cva(
11
+ "inline-flex items-center justify-center",
12
+ {
13
+ variants: {
14
+ orientation: {
15
+ horizontal: "flex-row",
16
+ vertical: "flex-col"
17
+ }
18
+ },
19
+ defaultVariants: {
20
+ orientation: "horizontal"
21
+ }
22
+ }
23
+ );
24
+ var toggleGroupItemVariants = cva(
25
+ "inline-flex items-center justify-center text-sm text-text-muted transition-all duration-micro focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-50",
26
+ {
27
+ variants: {
28
+ variant: {
29
+ default: "bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground",
30
+ outline: "border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground"
31
+ },
32
+ fontWeight: {
33
+ normal: "font-normal",
34
+ semibold: "font-semibold"
35
+ },
36
+ size: {
37
+ xs: "h-7 px-2.5 text-xs gap-1",
38
+ // 28px height, 10px paddingX, 12px font
39
+ sm: "h-8 px-3 text-sm gap-2",
40
+ // 32px height, 12px paddingX, 13px font
41
+ md: "h-9 px-3.5 text-md gap-2",
42
+ // 36px height, 14px paddingX, 14px font
43
+ default: "h-10 px-4 text-md gap-2",
44
+ // 40px height, 16px paddingX, 14px font
45
+ lg: "h-12 px-6 text-base gap-2"
46
+ // 48px height, 24px paddingX, 16px font
47
+ },
48
+ radius: {
49
+ none: "rounded-none",
50
+ sm: "rounded-sm",
51
+ base: "rounded",
52
+ default: "rounded-md",
53
+ lg: "rounded-lg",
54
+ xl: "rounded-xl",
55
+ "2xl": "rounded-2xl",
56
+ "3xl": "rounded-3xl",
57
+ full: "rounded-full"
58
+ }
59
+ },
60
+ defaultVariants: {
61
+ variant: "default",
62
+ size: "default",
63
+ radius: "default",
64
+ fontWeight: "normal"
65
+ }
66
+ }
67
+ );
68
+ var ToggleGroupContext = React.createContext({
69
+ variant: "default",
70
+ size: "default",
71
+ radius: "default",
72
+ fontWeight: "normal"
73
+ });
74
+ var ToggleGroup = React.forwardRef(({ className, orientation, variant, size, radius, fontWeight, children, ...props }, ref) => /* @__PURE__ */ React.createElement(
75
+ ToggleGroupPrimitive.Root,
76
+ {
77
+ ref,
78
+ className: cn(
79
+ toggleGroupVariants({ orientation }),
80
+ // Attached style for horizontal
81
+ orientation !== "vertical" && [
82
+ "[&>*:not(:first-child)]:rounded-l-none",
83
+ "[&>*:not(:last-child)]:rounded-r-none",
84
+ "[&>*:not(:first-child)]:-ml-px",
85
+ "[&>*]:relative",
86
+ "[&>*:hover]:z-10",
87
+ "[&>*:focus-visible]:z-10",
88
+ "[&>*:active]:scale-none"
89
+ ],
90
+ // Attached style for vertical
91
+ orientation === "vertical" && [
92
+ "[&>*:not(:first-child)]:rounded-t-none",
93
+ "[&>*:not(:last-child)]:rounded-b-none",
94
+ "[&>*:not(:first-child)]:-mt-px",
95
+ "[&>*]:relative",
96
+ "[&>*]:w-full",
97
+ "[&>*:hover]:z-10",
98
+ "[&>*:focus-visible]:z-10",
99
+ "[&>*:active]:scale-none"
100
+ ],
101
+ className
102
+ ),
103
+ orientation,
104
+ ...props
105
+ },
106
+ /* @__PURE__ */ React.createElement(ToggleGroupContext.Provider, { value: { variant, size, radius, fontWeight } }, children)
107
+ ));
108
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
109
+ var iconSizeClasses = {
110
+ xs: "[&>svg]:icon-xs",
111
+ // 14px
112
+ sm: "[&>svg]:icon-xs",
113
+ // 14px
114
+ md: "[&>svg]:icon-sm",
115
+ // 16px
116
+ default: "[&>svg]:icon-sm",
117
+ // 16px
118
+ lg: "[&>svg]:icon-sm"
119
+ // 16px
120
+ };
121
+ var ToggleGroupItem = React.forwardRef(({ className, variant, size, radius, fontWeight, children, ...props }, ref) => {
122
+ const context = React.useContext(ToggleGroupContext);
123
+ const resolvedSize = size || context.size || "default";
124
+ return /* @__PURE__ */ React.createElement(
125
+ ToggleGroupPrimitive.Item,
126
+ {
127
+ ref,
128
+ className: cn(
129
+ toggleGroupItemVariants({
130
+ variant: variant || context.variant,
131
+ size: resolvedSize,
132
+ radius: radius || context.radius,
133
+ fontWeight: fontWeight || context.fontWeight
134
+ }),
135
+ iconSizeClasses[resolvedSize],
136
+ className
137
+ ),
138
+ ...props
139
+ },
140
+ children
141
+ );
142
+ });
143
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
144
+
145
+ export {
146
+ toggleGroupVariants,
147
+ toggleGroupItemVariants,
148
+ ToggleGroup,
149
+ ToggleGroupItem
150
+ };
151
+ //# sourceMappingURL=chunk-S4DGVKBK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/toggle-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\nconst toggleGroupVariants = cva(\n 'inline-flex items-center justify-center',\n {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n)\n\nconst toggleGroupItemVariants = cva(\n 'inline-flex items-center justify-center text-sm text-text-muted transition-all duration-micro focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n outline: 'border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n },\n fontWeight: {\n normal: 'font-normal',\n semibold: 'font-semibold',\n },\n size: {\n xs: 'h-7 px-2.5 text-xs gap-1', // 28px height, 10px paddingX, 12px font\n sm: 'h-8 px-3 text-sm gap-2', // 32px height, 12px paddingX, 13px font\n md: 'h-9 px-3.5 text-md gap-2', // 36px height, 14px paddingX, 14px font\n default: 'h-10 px-4 text-md gap-2', // 40px height, 16px paddingX, 14px font\n lg: 'h-12 px-6 text-base gap-2', // 48px height, 24px paddingX, 16px font\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleGroupItemVariants>\n>({\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n})\n\ntype ToggleGroupSingleProps = {\n type: 'single'\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n}\n\ntype ToggleGroupMultipleProps = {\n type: 'multiple'\n value?: string[]\n defaultValue?: string[]\n onValueChange?: (value: string[]) => void\n}\n\ntype ToggleGroupBaseProps = Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'defaultValue' | 'dir'\n> & {\n disabled?: boolean\n rovingFocus?: boolean\n orientation?: 'horizontal' | 'vertical'\n dir?: 'ltr' | 'rtl'\n loop?: boolean\n children?: React.ReactNode\n}\n\nexport type ToggleGroupProps = ToggleGroupBaseProps &\n VariantProps<typeof toggleGroupVariants> &\n VariantProps<typeof toggleGroupItemVariants> &\n (ToggleGroupSingleProps | ToggleGroupMultipleProps)\n\nconst ToggleGroup = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Root>,\n ToggleGroupProps\n>(({ className, orientation, variant, size, radius, fontWeight, children, ...props }, ref) => (\n <ToggleGroupPrimitive.Root\n ref={ref}\n className={cn(\n toggleGroupVariants({ orientation }),\n // Attached style for horizontal\n orientation !== 'vertical' && [\n '[&>*:not(:first-child)]:rounded-l-none',\n '[&>*:not(:last-child)]:rounded-r-none',\n '[&>*:not(:first-child)]:-ml-px',\n '[&>*]:relative',\n '[&>*:hover]:z-10',\n '[&>*:focus-visible]:z-10',\n '[&>*:active]:scale-none',\n ],\n // Attached style for vertical\n orientation === 'vertical' && [\n '[&>*:not(:first-child)]:rounded-t-none',\n '[&>*:not(:last-child)]:rounded-b-none',\n '[&>*:not(:first-child)]:-mt-px',\n '[&>*]:relative',\n '[&>*]:w-full',\n '[&>*:hover]:z-10',\n '[&>*:focus-visible]:z-10',\n '[&>*:active]:scale-none',\n ],\n className\n )}\n orientation={orientation}\n {...(props as React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root>)}\n >\n <ToggleGroupContext.Provider value={{ variant, size, radius, fontWeight }}>\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n))\nToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName\n\nexport interface ToggleGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item>,\n Omit<VariantProps<typeof toggleGroupItemVariants>, 'fontWeight'> {\n fontWeight?: 'normal' | 'semibold'\n}\n\n// Icon size for toggle group (5-step scale, Icon+Text mode)\n// xs~sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n xs: '[&>svg]:icon-xs', // 14px\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nconst ToggleGroupItem = React.forwardRef<\n React.ElementRef<typeof ToggleGroupPrimitive.Item>,\n ToggleGroupItemProps\n>(({ className, variant, size, radius, fontWeight, children, ...props }, ref) => {\n const context = React.useContext(ToggleGroupContext)\n const resolvedSize = size || context.size || 'default'\n\n return (\n <ToggleGroupPrimitive.Item\n ref={ref}\n className={cn(\n toggleGroupItemVariants({\n variant: variant || context.variant,\n size: resolvedSize,\n radius: radius || context.radius,\n fontWeight: fontWeight || context.fontWeight,\n }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n})\nToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName\n\nexport { ToggleGroup, ToggleGroupItem, toggleGroupVariants, toggleGroupItemVariants }\n"],"mappings":"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","names":[]}
@@ -0,0 +1,114 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/typing-indicator.tsx
7
+ import * as React from "react";
8
+ import { cva } from "class-variance-authority";
9
+ var DOT_SIZES = { sm: 4, default: 6, lg: 8 };
10
+ var DOT_GAP = { sm: 3, default: 4, lg: 5 };
11
+ var SPEED_MS = { slow: 1600, default: 1100, fast: 700 };
12
+ var DOT_COUNT = 3;
13
+ var bgColorMap = {
14
+ default: "bg-foreground",
15
+ primary: "bg-primary",
16
+ muted: "bg-text-subtle"
17
+ };
18
+ var typingIndicatorVariants = cva(
19
+ "inline-flex items-center",
20
+ {
21
+ variants: {
22
+ size: {
23
+ sm: "gap-1.5 text-xs",
24
+ default: "gap-2 text-sm",
25
+ lg: "gap-2.5 text-base"
26
+ }
27
+ },
28
+ defaultVariants: {
29
+ size: "default"
30
+ }
31
+ }
32
+ );
33
+ var TypingIndicator = React.forwardRef(
34
+ ({
35
+ className,
36
+ variant = "dots",
37
+ size,
38
+ color = "muted",
39
+ speed = "default",
40
+ label = "Typing",
41
+ showLabel = false,
42
+ ...props
43
+ }, ref) => {
44
+ const resolvedSize = size ?? "default";
45
+ return /* @__PURE__ */ React.createElement(
46
+ "div",
47
+ {
48
+ ref,
49
+ role: "status",
50
+ "aria-live": "polite",
51
+ "aria-label": label,
52
+ className: cn(typingIndicatorVariants({ size }), className),
53
+ ...props
54
+ },
55
+ variant === "dots" && /* @__PURE__ */ React.createElement(DotsIndicator, { size: resolvedSize, color, speed }),
56
+ variant === "cursor" && /* @__PURE__ */ React.createElement(CursorIndicator, { size: resolvedSize, color }),
57
+ showLabel && /* @__PURE__ */ React.createElement("span", { className: "text-text-muted select-none" }, label)
58
+ );
59
+ }
60
+ );
61
+ TypingIndicator.displayName = "TypingIndicator";
62
+ function DotsIndicator({
63
+ size,
64
+ color,
65
+ speed
66
+ }) {
67
+ const dotSize = DOT_SIZES[size];
68
+ const gap = DOT_GAP[size];
69
+ const duration = SPEED_MS[speed];
70
+ return /* @__PURE__ */ React.createElement("div", { className: "inline-flex items-center", style: { gap } }, Array.from({ length: DOT_COUNT }, (_, i) => /* @__PURE__ */ React.createElement(
71
+ "div",
72
+ {
73
+ key: i,
74
+ className: cn(
75
+ "rounded-full animate-spinner-dot motion-reduce:animate-none motion-reduce:opacity-60",
76
+ bgColorMap[color]
77
+ ),
78
+ style: {
79
+ width: dotSize,
80
+ height: dotSize,
81
+ animationDuration: `${duration}ms`,
82
+ animationDelay: `${i * (duration / DOT_COUNT / 1.5)}ms`
83
+ }
84
+ }
85
+ )));
86
+ }
87
+ var CURSOR_SIZE = {
88
+ sm: { width: 2, height: 14 },
89
+ default: { width: 2.5, height: 20 },
90
+ lg: { width: 3, height: 26 }
91
+ };
92
+ function CursorIndicator({
93
+ size,
94
+ color
95
+ }) {
96
+ const { width, height } = CURSOR_SIZE[size];
97
+ return /* @__PURE__ */ React.createElement(
98
+ "div",
99
+ {
100
+ "aria-hidden": "true",
101
+ className: cn(
102
+ "rounded-full animate-typing-cursor motion-reduce:animate-none motion-reduce:opacity-60",
103
+ bgColorMap[color]
104
+ ),
105
+ style: { width, height, animationDuration: "1200ms" }
106
+ }
107
+ );
108
+ }
109
+
110
+ export {
111
+ typingIndicatorVariants,
112
+ TypingIndicator
113
+ };
114
+ //# sourceMappingURL=chunk-S4T4PU7F.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/typing-indicator.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Dot diameter per size (px) */\nconst DOT_SIZES = { sm: 4, default: 6, lg: 8 } as const\n\n/** Gap between dots per size (px) */\nconst DOT_GAP = { sm: 3, default: 4, lg: 5 } as const\n\n/** Animation speed in ms */\nconst SPEED_MS = { slow: 1600, default: 1100, fast: 700 } as const\n\n/** Number of dots */\nconst DOT_COUNT = 3\n\n// ============================================================================\n// Color mapping\n// ============================================================================\n\nconst bgColorMap = {\n default: 'bg-foreground',\n primary: 'bg-primary',\n muted: 'bg-text-subtle',\n} as const\n\n// ============================================================================\n// Variants (CVA)\n// ============================================================================\n\nconst typingIndicatorVariants = cva(\n 'inline-flex items-center',\n {\n variants: {\n size: {\n sm: 'gap-1.5 text-xs',\n default: 'gap-2 text-sm',\n lg: 'gap-2.5 text-base',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TypingIndicatorProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof typingIndicatorVariants> {\n /** Animation style */\n variant?: 'dots' | 'cursor'\n /** Indicator color */\n color?: 'default' | 'primary' | 'muted'\n /** Animation speed */\n speed?: 'slow' | 'default' | 'fast'\n /** Accessible label (also shown as visual text when showLabel is true) */\n label?: string\n /** Render label text alongside the indicator */\n showLabel?: boolean\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nconst TypingIndicator = React.forwardRef<HTMLDivElement, TypingIndicatorProps>(\n (\n {\n className,\n variant = 'dots',\n size,\n color = 'muted',\n speed = 'default',\n label = 'Typing',\n showLabel = false,\n ...props\n },\n ref\n ) => {\n const resolvedSize = size ?? 'default'\n\n return (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={label}\n className={cn(typingIndicatorVariants({ size }), className)}\n {...props}\n >\n {variant === 'dots' && (\n <DotsIndicator size={resolvedSize} color={color} speed={speed} />\n )}\n {variant === 'cursor' && (\n <CursorIndicator size={resolvedSize} color={color} />\n )}\n {showLabel && (\n <span className=\"text-text-muted select-none\">{label}</span>\n )}\n </div>\n )\n }\n)\nTypingIndicator.displayName = 'TypingIndicator'\n\n// ============================================================================\n// Dots Indicator — 3 staggered bouncing dots (reuses animate-spinner-dot)\n// ============================================================================\n\nfunction DotsIndicator({\n size,\n color,\n speed,\n}: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'muted'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const dotSize = DOT_SIZES[size]\n const gap = DOT_GAP[size]\n const duration = SPEED_MS[speed]\n\n return (\n <div className=\"inline-flex items-center\" style={{ gap }}>\n {Array.from({ length: DOT_COUNT }, (_, i) => (\n <div\n key={i}\n className={cn(\n 'rounded-full animate-spinner-dot motion-reduce:animate-none motion-reduce:opacity-60',\n bgColorMap[color]\n )}\n style={{\n width: dotSize,\n height: dotSize,\n animationDuration: `${duration}ms`,\n animationDelay: `${i * (duration / DOT_COUNT / 1.5)}ms`,\n }}\n />\n ))}\n </div>\n )\n}\n\n// ============================================================================\n// Cursor sizes per component size\n// ============================================================================\n\nconst CURSOR_SIZE = {\n sm: { width: 2, height: 14 },\n default: { width: 2.5, height: 20 },\n lg: { width: 3, height: 26 },\n} as const\n\n// ============================================================================\n// Cursor Indicator — blinking cursor (text-cursor style)\n// ============================================================================\n\nfunction CursorIndicator({\n size,\n color,\n}: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'muted'\n}) {\n const { width, height } = CURSOR_SIZE[size]\n\n return (\n <div\n aria-hidden=\"true\"\n className={cn(\n 'rounded-full animate-typing-cursor motion-reduce:animate-none motion-reduce:opacity-60',\n bgColorMap[color]\n )}\n style={{ width, height, animationDuration: '1200ms' }}\n />\n )\n}\n\nexport { TypingIndicator, typingIndicatorVariants }\n"],"mappings":";;;;;;AAEA,YAAY,WAAW;AACvB,SAAS,WAA8B;AAQvC,IAAM,YAAY,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI,EAAE;AAG7C,IAAM,UAAU,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI,EAAE;AAG3C,IAAM,WAAW,EAAE,MAAM,MAAM,SAAS,MAAM,MAAM,IAAI;AAGxD,IAAM,YAAY;AAMlB,IAAM,aAAa;AAAA,EACjB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAS;AACX;AAMA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAS;AAAA,QACT,SAAS;AAAA,QACT,IAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAyBA,IAAM,kBAAwB;AAAA,EAC5B,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,eAAe,QAAQ;AAE7B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,aAAU;AAAA,QACV,cAAY;AAAA,QACZ,WAAW,GAAG,wBAAwB,EAAE,KAAK,CAAC,GAAG,SAAS;AAAA,QACzD,GAAG;AAAA;AAAA,MAEH,YAAY,UACX,oCAAC,iBAAc,MAAM,cAAc,OAAc,OAAc;AAAA,MAEhE,YAAY,YACX,oCAAC,mBAAgB,MAAM,cAAc,OAAc;AAAA,MAEpD,aACC,oCAAC,UAAK,WAAU,iCAA+B,KAAM;AAAA,IAEzD;AAAA,EAEJ;AACF;AACA,gBAAgB,cAAc;AAM9B,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,UAAU,UAAU,IAAI;AAC9B,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,WAAW,SAAS,KAAK;AAE/B,SACE,oCAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,IAAI,KACpD,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,CAAC,GAAG,MACrC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,mBAAmB,GAAG,QAAQ;AAAA,QAC9B,gBAAgB,GAAG,KAAK,WAAW,YAAY,IAAI;AAAA,MACrD;AAAA;AAAA,EACF,CACD,CACH;AAEJ;AAMA,IAAM,cAAc;AAAA,EAClB,IAAS,EAAE,OAAO,GAAG,QAAQ,GAAG;AAAA,EAChC,SAAS,EAAE,OAAO,KAAK,QAAQ,GAAG;AAAA,EAClC,IAAS,EAAE,OAAO,GAAG,QAAQ,GAAG;AAClC;AAMA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AACF,GAGG;AACD,QAAM,EAAE,OAAO,OAAO,IAAI,YAAY,IAAI;AAE1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,OAAO,EAAE,OAAO,QAAQ,mBAAmB,SAAS;AAAA;AAAA,EACtD;AAEJ;","names":[]}
@@ -0,0 +1,224 @@
1
+ "use client";
2
+ import {
3
+ useFieldContext,
4
+ useFieldControl
5
+ } from "./chunk-T5A4APEL.mjs";
6
+ import {
7
+ cn
8
+ } from "./chunk-53MIUPSY.mjs";
9
+
10
+ // src/components/ui/input.tsx
11
+ import * as React from "react";
12
+ import { cva } from "class-variance-authority";
13
+ var inputVariants = cva(
14
+ [
15
+ "flex w-full bg-background text-foreground placeholder:text-foreground/30",
16
+ "border transition-colors duration-micro outline-transparent",
17
+ "focus:[outline:2px_solid_transparent]",
18
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-background-muted",
19
+ "file:border-0 file:bg-transparent file:text-sm file:font-semibold"
20
+ ].join(" "),
21
+ {
22
+ variants: {
23
+ variant: {
24
+ default: "border-border hover:border-border-strong",
25
+ filled: "border-transparent bg-background-muted"
26
+ },
27
+ focusRing: {
28
+ true: "",
29
+ false: ""
30
+ },
31
+ size: {
32
+ xs: "h-9 px-3 text-sm",
33
+ // 36px / 12px padding / 13px font (3.0:1)
34
+ sm: "h-10 px-3 text-md",
35
+ // 40px / 12px padding / 14px font (3.3:1)
36
+ default: "h-11 px-4 text-base",
37
+ // 44px / 16px padding / 16px font (2.75:1)
38
+ lg: "h-12 px-4 text-base",
39
+ // 48px / 16px padding / 16px font (3.0:1)
40
+ xl: "h-14 px-4 text-base"
41
+ // 56px / 16px padding / 16px font (3.5:1)
42
+ },
43
+ radius: {
44
+ none: "rounded-none",
45
+ sm: "rounded-sm",
46
+ base: "rounded",
47
+ default: "rounded-md",
48
+ lg: "rounded-lg",
49
+ xl: "rounded-xl",
50
+ "2xl": "rounded-2xl",
51
+ "3xl": "rounded-3xl",
52
+ full: "rounded-full"
53
+ },
54
+ state: {
55
+ default: "",
56
+ error: "border-error hover:border-error focus:border-error shadow-[0_0_0_2px_var(--color-focus-ring-error)]"
57
+ }
58
+ },
59
+ compoundVariants: [
60
+ // focusRing: true → show custom focus ring
61
+ { focusRing: true, className: "focus-visible:shadow-[0_0_0_2px_var(--color-focus-ring)]" },
62
+ // focusRing: false → keep same state as hover
63
+ { variant: "default", focusRing: false, className: "focus:border-border-strong" },
64
+ // filled + error
65
+ {
66
+ variant: "filled",
67
+ state: "error",
68
+ className: "border-transparent hover:border-transparent focus:border-transparent bg-[var(--color-error-bg)] hover:bg-[var(--color-error-bg)] focus:bg-[var(--color-error-bg)] shadow-none"
69
+ }
70
+ ],
71
+ defaultVariants: {
72
+ variant: "default",
73
+ size: "default",
74
+ radius: "default",
75
+ state: "default",
76
+ focusRing: false
77
+ }
78
+ }
79
+ );
80
+ var iconSizeClasses = {
81
+ xs: "icon-xs",
82
+ // 14px
83
+ sm: "icon-xs",
84
+ // 14px
85
+ default: "icon-sm",
86
+ // 16px
87
+ lg: "icon-sm",
88
+ // 16px
89
+ xl: "icon-sm"
90
+ // 16px
91
+ };
92
+ var iconPaddingClasses = {
93
+ xs: { left: "pl-8", right: "pr-8" },
94
+ // 12px + 14px icon + 6px gap = 32px
95
+ sm: { left: "pl-9", right: "pr-9" },
96
+ // 12px + 14px icon + 8px gap = 34px → 36px
97
+ default: { left: "pl-10", right: "pr-10" },
98
+ // 16px + 16px icon + 8px gap = 40px
99
+ lg: { left: "pl-10", right: "pr-10" },
100
+ // 16px + 16px icon + 8px gap = 40px
101
+ xl: { left: "pl-10", right: "pr-10" }
102
+ // 16px + 16px icon + 8px gap = 40px
103
+ };
104
+ var iconPositionClasses = {
105
+ xs: { left: "left-3", right: "right-3" },
106
+ // 12px
107
+ sm: { left: "left-3", right: "right-3" },
108
+ // 12px
109
+ default: { left: "left-4", right: "right-4" },
110
+ // 16px
111
+ lg: { left: "left-4", right: "right-4" },
112
+ // 16px
113
+ xl: { left: "left-4", right: "right-4" }
114
+ // 16px
115
+ };
116
+ var Input = React.forwardRef(
117
+ ({ className, variant, size, radius, state, type, leftIcon, rightIcon, error, focusRing, id, onPointerDown, onFocus, onBlur, ...props }, ref) => {
118
+ const fieldContext = useFieldContext();
119
+ const resolvedSize = size || "default";
120
+ const resolvedError = error ?? fieldContext?.error;
121
+ const resolvedState = resolvedError ? "error" : state;
122
+ const inputId = id ?? fieldContext?.id;
123
+ useFieldControl("single", Boolean(fieldContext) && !id);
124
+ const isDisabled = props.disabled ?? fieldContext?.disabled;
125
+ const pointerRef = React.useRef(false);
126
+ const windowBlurredRef = React.useRef(false);
127
+ const [keyboardFocus, setKeyboardFocus] = React.useState(false);
128
+ React.useEffect(() => {
129
+ const onBlur2 = () => {
130
+ windowBlurredRef.current = true;
131
+ };
132
+ const onFocus2 = () => {
133
+ requestAnimationFrame(() => {
134
+ windowBlurredRef.current = false;
135
+ });
136
+ };
137
+ window.addEventListener("blur", onBlur2);
138
+ window.addEventListener("focus", onFocus2);
139
+ return () => {
140
+ window.removeEventListener("blur", onBlur2);
141
+ window.removeEventListener("focus", onFocus2);
142
+ };
143
+ }, []);
144
+ const handlePointerDown = React.useCallback((e) => {
145
+ pointerRef.current = true;
146
+ onPointerDown?.(e);
147
+ }, [onPointerDown]);
148
+ const handleFocus = React.useCallback((e) => {
149
+ if (!pointerRef.current && !focusRing && !windowBlurredRef.current) {
150
+ setKeyboardFocus(true);
151
+ }
152
+ pointerRef.current = false;
153
+ onFocus?.(e);
154
+ }, [focusRing, onFocus]);
155
+ const handleBlur = React.useCallback((e) => {
156
+ setKeyboardFocus(false);
157
+ pointerRef.current = false;
158
+ onBlur?.(e);
159
+ }, [onBlur]);
160
+ const ariaDescribedBy = fieldContext ? [
161
+ resolvedError ? `${fieldContext.id}-error` : null
162
+ ].filter(Boolean).join(" ") || void 0 : void 0;
163
+ const focusHandlers = {
164
+ onPointerDown: handlePointerDown,
165
+ onFocus: handleFocus,
166
+ onBlur: handleBlur
167
+ };
168
+ if (leftIcon || rightIcon) {
169
+ return /* @__PURE__ */ React.createElement("div", { className: "relative w-full" }, leftIcon && /* @__PURE__ */ React.createElement("div", { className: cn(
170
+ "absolute top-1/2 -translate-y-1/2 pointer-events-none text-text-muted z-10",
171
+ iconPositionClasses[resolvedSize].left,
172
+ `[&>svg]:${iconSizeClasses[resolvedSize]}`
173
+ ) }, leftIcon), /* @__PURE__ */ React.createElement(
174
+ "input",
175
+ {
176
+ type,
177
+ id: inputId,
178
+ className: cn(
179
+ inputVariants({ variant, size, radius, state: resolvedState, focusRing }),
180
+ keyboardFocus && "shadow-[0_0_0_2px_var(--color-focus-ring)]",
181
+ leftIcon && iconPaddingClasses[resolvedSize].left,
182
+ rightIcon && iconPaddingClasses[resolvedSize].right,
183
+ className
184
+ ),
185
+ "aria-invalid": resolvedError || void 0,
186
+ "aria-describedby": ariaDescribedBy,
187
+ disabled: isDisabled,
188
+ ref,
189
+ ...focusHandlers,
190
+ ...props
191
+ }
192
+ ), rightIcon && /* @__PURE__ */ React.createElement("div", { className: cn(
193
+ "absolute top-1/2 -translate-y-1/2 pointer-events-none text-text-muted z-10",
194
+ iconPositionClasses[resolvedSize].right,
195
+ `[&>svg]:${iconSizeClasses[resolvedSize]}`
196
+ ) }, rightIcon));
197
+ }
198
+ return /* @__PURE__ */ React.createElement(
199
+ "input",
200
+ {
201
+ type,
202
+ id: inputId,
203
+ className: cn(
204
+ inputVariants({ variant, size, radius, state: resolvedState, focusRing }),
205
+ keyboardFocus && "shadow-[0_0_0_2px_var(--color-focus-ring)]",
206
+ className
207
+ ),
208
+ "aria-invalid": resolvedError || void 0,
209
+ "aria-describedby": ariaDescribedBy,
210
+ disabled: isDisabled,
211
+ ref,
212
+ ...focusHandlers,
213
+ ...props
214
+ }
215
+ );
216
+ }
217
+ );
218
+ Input.displayName = "Input";
219
+
220
+ export {
221
+ inputVariants,
222
+ Input
223
+ };
224
+ //# sourceMappingURL=chunk-SDDAGZWA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/input.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { useFieldContext, useFieldControl } from './field'\n\nconst inputVariants = cva(\n [\n 'flex w-full bg-background text-foreground placeholder:text-foreground/30',\n 'border transition-colors duration-micro outline-transparent',\n 'focus:[outline:2px_solid_transparent]',\n 'disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-background-muted',\n 'file:border-0 file:bg-transparent file:text-sm file:font-semibold',\n ].join(' '),\n {\n variants: {\n variant: {\n default: 'border-border hover:border-border-strong',\n filled: 'border-transparent bg-background-muted',\n },\n focusRing: {\n true: '',\n false: '',\n },\n size: {\n xs: 'h-9 px-3 text-sm', // 36px / 12px padding / 13px font (3.0:1)\n sm: 'h-10 px-3 text-md', // 40px / 12px padding / 14px font (3.3:1)\n default: 'h-11 px-4 text-base', // 44px / 16px padding / 16px font (2.75:1)\n lg: 'h-12 px-4 text-base', // 48px / 16px padding / 16px font (3.0:1)\n xl: 'h-14 px-4 text-base', // 56px / 16px padding / 16px font (3.5:1)\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n state: {\n default: '',\n error: 'border-error hover:border-error focus:border-error shadow-[0_0_0_2px_var(--color-focus-ring-error)]',\n },\n },\n compoundVariants: [\n // focusRing: true → show custom focus ring\n { focusRing: true, className: 'focus-visible:shadow-[0_0_0_2px_var(--color-focus-ring)]' },\n // focusRing: false → keep same state as hover\n { variant: 'default', focusRing: false, className: 'focus:border-border-strong' },\n // filled + error\n {\n variant: 'filled',\n state: 'error',\n className: 'border-transparent hover:border-transparent focus:border-transparent bg-[var(--color-error-bg)] hover:bg-[var(--color-error-bg)] focus:bg-[var(--color-error-bg)] shadow-none',\n },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n state: 'default',\n focusRing: false,\n },\n }\n)\n\nexport interface InputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>,\n VariantProps<typeof inputVariants> {\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n error?: boolean\n focusRing?: boolean\n}\n\n// Icon size for input (2-step scale)\n// xs~sm: 14px, default~xl: 16px\nconst iconSizeClasses = {\n xs: 'icon-xs', // 14px\n sm: 'icon-xs', // 14px\n default: 'icon-sm', // 16px\n lg: 'icon-sm', // 16px\n xl: 'icon-sm', // 16px\n}\n\n// Icon padding (padding + icon + gap)\nconst iconPaddingClasses = {\n xs: { left: 'pl-8', right: 'pr-8' }, // 12px + 14px icon + 6px gap = 32px\n sm: { left: 'pl-9', right: 'pr-9' }, // 12px + 14px icon + 8px gap = 34px → 36px\n default: { left: 'pl-10', right: 'pr-10' }, // 16px + 16px icon + 8px gap = 40px\n lg: { left: 'pl-10', right: 'pr-10' }, // 16px + 16px icon + 8px gap = 40px\n xl: { left: 'pl-10', right: 'pr-10' }, // 16px + 16px icon + 8px gap = 40px\n}\n\n// Icon position (matches horizontal padding)\nconst iconPositionClasses = {\n xs: { left: 'left-3', right: 'right-3' }, // 12px\n sm: { left: 'left-3', right: 'right-3' }, // 12px\n default: { left: 'left-4', right: 'right-4' }, // 16px\n lg: { left: 'left-4', right: 'right-4' }, // 16px\n xl: { left: 'left-4', right: 'right-4' }, // 16px\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, variant, size, radius, state, type, leftIcon, rightIcon, error, focusRing, id, onPointerDown, onFocus, onBlur, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedSize = size || 'default'\n const resolvedError = error ?? fieldContext?.error\n const resolvedState = resolvedError ? 'error' : state\n const inputId = id ?? fieldContext?.id\n useFieldControl('single', Boolean(fieldContext) && !id)\n const isDisabled = props.disabled ?? fieldContext?.disabled\n\n // Keyboard focus detection (when focusRing: false, auto-show ring on Tab navigation)\n const pointerRef = React.useRef(false)\n const windowBlurredRef = React.useRef(false)\n const [keyboardFocus, setKeyboardFocus] = React.useState(false)\n\n // Track window blur/focus to distinguish Tab navigation from window re-activation\n React.useEffect(() => {\n const onBlur = () => { windowBlurredRef.current = true }\n const onFocus = () => { requestAnimationFrame(() => { windowBlurredRef.current = false }) }\n window.addEventListener('blur', onBlur)\n window.addEventListener('focus', onFocus)\n return () => { window.removeEventListener('blur', onBlur); window.removeEventListener('focus', onFocus) }\n }, [])\n\n const handlePointerDown = React.useCallback((e: React.PointerEvent<HTMLInputElement>) => {\n pointerRef.current = true\n onPointerDown?.(e)\n }, [onPointerDown])\n\n const handleFocus = React.useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n if (!pointerRef.current && !focusRing && !windowBlurredRef.current) {\n setKeyboardFocus(true)\n }\n pointerRef.current = false\n onFocus?.(e)\n }, [focusRing, onFocus])\n\n const handleBlur = React.useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n setKeyboardFocus(false)\n pointerRef.current = false\n onBlur?.(e)\n }, [onBlur])\n\n // Build aria-describedby from context\n const ariaDescribedBy = fieldContext\n ? [\n resolvedError ? `${fieldContext.id}-error` : null,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n : undefined\n\n const focusHandlers = {\n onPointerDown: handlePointerDown,\n onFocus: handleFocus,\n onBlur: handleBlur,\n }\n\n // If icons are present, wrap input in a container\n if (leftIcon || rightIcon) {\n return (\n <div className=\"relative w-full\">\n {leftIcon && (\n <div className={cn(\n 'absolute top-1/2 -translate-y-1/2 pointer-events-none text-text-muted z-10',\n iconPositionClasses[resolvedSize].left,\n `[&>svg]:${iconSizeClasses[resolvedSize]}`\n )}>\n {leftIcon}\n </div>\n )}\n <input\n type={type}\n id={inputId}\n className={cn(\n inputVariants({ variant, size, radius, state: resolvedState, focusRing }),\n keyboardFocus && 'shadow-[0_0_0_2px_var(--color-focus-ring)]',\n leftIcon && iconPaddingClasses[resolvedSize].left,\n rightIcon && iconPaddingClasses[resolvedSize].right,\n className\n )}\n aria-invalid={resolvedError || undefined}\n aria-describedby={ariaDescribedBy}\n disabled={isDisabled}\n ref={ref}\n {...focusHandlers}\n {...props}\n />\n {rightIcon && (\n <div className={cn(\n 'absolute top-1/2 -translate-y-1/2 pointer-events-none text-text-muted z-10',\n iconPositionClasses[resolvedSize].right,\n `[&>svg]:${iconSizeClasses[resolvedSize]}`\n )}>\n {rightIcon}\n </div>\n )}\n </div>\n )\n }\n\n return (\n <input\n type={type}\n id={inputId}\n className={cn(\n inputVariants({ variant, size, radius, state: resolvedState, focusRing }),\n keyboardFocus && 'shadow-[0_0_0_2px_var(--color-focus-ring)]',\n className\n )}\n aria-invalid={resolvedError || undefined}\n aria-describedby={ariaDescribedBy}\n disabled={isDisabled}\n ref={ref}\n {...focusHandlers}\n {...props}\n />\n )\n }\n)\nInput.displayName = 'Input'\n\nexport { Input, inputVariants }\n"],"mappings":"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","names":["onBlur","onFocus"]}