@giddaa-housing/ui 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/README.md +18 -6
  2. package/css/base.css +37 -0
  3. package/css/components.css +135 -0
  4. package/css/generated/shared.css +1 -0
  5. package/css/giddaa.css +402 -0
  6. package/css/preset.css +77 -0
  7. package/css/styles.css +2 -0
  8. package/css/theme.css +255 -0
  9. package/dist/accordion.d.ts +9 -10
  10. package/dist/accordion.js +41 -117
  11. package/dist/activity-timeline.d.ts +29 -0
  12. package/dist/activity-timeline.js +97 -0
  13. package/dist/alert.d.ts +8 -9
  14. package/dist/alert.js +53 -141
  15. package/dist/auth-layout.d.ts +23 -0
  16. package/dist/auth-layout.js +153 -0
  17. package/dist/avatar.d.ts +6 -6
  18. package/dist/avatar.js +40 -142
  19. package/dist/badge.d.ts +12 -13
  20. package/dist/badge.js +66 -114
  21. package/dist/bar-chart.d.ts +136 -114
  22. package/dist/bar-chart.js +244 -297
  23. package/dist/breadcrumb.d.ts +5 -5
  24. package/dist/breadcrumb.js +56 -148
  25. package/dist/bullet-chart.d.ts +33 -33
  26. package/dist/bullet-chart.js +123 -183
  27. package/dist/button-BZIeyUw6.d.ts +17 -0
  28. package/dist/button-group.d.ts +13 -16
  29. package/dist/button-group.js +38 -163
  30. package/dist/button.d.ts +2 -19
  31. package/dist/button.js +90 -142
  32. package/dist/calendar.d.ts +6 -6
  33. package/dist/calendar.js +134 -288
  34. package/dist/card.d.ts +14 -16
  35. package/dist/card.js +58 -174
  36. package/dist/carousel.d.ts +34 -35
  37. package/dist/carousel.js +319 -378
  38. package/dist/chart.d.ts +58 -59
  39. package/dist/chart.js +350 -466
  40. package/dist/checkbox.d.ts +10 -12
  41. package/dist/checkbox.js +84 -84
  42. package/dist/cn-BI_4DMBf.js +23 -0
  43. package/dist/collapsible.d.ts +7 -8
  44. package/dist/collapsible.js +23 -77
  45. package/dist/combobox.d.ts +10 -10
  46. package/dist/combobox.js +220 -696
  47. package/dist/cta.d.ts +64 -0
  48. package/dist/cta.js +192 -0
  49. package/dist/currency-selector.d.ts +41 -0
  50. package/dist/currency-selector.js +114 -0
  51. package/dist/data-table.d.ts +164 -0
  52. package/dist/data-table.js +673 -0
  53. package/dist/date-picker.d.ts +27 -20
  54. package/dist/date-picker.js +122 -520
  55. package/dist/details-card.d.ts +19 -0
  56. package/dist/details-card.js +118 -0
  57. package/dist/dialog.d.ts +13 -14
  58. package/dist/dialog.js +117 -320
  59. package/dist/dropdown-menu.d.ts +14 -14
  60. package/dist/dropdown-menu.js +170 -365
  61. package/dist/dropzone.d.ts +55 -55
  62. package/dist/dropzone.js +328 -467
  63. package/dist/editorial-card.d.ts +27 -0
  64. package/dist/editorial-card.js +144 -0
  65. package/dist/empty-state.d.ts +8 -9
  66. package/dist/empty-state.js +48 -135
  67. package/dist/field.d.ts +23 -25
  68. package/dist/field.js +111 -327
  69. package/dist/filter.d.ts +118 -0
  70. package/dist/filter.js +775 -0
  71. package/dist/footer.d.ts +40 -0
  72. package/dist/footer.js +227 -0
  73. package/dist/funnel-chart.d.ts +38 -41
  74. package/dist/funnel-chart.js +168 -563
  75. package/dist/gallery-indicator.d.ts +17 -0
  76. package/dist/gallery-indicator.js +75 -0
  77. package/dist/heatmap-chart.d.ts +95 -0
  78. package/dist/heatmap-chart.js +197 -0
  79. package/dist/infotip.d.ts +10 -0
  80. package/dist/infotip.js +40 -0
  81. package/dist/input-CfoEJ8A6.d.ts +12 -0
  82. package/dist/input-group.d.ts +16 -19
  83. package/dist/input-group.js +92 -372
  84. package/dist/input-size-context-C-SFx9sx.d.ts +10 -0
  85. package/dist/input-size-context.d.ts +2 -11
  86. package/dist/input-size-context.js +14 -20
  87. package/dist/input.d.ts +2 -13
  88. package/dist/input.js +23 -79
  89. package/dist/item.d.ts +7 -8
  90. package/dist/item.js +22 -89
  91. package/dist/kpi-card.d.ts +18 -20
  92. package/dist/kpi-card.js +84 -232
  93. package/dist/label.d.ts +6 -6
  94. package/dist/label.js +39 -66
  95. package/dist/line-chart.d.ts +88 -89
  96. package/dist/line-chart.js +143 -262
  97. package/dist/logo.d.ts +4 -4
  98. package/dist/logo.js +87 -141
  99. package/dist/map-indicator.d.ts +13 -0
  100. package/dist/map-indicator.js +83 -0
  101. package/dist/match.d.ts +15 -0
  102. package/dist/match.js +68 -0
  103. package/dist/media-gallery-hero.d.ts +58 -0
  104. package/dist/media-gallery-hero.js +201 -0
  105. package/dist/media-player.d.ts +60 -0
  106. package/dist/media-player.js +919 -0
  107. package/dist/multi-step-form.d.ts +56 -0
  108. package/dist/multi-step-form.js +342 -0
  109. package/dist/number-input.d.ts +34 -34
  110. package/dist/number-input.js +62 -413
  111. package/dist/page-header.d.ts +10 -11
  112. package/dist/page-header.js +34 -107
  113. package/dist/pagination.d.ts +17 -20
  114. package/dist/pagination.js +132 -341
  115. package/dist/password-input.d.ts +5 -12
  116. package/dist/password-input.js +32 -354
  117. package/dist/phone-input.d.ts +19 -19
  118. package/dist/phone-input.js +232 -561
  119. package/dist/photo-gallery.d.ts +20 -20
  120. package/dist/photo-gallery.js +314 -746
  121. package/dist/picker-lzgmsNfG.js +32 -0
  122. package/dist/pie-chart.d.ts +60 -60
  123. package/dist/pie-chart.js +141 -184
  124. package/dist/popover.d.ts +9 -9
  125. package/dist/popover.js +60 -156
  126. package/dist/price-tag.d.ts +34 -0
  127. package/dist/price-tag.js +118 -0
  128. package/dist/progress.d.ts +18 -16
  129. package/dist/progress.js +156 -300
  130. package/dist/property-listing-card.d.ts +29 -0
  131. package/dist/property-listing-card.js +117 -0
  132. package/dist/radar-chart.d.ts +108 -0
  133. package/dist/radar-chart.js +172 -0
  134. package/dist/radio-group.d.ts +11 -13
  135. package/dist/radio-group.js +47 -96
  136. package/dist/review-block.d.ts +18 -0
  137. package/dist/review-block.js +154 -0
  138. package/dist/rich-text-editor.d.ts +30 -14
  139. package/dist/rich-text-editor.js +594 -979
  140. package/dist/scatter-chart.d.ts +140 -0
  141. package/dist/scatter-chart.js +248 -0
  142. package/dist/search-input.d.ts +8 -15
  143. package/dist/search-input.js +58 -408
  144. package/dist/select.d.ts +8 -8
  145. package/dist/select.js +131 -291
  146. package/dist/separator.d.ts +8 -9
  147. package/dist/separator.js +31 -70
  148. package/dist/sheet.d.ts +11 -11
  149. package/dist/sheet.js +84 -262
  150. package/dist/sidebar.d.ts +32 -37
  151. package/dist/sidebar.js +380 -1055
  152. package/dist/size-context-D4mYvcg8.d.ts +10 -0
  153. package/dist/size-context.d.ts +2 -11
  154. package/dist/size-context.js +14 -18
  155. package/dist/skeleton.d.ts +4 -5
  156. package/dist/skeleton.js +9 -45
  157. package/dist/slider.d.ts +27 -0
  158. package/dist/slider.js +81 -0
  159. package/dist/sparkline.d.ts +43 -46
  160. package/dist/sparkline.js +223 -561
  161. package/dist/stepper.d.ts +23 -24
  162. package/dist/stepper.js +149 -276
  163. package/dist/styles.css +9995 -2
  164. package/dist/switch.d.ts +10 -12
  165. package/dist/switch.js +49 -106
  166. package/dist/table-card.d.ts +35 -0
  167. package/dist/table-card.js +125 -0
  168. package/dist/table.d.ts +18 -14
  169. package/dist/table.js +114 -182
  170. package/dist/tabs.d.ts +23 -15
  171. package/dist/tabs.js +62 -149
  172. package/dist/tag.d.ts +22 -23
  173. package/dist/tag.js +104 -156
  174. package/dist/testimonial-block.d.ts +33 -0
  175. package/dist/testimonial-block.js +208 -0
  176. package/dist/textarea-IS_D8pXf.d.ts +11 -0
  177. package/dist/textarea.d.ts +2 -12
  178. package/dist/textarea.js +20 -74
  179. package/dist/time-picker.d.ts +11 -11
  180. package/dist/time-picker.js +247 -464
  181. package/dist/toast.d.ts +16 -18
  182. package/dist/toast.js +154 -310
  183. package/dist/tooltip.d.ts +9 -10
  184. package/dist/tooltip.js +33 -91
  185. package/dist/tree-map.d.ts +54 -57
  186. package/dist/tree-map.js +231 -646
  187. package/dist/use-uncontrolled-CLfM1XbB.js +21 -0
  188. package/dist/waterfall-chart.d.ts +126 -0
  189. package/dist/waterfall-chart.js +480 -0
  190. package/package.json +123 -34
  191. package/dist/accordion.js.map +0 -1
  192. package/dist/alert.js.map +0 -1
  193. package/dist/avatar.js.map +0 -1
  194. package/dist/badge.js.map +0 -1
  195. package/dist/bar-chart.js.map +0 -1
  196. package/dist/base.css +0 -32
  197. package/dist/breadcrumb.js.map +0 -1
  198. package/dist/bullet-chart.js.map +0 -1
  199. package/dist/button-group.js.map +0 -1
  200. package/dist/button.js.map +0 -1
  201. package/dist/calendar.js.map +0 -1
  202. package/dist/card.js.map +0 -1
  203. package/dist/carousel.js.map +0 -1
  204. package/dist/chart.js.map +0 -1
  205. package/dist/checkbox.js.map +0 -1
  206. package/dist/collapsible.js.map +0 -1
  207. package/dist/combobox.js.map +0 -1
  208. package/dist/date-picker.js.map +0 -1
  209. package/dist/dialog.js.map +0 -1
  210. package/dist/dropdown-menu.js.map +0 -1
  211. package/dist/dropzone.js.map +0 -1
  212. package/dist/empty-state.js.map +0 -1
  213. package/dist/field.js.map +0 -1
  214. package/dist/files/red-hat-display-latin-300-italic.woff +0 -0
  215. package/dist/files/red-hat-display-latin-300-italic.woff2 +0 -0
  216. package/dist/files/red-hat-display-latin-300-normal.woff +0 -0
  217. package/dist/files/red-hat-display-latin-300-normal.woff2 +0 -0
  218. package/dist/files/red-hat-display-latin-400-italic.woff +0 -0
  219. package/dist/files/red-hat-display-latin-400-italic.woff2 +0 -0
  220. package/dist/files/red-hat-display-latin-400-normal.woff +0 -0
  221. package/dist/files/red-hat-display-latin-400-normal.woff2 +0 -0
  222. package/dist/files/red-hat-display-latin-500-italic.woff +0 -0
  223. package/dist/files/red-hat-display-latin-500-italic.woff2 +0 -0
  224. package/dist/files/red-hat-display-latin-500-normal.woff +0 -0
  225. package/dist/files/red-hat-display-latin-500-normal.woff2 +0 -0
  226. package/dist/files/red-hat-display-latin-600-italic.woff +0 -0
  227. package/dist/files/red-hat-display-latin-600-italic.woff2 +0 -0
  228. package/dist/files/red-hat-display-latin-600-normal.woff +0 -0
  229. package/dist/files/red-hat-display-latin-600-normal.woff2 +0 -0
  230. package/dist/files/red-hat-display-latin-700-italic.woff +0 -0
  231. package/dist/files/red-hat-display-latin-700-italic.woff2 +0 -0
  232. package/dist/files/red-hat-display-latin-700-normal.woff +0 -0
  233. package/dist/files/red-hat-display-latin-700-normal.woff2 +0 -0
  234. package/dist/files/red-hat-display-latin-800-italic.woff +0 -0
  235. package/dist/files/red-hat-display-latin-800-italic.woff2 +0 -0
  236. package/dist/files/red-hat-display-latin-800-normal.woff +0 -0
  237. package/dist/files/red-hat-display-latin-800-normal.woff2 +0 -0
  238. package/dist/files/red-hat-display-latin-900-italic.woff +0 -0
  239. package/dist/files/red-hat-display-latin-900-italic.woff2 +0 -0
  240. package/dist/files/red-hat-display-latin-900-normal.woff +0 -0
  241. package/dist/files/red-hat-display-latin-900-normal.woff2 +0 -0
  242. package/dist/files/red-hat-display-latin-ext-300-italic.woff +0 -0
  243. package/dist/files/red-hat-display-latin-ext-300-italic.woff2 +0 -0
  244. package/dist/files/red-hat-display-latin-ext-300-normal.woff +0 -0
  245. package/dist/files/red-hat-display-latin-ext-300-normal.woff2 +0 -0
  246. package/dist/files/red-hat-display-latin-ext-400-italic.woff +0 -0
  247. package/dist/files/red-hat-display-latin-ext-400-italic.woff2 +0 -0
  248. package/dist/files/red-hat-display-latin-ext-400-normal.woff +0 -0
  249. package/dist/files/red-hat-display-latin-ext-400-normal.woff2 +0 -0
  250. package/dist/files/red-hat-display-latin-ext-500-italic.woff +0 -0
  251. package/dist/files/red-hat-display-latin-ext-500-italic.woff2 +0 -0
  252. package/dist/files/red-hat-display-latin-ext-500-normal.woff +0 -0
  253. package/dist/files/red-hat-display-latin-ext-500-normal.woff2 +0 -0
  254. package/dist/files/red-hat-display-latin-ext-600-italic.woff +0 -0
  255. package/dist/files/red-hat-display-latin-ext-600-italic.woff2 +0 -0
  256. package/dist/files/red-hat-display-latin-ext-600-normal.woff +0 -0
  257. package/dist/files/red-hat-display-latin-ext-600-normal.woff2 +0 -0
  258. package/dist/files/red-hat-display-latin-ext-700-italic.woff +0 -0
  259. package/dist/files/red-hat-display-latin-ext-700-italic.woff2 +0 -0
  260. package/dist/files/red-hat-display-latin-ext-700-normal.woff +0 -0
  261. package/dist/files/red-hat-display-latin-ext-700-normal.woff2 +0 -0
  262. package/dist/files/red-hat-display-latin-ext-800-italic.woff +0 -0
  263. package/dist/files/red-hat-display-latin-ext-800-italic.woff2 +0 -0
  264. package/dist/files/red-hat-display-latin-ext-800-normal.woff +0 -0
  265. package/dist/files/red-hat-display-latin-ext-800-normal.woff2 +0 -0
  266. package/dist/files/red-hat-display-latin-ext-900-italic.woff +0 -0
  267. package/dist/files/red-hat-display-latin-ext-900-italic.woff2 +0 -0
  268. package/dist/files/red-hat-display-latin-ext-900-normal.woff +0 -0
  269. package/dist/files/red-hat-display-latin-ext-900-normal.woff2 +0 -0
  270. package/dist/funnel-chart.js.map +0 -1
  271. package/dist/index.d.ts +0 -87
  272. package/dist/index.js +0 -10448
  273. package/dist/index.js.map +0 -1
  274. package/dist/input-group.js.map +0 -1
  275. package/dist/input-size-context.js.map +0 -1
  276. package/dist/input.js.map +0 -1
  277. package/dist/item.js.map +0 -1
  278. package/dist/kpi-card.js.map +0 -1
  279. package/dist/label.js.map +0 -1
  280. package/dist/line-chart.js.map +0 -1
  281. package/dist/logo.js.map +0 -1
  282. package/dist/number-input.js.map +0 -1
  283. package/dist/page-header.js.map +0 -1
  284. package/dist/pagination.js.map +0 -1
  285. package/dist/password-input.js.map +0 -1
  286. package/dist/phone-input.js.map +0 -1
  287. package/dist/photo-gallery.js.map +0 -1
  288. package/dist/pie-chart.js.map +0 -1
  289. package/dist/popover.js.map +0 -1
  290. package/dist/progress.js.map +0 -1
  291. package/dist/radio-group.js.map +0 -1
  292. package/dist/red-hat-display.css +0 -2
  293. package/dist/rich-text-editor.js.map +0 -1
  294. package/dist/search-input.js.map +0 -1
  295. package/dist/select.js.map +0 -1
  296. package/dist/separator.js.map +0 -1
  297. package/dist/sheet.js.map +0 -1
  298. package/dist/sidebar.js.map +0 -1
  299. package/dist/size-context.js.map +0 -1
  300. package/dist/skeleton.js.map +0 -1
  301. package/dist/sparkline.js.map +0 -1
  302. package/dist/stepper.js.map +0 -1
  303. package/dist/switch.js.map +0 -1
  304. package/dist/tab-list.d.ts +0 -38
  305. package/dist/tab-list.js +0 -394
  306. package/dist/tab-list.js.map +0 -1
  307. package/dist/table.js.map +0 -1
  308. package/dist/tabs.js.map +0 -1
  309. package/dist/tag.js.map +0 -1
  310. package/dist/textarea.js.map +0 -1
  311. package/dist/theme/giddaa.css +0 -2
  312. package/dist/time-picker.js.map +0 -1
  313. package/dist/toast.js.map +0 -1
  314. package/dist/tooltip.js.map +0 -1
  315. package/dist/tree-map.js.map +0 -1
