@mieweb/ui 0.7.3 → 0.8.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 (323) hide show
  1. package/README.md +45 -24
  2. package/agent/README.md +20 -0
  3. package/agent/init-agent.mjs +61 -0
  4. package/agent/mieweb-ui.instructions.md +169 -0
  5. package/dist/ag-grid.cjs +11 -0
  6. package/dist/ag-grid.cjs.map +1 -1
  7. package/dist/ag-grid.d.cts +4 -0
  8. package/dist/ag-grid.d.ts +4 -0
  9. package/dist/ag-grid.js +11 -0
  10. package/dist/ag-grid.js.map +1 -1
  11. package/dist/brands/index.cjs +12 -12
  12. package/dist/brands/index.js +3 -3
  13. package/dist/chunk-3IMM2PM4.js +259 -0
  14. package/dist/chunk-3IMM2PM4.js.map +1 -0
  15. package/dist/chunk-3SHLOF4V.cjs +128 -0
  16. package/dist/chunk-3SHLOF4V.cjs.map +1 -0
  17. package/dist/chunk-3TXOFAXP.cjs +139 -0
  18. package/dist/chunk-3TXOFAXP.cjs.map +1 -0
  19. package/dist/{chunk-ZBI52NP2.cjs → chunk-56QJHQ5C.cjs} +156 -39
  20. package/dist/chunk-56QJHQ5C.cjs.map +1 -0
  21. package/dist/chunk-5JZIDILK.cjs +164 -0
  22. package/dist/chunk-5JZIDILK.cjs.map +1 -0
  23. package/dist/chunk-5MXO6PEV.cjs +78 -0
  24. package/dist/chunk-5MXO6PEV.cjs.map +1 -0
  25. package/dist/chunk-5QZ73PZC.js +62 -0
  26. package/dist/chunk-5QZ73PZC.js.map +1 -0
  27. package/dist/chunk-6NZXWKUE.js +3 -0
  28. package/dist/chunk-6NZXWKUE.js.map +1 -0
  29. package/dist/chunk-6SCQ7FKT.js +115 -0
  30. package/dist/chunk-6SCQ7FKT.js.map +1 -0
  31. package/dist/{chunk-KFLDXJEE.js → chunk-753Z3NXL.js} +46 -15
  32. package/dist/chunk-753Z3NXL.js.map +1 -0
  33. package/dist/{chunk-S3MKIDYG.cjs → chunk-7AECNMYV.cjs} +46 -15
  34. package/dist/chunk-7AECNMYV.cjs.map +1 -0
  35. package/dist/chunk-7IKLGH3Z.cjs +92 -0
  36. package/dist/chunk-7IKLGH3Z.cjs.map +1 -0
  37. package/dist/chunk-7L7OPISJ.cjs +291 -0
  38. package/dist/chunk-7L7OPISJ.cjs.map +1 -0
  39. package/dist/chunk-7RV6CAP6.cjs +106 -0
  40. package/dist/chunk-7RV6CAP6.cjs.map +1 -0
  41. package/dist/{chunk-LC7YHZXM.js → chunk-A5YOIJKL.js} +5 -5
  42. package/dist/{chunk-LC7YHZXM.js.map → chunk-A5YOIJKL.js.map} +1 -1
  43. package/dist/{chunk-6MMIWE7H.js → chunk-AESFOMSH.js} +373 -4
  44. package/dist/chunk-AESFOMSH.js.map +1 -0
  45. package/dist/{chunk-RBS3GHDZ.cjs → chunk-BOW7ZGI2.cjs} +4 -4
  46. package/dist/{chunk-RBS3GHDZ.cjs.map → chunk-BOW7ZGI2.cjs.map} +1 -1
  47. package/dist/{chunk-WUNWHOLA.cjs → chunk-BSDBI6H7.cjs} +116 -26
  48. package/dist/chunk-BSDBI6H7.cjs.map +1 -0
  49. package/dist/chunk-CG4ZKJLE.js +84 -0
  50. package/dist/chunk-CG4ZKJLE.js.map +1 -0
  51. package/dist/{chunk-Z4PECE5S.js → chunk-DX64KLSN.js} +2 -2
  52. package/dist/{chunk-Z4PECE5S.js.map → chunk-DX64KLSN.js.map} +1 -1
  53. package/dist/chunk-ELYGV32O.cjs +230 -0
  54. package/dist/chunk-ELYGV32O.cjs.map +1 -0
  55. package/dist/{chunk-QUUBTNMH.js → chunk-EPSB4WTL.js} +45 -15
  56. package/dist/chunk-EPSB4WTL.js.map +1 -0
  57. package/dist/chunk-F57VRLKP.js +708 -0
  58. package/dist/chunk-F57VRLKP.js.map +1 -0
  59. package/dist/{chunk-5IDYOJHO.cjs → chunk-G7EQ3JPX.cjs} +45 -15
  60. package/dist/chunk-G7EQ3JPX.cjs.map +1 -0
  61. package/dist/{chunk-FKLUSYFP.cjs → chunk-GQVL2JKQ.cjs} +4 -4
  62. package/dist/{chunk-FKLUSYFP.cjs.map → chunk-GQVL2JKQ.cjs.map} +1 -1
  63. package/dist/{chunk-3D4ITDLO.js → chunk-GXODR6V4.js} +3 -3
  64. package/dist/{chunk-3D4ITDLO.js.map → chunk-GXODR6V4.js.map} +1 -1
  65. package/dist/{chunk-AFGADE3B.js → chunk-H3YO5GBM.js} +117 -27
  66. package/dist/chunk-H3YO5GBM.js.map +1 -0
  67. package/dist/chunk-HK3AMH3Q.cjs +151 -0
  68. package/dist/chunk-HK3AMH3Q.cjs.map +1 -0
  69. package/dist/chunk-HQ3XPCHG.js +114 -0
  70. package/dist/chunk-HQ3XPCHG.js.map +1 -0
  71. package/dist/chunk-I44YNYI6.cjs +4 -0
  72. package/dist/chunk-I44YNYI6.cjs.map +1 -0
  73. package/dist/{chunk-EGWWTIWS.js → chunk-IILJGFI5.js} +125 -95
  74. package/dist/chunk-IILJGFI5.js.map +1 -0
  75. package/dist/{chunk-KRGKPUJH.js → chunk-IYXCFIMP.js} +8 -8
  76. package/dist/{chunk-KRGKPUJH.js.map → chunk-IYXCFIMP.js.map} +1 -1
  77. package/dist/{chunk-6J7UGYT5.cjs → chunk-JHGMZX4I.cjs} +47 -7
  78. package/dist/chunk-JHGMZX4I.cjs.map +1 -0
  79. package/dist/chunk-JHZW3Y62.js +142 -0
  80. package/dist/chunk-JHZW3Y62.js.map +1 -0
  81. package/dist/{chunk-JDHIBJ5K.cjs → chunk-JWTCEWQ4.cjs} +2 -2
  82. package/dist/{chunk-JDHIBJ5K.cjs.map → chunk-JWTCEWQ4.cjs.map} +1 -1
  83. package/dist/{chunk-URHXR5SC.cjs → chunk-KVE7PQ5P.cjs} +7 -7
  84. package/dist/{chunk-URHXR5SC.cjs.map → chunk-KVE7PQ5P.cjs.map} +1 -1
  85. package/dist/{chunk-LJDBD2DD.cjs → chunk-L6D4CKLV.cjs} +373 -4
  86. package/dist/chunk-L6D4CKLV.cjs.map +1 -0
  87. package/dist/chunk-L6MDULYB.js +87 -0
  88. package/dist/chunk-L6MDULYB.js.map +1 -0
  89. package/dist/{chunk-SYIFEJSF.cjs → chunk-LQHI44OZ.cjs} +13 -13
  90. package/dist/{chunk-SYIFEJSF.cjs.map → chunk-LQHI44OZ.cjs.map} +1 -1
  91. package/dist/{chunk-HIDV32ZX.js → chunk-LZU7YBXG.js} +3 -3
  92. package/dist/{chunk-HIDV32ZX.js.map → chunk-LZU7YBXG.js.map} +1 -1
  93. package/dist/chunk-N5O47VGS.cjs +109 -0
  94. package/dist/chunk-N5O47VGS.cjs.map +1 -0
  95. package/dist/chunk-NGSDBWKA.cjs +84 -0
  96. package/dist/chunk-NGSDBWKA.cjs.map +1 -0
  97. package/dist/chunk-NMBYU7D7.cjs +31 -0
  98. package/dist/chunk-NMBYU7D7.cjs.map +1 -0
  99. package/dist/{chunk-P6L74SKG.js → chunk-QGZC43L7.js} +47 -7
  100. package/dist/chunk-QGZC43L7.js.map +1 -0
  101. package/dist/{chunk-FTRGZOVJ.js → chunk-QHTDWIED.js} +3 -3
  102. package/dist/{chunk-FTRGZOVJ.js.map → chunk-QHTDWIED.js.map} +1 -1
  103. package/dist/chunk-RUGHNFQG.js +28 -0
  104. package/dist/chunk-RUGHNFQG.js.map +1 -0
  105. package/dist/{chunk-NQ2D2V6O.cjs → chunk-SK7H3Z67.cjs} +37 -37
  106. package/dist/{chunk-NQ2D2V6O.cjs.map → chunk-SK7H3Z67.cjs.map} +1 -1
  107. package/dist/{chunk-MO65V64I.js → chunk-TXRQQMG5.js} +2 -2
  108. package/dist/{chunk-MO65V64I.js.map → chunk-TXRQQMG5.js.map} +1 -1
  109. package/dist/{chunk-OAHORW4N.cjs → chunk-U5TTXN45.cjs} +127 -97
  110. package/dist/chunk-U5TTXN45.cjs.map +1 -0
  111. package/dist/chunk-WBGUYSWY.js +90 -0
  112. package/dist/chunk-WBGUYSWY.js.map +1 -0
  113. package/dist/{chunk-LJBWCUKP.cjs → chunk-WIYQI35R.cjs} +2 -2
  114. package/dist/{chunk-LJBWCUKP.cjs.map → chunk-WIYQI35R.cjs.map} +1 -1
  115. package/dist/chunk-WKSUL2ZN.js +56 -0
  116. package/dist/chunk-WKSUL2ZN.js.map +1 -0
  117. package/dist/chunk-X5ZPYYMS.js +105 -0
  118. package/dist/chunk-X5ZPYYMS.js.map +1 -0
  119. package/dist/{chunk-DLBV42JD.js → chunk-XBKOZRDO.js} +156 -39
  120. package/dist/chunk-XBKOZRDO.js.map +1 -0
  121. package/dist/{chunk-XB54G7WS.cjs → chunk-XJTFZLWH.cjs} +2 -86
  122. package/dist/chunk-XJTFZLWH.cjs.map +1 -0
  123. package/dist/chunk-XMECP2MD.js +208 -0
  124. package/dist/chunk-XMECP2MD.js.map +1 -0
  125. package/dist/{chunk-GTHNWP4P.js → chunk-XUVEF2RQ.js} +4 -87
  126. package/dist/chunk-XUVEF2RQ.js.map +1 -0
  127. package/dist/chunk-XWYKLEKG.js +269 -0
  128. package/dist/chunk-XWYKLEKG.js.map +1 -0
  129. package/dist/chunk-Y6YSJPVC.js +129 -0
  130. package/dist/chunk-Y6YSJPVC.js.map +1 -0
  131. package/dist/chunk-YVIH26FG.cjs +736 -0
  132. package/dist/chunk-YVIH26FG.cjs.map +1 -0
  133. package/dist/chunk-Z5S5JEJD.cjs +286 -0
  134. package/dist/chunk-Z5S5JEJD.cjs.map +1 -0
  135. package/dist/chunk-ZO4L6C2Y.cjs +137 -0
  136. package/dist/chunk-ZO4L6C2Y.cjs.map +1 -0
  137. package/dist/{collabKit-QZL4P5T5.js → collabKit-A643VH2I.js} +7 -3
  138. package/dist/collabKit-A643VH2I.js.map +1 -0
  139. package/dist/{collabKit-UF7E6V3N.cjs → collabKit-Q4A36LDA.cjs} +7 -3
  140. package/dist/collabKit-Q4A36LDA.cjs.map +1 -0
  141. package/dist/components/Accordion/index.cjs +13 -0
  142. package/dist/components/Accordion/index.cjs.map +1 -0
  143. package/dist/components/Accordion/index.d.cts +50 -0
  144. package/dist/components/Accordion/index.d.ts +50 -0
  145. package/dist/components/Accordion/index.js +4 -0
  146. package/dist/components/Accordion/index.js.map +1 -0
  147. package/dist/components/Alert/index.d.cts +1 -1
  148. package/dist/components/Alert/index.d.ts +1 -1
  149. package/dist/components/Autocomplete/index.cjs +4 -3
  150. package/dist/components/Autocomplete/index.d.cts +20 -3
  151. package/dist/components/Autocomplete/index.d.ts +20 -3
  152. package/dist/components/Autocomplete/index.js +3 -2
  153. package/dist/components/Badge/index.d.cts +1 -1
  154. package/dist/components/Badge/index.d.ts +1 -1
  155. package/dist/components/Card/index.d.cts +1 -1
  156. package/dist/components/Card/index.d.ts +1 -1
  157. package/dist/components/Checkbox/index.cjs +5 -4
  158. package/dist/components/Checkbox/index.d.cts +9 -1
  159. package/dist/components/Checkbox/index.d.ts +9 -1
  160. package/dist/components/Checkbox/index.js +2 -1
  161. package/dist/components/ClampedText/index.cjs +13 -0
  162. package/dist/components/ClampedText/index.cjs.map +1 -0
  163. package/dist/components/ClampedText/index.d.cts +33 -0
  164. package/dist/components/ClampedText/index.d.ts +33 -0
  165. package/dist/components/ClampedText/index.js +4 -0
  166. package/dist/components/ClampedText/index.js.map +1 -0
  167. package/dist/components/CopyButton/index.cjs +13 -0
  168. package/dist/components/CopyButton/index.cjs.map +1 -0
  169. package/dist/components/CopyButton/index.d.cts +29 -0
  170. package/dist/components/CopyButton/index.d.ts +29 -0
  171. package/dist/components/CopyButton/index.js +4 -0
  172. package/dist/components/CopyButton/index.js.map +1 -0
  173. package/dist/components/CustomizableDashboard/index.cjs +43 -0
  174. package/dist/components/CustomizableDashboard/index.cjs.map +1 -0
  175. package/dist/components/CustomizableDashboard/index.d.cts +195 -0
  176. package/dist/components/CustomizableDashboard/index.d.ts +195 -0
  177. package/dist/components/CustomizableDashboard/index.js +10 -0
  178. package/dist/components/CustomizableDashboard/index.js.map +1 -0
  179. package/dist/components/DateInput/index.cjs +4 -3
  180. package/dist/components/DateInput/index.d.cts +1 -0
  181. package/dist/components/DateInput/index.d.ts +1 -0
  182. package/dist/components/DateInput/index.js +3 -2
  183. package/dist/components/Dropdown/index.cjs +9 -8
  184. package/dist/components/Dropdown/index.js +3 -2
  185. package/dist/components/FilterSummaryBar/index.cjs +13 -0
  186. package/dist/components/FilterSummaryBar/index.cjs.map +1 -0
  187. package/dist/components/FilterSummaryBar/index.d.cts +53 -0
  188. package/dist/components/FilterSummaryBar/index.d.ts +53 -0
  189. package/dist/components/FilterSummaryBar/index.js +4 -0
  190. package/dist/components/FilterSummaryBar/index.js.map +1 -0
  191. package/dist/components/FreshnessBadge/index.cjs +25 -0
  192. package/dist/components/FreshnessBadge/index.cjs.map +1 -0
  193. package/dist/components/FreshnessBadge/index.d.cts +49 -0
  194. package/dist/components/FreshnessBadge/index.d.ts +49 -0
  195. package/dist/components/FreshnessBadge/index.js +4 -0
  196. package/dist/components/FreshnessBadge/index.js.map +1 -0
  197. package/dist/components/GlossaryTooltip/index.cjs +15 -0
  198. package/dist/components/GlossaryTooltip/index.cjs.map +1 -0
  199. package/dist/components/GlossaryTooltip/index.d.cts +64 -0
  200. package/dist/components/GlossaryTooltip/index.d.ts +64 -0
  201. package/dist/components/GlossaryTooltip/index.js +6 -0
  202. package/dist/components/GlossaryTooltip/index.js.map +1 -0
  203. package/dist/components/Input/index.cjs +20 -3
  204. package/dist/components/Input/index.d.cts +37 -2
  205. package/dist/components/Input/index.d.ts +37 -2
  206. package/dist/components/Input/index.js +2 -1
  207. package/dist/components/KeyboardShortcutsOverlay/index.cjs +21 -0
  208. package/dist/components/KeyboardShortcutsOverlay/index.cjs.map +1 -0
  209. package/dist/components/KeyboardShortcutsOverlay/index.d.cts +54 -0
  210. package/dist/components/KeyboardShortcutsOverlay/index.d.ts +54 -0
  211. package/dist/components/KeyboardShortcutsOverlay/index.js +8 -0
  212. package/dist/components/KeyboardShortcutsOverlay/index.js.map +1 -0
  213. package/dist/components/Markdown/index.cjs +10 -10
  214. package/dist/components/Markdown/index.js +2 -2
  215. package/dist/components/MediaEditor/index.cjs +10 -9
  216. package/dist/components/MediaEditor/index.js +5 -4
  217. package/dist/components/PhoneInput/index.cjs +5 -4
  218. package/dist/components/PhoneInput/index.js +3 -2
  219. package/dist/components/Progress/index.d.cts +1 -1
  220. package/dist/components/Progress/index.d.ts +1 -1
  221. package/dist/components/Radio/index.cjs +5 -4
  222. package/dist/components/Radio/index.d.cts +9 -1
  223. package/dist/components/Radio/index.d.ts +9 -1
  224. package/dist/components/Radio/index.js +2 -1
  225. package/dist/components/ReadingProgressBar/index.cjs +13 -0
  226. package/dist/components/ReadingProgressBar/index.cjs.map +1 -0
  227. package/dist/components/ReadingProgressBar/index.d.cts +20 -0
  228. package/dist/components/ReadingProgressBar/index.d.ts +20 -0
  229. package/dist/components/ReadingProgressBar/index.js +4 -0
  230. package/dist/components/ReadingProgressBar/index.js.map +1 -0
  231. package/dist/components/RichTextEditor/index.cjs +7 -6
  232. package/dist/components/RichTextEditor/index.js +4 -3
  233. package/dist/components/SectionSpyNav/index.cjs +15 -0
  234. package/dist/components/SectionSpyNav/index.cjs.map +1 -0
  235. package/dist/components/SectionSpyNav/index.d.cts +63 -0
  236. package/dist/components/SectionSpyNav/index.d.ts +63 -0
  237. package/dist/components/SectionSpyNav/index.js +6 -0
  238. package/dist/components/SectionSpyNav/index.js.map +1 -0
  239. package/dist/components/Select/index.cjs +5 -3
  240. package/dist/components/Select/index.d.cts +56 -9
  241. package/dist/components/Select/index.d.ts +56 -9
  242. package/dist/components/Select/index.js +3 -1
  243. package/dist/components/Slider/index.d.cts +2 -2
  244. package/dist/components/Slider/index.d.ts +2 -2
  245. package/dist/components/SourceTip/index.cjs +15 -0
  246. package/dist/components/SourceTip/index.cjs.map +1 -0
  247. package/dist/components/SourceTip/index.d.cts +58 -0
  248. package/dist/components/SourceTip/index.d.ts +58 -0
  249. package/dist/components/SourceTip/index.js +6 -0
  250. package/dist/components/SourceTip/index.js.map +1 -0
  251. package/dist/components/Sparkline/index.cjs +13 -0
  252. package/dist/components/Sparkline/index.cjs.map +1 -0
  253. package/dist/components/Sparkline/index.d.cts +53 -0
  254. package/dist/components/Sparkline/index.d.ts +53 -0
  255. package/dist/components/Sparkline/index.js +4 -0
  256. package/dist/components/Sparkline/index.js.map +1 -0
  257. package/dist/components/Spinner/index.d.cts +1 -1
  258. package/dist/components/Spinner/index.d.ts +1 -1
  259. package/dist/components/SuperChat/index.cjs +8 -7
  260. package/dist/components/SuperChat/index.cjs.map +1 -1
  261. package/dist/components/SuperChat/index.js +4 -3
  262. package/dist/components/SuperChat/index.js.map +1 -1
  263. package/dist/components/SuperChat/plugins/index.cjs +2 -22
  264. package/dist/components/SuperChat/plugins/index.cjs.map +1 -1
  265. package/dist/components/SuperChat/plugins/index.js +1 -21
  266. package/dist/components/SuperChat/plugins/index.js.map +1 -1
  267. package/dist/components/Text/index.d.cts +1 -1
  268. package/dist/components/Text/index.d.ts +1 -1
  269. package/dist/components/Textarea/index.cjs +5 -3
  270. package/dist/components/Textarea/index.d.cts +19 -1
  271. package/dist/components/Textarea/index.d.ts +19 -1
  272. package/dist/components/Textarea/index.js +3 -1
  273. package/dist/datavis.cjs +1 -1
  274. package/dist/datavis.js +1 -1
  275. package/dist/esheet.cjs +11 -10
  276. package/dist/esheet.cjs.map +1 -1
  277. package/dist/esheet.js +8 -7
  278. package/dist/esheet.js.map +1 -1
  279. package/dist/hooks/index.cjs +27 -17
  280. package/dist/hooks/index.d.cts +16 -1
  281. package/dist/hooks/index.d.ts +16 -1
  282. package/dist/hooks/index.js +3 -1
  283. package/dist/index.cjs +2907 -1989
  284. package/dist/index.cjs.map +1 -1
  285. package/dist/index.d.cts +191 -46
  286. package/dist/index.d.ts +191 -46
  287. package/dist/index.js +2130 -1325
  288. package/dist/index.js.map +1 -1
  289. package/dist/kerebron.cjs +200 -68
  290. package/dist/kerebron.cjs.map +1 -1
  291. package/dist/kerebron.css +129 -0
  292. package/dist/kerebron.d.cts +52 -3
  293. package/dist/kerebron.d.ts +52 -3
  294. package/dist/kerebron.js +201 -69
  295. package/dist/kerebron.js.map +1 -1
  296. package/dist/styles.css +1 -1
  297. package/dist/tailwind-preset.cjs +4 -4
  298. package/dist/tailwind-preset.js +1 -1
  299. package/dist/utils/index.cjs +9 -9
  300. package/dist/utils/index.js +1 -1
  301. package/package.json +13 -4
  302. package/dist/chunk-5IDYOJHO.cjs.map +0 -1
  303. package/dist/chunk-6ECKH4DJ.cjs +0 -147
  304. package/dist/chunk-6ECKH4DJ.cjs.map +0 -1
  305. package/dist/chunk-6J7UGYT5.cjs.map +0 -1
  306. package/dist/chunk-6MMIWE7H.js.map +0 -1
  307. package/dist/chunk-AFGADE3B.js.map +0 -1
  308. package/dist/chunk-DLBV42JD.js.map +0 -1
  309. package/dist/chunk-EGWWTIWS.js.map +0 -1
  310. package/dist/chunk-GTHNWP4P.js.map +0 -1
  311. package/dist/chunk-KFLDXJEE.js.map +0 -1
  312. package/dist/chunk-LJDBD2DD.cjs.map +0 -1
  313. package/dist/chunk-OAHORW4N.cjs.map +0 -1
  314. package/dist/chunk-P6L74SKG.js.map +0 -1
  315. package/dist/chunk-QUUBTNMH.js.map +0 -1
  316. package/dist/chunk-S3MKIDYG.cjs.map +0 -1
  317. package/dist/chunk-WUNWHOLA.cjs.map +0 -1
  318. package/dist/chunk-XB54G7WS.cjs.map +0 -1
  319. package/dist/chunk-YXCE2HSK.js +0 -124
  320. package/dist/chunk-YXCE2HSK.js.map +0 -1
  321. package/dist/chunk-ZBI52NP2.cjs.map +0 -1
  322. package/dist/collabKit-QZL4P5T5.js.map +0 -1
  323. package/dist/collabKit-UF7E6V3N.cjs.map +0 -1