@@ -1,573 +1,244 @@
1
- // src/components/ui/phone-input.tsx
2
- import {
3
- AsYouType,
4
- getCountries,
5
- getCountryCallingCode,
6
- parsePhoneNumber
7
- } from "libphonenumber-js";
1
+ "use client";
2
+ import { t as cn } from "./cn-BI_4DMBf.js";
3
+ import { useComponentSize } from "./size-context.js";
4
+ import { Separator } from "./separator.js";
5
+ import { InputGroup, InputGroupAddon, InputGroupInput } from "./input-group.js";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
8
7
  import { CheckIcon, ChevronDownIcon, SearchIcon } from "lucide-react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import * as React from "react";
10
+ import { AsYouType, getCountries, getCountryCallingCode, parsePhoneNumber } from "libphonenumber-js";
10
11
  import flags from "react-phone-number-input/flags";
11
-
12
- // src/lib/cn.ts
13
- import { clsx } from "clsx";
14
- import { extendTailwindMerge } from "tailwind-merge";
15
- var twMerge = extendTailwindMerge({
16
- extend: {
17
- classGroups: {
18
- "font-size": [
19
- {
20
- text: [
21
- "gdt-display",
22
- "gdt-h1",
23
- "gdt-h2",
24
- "gdt-h3",
25
- "gdt-h4",
26
- "gdt-h5",
27
- "gdt-xl",
28
- "gdt-lg",
29
- "gdt-md",
30
- "gdt-sm",
31
- "gdt-xs",
32
- "gdt-subtext",
33
- "gdt-capitalized"
34
- ]
35
- }
36
- ]
37
- }
38
- }
39
- });
40
- function cn(...inputs) {
41
- return twMerge(clsx(inputs));
42
- }
43
-
44
- // src/components/ui/input-group.tsx
45
- import { cva as cva2 } from "class-variance-authority";
46
-
47
- // src/components/ui/size-context.tsx
48
- import { createContext, useContext } from "react";
49
- import { Fragment, jsx } from "react/jsx-runtime";
50
- var SizeContext = createContext(void 0);
51
- function SizeProvider({
52
- children,
53
- size
54
- }) {
55
- if (!size) {
56
- return /* @__PURE__ */ jsx(Fragment, { children });
57
- }
58
- return /* @__PURE__ */ jsx(SizeContext.Provider, { value: size, children });
59
- }
60
- function useComponentSize(size, fallback = "md") {
61
- const inheritedSize = useContext(SizeContext);
62
- return size ?? inheritedSize ?? fallback;
63
- }
64
-
65
- // src/components/ui/input.tsx
66
- import { Input as InputPrimitive } from "@base-ui/react/input";
67
- import { cva } from "class-variance-authority";
68
-
69
- // src/components/ui/input-size-context.tsx
70
- import { createContext as createContext2, useContext as useContext2 } from "react";
71
- import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
72
- var InputSizeContext = createContext2(
73
- void 0
74
- );
75
- function InputSizeProvider({
76
- children,
77
- size
78
- }) {
79
- if (!size) {
80
- return /* @__PURE__ */ jsx2(Fragment2, { children });
81
- }
82
- return /* @__PURE__ */ jsx2(InputSizeContext.Provider, { value: size, children });
83
- }
84
- function useInputComponentSize(size, fallback = "md") {
85
- const inheritedSize = useContext2(InputSizeContext);
86
- return size ?? inheritedSize ?? fallback;
87
- }
88
-
89
- // src/components/ui/input.tsx
90
- import { jsx as jsx3 } from "react/jsx-runtime";
91
- var inputVariants = cva(
92
- "flex w-full min-w-0 rounded-full border border-line bg-canvas text-fg-primary transition-[background-color,border-color,box-shadow,color] outline-none file:inline-flex file:border-0 file:bg-transparent file:font-normal file:text-fg-primary placeholder:text-fg-muted hover:border-line-strong focus-visible:border-line-focus focus-visible:inset-ring-1 inset-ring-line-focus disabled:pointer-events-none disabled:cursor-not-allowed disabled:border-line-subtle disabled:bg-surface disabled:text-fg-muted disabled:placeholder:text-fg-muted aria-invalid:border-line-danger aria-invalid:text-fg-danger aria-invalid:placeholder:text-fg-danger aria-invalid:shadow-none",
93
- {
94
- variants: {
95
- size: {
96
- sm: "h-8 px-3 text-gdt-xs font-normal file:text-gdt-xs",
97
- md: "h-10 px-3.5 text-gdt-sm font-normal file:text-gdt-sm",
98
- lg: "h-12 px-4 text-gdt-md font-normal file:text-gdt-md",
99
- xl: "h-14 px-4.5 text-gdt-lg font-normal file:text-gdt-lg"
100
- }
101
- },
102
- defaultVariants: {
103
- size: "md"
104
- }
105
- }
106
- );
107
- function Input({ className, size, type, ...props }) {
108
- const resolvedSize = useInputComponentSize(size);
109
- return /* @__PURE__ */ jsx3(
110
- InputPrimitive,
111
- {
112
- type,
113
- "data-slot": "input",
114
- "data-size": resolvedSize,
115
- className: cn(inputVariants({ size: resolvedSize }), className),
116
- ...props
117
- }
118
- );
119
- }
120
-
121
- // src/components/ui/input-group.tsx
122
- import { jsx as jsx4 } from "react/jsx-runtime";
123
- var inputGroupVariants = cva2(
124
- "group/input-group relative flex w-full min-w-0 items-center rounded-full has-[textarea]:rounded-xl has-data-[align=block-end]:rounded-xl has-data-[align=block-start]:rounded-xl border border-line bg-canvas transition-[background-color,border-color,box-shadow,color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:border-line-subtle has-disabled:bg-surface has-disabled:text-fg-muted focus-within:border-line-focus focus-within:inset-ring-1 inset-ring-line-focus has-[[data-slot][aria-invalid=true]]:border-line-danger has-[[data-slot][aria-invalid=true]]:inset-shadow-none has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:group-data-[size=sm]/input-group:pl-2 has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:group-data-[size=md]/input-group:pl-2.5 has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:group-data-[size=lg]/input-group:pl-3 has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:group-data-[size=xl]/input-group:pl-3 has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:group-data-[size=sm]/input-group:pr-2 has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:group-data-[size=md]/input-group:pr-2.5 has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:group-data-[size=lg]/input-group:pr-3 has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:group-data-[size=xl]/input-group:pr-3",
125
- {
126
- variants: {
127
- size: {
128
- sm: "h-8",
129
- md: "h-10",
130
- lg: "h-12",
131
- xl: "h-14"
132
- }
133
- },
134
- defaultVariants: {
135
- size: "md"
136
- }
137
- }
138
- );
139
- function InputGroup({
140
- className,
141
- size,
142
- ...props
143
- }) {
144
- const inheritedSize = useComponentSize();
145
- const resolvedSize = size ?? inheritedSize;
146
- const componentSize = resolvedSize === "xl" ? void 0 : resolvedSize;
147
- return /* @__PURE__ */ jsx4(SizeProvider, { size: componentSize, children: /* @__PURE__ */ jsx4(InputSizeProvider, { size: resolvedSize, children: /* @__PURE__ */ jsx4(
148
- "div",
149
- {
150
- "data-slot": "input-group",
151
- "data-size": resolvedSize,
152
- role: "group",
153
- className: cn(inputGroupVariants({ size: resolvedSize }), className),
154
- ...props
155
- }
156
- ) }) });
157
- }
158
- var inputGroupAddonVariants = cva2(
159
- "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-gdt-sm font-normal text-fg-secondary select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[size=lg]/input-group:[&>svg:not([class*='size-'])]:size-4.5 group-data-[size=xl]/input-group:[&>svg:not([class*='size-'])]:size-5 [&>svg:not([class*='size-'])]:size-4",
160
- {
161
- variants: {
162
- align: {
163
- "inline-start": "order-first group-data-[size=sm]/input-group:pl-3 group-data-[size=md]/input-group:pl-3.5 group-data-[size=lg]/input-group:pl-4 group-data-[size=xl]/input-group:pl-4.5 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
164
- "inline-end": "order-last group-data-[size=sm]/input-group:pr-3 group-data-[size=md]/input-group:pr-3.5 group-data-[size=lg]/input-group:pr-4 group-data-[size=xl]/input-group:pr-4.5 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
165
- "block-start": "order-first w-full justify-start px-3 group-data-[size=md]/input-group:px-3.5 group-data-[size=lg]/input-group:px-4 group-data-[size=xl]/input-group:px-4.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
166
- "block-end": "order-last w-full justify-start px-3 group-data-[size=md]/input-group:px-3.5 group-data-[size=lg]/input-group:px-4 group-data-[size=xl]/input-group:px-4.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
167
- }
168
- },
169
- defaultVariants: {
170
- align: "inline-start"
171
- }
172
- }
173
- );
174
- function InputGroupAddon({
175
- className,
176
- align = "inline-start",
177
- ...props
178
- }) {
179
- return (
180
- // biome-ignore lint/a11y/useSemanticElements: addon is a structural wrapper for grouped input affordances.
181
- // biome-ignore lint/a11y/useKeyWithClickEvents: click only forwards focus to the sibling input and is not a standalone action target.
182
- /* @__PURE__ */ jsx4(
183
- "div",
184
- {
185
- role: "group",
186
- "data-slot": "input-group-addon",
187
- "data-align": align,
188
- className: cn(inputGroupAddonVariants({ align }), className),
189
- onClick: (e) => {
190
- if (e.target.closest("button")) {
191
- return;
192
- }
193
- e.currentTarget.parentElement?.querySelector("input")?.focus();
194
- },
195
- ...props
196
- }
197
- )
198
- );
199
- }
200
- var inputGroupButtonVariants = cva2(
201
- "flex items-center gap-2 text-sm shadow-none rounded-full",
202
- {
203
- variants: {
204
- size: {
205
- xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
206
- sm: "",
207
- "icon-xs": "size-6 p-0 has-[>svg]:p-0",
208
- "icon-sm": "size-8 p-0 has-[>svg]:p-0"
209
- }
210
- },
211
- defaultVariants: {
212
- size: "xs"
213
- }
214
- }
215
- );
216
- function InputGroupInput({
217
- className,
218
- size,
219
- ...props
220
- }) {
221
- return /* @__PURE__ */ jsx4(
222
- Input,
223
- {
224
- "data-slot": "input-group-control",
225
- size,
226
- className: cn(
227
- "flex-1 rounded-none border-0 bg-transparent shadow-none inset-shadow-none inset-ring-0 focus:border-transparent focus:shadow-none focus:inset-shadow-none focus-visible:border-transparent focus-visible:shadow-none focus-visible:ring-0 focus-visible:inset-ring-0 focus-visible:inset-shadow-none disabled:bg-transparent aria-invalid:ring-0 aria-invalid:inset-ring-0 dark:bg-transparent dark:disabled:bg-transparent",
228
- className
229
- ),
230
- ...props
231
- }
232
- );
233
- }
234
-
235
- // src/components/ui/popover.tsx
236
- import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
237
- import { jsx as jsx5, jsxs } from "react/jsx-runtime";
238
- function Popover({ ...props }) {
239
- return /* @__PURE__ */ jsx5(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
240
- }
241
- function PopoverTrigger({ ...props }) {
242
- return /* @__PURE__ */ jsx5(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
243
- }
244
- function PopoverContent({
245
- className,
246
- align = "center",
247
- alignOffset = 0,
248
- side = "bottom",
249
- sideOffset = 6,
250
- showArrow = true,
251
- size = "md",
252
- children,
253
- ...props
254
- }) {
255
- return /* @__PURE__ */ jsx5(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx5(
256
- PopoverPrimitive.Positioner,
257
- {
258
- align,
259
- alignOffset,
260
- side,
261
- sideOffset,
262
- className: "isolate z-50",
263
- children: /* @__PURE__ */ jsxs(
264
- PopoverPrimitive.Popup,
265
- {
266
- "data-slot": "popover-content",
267
- className: cn(
268
- "z-50 relative flex w-72 max-w-[calc(100vw-2rem)] origin-(--transform-origin) flex-col rounded-lg border-0 bg-surface-overlay py-4 text-gdt-sm text-fg-primary shadow-2 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 has-[&_[data-slot=popover-footer]]:pb-0",
269
- className
270
- ),
271
- ...props,
272
- children: [
273
- /* @__PURE__ */ jsx5(SizeProvider, { size, children }),
274
- showArrow ? /* @__PURE__ */ jsx5(PopoverPrimitive.Arrow, { className: "relative block w-3 h-1.5 overflow-clip data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180 before:content-[''] before:absolute before:bottom-0 before:left-1/2 before:w-[calc(6px*sqrt(2))] before:h-[calc(6px*sqrt(2))] before:bg-surface-overlay before:border before:border-line before:[transform:translate(-50%,50%)_rotate(45deg)]" }) : null
275
- ]
276
- }
277
- )
278
- }
279
- ) });
280
- }
281
-
282
- // src/components/ui/separator.tsx
283
- import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
284
- import { jsx as jsx6 } from "react/jsx-runtime";
285
- function Separator({
286
- className,
287
- orientation = "horizontal",
288
- dashed = false,
289
- shade = "feint",
290
- thickness = "default",
291
- ...props
292
- }) {
293
- return /* @__PURE__ */ jsx6(
294
- SeparatorPrimitive,
295
- {
296
- "data-slot": "separator",
297
- orientation,
298
- className: cn(
299
- "shrink-0 data-horizontal:h-0 data-horizontal:w-full data-vertical:w-0 data-vertical:self-stretch",
300
- // style
301
- dashed ? "border-dashed" : "border-solid",
302
- // shade
303
- shade === "feint" && "border-line-subtle",
304
- shade === "deep" && "border-line",
305
- // thickness
306
- thickness === "hairline" && "data-horizontal:border-t-[0.5px] data-vertical:border-l-[0.5px]",
307
- thickness === "default" && "data-horizontal:border-t data-vertical:border-l",
308
- thickness === "thick" && "data-horizontal:border-t-2 data-vertical:border-l-2",
309
- thickness === "extra-thick" && "data-horizontal:border-t-[3px] data-vertical:border-l-[3px]",
310
- className
311
- ),
312
- ...props
313
- }
314
- );
315
- }
316
-
317
- // src/components/ui/phone-input.tsx
318
- import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
319
- var regionNames = typeof Intl !== "undefined" && "DisplayNames" in Intl ? new Intl.DisplayNames(["en"], { type: "region" }) : void 0;
320
- var COUNTRIES = getCountries().map((code) => ({
321
- code,
322
- name: regionNames?.of(code) ?? code,
323
- calling: getCountryCallingCode(code)
12
+ //#region src/phone-input.tsx
13
+ const regionNames = typeof Intl !== "undefined" && "DisplayNames" in Intl ? new Intl.DisplayNames(["en"], { type: "region" }) : void 0;
14
+ const COUNTRIES = getCountries().map((code) => ({
15
+ code,
16
+ name: regionNames?.of(code) ?? code,
17
+ calling: getCountryCallingCode(code)
324
18
  })).sort((a, b) => a.name.localeCompare(b.name));
325
19
  function getNationalDigits(value) {
326
- return value.replace(/\D/g, "");
20
+ return value.replace(/\D/g, "");
327
21
  }
328
22
  function formatNational(digits, country) {
329
- if (!digits) return "";
330
- return new AsYouType(country).input(digits);
23
+ if (!digits) return "";
24
+ return new AsYouType(country).input(digits);
331
25
  }
332
26
  function toE164(digits, country) {
333
- if (!digits) return void 0;
334
- return `+${getCountryCallingCode(country)}${digits}`;
27
+ if (!digits) return void 0;
28
+ return `+${getCountryCallingCode(country)}${digits}`;
335
29
  }
336
30
  function parseValue(value) {
337
- if (!value) return { digits: "" };
338
- try {
339
- const parsed = parsePhoneNumber(value);
340
- if (parsed?.nationalNumber) {
341
- return { country: parsed.country, digits: parsed.nationalNumber };
342
- }
343
- } catch {
344
- }
345
- return { digits: "" };
346
- }
347
- var flagSizeVariants = {
348
- sm: "h-3 w-[18px]",
349
- md: "h-3.5 w-5",
350
- lg: "h-4 w-6"
351
- };
352
- function CountryFlag({
353
- country,
354
- size,
355
- className
356
- }) {
357
- const Flag = flags[country];
358
- return /* @__PURE__ */ jsx7(
359
- "span",
360
- {
361
- className: cn(
362
- "inline-flex shrink-0 items-center justify-center overflow-hidden rounded-[3px] bg-surface-raised [&>svg]:h-full [&>svg]:w-full [&>svg]:object-cover",
363
- flagSizeVariants[size],
364
- className
365
- ),
366
- children: Flag ? /* @__PURE__ */ jsx7(Flag, { title: country }) : /* @__PURE__ */ jsx7("span", { className: "text-gdt-xs text-fg-secondary", children: country })
367
- }
368
- );
369
- }
370
- function CountrySelect({
371
- country,
372
- size,
373
- disabled,
374
- onSelect
375
- }) {
376
- const [open, setOpen] = React.useState(false);
377
- const [query, setQuery] = React.useState("");
378
- const searchRef = React.useRef(null);
379
- React.useEffect(() => {
380
- if (!open) return;
381
- const frame = requestAnimationFrame(() => searchRef.current?.focus());
382
- return () => cancelAnimationFrame(frame);
383
- }, [open]);
384
- const filtered = React.useMemo(() => {
385
- const q = query.trim().toLowerCase();
386
- if (!q) return COUNTRIES;
387
- const normalized = q.replace(/^\+/, "");
388
- return COUNTRIES.filter(
389
- (entry) => entry.name.toLowerCase().includes(q) || entry.calling.includes(normalized) || entry.code.toLowerCase().includes(q)
390
- );
391
- }, [query]);
392
- function handleOpenChange(next) {
393
- setOpen(next);
394
- if (!next) setQuery("");
395
- }
396
- return /* @__PURE__ */ jsxs2(Popover, { open, onOpenChange: handleOpenChange, children: [
397
- /* @__PURE__ */ jsxs2(
398
- PopoverTrigger,
399
- {
400
- disabled,
401
- "data-slot": "phone-country-trigger",
402
- className: cn(
403
- "flex shrink-0 items-center gap-1.5 rounded-full font-normal text-fg-primary outline-none transition-colors select-none",
404
- "focus-visible:text-fg-brand disabled:cursor-not-allowed disabled:text-fg-caption-placeholder",
405
- size === "sm" && "text-gdt-xs",
406
- size === "md" && "text-gdt-sm",
407
- size === "lg" && "text-gdt-md"
408
- ),
409
- children: [
410
- /* @__PURE__ */ jsx7(CountryFlag, { country, size }),
411
- /* @__PURE__ */ jsxs2("span", { children: [
412
- "+",
413
- getCountryCallingCode(country)
414
- ] }),
415
- /* @__PURE__ */ jsx7(
416
- ChevronDownIcon,
417
- {
418
- className: cn(
419
- "text-fg-secondary transition-transform",
420
- open && "rotate-180",
421
- size === "lg" ? "size-4" : "size-3.5"
422
- )
423
- }
424
- )
425
- ]
426
- }
427
- ),
428
- /* @__PURE__ */ jsxs2(
429
- PopoverContent,
430
- {
431
- showArrow: false,
432
- align: "start",
433
- alignOffset: 0,
434
- sideOffset: 10,
435
- className: "w-72 gap-0 overflow-hidden p-0",
436
- children: [
437
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 border-b border-line-subtle px-3.5 py-2.5", children: [
438
- /* @__PURE__ */ jsx7(SearchIcon, { className: "size-4 shrink-0 text-fg-secondary" }),
439
- /* @__PURE__ */ jsx7(
440
- "input",
441
- {
442
- ref: searchRef,
443
- value: query,
444
- onChange: (event) => setQuery(event.target.value),
445
- placeholder: "Search country",
446
- className: "w-full bg-transparent text-gdt-sm text-fg-primary outline-none placeholder:text-fg-caption-placeholder"
447
- }
448
- )
449
- ] }),
450
- /* @__PURE__ */ jsx7("div", { className: "no-scrollbar max-h-64 overflow-y-auto py-1.5", children: filtered.length === 0 ? /* @__PURE__ */ jsx7("p", { className: "px-3.5 py-6 text-center text-gdt-sm text-fg-secondary", children: "No country found" }) : filtered.map((entry) => {
451
- const selected = entry.code === country;
452
- return /* @__PURE__ */ jsxs2(
453
- "button",
454
- {
455
- type: "button",
456
- onClick: () => {
457
- onSelect(entry.code);
458
- handleOpenChange(false);
459
- },
460
- className: cn(
461
- "flex w-full items-center gap-2.5 px-3.5 py-2 text-left text-gdt-sm outline-none transition-colors hover:bg-surface focus-visible:bg-surface",
462
- selected ? "font-medium text-fg-brand" : "text-fg-primary"
463
- ),
464
- children: [
465
- /* @__PURE__ */ jsx7(CountryFlag, { country: entry.code, size: "md" }),
466
- /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: entry.name }),
467
- /* @__PURE__ */ jsxs2("span", { className: "shrink-0 text-fg-secondary", children: [
468
- "+",
469
- entry.calling
470
- ] }),
471
- selected && /* @__PURE__ */ jsx7(CheckIcon, { className: "size-4 shrink-0 text-fg-brand" })
472
- ]
473
- },
474
- entry.code
475
- );
476
- }) })
477
- ]
478
- }
479
- )
480
- ] });
481
- }
482
- function PhoneInput({
483
- value,
484
- onChange,
485
- defaultCountry = "NG",
486
- size,
487
- disabled = false,
488
- readOnly = false,
489
- placeholder = "(0000) 000-0000",
490
- className,
491
- id,
492
- name,
493
- "aria-invalid": ariaInvalid
494
- }) {
495
- const resolvedSize = useComponentSize(size);
496
- const initial = React.useMemo(() => parseValue(value), []);
497
- const [country, setCountry] = React.useState(
498
- initial.country ?? defaultCountry
499
- );
500
- const [national, setNational] = React.useState(
501
- () => formatNational(initial.digits, initial.country ?? defaultCountry)
502
- );
503
- React.useEffect(() => {
504
- const currentDigits = getNationalDigits(national);
505
- if (toE164(currentDigits, country) === value) return;
506
- const next = parseValue(value);
507
- const nextCountry = next.country ?? country;
508
- setCountry(nextCountry);
509
- setNational(formatNational(next.digits, nextCountry));
510
- }, [value]);
511
- function emit(digits, nextCountry) {
512
- onChange?.(toE164(digits, nextCountry));
513
- }
514
- function handleInputChange(event) {
515
- const digits = getNationalDigits(event.target.value);
516
- setNational(formatNational(digits, country));
517
- emit(digits, country);
518
- }
519
- function handleCountrySelect(nextCountry) {
520
- const digits = getNationalDigits(national);
521
- setCountry(nextCountry);
522
- setNational(formatNational(digits, nextCountry));
523
- emit(digits, nextCountry);
524
- }
525
- const dividerStateClasses = cn(
526
- "group-hover/input-group:bg-line-strong",
527
- "group-focus-within/input-group:bg-line-focus",
528
- "group-has-[[aria-invalid=true]]/input-group:bg-line-danger",
529
- "group-has-disabled/input-group:bg-line-subtle"
530
- );
531
- return /* @__PURE__ */ jsxs2(InputGroup, { size: resolvedSize, className, children: [
532
- /* @__PURE__ */ jsxs2(InputGroupAddon, { align: "inline-start", className: "gap-2", children: [
533
- /* @__PURE__ */ jsx7(
534
- CountrySelect,
535
- {
536
- country,
537
- size: resolvedSize,
538
- disabled,
539
- onSelect: handleCountrySelect
540
- }
541
- ),
542
- /* @__PURE__ */ jsx7(
543
- Separator,
544
- {
545
- orientation: "vertical",
546
- shade: "deep",
547
- className: cn("self-stretch transition-colors", dividerStateClasses)
548
- }
549
- )
550
- ] }),
551
- /* @__PURE__ */ jsx7(
552
- InputGroupInput,
553
- {
554
- id,
555
- name,
556
- type: "tel",
557
- inputMode: "tel",
558
- autoComplete: "tel",
559
- value: national,
560
- onChange: handleInputChange,
561
- placeholder,
562
- disabled,
563
- readOnly,
564
- "aria-invalid": ariaInvalid || void 0,
565
- className: "pl-0"
566
- }
567
- )
568
- ] });
569
- }
570
- export {
571
- PhoneInput
31
+ if (!value) return { digits: "" };
32
+ try {
33
+ const parsed = parsePhoneNumber(value);
34
+ if (parsed?.nationalNumber) return {
35
+ country: parsed.country,
36
+ digits: parsed.nationalNumber
37
+ };
38
+ } catch {}
39
+ return { digits: "" };
40
+ }
41
+ const flagSizeVariants = {
42
+ sm: "h-3 w-[18px]",
43
+ md: "h-3.5 w-5",
44
+ lg: "h-4 w-6"
572
45
  };
573
- //# sourceMappingURL=phone-input.js.map
46
+ function CountryFlag({ country, size, className }) {
47
+ const Flag = flags[country];
48
+ return /* @__PURE__ */ jsx("span", {
49
+ className: cn("inline-flex shrink-0 items-center justify-center overflow-hidden rounded-[3px] bg-surface-raised [&>svg]:h-full [&>svg]:w-full [&>svg]:object-cover", flagSizeVariants[size], className),
50
+ children: Flag ? /* @__PURE__ */ jsx(Flag, { title: country }) : /* @__PURE__ */ jsx("span", {
51
+ className: "text-gdt-xs text-fg-secondary",
52
+ children: country
53
+ })
54
+ });
55
+ }
56
+ const ROW_HEIGHT = 40;
57
+ const LIST_PADDING = 6;
58
+ const OVERSCAN = 6;
59
+ function CountryList({ items, country, onSelect }) {
60
+ const scrollRef = React.useRef(null);
61
+ const [viewport, setViewport] = React.useState(256);
62
+ const [scrollTop, setScrollTop] = React.useState(() => {
63
+ const index = items.findIndex((entry) => entry.code === country);
64
+ return index > 0 ? index * ROW_HEIGHT : 0;
65
+ });
66
+ React.useLayoutEffect(() => {
67
+ const el = scrollRef.current;
68
+ if (!el) return;
69
+ setViewport(el.clientHeight);
70
+ el.scrollTop = scrollTop;
71
+ }, []);
72
+ if (items.length === 0) return /* @__PURE__ */ jsx("p", {
73
+ className: "px-3.5 py-6 text-center text-gdt-sm text-fg-secondary",
74
+ children: "No country found"
75
+ });
76
+ const total = items.length;
77
+ const first = Math.max(0, Math.floor(scrollTop / ROW_HEIGHT) - OVERSCAN);
78
+ const last = Math.min(total, Math.ceil((scrollTop + viewport) / ROW_HEIGHT) + OVERSCAN);
79
+ const visible = items.slice(first, last);
80
+ return /* @__PURE__ */ jsx("div", {
81
+ ref: scrollRef,
82
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
83
+ className: "no-scrollbar max-h-64 overflow-y-auto",
84
+ children: /* @__PURE__ */ jsx("div", {
85
+ className: "relative w-full",
86
+ style: { height: total * ROW_HEIGHT + LIST_PADDING * 2 },
87
+ children: visible.map((entry, i) => {
88
+ const index = first + i;
89
+ const selected = entry.code === country;
90
+ return /* @__PURE__ */ jsxs("button", {
91
+ type: "button",
92
+ style: {
93
+ position: "absolute",
94
+ top: index * ROW_HEIGHT + LIST_PADDING,
95
+ height: ROW_HEIGHT
96
+ },
97
+ onClick: () => onSelect(entry.code),
98
+ className: cn("flex w-full items-center gap-2.5 px-3.5 text-left text-gdt-sm outline-none transition-colors hover:bg-surface focus-visible:bg-surface", selected ? "font-medium text-fg-brand" : "text-fg-primary"),
99
+ children: [
100
+ /* @__PURE__ */ jsx(CountryFlag, {
101
+ country: entry.code,
102
+ size: "md"
103
+ }),
104
+ /* @__PURE__ */ jsx("span", {
105
+ className: "min-w-0 flex-1 truncate",
106
+ children: entry.name
107
+ }),
108
+ /* @__PURE__ */ jsxs("span", {
109
+ className: "shrink-0 text-fg-secondary",
110
+ children: ["+", entry.calling]
111
+ }),
112
+ selected && /* @__PURE__ */ jsx(CheckIcon, { className: "size-4 shrink-0 text-fg-brand" })
113
+ ]
114
+ }, entry.code);
115
+ })
116
+ })
117
+ });
118
+ }
119
+ function CountrySelect({ country, size, disabled, onSelect, finalFocusRef }) {
120
+ const [open, setOpen] = React.useState(false);
121
+ const [query, setQuery] = React.useState("");
122
+ const searchRef = React.useRef(null);
123
+ const filtered = React.useMemo(() => {
124
+ const q = query.trim().toLowerCase();
125
+ if (!q) return COUNTRIES;
126
+ const normalized = q.replace(/^\+/, "");
127
+ return COUNTRIES.filter((entry) => entry.name.toLowerCase().includes(q) || entry.calling.includes(normalized) || entry.code.toLowerCase().includes(q));
128
+ }, [query]);
129
+ function handleOpenChange(next) {
130
+ setOpen(next);
131
+ if (!next) setQuery("");
132
+ }
133
+ function handleSelect(next) {
134
+ onSelect(next);
135
+ handleOpenChange(false);
136
+ }
137
+ return /* @__PURE__ */ jsxs(Popover, {
138
+ open,
139
+ onOpenChange: handleOpenChange,
140
+ children: [/* @__PURE__ */ jsxs(PopoverTrigger, {
141
+ disabled,
142
+ "data-slot": "phone-country-trigger",
143
+ className: cn("flex shrink-0 items-center gap-1.5 rounded-full font-normal text-fg-primary outline-none transition-colors select-none", "focus-visible:text-fg-brand disabled:cursor-not-allowed disabled:text-fg-caption-placeholder", size === "sm" && "text-gdt-xs", size === "md" && "text-gdt-sm", size === "lg" && "text-gdt-md"),
144
+ children: [
145
+ /* @__PURE__ */ jsx(CountryFlag, {
146
+ country,
147
+ size
148
+ }),
149
+ /* @__PURE__ */ jsxs("span", { children: ["+", getCountryCallingCode(country)] }),
150
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("text-fg-secondary transition-transform", open && "rotate-180", size === "lg" ? "size-4" : "size-3.5") })
151
+ ]
152
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
153
+ showArrow: false,
154
+ align: "start",
155
+ alignOffset: 0,
156
+ sideOffset: 10,
157
+ finalFocus: finalFocusRef,
158
+ className: "w-72 gap-0 overflow-hidden p-0",
159
+ children: [/* @__PURE__ */ jsxs("div", {
160
+ className: "flex items-center gap-2 border-b border-line-subtle px-3.5 py-2.5",
161
+ children: [/* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 text-fg-secondary" }), /* @__PURE__ */ jsx("input", {
162
+ ref: searchRef,
163
+ value: query,
164
+ onChange: (event) => setQuery(event.target.value),
165
+ placeholder: "Search country",
166
+ className: "w-full bg-transparent text-gdt-sm text-fg-primary outline-none placeholder:text-fg-caption-placeholder"
167
+ })]
168
+ }), /* @__PURE__ */ jsx(CountryList, {
169
+ items: filtered,
170
+ country,
171
+ onSelect: handleSelect
172
+ }, query)]
173
+ })]
174
+ });
175
+ }
176
+ function PhoneInput({ value, onChange, defaultCountry = "NG", size, disabled = false, readOnly = false, placeholder = "(0000) 000-0000", className, id, name, ref, "aria-invalid": ariaInvalid }) {
177
+ const resolvedSize = useComponentSize(size);
178
+ const inputRef = React.useRef(null);
179
+ const setInputRef = React.useCallback((node) => {
180
+ inputRef.current = node;
181
+ if (typeof ref === "function") ref(node);
182
+ else if (ref) ref.current = node;
183
+ }, [ref]);
184
+ const initial = React.useMemo(() => parseValue(value), []);
185
+ const [country, setCountry] = React.useState(initial.country ?? defaultCountry);
186
+ const [national, setNational] = React.useState(() => formatNational(initial.digits, initial.country ?? defaultCountry));
187
+ React.useEffect(() => {
188
+ if (toE164(getNationalDigits(national), country) === value) return;
189
+ const next = parseValue(value);
190
+ const nextCountry = next.country ?? country;
191
+ setCountry(nextCountry);
192
+ setNational(formatNational(next.digits, nextCountry));
193
+ }, [value]);
194
+ function emit(digits, nextCountry) {
195
+ onChange?.(toE164(digits, nextCountry));
196
+ }
197
+ function handleInputChange(event) {
198
+ const digits = getNationalDigits(event.target.value);
199
+ setNational(formatNational(digits, country));
200
+ emit(digits, country);
201
+ }
202
+ function handleCountrySelect(nextCountry) {
203
+ const digits = getNationalDigits(national);
204
+ setCountry(nextCountry);
205
+ setNational(formatNational(digits, nextCountry));
206
+ emit(digits, nextCountry);
207
+ }
208
+ const dividerStateClasses = cn("group-hover/input-group:bg-line-strong", "group-focus-within/input-group:bg-line-focus", "group-has-[[aria-invalid=true]]/input-group:bg-line-danger", "group-has-disabled/input-group:bg-line-subtle");
209
+ return /* @__PURE__ */ jsxs(InputGroup, {
210
+ size: resolvedSize,
211
+ className,
212
+ children: [/* @__PURE__ */ jsxs(InputGroupAddon, {
213
+ align: "inline-start",
214
+ className: "gap-2 self-stretch py-0",
215
+ children: [/* @__PURE__ */ jsx(CountrySelect, {
216
+ country,
217
+ size: resolvedSize,
218
+ disabled,
219
+ onSelect: handleCountrySelect,
220
+ finalFocusRef: inputRef
221
+ }), /* @__PURE__ */ jsx(Separator, {
222
+ orientation: "vertical",
223
+ shade: "deep",
224
+ className: cn("self-stretch transition-colors", dividerStateClasses)
225
+ })]
226
+ }), /* @__PURE__ */ jsx(InputGroupInput, {
227
+ ref: setInputRef,
228
+ id,
229
+ name,
230
+ type: "tel",
231
+ inputMode: "tel",
232
+ autoComplete: "tel",
233
+ value: national,
234
+ onChange: handleInputChange,
235
+ placeholder,
236
+ disabled,
237
+ readOnly,
238
+ "aria-invalid": ariaInvalid || void 0,
239
+ className: "pl-0"
240
+ })]
241
+ });
242
+ }
243
+ //#endregion
244
+ export { PhoneInput };