@@ -1,3 +1,4 @@
1
+ import { RequiredMark } from './chunk-3IMM2PM4.js';
1
2
  import { useEscapeKey } from './chunk-T4ME7QCT.js';
2
3
  import { useClickOutside } from './chunk-62ZOA6PX.js';
3
4
  import { useAnchoredPosition } from './chunk-BOOJDRJO.js';
@@ -26,37 +27,97 @@ var selectTriggerVariants = cva(
26
27
  hasError: {
27
28
  true: "border-destructive focus:ring-destructive",
28
29
  false: ""
30
+ },
31
+ labelVariant: {
32
+ stacked: "",
33
+ floating: "peer"
34
+ }
35
+ },
36
+ compoundVariants: [
37
+ { labelVariant: "floating", size: "sm", className: "h-11" },
38
+ { labelVariant: "floating", size: "md", className: "h-14" },
39
+ { labelVariant: "floating", size: "lg", className: "h-16" }
40
+ ],
41
+ defaultVariants: {
42
+ size: "md",
43
+ hasError: false,
44
+ labelVariant: "stacked"
45
+ }
46
+ }
47
+ );
48
+ var floatingLabelVariants = cva(
49
+ [
50
+ "absolute start-3 pointer-events-none select-none",
51
+ "transition-all duration-200 ease-out"
52
+ ],
53
+ {
54
+ variants: {
55
+ size: {
56
+ sm: [
57
+ "peer-focus:top-0.5 peer-focus:translate-y-0 peer-focus:text-[0.65rem]"
58
+ ],
59
+ md: ["peer-focus:top-1 peer-focus:translate-y-0 peer-focus:text-xs"],
60
+ lg: ["peer-focus:top-1.5 peer-focus:translate-y-0 peer-focus:text-sm"]
61
+ },
62
+ floated: {
63
+ true: "",
64
+ false: "top-1/2 -translate-y-1/2"
65
+ },
66
+ hasError: {
67
+ true: "text-destructive",
68
+ false: "text-muted-foreground"
29
69
  }
30
70
  },
71
+ compoundVariants: [
72
+ { size: "sm", floated: false, className: "text-sm" },
73
+ { size: "md", floated: false, className: "text-base" },
74
+ { size: "lg", floated: false, className: "text-lg" },
75
+ {
76
+ size: "sm",
77
+ floated: true,
78
+ className: "top-0.5 translate-y-0 text-[0.65rem]"
79
+ },
80
+ { size: "md", floated: true, className: "top-1 translate-y-0 text-xs" },
81
+ { size: "lg", floated: true, className: "top-1.5 translate-y-0 text-sm" }
82
+ ],
31
83
  defaultVariants: {
32
84
  size: "md",
85
+ floated: false,
33
86
  hasError: false
34
87
  }
35
88
  }
36
89
  );
37
- function Select({
38
- options,
39
- value: controlledValue,
40
- defaultValue,
41
- onValueChange,
42
- placeholder = "Select an option",
43
- disabled = false,
44
- label,
45
- hideLabel = false,
46
- error,
47
- helperText,
48
- size,
49
- hasError,
50
- "aria-label": ariaLabel,
51
- searchable = false,
52
- searchPlaceholder = "Search...",
53
- noResultsText = "No results found",
54
- className,
55
- id
56
- }) {
90
+ var floatingValuePadding = {
91
+ sm: "pt-4 pb-1",
92
+ md: "pt-5 pb-1.5",
93
+ lg: "pt-6 pb-2"
94
+ };
95
+ function Select(props) {
96
+ const {
97
+ options,
98
+ placeholder = "Select an option",
99
+ disabled = false,
100
+ label,
101
+ hideLabel = false,
102
+ labelVariant = "stacked",
103
+ error,
104
+ helperText,
105
+ required = false,
106
+ requiredVariant,
107
+ size,
108
+ hasError,
109
+ "aria-label": ariaLabel,
110
+ searchable = false,
111
+ searchPlaceholder = "Search...",
112
+ noResultsText = "No results found",
113
+ className,
114
+ id
115
+ } = props;
116
+ const multiple = props.multiple === true;
117
+ const onValueChange = props.onValueChange;
57
118
  const [isOpen, setIsOpen] = React.useState(false);
58
- const [uncontrolledValue, setUncontrolledValue] = React.useState(
59
- defaultValue || ""
119
+ const [uncontrolledValues, setUncontrolledValues] = React.useState(
120
+ () => toValueArray(props.defaultValue)
60
121
  );
61
122
  const [searchQuery, setSearchQuery] = React.useState("");
62
123
  const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
@@ -74,8 +135,13 @@ function Select({
74
135
  const listboxId = `${selectId}-listbox`;
75
136
  const errorId = `${selectId}-error`;
76
137
  const helperId = `${selectId}-helper`;
77
- const isControlled = controlledValue !== void 0;
78
- const value = isControlled ? controlledValue : uncontrolledValue;
138
+ const isControlled = props.value !== void 0;
139
+ const controlledValue = props.value;
140
+ const controlledValues = React.useMemo(
141
+ () => toValueArray(controlledValue),
142
+ [controlledValue]
143
+ );
144
+ const selectedValues = isControlled ? controlledValues : uncontrolledValues;
79
145
  const flatOptions = React.useMemo(() => {
80
146
  const result = [];
81
147
  for (const item of options) {
@@ -118,7 +184,9 @@ function Select({
118
184
  }
119
185
  return result;
120
186
  }, [filteredOptions]);
121
- const selectedOption = flatOptions.find((opt) => opt.value === value);
187
+ const selectedOptions = selectedValues.map((v) => flatOptions.find((opt) => opt.value === v)).filter((opt) => opt !== void 0);
188
+ const hasSelection = selectedOptions.length > 0;
189
+ const displayLabel = selectedOptions.map((opt) => opt.label).join(", ");
122
190
  const outsideRefs = React.useMemo(() => [containerRef, dropdownRef], []);
123
191
  useClickOutside(outsideRefs, () => setIsOpen(false), isOpen);
124
192
  useEscapeKey(() => {
@@ -137,16 +205,29 @@ function Select({
137
205
  maxHeight: 300
138
206
  });
139
207
  const handleValueChange = React.useCallback(
140
- (newValue) => {
208
+ (optionValue) => {
209
+ if (multiple) {
210
+ const next = selectedValues.includes(optionValue) ? selectedValues.filter((v) => v !== optionValue) : [...selectedValues, optionValue];
211
+ if (!isControlled) {
212
+ setUncontrolledValues(next);
213
+ }
214
+ onValueChange?.(next);
215
+ if (searchable) {
216
+ searchInputRef.current?.focus();
217
+ } else {
218
+ triggerRef.current?.focus();
219
+ }
220
+ return;
221
+ }
141
222
  if (!isControlled) {
142
- setUncontrolledValue(newValue);
223
+ setUncontrolledValues([optionValue]);
143
224
  }
144
- onValueChange?.(newValue);
225
+ onValueChange?.(optionValue);
145
226
  setIsOpen(false);
146
227
  setSearchQuery("");
147
228
  triggerRef.current?.focus();
148
229
  },
149
- [isControlled, onValueChange]
230
+ [isControlled, multiple, onValueChange, searchable, selectedValues]
150
231
  );
151
232
  const handleKeyDown = React.useCallback(
152
233
  (e) => {
@@ -267,13 +348,17 @@ function Select({
267
348
  error ? errorId : null,
268
349
  helperText && !error ? helperId : null
269
350
  ].filter(Boolean).join(" ");
351
+ const isFloating = labelVariant === "floating" && !!label && !hideLabel;
352
+ const isFloated = isOpen || hasSelection;
353
+ const resolvedSize = size ?? "md";
354
+ const requiredMark = required && /* @__PURE__ */ jsx(RequiredMark, { variant: requiredVariant });
270
355
  return /* @__PURE__ */ jsxs(
271
356
  "div",
272
357
  {
273
358
  "data-slot": "select-wrapper",
274
359
  className: cn("flex flex-col gap-1.5", className),
275
360
  children: [
276
- label && /* @__PURE__ */ jsx(
361
+ label && !isFloating && /* @__PURE__ */ jsxs(
277
362
  "label",
278
363
  {
279
364
  "data-slot": "select-label",
@@ -282,7 +367,10 @@ function Select({
282
367
  "text-foreground text-sm font-medium",
283
368
  hideLabel && "sr-only"
284
369
  ),
285
- children: label
370
+ children: [
371
+ label,
372
+ requiredMark
373
+ ]
286
374
  }
287
375
  ),
288
376
  /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
@@ -299,15 +387,20 @@ function Select({
299
387
  role: "combobox",
300
388
  "aria-haspopup": "listbox",
301
389
  "aria-expanded": isOpen,
302
- "aria-controls": listboxId,
390
+ "aria-controls": isOpen ? listboxId : void 0,
303
391
  "aria-invalid": hasError || !!error,
392
+ "aria-required": required || void 0,
304
393
  "aria-label": !label ? ariaLabel : void 0,
305
394
  "aria-describedby": describedByIds || void 0,
306
395
  disabled,
307
396
  onClick: () => setIsOpen(!isOpen),
308
397
  onKeyDown: handleKeyDown,
309
398
  className: cn(
310
- selectTriggerVariants({ size, hasError: hasError || !!error })
399
+ selectTriggerVariants({
400
+ size,
401
+ hasError: hasError || !!error,
402
+ labelVariant: isFloating ? "floating" : "stacked"
403
+ })
311
404
  ),
312
405
  children: [
313
406
  /* @__PURE__ */ jsx(
@@ -315,9 +408,10 @@ function Select({
315
408
  {
316
409
  className: cn(
317
410
  "truncate",
318
- !selectedOption && "text-muted-foreground"
411
+ !hasSelection && "text-muted-foreground",
412
+ isFloating && floatingValuePadding[resolvedSize]
319
413
  ),
320
- children: selectedOption?.label || placeholder
414
+ children: isFloating ? hasSelection ? displayLabel : "\xA0" : hasSelection ? displayLabel : placeholder
321
415
  }
322
416
  ),
323
417
  /* @__PURE__ */ jsx(
@@ -332,6 +426,22 @@ function Select({
332
426
  ]
333
427
  }
334
428
  ),
429
+ isFloating && /* @__PURE__ */ jsxs(
430
+ "label",
431
+ {
432
+ "data-slot": "select-label",
433
+ htmlFor: selectId,
434
+ className: floatingLabelVariants({
435
+ size: resolvedSize,
436
+ floated: isFloated,
437
+ hasError: hasError || !!error
438
+ }),
439
+ children: [
440
+ label,
441
+ requiredMark
442
+ ]
443
+ }
444
+ ),
335
445
  isOpen && createPortal(
336
446
  /* @__PURE__ */ jsxs(
337
447
  "div",
@@ -379,6 +489,7 @@ function Select({
379
489
  id: listboxId,
380
490
  role: "listbox",
381
491
  "aria-label": label || "Options",
492
+ "aria-multiselectable": multiple || void 0,
382
493
  "data-slot": "select-listbox",
383
494
  className: "flex-1 overflow-auto p-1",
384
495
  children: filteredFlatOptions.length === 0 ? /* @__PURE__ */ jsx("li", { className: "text-muted-foreground px-3 py-2 text-center text-sm", children: noResultsText }) : filteredOptions.map((item) => {
@@ -396,7 +507,9 @@ function Select({
396
507
  SelectOptionItem,
397
508
  {
398
509
  option,
399
- isSelected: option.value === value,
510
+ isSelected: selectedValues.includes(
511
+ option.value
512
+ ),
400
513
  isHighlighted: filteredFlatOptions[highlightedIndex]?.value === option.value,
401
514
  onSelect: () => handleValueChange(option.value),
402
515
  onMouseEnter: () => {
@@ -414,7 +527,7 @@ function Select({
414
527
  SelectOptionItem,
415
528
  {
416
529
  option: item,
417
- isSelected: item.value === value,
530
+ isSelected: selectedValues.includes(item.value),
418
531
  isHighlighted: filteredFlatOptions[highlightedIndex]?.value === item.value,
419
532
  onSelect: () => handleValueChange(item.value),
420
533
  onMouseEnter: () => {
@@ -459,6 +572,10 @@ function Select({
459
572
  );
460
573
  }
461
574
  Select.displayName = "Select";
575
+ function toValueArray(value) {
576
+ if (value === void 0 || value === "") return [];
577
+ return Array.isArray(value) ? value : [value];
578
+ }
462
579
  function SelectOptionItem({
463
580
  option,
464
581
  isSelected,
@@ -541,5 +658,5 @@ function CheckIcon({ className }) {
541
658
  }
542
659
 
543
660
  export { Select, selectTriggerVariants };
544
- //# sourceMappingURL=chunk-DLBV42JD.js.map
545
- //# sourceMappingURL=chunk-DLBV42JD.js.map
661
+ //# sourceMappingURL=chunk-XBKOZRDO.js.map
662
+ //# sourceMappingURL=chunk-XBKOZRDO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Select/Select.tsx"],"names":[],"mappings":"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","file":"chunk-XBKOZRDO.js","sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport { useClickOutside } from '../../hooks/useClickOutside';\nimport { useAnchoredPosition } from '../../hooks/useAnchoredPosition';\nimport { RequiredMark, type RequiredMarkVariant } from '../Input';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SelectOption {\n /** Unique value for the option */\n value: string;\n /** Display label for the option */\n label: string;\n /** Whether the option is disabled */\n disabled?: boolean;\n /** Optional group this option belongs to */\n group?: string;\n}\n\nexport interface SelectGroup {\n /** Group label */\n label: string;\n /** Options in this group */\n options: SelectOption[];\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst selectTriggerVariants = cva(\n [\n 'flex w-full items-center justify-between gap-2',\n 'border border-input rounded-lg',\n 'bg-background text-foreground',\n 'transition-colors duration-200',\n 'focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: 'h-8 px-3 text-sm',\n md: 'h-10 px-3 text-base',\n lg: 'h-12 px-4 text-lg',\n },\n hasError: {\n true: 'border-destructive focus:ring-destructive',\n false: '',\n },\n labelVariant: {\n stacked: '',\n floating: 'peer',\n },\n },\n compoundVariants: [\n { labelVariant: 'floating', size: 'sm', className: 'h-11' },\n { labelVariant: 'floating', size: 'md', className: 'h-14' },\n { labelVariant: 'floating', size: 'lg', className: 'h-16' },\n ],\n defaultVariants: {\n size: 'md',\n hasError: false,\n labelVariant: 'stacked',\n },\n }\n);\n\nconst floatingLabelVariants = cva(\n [\n 'absolute start-3 pointer-events-none select-none',\n 'transition-all duration-200 ease-out',\n ],\n {\n variants: {\n size: {\n sm: [\n 'peer-focus:top-0.5 peer-focus:translate-y-0 peer-focus:text-[0.65rem]',\n ],\n md: ['peer-focus:top-1 peer-focus:translate-y-0 peer-focus:text-xs'],\n lg: ['peer-focus:top-1.5 peer-focus:translate-y-0 peer-focus:text-sm'],\n },\n floated: {\n true: '',\n false: 'top-1/2 -translate-y-1/2',\n },\n hasError: {\n true: 'text-destructive',\n false: 'text-muted-foreground',\n },\n },\n compoundVariants: [\n { size: 'sm', floated: false, className: 'text-sm' },\n { size: 'md', floated: false, className: 'text-base' },\n { size: 'lg', floated: false, className: 'text-lg' },\n {\n size: 'sm',\n floated: true,\n className: 'top-0.5 translate-y-0 text-[0.65rem]',\n },\n { size: 'md', floated: true, className: 'top-1 translate-y-0 text-xs' },\n { size: 'lg', floated: true, className: 'top-1.5 translate-y-0 text-sm' },\n ],\n defaultVariants: {\n size: 'md',\n floated: false,\n hasError: false,\n },\n }\n);\n\nconst floatingValuePadding = {\n sm: 'pt-4 pb-1',\n md: 'pt-5 pb-1.5',\n lg: 'pt-6 pb-2',\n} as const;\n\n// ============================================================================\n// Select Component\n// ============================================================================\n\n/**\n * Props shared by both single- and multiple-selection modes. Exported so\n * wrapper components can extend the common shape (`SelectProps` itself is a\n * discriminated union, which interfaces cannot extend).\n */\nexport interface SelectBaseProps extends Omit<\n VariantProps<typeof selectTriggerVariants>,\n 'labelVariant'\n> {\n /** Array of options or groups */\n options: (SelectOption | SelectGroup)[];\n /** Placeholder text */\n placeholder?: string;\n /** Whether the select is disabled */\n disabled?: boolean;\n /** Label for the select */\n label?: string;\n /** Hide the label visually */\n hideLabel?: boolean;\n /**\n * Visual style of the label.\n * - `stacked` (default): label sits above the trigger.\n * - `floating`: label rests inside the trigger like a placeholder and\n * floats up (staying inside the trigger) when open or a value is\n * selected. The `placeholder` prop is ignored in this mode.\n */\n labelVariant?: 'stacked' | 'floating';\n /** Error message */\n error?: string;\n /** Helper text */\n helperText?: string;\n /** Whether a selection is required (shows an asterisk next to the label) */\n required?: boolean;\n /**\n * Color of the required asterisk.\n * - `default`: destructive (hard requirement).\n * - `warning`: warning color (soft requirement / recommended).\n */\n requiredVariant?: RequiredMarkVariant;\n /** Enable search/filter */\n searchable?: boolean;\n /** Search placeholder */\n searchPlaceholder?: string;\n /** No results text */\n noResultsText?: string;\n /** Accessible label for the trigger (used when no `label` prop is provided) */\n 'aria-label'?: string;\n /** Additional class name */\n className?: string;\n /** ID for the select */\n id?: string;\n}\n\nexport interface SelectSingleProps extends SelectBaseProps {\n /** Single-selection mode (default). */\n multiple?: false;\n /** Controlled value */\n value?: string;\n /** Default value (uncontrolled) */\n defaultValue?: string;\n /** Callback when value changes */\n onValueChange?: (value: string) => void;\n}\n\nexport interface SelectMultipleProps extends SelectBaseProps {\n /** Multiple-selection mode: selecting an option toggles it and keeps the dropdown open. */\n multiple: true;\n /** Controlled values */\n value?: string[];\n /** Default values (uncontrolled) */\n defaultValue?: string[];\n /** Callback when values change */\n onValueChange?: (value: string[]) => void;\n}\n\nexport type SelectProps = SelectSingleProps | SelectMultipleProps;\n\n/**\n * An accessible select/dropdown component with search support.\n *\n * @example\n * ```tsx\n * <Select\n * label=\"Country\"\n * placeholder=\"Select a country\"\n * options={[\n * { value: 'us', label: 'United States' },\n * { value: 'ca', label: 'Canada' },\n * { value: 'uk', label: 'United Kingdom' },\n * ]}\n * onValueChange={(value) => console.log(value)}\n * />\n *\n * // Multiple selection — value/onValueChange use string[]\n * <Select\n * multiple\n * label=\"Symptoms\"\n * options={options}\n * onValueChange={(values) => console.log(values)}\n * />\n * ```\n */\nfunction Select(props: SelectProps) {\n const {\n options,\n placeholder = 'Select an option',\n disabled = false,\n label,\n hideLabel = false,\n labelVariant = 'stacked',\n error,\n helperText,\n required = false,\n requiredVariant,\n size,\n hasError,\n 'aria-label': ariaLabel,\n searchable = false,\n searchPlaceholder = 'Search...',\n noResultsText = 'No results found',\n className,\n id,\n } = props;\n const multiple = props.multiple === true;\n // The discriminated union types onValueChange as either a string or string[]\n // callback; widen it once here so handlers can use it without referencing\n // the whole `props` object. Runtime calls stay consistent with `multiple`.\n const onValueChange = props.onValueChange as\n | ((value: string | string[]) => void)\n | undefined;\n const [isOpen, setIsOpen] = React.useState(false);\n const [uncontrolledValues, setUncontrolledValues] = React.useState<string[]>(\n () => toValueArray(props.defaultValue)\n );\n const [searchQuery, setSearchQuery] = React.useState('');\n const [highlightedIndex, setHighlightedIndex] = React.useState(-1);\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n const listRef = React.useRef<HTMLUListElement>(null);\n const dropdownRef = React.useRef<HTMLDivElement>(null);\n const typeaheadRef = React.useRef<{ query: string; timer: number | null }>({\n query: '',\n timer: null,\n });\n\n const generatedId = React.useId();\n const selectId = id || generatedId;\n const listboxId = `${selectId}-listbox`;\n const errorId = `${selectId}-error`;\n const helperId = `${selectId}-helper`;\n\n const isControlled = props.value !== undefined;\n const controlledValue = props.value;\n // Memoize the controlled normalization: toValueArray allocates a fresh\n // array when value is a string, which would otherwise churn callback\n // identities (handleValueChange depends on selectedValues) every render.\n const controlledValues = React.useMemo(\n () => toValueArray(controlledValue),\n [controlledValue]\n );\n const selectedValues = isControlled ? controlledValues : uncontrolledValues;\n\n // Flatten options for easy access\n const flatOptions = React.useMemo(() => {\n const result: SelectOption[] = [];\n for (const item of options) {\n if ('options' in item) {\n result.push(...item.options);\n } else {\n result.push(item);\n }\n }\n return result;\n }, [options]);\n\n // Filter options based on search query\n const filteredOptions = React.useMemo(() => {\n if (!searchQuery) return options;\n\n const query = searchQuery.toLowerCase();\n const result: (SelectOption | SelectGroup)[] = [];\n\n for (const item of options) {\n if ('options' in item) {\n const filteredGroupOptions = item.options.filter((opt) =>\n opt.label.toLowerCase().includes(query)\n );\n if (filteredGroupOptions.length > 0) {\n result.push({ ...item, options: filteredGroupOptions });\n }\n } else {\n if (item.label.toLowerCase().includes(query)) {\n result.push(item);\n }\n }\n }\n\n return result;\n }, [options, searchQuery]);\n\n // Get filtered flat options for keyboard navigation\n const filteredFlatOptions = React.useMemo(() => {\n const result: SelectOption[] = [];\n for (const item of filteredOptions) {\n if ('options' in item) {\n result.push(...item.options.filter((opt) => !opt.disabled));\n } else if (!item.disabled) {\n result.push(item);\n }\n }\n return result;\n }, [filteredOptions]);\n\n // Get selected options (in selection order)\n const selectedOptions = selectedValues\n .map((v) => flatOptions.find((opt) => opt.value === v))\n .filter((opt): opt is SelectOption => opt !== undefined);\n const hasSelection = selectedOptions.length > 0;\n const displayLabel = selectedOptions.map((opt) => opt.label).join(', ');\n\n // Close dropdown on click outside (handles both container and portaled dropdown)\n const outsideRefs = React.useMemo(() => [containerRef, dropdownRef], []);\n useClickOutside(outsideRefs, () => setIsOpen(false), isOpen);\n\n useEscapeKey(() => {\n if (isOpen) {\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }, isOpen);\n\n // Track trigger position for portal dropdown\n const {\n anchorRef,\n floatingRef,\n style: dropdownStyle,\n } = useAnchoredPosition<HTMLButtonElement, HTMLDivElement>({\n open: isOpen,\n matchWidth: true,\n maxHeight: 300,\n });\n\n // Handle option selection: single mode replaces and closes; multiple mode\n // toggles the option and keeps the dropdown open.\n const handleValueChange = React.useCallback(\n (optionValue: string) => {\n if (multiple) {\n const next = selectedValues.includes(optionValue)\n ? selectedValues.filter((v) => v !== optionValue)\n : [...selectedValues, optionValue];\n if (!isControlled) {\n setUncontrolledValues(next);\n }\n onValueChange?.(next);\n // The dropdown stays open; a mouse click focuses the option <li>,\n // which only handles Enter/Space. Restore focus so arrow-key\n // navigation and typeahead keep working.\n if (searchable) {\n searchInputRef.current?.focus();\n } else {\n triggerRef.current?.focus();\n }\n return;\n }\n if (!isControlled) {\n setUncontrolledValues([optionValue]);\n }\n onValueChange?.(optionValue);\n setIsOpen(false);\n setSearchQuery('');\n triggerRef.current?.focus();\n },\n [isControlled, multiple, onValueChange, searchable, selectedValues]\n );\n\n // Handle keyboard navigation\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n // Typeahead (native-select style): when not using the dedicated search\n // input, typing printable characters jumps to the first option whose\n // label starts with the typed string. Repeating the same key cycles\n // through matches. The buffer clears after a short pause.\n if (\n !searchable &&\n e.key.length === 1 &&\n e.key !== ' ' &&\n !e.metaKey &&\n !e.ctrlKey &&\n !e.altKey\n ) {\n e.preventDefault();\n if (!isOpen) setIsOpen(true);\n\n const hadPendingQuery = typeaheadRef.current.query !== '';\n if (typeaheadRef.current.timer !== null) {\n window.clearTimeout(typeaheadRef.current.timer);\n }\n const query = (typeaheadRef.current.query + e.key).toLowerCase();\n typeaheadRef.current.query = query;\n typeaheadRef.current.timer = window.setTimeout(() => {\n typeaheadRef.current.query = '';\n typeaheadRef.current.timer = null;\n }, 600);\n\n const len = filteredFlatOptions.length;\n if (len > 0) {\n const allSameChar = query.split('').every((c) => c === query[0]);\n const needle = allSameChar ? query[0] : query;\n const matches = (opt: SelectOption) =>\n opt.label.toLowerCase().startsWith(needle);\n\n // A fresh keystroke (or refining a multi-char query) searches from\n // the current option inclusive so typing \"car\" stays on \"Cardiology\";\n // repeating the same key cycles to the next match.\n const startInclusive = !hadPendingQuery || !allSameChar;\n const base = startInclusive\n ? Math.max(highlightedIndex, 0)\n : highlightedIndex + 1;\n\n for (let i = 0; i < len; i++) {\n const idx = (base + i) % len;\n if (matches(filteredFlatOptions[idx])) {\n setHighlightedIndex(idx);\n break;\n }\n }\n }\n return;\n }\n\n // Let Space type normally in the search input (e.g. \"new york\")\n // instead of being captured by the open/select handler below.\n if (e.key === ' ' && e.target === searchInputRef.current) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n } else {\n setHighlightedIndex((prev) =>\n prev < filteredFlatOptions.length - 1 ? prev + 1 : 0\n );\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isOpen) {\n setIsOpen(true);\n } else {\n setHighlightedIndex((prev) =>\n prev > 0 ? prev - 1 : filteredFlatOptions.length - 1\n );\n }\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n if (isOpen && highlightedIndex >= 0) {\n handleValueChange(filteredFlatOptions[highlightedIndex].value);\n } else if (!isOpen) {\n setIsOpen(true);\n }\n break;\n case 'Home':\n e.preventDefault();\n setHighlightedIndex(0);\n break;\n case 'End':\n e.preventDefault();\n setHighlightedIndex(filteredFlatOptions.length - 1);\n break;\n }\n },\n [\n isOpen,\n highlightedIndex,\n filteredFlatOptions,\n handleValueChange,\n searchable,\n ]\n );\n\n // Focus search input when dropdown opens\n React.useEffect(() => {\n if (isOpen && searchable && searchInputRef.current) {\n searchInputRef.current.focus();\n }\n }, [isOpen, searchable]);\n\n // Reset highlighted index when search changes\n React.useEffect(() => {\n setHighlightedIndex(filteredFlatOptions.length > 0 ? 0 : -1);\n }, [searchQuery, filteredFlatOptions.length]);\n\n // Keep the highlighted option visible within the listbox during keyboard\n // navigation. We adjust only the list's own scrollTop instead of calling the\n // native scrollIntoView: the dropdown is portaled to <body> with\n // position: fixed, and scrollIntoView would also scroll ancestor/window,\n // yanking the whole page.\n React.useEffect(() => {\n if (!isOpen || highlightedIndex < 0) return;\n const list = listRef.current;\n const el = list?.querySelector<HTMLElement>('[data-highlighted=\"true\"]');\n if (!list || !el) return;\n const listRect = list.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n if (elRect.top < listRect.top) {\n list.scrollTop -= listRect.top - elRect.top;\n } else if (elRect.bottom > listRect.bottom) {\n list.scrollTop += elRect.bottom - listRect.bottom;\n }\n }, [highlightedIndex, isOpen]);\n\n // Reset the typeahead buffer whenever the dropdown closes (Escape, click\n // outside, selection) so a stale query doesn't carry over on a quick reopen,\n // and clear any pending timer on unmount.\n const resetTypeahead = React.useCallback(() => {\n if (typeaheadRef.current.timer !== null) {\n window.clearTimeout(typeaheadRef.current.timer);\n typeaheadRef.current.timer = null;\n }\n typeaheadRef.current.query = '';\n }, []);\n\n React.useEffect(() => {\n if (!isOpen) resetTypeahead();\n }, [isOpen, resetTypeahead]);\n\n React.useEffect(() => resetTypeahead, [resetTypeahead]);\n\n // Build aria-describedby\n const describedByIds = [\n error ? errorId : null,\n helperText && !error ? helperId : null,\n ]\n .filter(Boolean)\n .join(' ');\n\n const isFloating = labelVariant === 'floating' && !!label && !hideLabel;\n const isFloated = isOpen || hasSelection;\n const resolvedSize = size ?? 'md';\n\n const requiredMark = required && <RequiredMark variant={requiredVariant} />;\n\n return (\n <div\n data-slot=\"select-wrapper\"\n className={cn('flex flex-col gap-1.5', className)}\n >\n {label && !isFloating && (\n <label\n data-slot=\"select-label\"\n htmlFor={selectId}\n className={cn(\n 'text-foreground text-sm font-medium',\n hideLabel && 'sr-only'\n )}\n >\n {label}\n {requiredMark}\n </label>\n )}\n\n <div ref={containerRef} className=\"relative\">\n {/* Trigger Button */}\n <button\n data-slot=\"select-trigger\"\n ref={(node) => {\n triggerRef.current = node;\n anchorRef.current = node;\n }}\n id={selectId}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n // Only reference the listbox while it exists in the DOM (it is\n // portaled and unmounted when closed) so the ID is always valid.\n aria-controls={isOpen ? listboxId : undefined}\n aria-invalid={hasError || !!error}\n aria-required={required || undefined}\n aria-label={!label ? ariaLabel : undefined}\n aria-describedby={describedByIds || undefined}\n disabled={disabled}\n onClick={() => setIsOpen(!isOpen)}\n onKeyDown={handleKeyDown}\n className={cn(\n selectTriggerVariants({\n size,\n hasError: hasError || !!error,\n labelVariant: isFloating ? 'floating' : 'stacked',\n })\n )}\n >\n <span\n className={cn(\n 'truncate',\n !hasSelection && 'text-muted-foreground',\n isFloating && floatingValuePadding[resolvedSize]\n )}\n >\n {isFloating\n ? hasSelection\n ? displayLabel\n : '\\u00A0'\n : hasSelection\n ? displayLabel\n : placeholder}\n </span>\n <ChevronDownIcon\n className={cn(\n 'text-muted-foreground h-4 w-4 shrink-0 transition-transform',\n isOpen && 'rotate-180'\n )}\n />\n </button>\n\n {/* Floating label (rendered after the trigger so `peer-focus` applies) */}\n {isFloating && (\n <label\n data-slot=\"select-label\"\n htmlFor={selectId}\n className={floatingLabelVariants({\n size: resolvedSize,\n floated: isFloated,\n hasError: hasError || !!error,\n })}\n >\n {label}\n {requiredMark}\n </label>\n )}\n\n {/* Dropdown (portaled to body to avoid overflow clipping) */}\n {isOpen &&\n createPortal(\n <div\n data-slot=\"select-dropdown\"\n ref={(node) => {\n dropdownRef.current = node;\n floatingRef.current = node;\n }}\n style={dropdownStyle}\n className={cn(\n 'border-border bg-card rounded-lg border shadow-lg',\n 'flex flex-col overflow-hidden',\n 'animate-in fade-in zoom-in-95 duration-100'\n )}\n >\n {/* Search Input */}\n {searchable && (\n <div\n data-slot=\"select-search\"\n className=\"border-border border-b p-2\"\n >\n <input\n ref={searchInputRef}\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={searchPlaceholder}\n className={cn(\n 'border-input bg-background w-full rounded-md border px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus:ring-ring focus:ring-2 focus:outline-none'\n )}\n aria-label=\"Search options\"\n />\n </div>\n )}\n\n {/* Options List */}\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label={label || 'Options'}\n aria-multiselectable={multiple || undefined}\n data-slot=\"select-listbox\"\n className=\"flex-1 overflow-auto p-1\"\n >\n {filteredFlatOptions.length === 0 ? (\n <li className=\"text-muted-foreground px-3 py-2 text-center text-sm\">\n {noResultsText}\n </li>\n ) : (\n filteredOptions.map((item) => {\n if ('options' in item) {\n // Render group\n return (\n <li key={`group-${item.label}`} role=\"presentation\">\n <div\n data-slot=\"select-group-label\"\n className=\"text-muted-foreground px-3 py-1.5 text-xs font-semibold tracking-wider uppercase\"\n >\n {item.label}\n </div>\n <ul role=\"group\" aria-label={item.label}>\n {item.options.map((option) => (\n <SelectOptionItem\n key={option.value}\n option={option}\n isSelected={selectedValues.includes(\n option.value\n )}\n isHighlighted={\n filteredFlatOptions[highlightedIndex]\n ?.value === option.value\n }\n onSelect={() => handleValueChange(option.value)}\n onMouseEnter={() => {\n const idx = filteredFlatOptions.findIndex(\n (o) => o.value === option.value\n );\n setHighlightedIndex(idx);\n }}\n />\n ))}\n </ul>\n </li>\n );\n }\n\n // Render single option\n return (\n <SelectOptionItem\n key={item.value}\n option={item}\n isSelected={selectedValues.includes(item.value)}\n isHighlighted={\n filteredFlatOptions[highlightedIndex]?.value ===\n item.value\n }\n onSelect={() => handleValueChange(item.value)}\n onMouseEnter={() => {\n const idx = filteredFlatOptions.findIndex(\n (o) => o.value === item.value\n );\n setHighlightedIndex(idx);\n }}\n />\n );\n })\n )}\n </ul>\n </div>,\n document.body\n )}\n </div>\n\n {/* Error Message */}\n {error && (\n <p\n id={errorId}\n data-slot=\"select-error\"\n className=\"text-destructive-700 dark:text-destructive-400 text-sm\"\n role=\"alert\"\n >\n {error}\n </p>\n )}\n\n {/* Helper Text */}\n {helperText && !error && (\n <p\n id={helperId}\n data-slot=\"select-helper\"\n className=\"text-muted-foreground text-sm\"\n >\n {helperText}\n </p>\n )}\n </div>\n );\n}\n\nSelect.displayName = 'Select';\n\n/** Normalize a single/multiple value prop into an array of selected values. */\nfunction toValueArray(value: string | string[] | undefined): string[] {\n if (value === undefined || value === '') return [];\n return Array.isArray(value) ? value : [value];\n}\n\n// ============================================================================\n// Select Option Item (Internal)\n// ============================================================================\n\ninterface SelectOptionItemProps {\n option: SelectOption;\n isSelected: boolean;\n isHighlighted: boolean;\n onSelect: () => void;\n onMouseEnter: () => void;\n}\n\nfunction SelectOptionItem({\n option,\n isSelected,\n isHighlighted,\n onSelect,\n onMouseEnter,\n}: SelectOptionItemProps) {\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!option.disabled) {\n onSelect();\n }\n }\n };\n\n return (\n <li\n data-slot=\"select-option\"\n role=\"option\"\n aria-selected={isSelected}\n aria-disabled={option.disabled}\n data-highlighted={isHighlighted}\n data-disabled={option.disabled}\n tabIndex={isHighlighted ? 0 : -1}\n onClick={option.disabled ? undefined : onSelect}\n onKeyDown={handleKeyDown}\n onMouseEnter={option.disabled ? undefined : onMouseEnter}\n className={cn(\n 'flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-sm',\n 'transition-colors outline-none',\n isHighlighted && 'bg-muted',\n isSelected &&\n 'bg-primary-50 text-primary-900 dark:bg-primary-950 dark:text-primary-100',\n option.disabled && 'cursor-not-allowed opacity-50'\n )}\n >\n <span className=\"flex-1 truncate\">{option.label}</span>\n {isSelected && (\n <CheckIcon className=\"text-primary-800 h-4 w-4 shrink-0\" />\n )}\n </li>\n );\n}\n\n// ============================================================================\n// Icons\n// ============================================================================\n\nfunction ChevronDownIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n );\n}\n\nexport { Select, selectTriggerVariants };\n"]}
@@ -126,89 +126,6 @@ function useIsLargeDesktop() {
126
126
  function useIsMobileOrTablet() {
127
127
  return useMediaQuery("(max-width: 1023px)");
128
128
  }
129
- function useScrollSpy({
130
- selectors,
131
- ids,
132
- rootMargin = "0px 0px -60% 0px",
133
- threshold = 0,
134
- root,
135
- enabled = true
136
- } = {}) {
137
- const [activeId, setActiveId] = react.useState(null);
138
- const visibleEntries = react.useRef(
139
- /* @__PURE__ */ new Map()
140
- );
141
- const rootEl = root?.current ?? null;
142
- react.useEffect(() => {
143
- if (!enabled) return;
144
- const container = rootEl ?? document;
145
- function resolveElements() {
146
- let els = [];
147
- if (ids && ids.length > 0) {
148
- els = ids.map((id) => document.getElementById(id)).filter((el) => el !== null);
149
- } else if (selectors) {
150
- els = Array.from(container.querySelectorAll(selectors));
151
- }
152
- return els.filter((el) => el.id);
153
- }
154
- let intersectionObserver = null;
155
- let mutationObserver = null;
156
- function startObserving() {
157
- const elements = resolveElements();
158
- if (elements.length === 0) return false;
159
- intersectionObserver = new IntersectionObserver(
160
- (entries2) => {
161
- for (const entry of entries2) {
162
- if (entry.isIntersecting) {
163
- visibleEntries.current.set(entry.target.id, entry);
164
- } else {
165
- visibleEntries.current.delete(entry.target.id);
166
- }
167
- }
168
- if (visibleEntries.current.size > 0) {
169
- let topmost = null;
170
- let topmostTop = Infinity;
171
- for (const [id, entry] of visibleEntries.current) {
172
- const top = entry.boundingClientRect.top;
173
- if (top < topmostTop) {
174
- topmostTop = top;
175
- topmost = id;
176
- }
177
- }
178
- if (topmost) {
179
- setActiveId(topmost);
180
- }
181
- }
182
- },
183
- {
184
- root: rootEl,
185
- rootMargin,
186
- threshold
187
- }
188
- );
189
- for (const el of elements) {
190
- intersectionObserver.observe(el);
191
- }
192
- mutationObserver?.disconnect();
193
- mutationObserver = null;
194
- return true;
195
- }
196
- if (!startObserving()) {
197
- const watchRoot = rootEl ?? document.body;
198
- mutationObserver = new MutationObserver(() => {
199
- startObserving();
200
- });
201
- mutationObserver.observe(watchRoot, { childList: true, subtree: true });
202
- }
203
- const entries = visibleEntries.current;
204
- return () => {
205
- mutationObserver?.disconnect();
206
- intersectionObserver?.disconnect();
207
- entries.clear();
208
- };
209
- }, [selectors, ids, rootMargin, threshold, rootEl, enabled]);
210
- return { activeId };
211
- }
212
129
 
213
130
  exports.RTL_LOCALES = RTL_LOCALES;
214
131
  exports.isRtlLocale = isRtlLocale;
@@ -222,6 +139,5 @@ exports.useIsSmallTablet = useIsSmallTablet;
222
139
  exports.useIsTablet = useIsTablet;
223
140
  exports.useKeyboardShortcut = useKeyboardShortcut;
224
141
  exports.useMediaQuery = useMediaQuery;
225
- exports.useScrollSpy = useScrollSpy;
226
- //# sourceMappingURL=chunk-XB54G7WS.cjs.map
227
- //# sourceMappingURL=chunk-XB54G7WS.cjs.map
142
+ //# sourceMappingURL=chunk-XJTFZLWH.cjs.map
143
+ //# sourceMappingURL=chunk-XJTFZLWH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useDirection.ts","../src/hooks/useKeyboardShortcut.ts","../src/hooks/useMediaQuery.ts"],"names":["useState","useEffect","useCallback"],"mappings":"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","file":"chunk-XJTFZLWH.cjs","sourcesContent":["import { useState, useEffect } from 'react';\nimport type { RefObject } from 'react';\n\nexport type Direction = 'ltr' | 'rtl';\n\n/** Locales whose primary script reads right-to-left. */\nexport const RTL_LOCALES = ['ar', 'he', 'fa', 'ur'] as const;\n\n/**\n * Returns true when the given locale (e.g. `ar`, `ar-SA`, `he_IL`) uses a\n * right-to-left script.\n */\nexport function isRtlLocale(locale: string): boolean {\n const lang = locale.toLowerCase().split(/[-_]/)[0];\n return (RTL_LOCALES as readonly string[]).includes(lang);\n}\n\nfunction resolveDirection(element?: HTMLElement | null): Direction {\n if (typeof document === 'undefined') return 'ltr';\n const target = element ?? document.documentElement;\n return getComputedStyle(target).direction === 'rtl' ? 'rtl' : 'ltr';\n}\n\n/**\n * Hook returning the effective text direction (`ltr` | `rtl`) inherited from\n * the nearest `dir` attribute — zero setup for consumers who set\n * `<html dir=\"rtl\">`.\n *\n * Use for JS-level direction logic that CSS logical properties can't cover:\n * inverting ArrowLeft/ArrowRight keyboard handling, popover/toast placement,\n * drag math, etc.\n *\n * @param elementRef - Optional ref; when provided, direction is resolved from\n * that element (respecting any local `dir` override) instead of `<html>`.\n *\n * @example\n * ```tsx\n * const direction = useDirection();\n * const nextKey = direction === 'rtl' ? 'ArrowLeft' : 'ArrowRight';\n * ```\n */\nexport function useDirection(\n elementRef?: RefObject<HTMLElement | null>\n): Direction {\n const [direction, setDirection] = useState<Direction>(() =>\n resolveDirection(elementRef?.current)\n );\n\n useEffect(() => {\n const update = () => setDirection(resolveDirection(elementRef?.current));\n update();\n // dir changes are rare; observing the whole tree for just this attribute is cheap.\n const observer = new MutationObserver(update);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['dir'],\n subtree: true,\n });\n return () => observer.disconnect();\n }, [elementRef]);\n\n // Re-sync when a re-render points elementRef.current at a different node:\n // the MutationObserver only fires on `dir` attribute mutations, so a swapped\n // ref target with a different inherited direction would otherwise go stale.\n const currentElement = elementRef?.current ?? null;\n useEffect(() => {\n setDirection(resolveDirection(currentElement));\n }, [currentElement]);\n\n return direction;\n}\n","import { useEffect, useCallback } from 'react';\n\n/**\n * Options for keyboard shortcut hook\n */\nexport interface KeyboardShortcutOptions {\n /** Whether the shortcut is currently enabled (default: true) */\n enabled?: boolean;\n /** Modifier keys required (default: none) */\n modifiers?: {\n ctrl?: boolean;\n shift?: boolean;\n alt?: boolean;\n meta?: boolean;\n };\n /** Whether to prevent default browser behavior (default: true) */\n preventDefault?: boolean;\n /** Whether to stop event propagation (default: false) */\n stopPropagation?: boolean;\n /** Element types to ignore when the shortcut is pressed (default: ['INPUT', 'TEXTAREA', 'SELECT']) */\n ignoreInputs?: boolean;\n}\n\n/**\n * Hook that triggers a callback when a specific keyboard shortcut is pressed.\n * Supports modifier keys (Ctrl, Shift, Alt, Meta) and ignores input fields by default.\n *\n * @param key - The key to listen for (e.g., 'k', 'Enter', 'Escape', '/')\n * @param callback - Function to call when the shortcut is pressed\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * // Cmd/Ctrl+K to open search\n * useKeyboardShortcut('k', openSearch, { modifiers: { meta: true, ctrl: true } });\n *\n * // Forward slash to focus search (ignoring when typing)\n * useKeyboardShortcut('/', focusSearch);\n *\n * // Escape to close modal\n * useKeyboardShortcut('Escape', closeModal);\n * ```\n */\nexport function useKeyboardShortcut(\n key: string,\n callback: (event: KeyboardEvent) => void,\n options: KeyboardShortcutOptions = {}\n): void {\n const {\n enabled = true,\n modifiers = {},\n preventDefault = true,\n stopPropagation = false,\n ignoreInputs = true,\n } = options;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n // Check if we should ignore input fields\n if (ignoreInputs) {\n const target = event.target as HTMLElement;\n const tagName = target.tagName.toUpperCase();\n if (\n tagName === 'INPUT' ||\n tagName === 'TEXTAREA' ||\n tagName === 'SELECT' ||\n target.isContentEditable\n ) {\n return;\n }\n }\n\n // Check modifiers\n const { ctrl, shift, alt, meta } = modifiers;\n\n // For Cmd+K style shortcuts, allow either meta (Mac) or ctrl (Windows/Linux)\n const metaOrCtrl = meta || ctrl;\n if (metaOrCtrl) {\n if (!(event.metaKey || event.ctrlKey)) return;\n } else {\n // If no meta/ctrl modifier specified, ensure neither is pressed\n if (event.metaKey || event.ctrlKey) return;\n }\n\n if (shift && !event.shiftKey) return;\n if (alt && !event.altKey) return;\n\n // Check key match (case-insensitive for letters)\n const eventKey =\n event.key.length === 1 ? event.key.toLowerCase() : event.key;\n const targetKey = key.length === 1 ? key.toLowerCase() : key;\n if (eventKey !== targetKey) return;\n\n if (preventDefault) {\n event.preventDefault();\n }\n if (stopPropagation) {\n event.stopPropagation();\n }\n\n callback(event);\n },\n [key, callback, modifiers, preventDefault, stopPropagation, ignoreInputs]\n );\n\n useEffect(() => {\n if (!enabled) return;\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [handleKeyDown, enabled]);\n}\n\n/**\n * Hook for the common Cmd/Ctrl+K shortcut pattern (command palette, search, etc.)\n *\n * @param callback - Function to call when Cmd/Ctrl+K is pressed\n * @param enabled - Whether the shortcut is active (default: true)\n *\n * @example\n * ```tsx\n * useCommandK(() => setIsOpen(true));\n * ```\n */\nexport function useCommandK(callback: () => void, enabled = true): void {\n useKeyboardShortcut('k', callback, {\n enabled,\n modifiers: { meta: true, ctrl: true },\n ignoreInputs: false, // Cmd+K should work even in inputs\n });\n}\n","import { useState, useEffect } from 'react';\n\n/**\n * Hook that tracks whether a media query matches.\n * Uses the native `matchMedia` API for efficient media query tracking.\n *\n * @param query - CSS media query string (e.g., '(min-width: 768px)')\n * @returns Boolean indicating whether the media query matches\n *\n * @example\n * ```tsx\n * function ResponsiveComponent() {\n * const isMobile = useMediaQuery('(max-width: 767px)');\n * const isTablet = useMediaQuery('(min-width: 768px) and (max-width: 1023px)');\n * const isDesktop = useMediaQuery('(min-width: 1024px)');\n *\n * return (\n * <div>\n * {isMobile && <MobileLayout />}\n * {isTablet && <TabletLayout />}\n * {isDesktop && <DesktopLayout />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useMediaQuery(query: string): boolean {\n // Initialize with null to indicate SSR/initial state\n const [matches, setMatches] = useState<boolean>(() => {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mediaQuery = window.matchMedia(query);\n\n // Set initial value\n setMatches(mediaQuery.matches);\n\n // Handler for media query changes\n const handler = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n // Modern browsers use addEventListener\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handler);\n return () => mediaQuery.removeEventListener('change', handler);\n }\n\n // Fallback for older browsers\n mediaQuery.addListener(handler);\n return () => mediaQuery.removeListener(handler);\n }, [query]);\n\n return matches;\n}\n\n/**\n * Preset breakpoint hooks following common responsive design patterns\n */\n\n/** Returns true when viewport is smaller than 640px (mobile) */\nexport function useIsMobile(): boolean {\n return useMediaQuery('(max-width: 639px)');\n}\n\n/** Returns true when viewport is 640px-767px (large mobile / small tablet) */\nexport function useIsSmallTablet(): boolean {\n return useMediaQuery('(min-width: 640px) and (max-width: 767px)');\n}\n\n/** Returns true when viewport is 768px-1023px (tablet) */\nexport function useIsTablet(): boolean {\n return useMediaQuery('(min-width: 768px) and (max-width: 1023px)');\n}\n\n/** Returns true when viewport is 1024px or larger (desktop) */\nexport function useIsDesktop(): boolean {\n return useMediaQuery('(min-width: 1024px)');\n}\n\n/** Returns true when viewport is 1280px or larger (large desktop) */\nexport function useIsLargeDesktop(): boolean {\n return useMediaQuery('(min-width: 1280px)');\n}\n\n/** Returns true when viewport is smaller than 1024px (mobile/tablet) */\nexport function useIsMobileOrTablet(): boolean {\n return useMediaQuery('(max-width: 1023px)');\n}\n"]}