@jbpark/ui-kit 10.2.0 → 10.3.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 (351) hide show
  1. package/dist/Alert.d.mts +2 -2
  2. package/dist/Alert.d.mts.map +1 -1
  3. package/dist/Alert.mjs +1 -1
  4. package/dist/Anchor.d.mts +29 -0
  5. package/dist/Anchor.d.mts.map +1 -0
  6. package/dist/Anchor.mjs +120 -0
  7. package/dist/Anchor.mjs.map +1 -0
  8. package/dist/AutoComplete.d.mts +34 -0
  9. package/dist/AutoComplete.d.mts.map +1 -0
  10. package/dist/AutoComplete.mjs +82 -0
  11. package/dist/AutoComplete.mjs.map +1 -0
  12. package/dist/Avatar.d.mts +2 -2
  13. package/dist/Avatar.d.mts.map +1 -1
  14. package/dist/Avatar.mjs +2 -2
  15. package/dist/Badge.d.mts +2 -2
  16. package/dist/Badge.d.mts.map +1 -1
  17. package/dist/Breadcrumb.d.mts +3 -3
  18. package/dist/Breadcrumb.d.mts.map +1 -1
  19. package/dist/Breadcrumb.mjs +1 -1
  20. package/dist/Breadcrumb.mjs.map +1 -1
  21. package/dist/Button.d.mts +3 -3
  22. package/dist/Button.d.mts.map +1 -1
  23. package/dist/Button.mjs +1 -1
  24. package/dist/Calendar.d.mts +28 -0
  25. package/dist/Calendar.d.mts.map +1 -0
  26. package/dist/Calendar.mjs +64 -0
  27. package/dist/Calendar.mjs.map +1 -0
  28. package/dist/Card.d.mts +2 -2
  29. package/dist/Card.d.mts.map +1 -1
  30. package/dist/Cascader.d.mts +34 -0
  31. package/dist/Cascader.d.mts.map +1 -0
  32. package/dist/Cascader.mjs +144 -0
  33. package/dist/Cascader.mjs.map +1 -0
  34. package/dist/CodeEditor.d.mts +2 -2
  35. package/dist/CodeEditor.d.mts.map +1 -1
  36. package/dist/ContextMenu.d.mts +33 -0
  37. package/dist/ContextMenu.d.mts.map +1 -0
  38. package/dist/ContextMenu.mjs +92 -0
  39. package/dist/ContextMenu.mjs.map +1 -0
  40. package/dist/Descriptions.d.mts +31 -0
  41. package/dist/Descriptions.d.mts.map +1 -0
  42. package/dist/Descriptions.mjs +67 -0
  43. package/dist/Descriptions.mjs.map +1 -0
  44. package/dist/Divider.d.mts +18 -0
  45. package/dist/Divider.d.mts.map +1 -0
  46. package/dist/Divider.mjs +44 -0
  47. package/dist/Divider.mjs.map +1 -0
  48. package/dist/Form.d.mts +12 -0
  49. package/dist/Form.d.mts.map +1 -0
  50. package/dist/Form.mjs +11 -0
  51. package/dist/Form.mjs.map +1 -0
  52. package/dist/Layout.d.mts.map +1 -1
  53. package/dist/Mentions.d.mts +34 -0
  54. package/dist/Mentions.d.mts.map +1 -0
  55. package/dist/Mentions.mjs +207 -0
  56. package/dist/Mentions.mjs.map +1 -0
  57. package/dist/Menu.mjs +1 -2
  58. package/dist/Pagination.d.mts +2 -2
  59. package/dist/Pagination.d.mts.map +1 -1
  60. package/dist/Pagination.mjs +1 -1
  61. package/dist/Popconfirm.d.mts +33 -0
  62. package/dist/Popconfirm.d.mts.map +1 -0
  63. package/dist/Popconfirm.mjs +119 -0
  64. package/dist/Popconfirm.mjs.map +1 -0
  65. package/dist/Rate.d.mts +27 -0
  66. package/dist/Rate.d.mts.map +1 -0
  67. package/dist/Rate.mjs +81 -0
  68. package/dist/Rate.mjs.map +1 -0
  69. package/dist/Reveals.d.mts.map +1 -1
  70. package/dist/ScrollArea.d.mts +8 -0
  71. package/dist/ScrollArea.d.mts.map +1 -0
  72. package/dist/ScrollArea.mjs +11 -0
  73. package/dist/ScrollArea.mjs.map +1 -0
  74. package/dist/Segmented.d.mts +3 -3
  75. package/dist/Segmented.d.mts.map +1 -1
  76. package/dist/Space.d.mts +2 -2
  77. package/dist/Space.d.mts.map +1 -1
  78. package/dist/Statistic.d.mts +22 -0
  79. package/dist/Statistic.d.mts.map +1 -0
  80. package/dist/Statistic.mjs +53 -0
  81. package/dist/Statistic.mjs.map +1 -0
  82. package/dist/Steps.d.mts +3 -3
  83. package/dist/Steps.d.mts.map +1 -1
  84. package/dist/Steps.mjs +1 -1
  85. package/dist/Table.d.mts +4 -4
  86. package/dist/Table.d.mts.map +1 -1
  87. package/dist/Tag.d.mts +3 -3
  88. package/dist/Tag.d.mts.map +1 -1
  89. package/dist/TimePicker.d.mts +26 -0
  90. package/dist/TimePicker.d.mts.map +1 -0
  91. package/dist/TimePicker.mjs +77 -0
  92. package/dist/TimePicker.mjs.map +1 -0
  93. package/dist/Timeline.d.mts +35 -0
  94. package/dist/Timeline.d.mts.map +1 -0
  95. package/dist/Timeline.mjs +59 -0
  96. package/dist/Timeline.mjs.map +1 -0
  97. package/dist/Tour.d.mts +37 -0
  98. package/dist/Tour.d.mts.map +1 -0
  99. package/dist/Tour.mjs +192 -0
  100. package/dist/Tour.mjs.map +1 -0
  101. package/dist/Transfer.d.mts +36 -0
  102. package/dist/Transfer.d.mts.map +1 -0
  103. package/dist/Transfer.mjs +147 -0
  104. package/dist/Transfer.mjs.map +1 -0
  105. package/dist/Tree.d.mts +62 -0
  106. package/dist/Tree.d.mts.map +1 -0
  107. package/dist/Tree.mjs +462 -0
  108. package/dist/Tree.mjs.map +1 -0
  109. package/dist/TreeSelect.d.mts +34 -0
  110. package/dist/TreeSelect.d.mts.map +1 -0
  111. package/dist/TreeSelect.mjs +135 -0
  112. package/dist/TreeSelect.mjs.map +1 -0
  113. package/dist/Typography.d.mts.map +1 -1
  114. package/dist/components/atoms/checkbox/checkbox.d.mts +5 -3
  115. package/dist/components/atoms/checkbox/checkbox.d.mts.map +1 -1
  116. package/dist/components/atoms/checkbox/checkbox.mjs +8 -4
  117. package/dist/components/atoms/checkbox/checkbox.mjs.map +1 -1
  118. package/dist/components/atoms/checkbox/group.d.mts +2 -2
  119. package/dist/components/atoms/checkbox/group.d.mts.map +1 -1
  120. package/dist/components/atoms/checkbox/index.d.mts.map +1 -1
  121. package/dist/components/atoms/color-picker.d.mts +2 -2
  122. package/dist/components/atoms/color-picker.d.mts.map +1 -1
  123. package/dist/components/atoms/date-picker.d.mts +5 -1
  124. package/dist/components/atoms/date-picker.d.mts.map +1 -1
  125. package/dist/components/atoms/date-picker.mjs +54 -10
  126. package/dist/components/atoms/date-picker.mjs.map +1 -1
  127. package/dist/components/atoms/float-button/back-top.d.mts +2 -2
  128. package/dist/components/atoms/float-button/back-top.d.mts.map +1 -1
  129. package/dist/components/atoms/float-button/back-top.mjs +1 -1
  130. package/dist/components/atoms/float-button/float-button.d.mts +2 -2
  131. package/dist/components/atoms/float-button/float-button.d.mts.map +1 -1
  132. package/dist/components/atoms/float-button/index.d.mts.map +1 -1
  133. package/dist/components/atoms/index.d.mts +13 -6
  134. package/dist/components/atoms/input/index.d.mts +3 -1
  135. package/dist/components/atoms/input/index.d.mts.map +1 -1
  136. package/dist/components/atoms/input/index.mjs +3 -1
  137. package/dist/components/atoms/input/index.mjs.map +1 -1
  138. package/dist/components/atoms/input/number.d.mts +2 -2
  139. package/dist/components/atoms/input/number.d.mts.map +1 -1
  140. package/dist/components/atoms/input/number.mjs +1 -1
  141. package/dist/components/atoms/input/otp.d.mts +26 -0
  142. package/dist/components/atoms/input/otp.d.mts.map +1 -0
  143. package/dist/components/atoms/input/otp.mjs +52 -0
  144. package/dist/components/atoms/input/otp.mjs.map +1 -0
  145. package/dist/components/atoms/input/search.d.mts +2 -2
  146. package/dist/components/atoms/input/search.d.mts.map +1 -1
  147. package/dist/components/atoms/input/search.mjs +2 -2
  148. package/dist/components/atoms/mentions-token.mjs +31 -0
  149. package/dist/components/atoms/mentions-token.mjs.map +1 -0
  150. package/dist/components/atoms/option-group.d.mts +4 -5
  151. package/dist/components/atoms/option-group.d.mts.map +1 -1
  152. package/dist/components/atoms/popover.d.mts +2 -2
  153. package/dist/components/atoms/popover.d.mts.map +1 -1
  154. package/dist/components/atoms/progress.d.mts +2 -2
  155. package/dist/components/atoms/progress.d.mts.map +1 -1
  156. package/dist/components/atoms/radio/group.d.mts +2 -2
  157. package/dist/components/atoms/radio/group.d.mts.map +1 -1
  158. package/dist/components/atoms/radio/group.mjs +1 -1
  159. package/dist/components/atoms/radio/index.d.mts.map +1 -1
  160. package/dist/components/atoms/radio/radio.d.mts +2 -2
  161. package/dist/components/atoms/radio/radio.d.mts.map +1 -1
  162. package/dist/components/atoms/radio/radio.mjs +1 -1
  163. package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts +2 -2
  164. package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts.map +1 -1
  165. package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs +2 -2
  166. package/dist/components/atoms/rich-text-editor/types.d.mts +2 -3
  167. package/dist/components/atoms/rich-text-editor/types.d.mts.map +1 -1
  168. package/dist/components/atoms/select-multiple.d.mts +2 -3
  169. package/dist/components/atoms/select-multiple.d.mts.map +1 -1
  170. package/dist/components/atoms/select-multiple.mjs +4 -3
  171. package/dist/components/atoms/select-multiple.mjs.map +1 -1
  172. package/dist/components/atoms/select-searchable-options.d.mts +3 -4
  173. package/dist/components/atoms/select-searchable-options.d.mts.map +1 -1
  174. package/dist/components/atoms/select-searchable.d.mts +2 -3
  175. package/dist/components/atoms/select-searchable.d.mts.map +1 -1
  176. package/dist/components/atoms/select-searchable.mjs +4 -3
  177. package/dist/components/atoms/select-searchable.mjs.map +1 -1
  178. package/dist/components/atoms/select.d.mts +3 -3
  179. package/dist/components/atoms/select.d.mts.map +1 -1
  180. package/dist/components/atoms/skeleton/button.d.mts.map +1 -1
  181. package/dist/components/atoms/skeleton/index.d.mts.map +1 -1
  182. package/dist/components/atoms/skeleton/node.d.mts.map +1 -1
  183. package/dist/components/atoms/skeleton/skeleton.d.mts +2 -2
  184. package/dist/components/atoms/skeleton/skeleton.d.mts.map +1 -1
  185. package/dist/components/atoms/slider/slider.d.mts +3 -3
  186. package/dist/components/atoms/slider/slider.d.mts.map +1 -1
  187. package/dist/components/atoms/spin.d.mts +2 -2
  188. package/dist/components/atoms/spin.d.mts.map +1 -1
  189. package/dist/components/atoms/spin.mjs +1 -1
  190. package/dist/components/atoms/switch.d.mts +2 -2
  191. package/dist/components/atoms/switch.d.mts.map +1 -1
  192. package/dist/components/atoms/tooltip.d.mts +2 -2
  193. package/dist/components/atoms/tooltip.d.mts.map +1 -1
  194. package/dist/components/atoms/typography/link.d.mts +2 -2
  195. package/dist/components/atoms/typography/link.d.mts.map +1 -1
  196. package/dist/components/atoms/typography/paragraph.d.mts +2 -2
  197. package/dist/components/atoms/typography/paragraph.d.mts.map +1 -1
  198. package/dist/components/atoms/typography/text.d.mts +2 -2
  199. package/dist/components/atoms/typography/text.d.mts.map +1 -1
  200. package/dist/components/atoms/typography/title.d.mts +2 -2
  201. package/dist/components/atoms/typography/title.d.mts.map +1 -1
  202. package/dist/components/atoms/typography/typography.d.mts +2 -2
  203. package/dist/components/atoms/typography/typography.d.mts.map +1 -1
  204. package/dist/components/molecules/collapse.d.mts +2 -2
  205. package/dist/components/molecules/collapse.d.mts.map +1 -1
  206. package/dist/components/molecules/dropdown.d.mts +2 -2
  207. package/dist/components/molecules/dropdown.d.mts.map +1 -1
  208. package/dist/components/molecules/index.d.mts +22 -14
  209. package/dist/components/molecules/marquees/index.d.mts.map +1 -1
  210. package/dist/components/molecules/marquees/item.d.mts +4 -4
  211. package/dist/components/molecules/marquees/item.d.mts.map +1 -1
  212. package/dist/components/molecules/marquees/item.mjs +5 -5
  213. package/dist/components/molecules/marquees/item.mjs.map +1 -1
  214. package/dist/components/molecules/marquees/marquees.d.mts +2 -2
  215. package/dist/components/molecules/marquees/marquees.d.mts.map +1 -1
  216. package/dist/components/molecules/marquees/marquees.mjs +4 -5
  217. package/dist/components/molecules/marquees/marquees.mjs.map +1 -1
  218. package/dist/components/molecules/menu/item/item.mjs +1 -1
  219. package/dist/components/molecules/menu/menu.d.mts +9 -9
  220. package/dist/components/molecules/menu/menu.d.mts.map +1 -1
  221. package/dist/components/molecules/reveals/item.d.mts +2 -2
  222. package/dist/components/molecules/reveals/item.d.mts.map +1 -1
  223. package/dist/components/molecules/reveals/reveals.d.mts +5 -5
  224. package/dist/components/molecules/reveals/reveals.d.mts.map +1 -1
  225. package/dist/components/molecules/splitter/index.d.mts.map +1 -1
  226. package/dist/components/molecules/splitter/panel.d.mts +3 -3
  227. package/dist/components/molecules/splitter/panel.d.mts.map +1 -1
  228. package/dist/components/molecules/splitter/splitter.d.mts +3 -3
  229. package/dist/components/molecules/splitter/splitter.d.mts.map +1 -1
  230. package/dist/components/molecules/tabs.d.mts +4 -4
  231. package/dist/components/molecules/tabs.d.mts.map +1 -1
  232. package/dist/components/molecules/upload.d.mts +3 -3
  233. package/dist/components/molecules/upload.d.mts.map +1 -1
  234. package/dist/components/molecules/upload.mjs +1 -1
  235. package/dist/components/organisms/drawer.d.mts +2 -2
  236. package/dist/components/organisms/drawer.d.mts.map +1 -1
  237. package/dist/components/organisms/drawer.mjs +2 -2
  238. package/dist/components/organisms/form/context.d.mts +4 -0
  239. package/dist/components/organisms/form/context.d.mts.map +1 -0
  240. package/dist/components/organisms/form/context.mjs +9 -0
  241. package/dist/components/organisms/form/context.mjs.map +1 -0
  242. package/dist/components/organisms/form/control.d.mts +11 -0
  243. package/dist/components/organisms/form/control.d.mts.map +1 -0
  244. package/dist/components/organisms/form/control.mjs +19 -0
  245. package/dist/components/organisms/form/control.mjs.map +1 -0
  246. package/dist/components/organisms/form/field.d.mts +25 -0
  247. package/dist/components/organisms/form/field.d.mts.map +1 -0
  248. package/dist/components/organisms/form/field.mjs +54 -0
  249. package/dist/components/organisms/form/field.mjs.map +1 -0
  250. package/dist/components/organisms/form/form.d.mts +14 -0
  251. package/dist/components/organisms/form/form.d.mts.map +1 -0
  252. package/dist/components/organisms/form/form.mjs +23 -0
  253. package/dist/components/organisms/form/form.mjs.map +1 -0
  254. package/dist/components/organisms/index.d.mts +14 -6
  255. package/dist/components/organisms/list/index.d.mts.map +1 -1
  256. package/dist/components/organisms/list/list.d.mts +2 -2
  257. package/dist/components/organisms/list/list.d.mts.map +1 -1
  258. package/dist/components/organisms/modal.d.mts +6 -3
  259. package/dist/components/organisms/modal.d.mts.map +1 -1
  260. package/dist/components/organisms/modal.mjs +25 -18
  261. package/dist/components/organisms/modal.mjs.map +1 -1
  262. package/dist/components/organisms/swiper/index.d.mts.map +1 -1
  263. package/dist/components/organisms/swiper/swiper.d.mts +2 -2
  264. package/dist/components/organisms/swiper/swiper.d.mts.map +1 -1
  265. package/dist/components/organisms/toast.d.mts +2 -2
  266. package/dist/components/organisms/toast.d.mts.map +1 -1
  267. package/dist/components/organisms/toast.mjs +1 -1
  268. package/dist/components/templates/container.d.mts +2 -2
  269. package/dist/components/templates/container.d.mts.map +1 -1
  270. package/dist/components/templates/empty.d.mts +2 -2
  271. package/dist/components/templates/empty.d.mts.map +1 -1
  272. package/dist/components/templates/empty.mjs +1 -1
  273. package/dist/components/templates/grid/col.d.mts +2 -2
  274. package/dist/components/templates/grid/col.d.mts.map +1 -1
  275. package/dist/components/templates/grid/row.d.mts +2 -2
  276. package/dist/components/templates/grid/row.d.mts.map +1 -1
  277. package/dist/components/templates/layout/content.d.mts +2 -2
  278. package/dist/components/templates/layout/content.d.mts.map +1 -1
  279. package/dist/components/templates/layout/footer.d.mts +2 -2
  280. package/dist/components/templates/layout/footer.d.mts.map +1 -1
  281. package/dist/components/templates/layout/header.d.mts +2 -2
  282. package/dist/components/templates/layout/header.d.mts.map +1 -1
  283. package/dist/components/templates/layout/layout.d.mts +2 -2
  284. package/dist/components/templates/layout/layout.d.mts.map +1 -1
  285. package/dist/components/templates/layout/sider.d.mts +2 -2
  286. package/dist/components/templates/layout/sider.d.mts.map +1 -1
  287. package/dist/components/templates/layout/sider.mjs +1 -1
  288. package/dist/components/templates/page-header.d.mts +2 -2
  289. package/dist/components/templates/page-header.d.mts.map +1 -1
  290. package/dist/components/templates/page-header.mjs +1 -1
  291. package/dist/components/templates/result.d.mts +2 -2
  292. package/dist/components/templates/result.d.mts.map +1 -1
  293. package/dist/components/templates/result.mjs +1 -1
  294. package/dist/core/accordion.mjs +1 -1
  295. package/dist/core/autocomplete.d.mts +2 -0
  296. package/dist/core/autocomplete.mjs +48 -0
  297. package/dist/core/autocomplete.mjs.map +1 -0
  298. package/dist/core/badge.d.mts +5 -3
  299. package/dist/core/badge.d.mts.map +1 -1
  300. package/dist/core/button.d.mts +6 -4
  301. package/dist/core/button.d.mts.map +1 -1
  302. package/dist/core/calendar.d.mts +13 -3
  303. package/dist/core/calendar.d.mts.map +1 -0
  304. package/dist/core/calendar.mjs +1 -1
  305. package/dist/core/checkbox.mjs +11 -8
  306. package/dist/core/checkbox.mjs.map +1 -1
  307. package/dist/core/combobox.d.mts +26 -4
  308. package/dist/core/combobox.d.mts.map +1 -1
  309. package/dist/core/combobox.mjs +2 -2
  310. package/dist/core/combobox.mjs.map +1 -1
  311. package/dist/core/dialog.mjs +2 -2
  312. package/dist/core/dialog.mjs.map +1 -1
  313. package/dist/core/form.d.mts +8 -0
  314. package/dist/core/form.d.mts.map +1 -0
  315. package/dist/core/form.mjs +3 -0
  316. package/dist/core/index.d.mts +13 -9
  317. package/dist/core/popover.mjs +10 -2
  318. package/dist/core/popover.mjs.map +1 -1
  319. package/dist/core/radio-group.mjs +1 -1
  320. package/dist/core/resizable.d.mts +7 -2
  321. package/dist/core/resizable.d.mts.map +1 -1
  322. package/dist/core/resizable.mjs +1 -1
  323. package/dist/core/scroll-area.d.mts +20 -0
  324. package/dist/core/scroll-area.d.mts.map +1 -0
  325. package/dist/core/scroll-area.mjs +57 -0
  326. package/dist/core/scroll-area.mjs.map +1 -0
  327. package/dist/core/select.d.mts +24 -2
  328. package/dist/core/select.d.mts.map +1 -1
  329. package/dist/core/select.mjs +1 -1
  330. package/dist/core/separator.d.mts +13 -2
  331. package/dist/core/separator.d.mts.map +1 -0
  332. package/dist/core/tabs.d.mts +16 -2
  333. package/dist/core/tabs.d.mts.map +1 -1
  334. package/dist/index.d.mts +59 -36
  335. package/dist/index.mjs +25 -6
  336. package/dist/lib/colors.d.mts +2 -3
  337. package/dist/lib/colors.d.mts.map +1 -1
  338. package/dist/providers/config/context.d.mts +2 -3
  339. package/dist/providers/config/context.d.mts.map +1 -1
  340. package/dist/providers/config/context.mjs +3 -1
  341. package/dist/providers/config/context.mjs.map +1 -1
  342. package/dist/providers/config/registry.d.mts +2 -3
  343. package/dist/providers/config/registry.d.mts.map +1 -1
  344. package/dist/providers/config/types.d.mts +8 -7
  345. package/dist/providers/config/types.d.mts.map +1 -1
  346. package/dist/style.css +689 -332
  347. package/dist/utils.d.mts +2 -3
  348. package/dist/utils.d.mts.map +1 -1
  349. package/package.json +122 -26
  350. package/dist/components/molecules/marquees/use-pause-on-hover.mjs +0 -26
  351. package/dist/components/molecules/marquees/use-pause-on-hover.mjs.map +0 -1
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { cn } from "./utils.mjs";
3
+ import { useConfig } from "./providers/config/context.mjs";
4
+ import { Separator } from "./core/separator.mjs";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/atoms/divider.tsx
7
+ const variants = {
8
+ solid: "border-solid",
9
+ dashed: "border-dashed",
10
+ dotted: "border-dotted"
11
+ };
12
+ const Divider = ({ children, orientation = "horizontal", decorative = true, variant = "solid", titlePlacement = "center", className, classNames, dir, "aria-label": ariaLabel, ...props }) => {
13
+ const { direction } = useConfig();
14
+ const hasLabel = children !== void 0 && children !== null && children !== false;
15
+ const isVertical = orientation === "vertical";
16
+ const label = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
17
+ const lineClassName = cn("border-border min-w-0 flex-1", isVertical ? "min-h-0 border-s" : "border-t", variants[variant], classNames?.line);
18
+ return /* @__PURE__ */ jsxs(Separator, {
19
+ ...props,
20
+ "data-slot": "divider",
21
+ dir: dir ?? direction,
22
+ orientation,
23
+ decorative,
24
+ "aria-label": decorative ? ariaLabel : ariaLabel ?? label,
25
+ className: cn(`text-foreground flex bg-transparent
26
+ data-[orientation=horizontal]:h-auto data-[orientation=vertical]:h-auto
27
+ data-[orientation=vertical]:w-auto`, isVertical ? "mx-2 h-auto w-auto flex-col items-center self-stretch" : "my-4 h-auto w-full items-center", hasLabel && "gap-3", className),
28
+ children: [/* @__PURE__ */ jsx("span", {
29
+ "aria-hidden": "true",
30
+ className: cn(lineClassName, hasLabel && titlePlacement === "start" && "flex-[0.1]")
31
+ }), hasLabel && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
32
+ "data-slot": "divider-label",
33
+ className: cn("min-w-0 shrink text-sm font-medium [overflow-wrap:anywhere]", classNames?.label),
34
+ children
35
+ }), /* @__PURE__ */ jsx("span", {
36
+ "aria-hidden": "true",
37
+ className: cn(lineClassName, titlePlacement === "end" && "flex-[0.1]")
38
+ })] })]
39
+ });
40
+ };
41
+ //#endregion
42
+ export { Divider as default };
43
+
44
+ //# sourceMappingURL=Divider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Divider.mjs","names":["separator.Separator"],"sources":["../src/components/atoms/divider.tsx"],"sourcesContent":["'use client';\n\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { separator } from '../../core';\n\nexport interface Props extends Omit<\n ComponentProps<typeof separator.Separator>,\n 'children' | 'className'\n> {\n children?: ReactNode;\n variant?: 'solid' | 'dashed' | 'dotted';\n titlePlacement?: 'start' | 'center' | 'end';\n className?: string;\n classNames?: {\n line?: string;\n label?: string;\n };\n}\n\nconst variants = {\n solid: 'border-solid',\n dashed: 'border-dashed',\n dotted: 'border-dotted',\n};\n\nconst Divider = ({\n children,\n orientation = 'horizontal',\n decorative = true,\n variant = 'solid',\n titlePlacement = 'center',\n className,\n classNames,\n dir,\n 'aria-label': ariaLabel,\n ...props\n}: Props) => {\n const { direction } = useConfig();\n const hasLabel =\n children !== undefined && children !== null && children !== false;\n const isVertical = orientation === 'vertical';\n const label =\n typeof children === 'string' || typeof children === 'number'\n ? String(children)\n : undefined;\n const lineClassName = cn(\n 'border-border min-w-0 flex-1',\n isVertical ? 'min-h-0 border-s' : 'border-t',\n variants[variant],\n classNames?.line,\n //\n );\n\n return (\n <separator.Separator\n {...props}\n data-slot=\"divider\"\n dir={dir ?? direction}\n orientation={orientation}\n decorative={decorative}\n aria-label={decorative ? ariaLabel : (ariaLabel ?? label)}\n className={cn(\n `text-foreground flex bg-transparent\n data-[orientation=horizontal]:h-auto data-[orientation=vertical]:h-auto\n data-[orientation=vertical]:w-auto`,\n isVertical\n ? 'mx-2 h-auto w-auto flex-col items-center self-stretch'\n : 'my-4 h-auto w-full items-center',\n hasLabel && 'gap-3',\n className,\n //\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n lineClassName,\n hasLabel && titlePlacement === 'start' && 'flex-[0.1]',\n //\n )}\n />\n {hasLabel && (\n <>\n <span\n data-slot=\"divider-label\"\n className={cn(\n 'min-w-0 shrink text-sm font-medium [overflow-wrap:anywhere]',\n classNames?.label,\n //\n )}\n >\n {children}\n </span>\n <span\n aria-hidden=\"true\"\n className={cn(\n lineClassName,\n titlePlacement === 'end' && 'flex-[0.1]',\n //\n )}\n />\n </>\n )}\n </separator.Separator>\n );\n};\n\nexport default Divider;\n"],"mappings":";;;;;;AAuBA,MAAM,WAAW;CACf,OAAO;CACP,QAAQ;CACR,QAAQ;AACV;AAEA,MAAM,WAAW,EACf,UACA,cAAc,cACd,aAAa,MACb,UAAU,SACV,iBAAiB,UACjB,WACA,YACA,KACA,cAAc,WACd,GAAG,YACQ;CACX,MAAM,EAAE,cAAc,UAAU;CAChC,MAAM,WACJ,aAAa,KAAA,KAAa,aAAa,QAAQ,aAAa;CAC9D,MAAM,aAAa,gBAAgB;CACnC,MAAM,QACJ,OAAO,aAAa,YAAY,OAAO,aAAa,WAChD,OAAO,QAAQ,IACf,KAAA;CACN,MAAM,gBAAgB,GACpB,gCACA,aAAa,qBAAqB,YAClC,SAAS,UACT,YAAY,IAEd;CAEA,OACE,qBAACA,WAAD;EACE,GAAI;EACJ,aAAU;EACV,KAAK,OAAO;EACC;EACD;EACZ,cAAY,aAAa,YAAa,aAAa;EACnD,WAAW,GACT;;6CAGA,aACI,0DACA,mCACJ,YAAY,SACZ,SAEF;EAjBF,UAAA,CAmBE,oBAAC,QAAD;GACE,eAAY;GACZ,WAAW,GACT,eACA,YAAY,mBAAmB,WAAW,YAE5C;EACD,CAAA,GACA,YACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GACE,aAAU;GACV,WAAW,GACT,+DACA,YAAY,KAEd;GAEC;EACG,CAAA,GACN,oBAAC,QAAD;GACE,eAAY;GACZ,WAAW,GACT,eACA,mBAAmB,SAAS,YAE9B;EACD,CAAA,CACD,EAAA,CAAA,CAEe;;AAEzB"}
@@ -0,0 +1,12 @@
1
+ import Control, { Props } from "./components/organisms/form/control.mjs";
2
+ import Field, { Props as Props$1 } from "./components/organisms/form/field.mjs";
3
+ import Form$1, { Props as Props$2 } from "./components/organisms/form/form.mjs";
4
+ //#region src/components/organisms/form/index.d.ts
5
+ type FormComponent = typeof Form$1 & {
6
+ Field: typeof Field;
7
+ Control: typeof Control;
8
+ };
9
+ declare const Form: FormComponent;
10
+ //#endregion
11
+ export { type Props as ControlProps, type Props$1 as FieldProps, type Props$2 as Props, Form as default };
12
+ //# sourceMappingURL=Form.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.d.mts","names":["FormImpl"],"sources":["../src/components/organisms/form/index.ts"],"mappings":";;;;KAIK,uBAAuBA;EAC1B,cAAc;EACd,gBAAgB;;cAGZ,MAAmB"}
package/dist/Form.mjs ADDED
@@ -0,0 +1,11 @@
1
+ import Control from "./components/organisms/form/control.mjs";
2
+ import Field from "./components/organisms/form/field.mjs";
3
+ import Form$1 from "./components/organisms/form/form.mjs";
4
+ //#region src/components/organisms/form/index.ts
5
+ const Form = Form$1;
6
+ Form.Field = Field;
7
+ Form.Control = Control;
8
+ //#endregion
9
+ export { Form as default };
10
+
11
+ //# sourceMappingURL=Form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.mjs","names":["FormImpl"],"sources":["../src/components/organisms/form/index.ts"],"sourcesContent":["import Control from './control';\nimport Field from './field';\nimport FormImpl, { type Props } from './form';\n\ntype FormComponent = typeof FormImpl & {\n Field: typeof Field;\n Control: typeof Control;\n};\n\nconst Form = FormImpl as FormComponent;\n\nForm.Field = Field;\nForm.Control = Control;\n\nexport default Form;\nexport type { Props };\nexport type { Props as FieldProps } from './field';\nexport type { Props as ControlProps } from './control';\n"],"mappings":";;;;AASA,MAAM,OAAOA;AAEb,KAAK,QAAQ;AACb,KAAK,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"Layout.d.mts","names":[],"sources":["../src/components/templates/layout/index.ts"],"mappings":";;;;;;KAMK,yBAAyB;EAC5B,gBAAgB;EAChB,eAAe;EACf,eAAe;EACf,cAAc;;cAGV,QAAuB"}
1
+ {"version":3,"file":"Layout.d.mts","names":["LayoutImpl"],"sources":["../src/components/templates/layout/index.ts"],"mappings":";;;;;;KAMK,yBAAyBA;EAC5B,gBAAgB;EAChB,eAAe;EACf,eAAe;EACf,cAAc;;cAGV,QAAuB"}
@@ -0,0 +1,34 @@
1
+ import { ComponentPropsWithRef, ReactNode } from "react";
2
+ //#region src/components/atoms/mentions.d.ts
3
+ export interface Option {
4
+ /** Unique, non-empty token text without whitespace or the prefix. */
5
+ value: string;
6
+ label?: string;
7
+ prefix?: string;
8
+ disabled?: boolean;
9
+ }
10
+ export interface Props extends Omit<ComponentPropsWithRef<'textarea'>, 'children' | 'value' | 'defaultValue' | 'onChange' | 'onSelect'> {
11
+ options: readonly Option[];
12
+ value?: string;
13
+ defaultValue?: string;
14
+ onChange?: (value: string) => void;
15
+ onSelect?: (option: Option, prefix: string) => void;
16
+ onSearch?: (query: string, prefix: string) => void;
17
+ prefixes?: readonly string[];
18
+ filterOption?: false | ((query: string, option: Option) => boolean);
19
+ loading?: boolean;
20
+ loadingText?: ReactNode;
21
+ emptyText?: ReactNode;
22
+ container?: HTMLElement;
23
+ classNames?: {
24
+ root?: string;
25
+ content?: string;
26
+ list?: string;
27
+ option?: string;
28
+ empty?: string;
29
+ };
30
+ }
31
+ declare const Mentions: ({ options, value, defaultValue, onChange, onSelect, onSearch, prefixes, filterOption, loading, loadingText, emptyText, container, disabled, readOnly, name, form, className, classNames, dir, ref, onFocus, onBlur, onClick, onKeyDown, onKeyUp, onCompositionStart, onCompositionEnd, ...props }: Props) => import("react").JSX.Element;
32
+ //#endregion
33
+ export { Mentions as default };
34
+ //# sourceMappingURL=Mentions.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mentions.d.mts","names":[],"sources":["../src/components/atoms/mentions.tsx"],"mappings":";;iBAoBiB;;EAEf;EACA;EACA;EACA;;iBAGe,cAAc,KAC7B;EAGA,kBAAkB;EAClB;EACA;EACA,YAAY;EACZ,YAAY,QAAQ,QAAQ;EAC5B,YAAY,eAAe;EAC3B;EACA,yBAAyB,eAAe,QAAQ;EAChD;EACA,cAAc;EACd,YAAY;EACZ,YAAY;EACZ;IACE;IACA;IACA;IACA;IACA;;;cAkBE,aAAY,SAAA,OAAA,cAAA,UAAA,UAAA,UAAA,UAAA,cAAA,SAAA,aAAA,WAAA,WAAA,UAAA,UAAA,MAAA,MAAA,WAAA,YAAA,KAAA,KAAA,SAAA,QAAA,SAAA,WAAA,SAAA,oBAAA,qBAAA,SA6Bf,0BAAK,IAAA"}
@@ -0,0 +1,207 @@
1
+ "use client";
2
+ import { cn } from "./utils.mjs";
3
+ import { useConfig } from "./providers/config/context.mjs";
4
+ import { autocomplete_exports } from "./core/autocomplete.mjs";
5
+ import Input from "./components/atoms/input/index.mjs";
6
+ import { findToken, insertToken } from "./components/atoms/mentions-token.mjs";
7
+ import { useEffect, useRef, useState } from "react";
8
+ import { useControllableState, useMergedRef } from "@jbpark/use-hooks";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/components/atoms/mentions.tsx
11
+ const DEFAULT_PREFIXES = ["@"];
12
+ function TextareaBridge({ primitiveRef, ref, ...props }) {
13
+ const mergedRef = useMergedRef(primitiveRef, ref);
14
+ return /* @__PURE__ */ jsx(Input.TextArea, {
15
+ ...props,
16
+ ref: mergedRef
17
+ });
18
+ }
19
+ const Mentions = ({ options, value, defaultValue = "", onChange, onSelect, onSearch, prefixes = DEFAULT_PREFIXES, filterOption, loading = false, loadingText = "Loading suggestions…", emptyText = "No suggestions", container, disabled, readOnly, name, form, className, classNames, dir, ref, onFocus, onBlur, onClick, onKeyDown, onKeyUp, onCompositionStart, onCompositionEnd, ...props }) => {
20
+ const { direction } = useConfig();
21
+ const textareaRef = useRef(null);
22
+ const mergedRef = useMergedRef(ref, textareaRef);
23
+ const composingRef = useRef(false);
24
+ const pendingCaret = useRef(null);
25
+ const [text, setText] = useControllableState({
26
+ value,
27
+ defaultValue,
28
+ onChange
29
+ });
30
+ const [focused, setFocused] = useState(false);
31
+ const [composing, setComposing] = useState(false);
32
+ const [selection, setSelection] = useState({
33
+ text: "",
34
+ start: 0,
35
+ end: 0
36
+ });
37
+ const [dismissed, setDismissed] = useState([]);
38
+ const token = focused && !composing && !disabled && !readOnly && selection.text === text ? findToken(text, selection.start, selection.end, prefixes) : null;
39
+ const signature = token ? JSON.stringify([
40
+ text,
41
+ selection.start,
42
+ selection.end,
43
+ token.prefix
44
+ ]) : null;
45
+ const open = token !== null && !dismissed.includes(signature);
46
+ const query = token?.query;
47
+ const prefix = token?.prefix;
48
+ const searchRef = useRef(onSearch);
49
+ useEffect(() => {
50
+ searchRef.current = onSearch;
51
+ }, [onSearch]);
52
+ useEffect(() => {
53
+ if (query !== void 0 && prefix !== void 0) searchRef.current?.(query, prefix);
54
+ }, [query, prefix]);
55
+ useEffect(() => {
56
+ const pending = pendingCaret.current;
57
+ const textarea = textareaRef.current;
58
+ if (pending && textarea && text === pending.value) {
59
+ pendingCaret.current = null;
60
+ if (textarea.ownerDocument.activeElement === textarea) textarea.setSelectionRange(pending.caret, pending.caret);
61
+ }
62
+ });
63
+ const syncSelection = (textarea) => {
64
+ setSelection((previous) => {
65
+ const next = {
66
+ text: textarea.value,
67
+ start: textarea.selectionStart,
68
+ end: textarea.selectionEnd
69
+ };
70
+ return previous.text === next.text && previous.start === next.start && previous.end === next.end ? previous : next;
71
+ });
72
+ };
73
+ const filtered = options.filter((option) => {
74
+ if (!option.value || /\s/u.test(option.value) || prefixes.some((prefix) => prefix.length > 0 && option.value.startsWith(prefix)) || option.prefix !== void 0 && option.prefix !== prefix) return false;
75
+ if (filterOption === false) return true;
76
+ return filterOption ? filterOption(query ?? "", option) : [option.value, option.label ?? ""].some((label) => label.toLowerCase().includes((query ?? "").toLowerCase()));
77
+ });
78
+ const select = (option) => {
79
+ const textarea = textareaRef.current;
80
+ if (!open || !textarea || composingRef.current || option.disabled || disabled || readOnly || textarea.value !== text) return;
81
+ const currentToken = findToken(text, textarea.selectionStart, textarea.selectionEnd, prefixes);
82
+ if (!currentToken || currentToken.start !== token?.start || currentToken.query !== token.query || currentToken.prefix !== option.prefix && option.prefix !== void 0) return;
83
+ const next = insertToken(text, currentToken, option.value);
84
+ pendingCaret.current = next;
85
+ setDismissed([signature, JSON.stringify([
86
+ next.value,
87
+ next.caret,
88
+ next.caret,
89
+ currentToken.prefix
90
+ ])]);
91
+ setText(next.value);
92
+ onSelect?.(option, currentToken.prefix);
93
+ };
94
+ const { Autocomplete: Root, AutocompleteInput, AutocompleteContent, AutocompleteList, AutocompleteItem } = autocomplete_exports;
95
+ return /* @__PURE__ */ jsx("div", {
96
+ "data-slot": "mentions",
97
+ dir: dir ?? direction,
98
+ className: cn("relative min-w-0", classNames?.root),
99
+ children: /* @__PURE__ */ jsxs(Root, {
100
+ items: loading ? [] : filtered,
101
+ filter: null,
102
+ value: text,
103
+ defaultValue,
104
+ onValueChange: (next, details) => {
105
+ if (details.reason === "item-press" || details.reason === "escape-key") {
106
+ details.cancel();
107
+ return;
108
+ }
109
+ pendingCaret.current = null;
110
+ setText(next);
111
+ if (textareaRef.current) syncSelection(textareaRef.current);
112
+ },
113
+ disabled,
114
+ readOnly,
115
+ name,
116
+ form,
117
+ open,
118
+ onOpenChange: (next) => {
119
+ if (!next) setDismissed([signature]);
120
+ },
121
+ itemToStringValue: (option) => option.value,
122
+ children: [/* @__PURE__ */ jsx(AutocompleteInput, { render: (inputProps) => {
123
+ const native = inputProps;
124
+ return /* @__PURE__ */ jsx(TextareaBridge, {
125
+ ...native,
126
+ ...props,
127
+ ref: mergedRef,
128
+ primitiveRef: native.ref,
129
+ dir: dir ?? direction,
130
+ "data-slot": "mentions-input",
131
+ className: cn(native.className, className),
132
+ onFocus: (event) => {
133
+ onFocus?.(event);
134
+ native.onFocus?.(event);
135
+ setFocused(true);
136
+ setDismissed([]);
137
+ syncSelection(event.currentTarget);
138
+ },
139
+ onBlur: (event) => {
140
+ onBlur?.(event);
141
+ native.onBlur?.(event);
142
+ setFocused(false);
143
+ },
144
+ onSelect: (event) => syncSelection(event.currentTarget),
145
+ onClick: (event) => {
146
+ onClick?.(event);
147
+ native.onClick?.(event);
148
+ syncSelection(event.currentTarget);
149
+ },
150
+ onKeyDown: (event) => {
151
+ onKeyDown?.(event);
152
+ if (event.defaultPrevented) return;
153
+ if (!open || composingRef.current || event.nativeEvent.isComposing || event.keyCode === 229 || event.key === "Home" || event.key === "End") return;
154
+ native.onKeyDown?.(event);
155
+ },
156
+ onKeyUp: (event) => {
157
+ onKeyUp?.(event);
158
+ native.onKeyUp?.(event);
159
+ syncSelection(event.currentTarget);
160
+ },
161
+ onCompositionStart: (event) => {
162
+ composingRef.current = true;
163
+ setComposing(true);
164
+ onCompositionStart?.(event);
165
+ native.onCompositionStart?.(event);
166
+ },
167
+ onCompositionEnd: (event) => {
168
+ composingRef.current = false;
169
+ setComposing(false);
170
+ onCompositionEnd?.(event);
171
+ native.onCompositionEnd?.(event);
172
+ syncSelection(event.currentTarget);
173
+ }
174
+ });
175
+ } }), /* @__PURE__ */ jsxs(AutocompleteContent, {
176
+ container,
177
+ dir: dir ?? direction,
178
+ className: classNames?.content,
179
+ children: [(loading || filtered.length === 0) && /* @__PURE__ */ jsx("div", {
180
+ role: "status",
181
+ className: cn("text-muted-foreground px-3 py-2 text-sm", classNames?.empty),
182
+ children: loading ? loadingText : emptyText
183
+ }), /* @__PURE__ */ jsx(AutocompleteList, {
184
+ className: cn("max-h-60 overflow-y-auto p-1", classNames?.list),
185
+ children: (option) => /* @__PURE__ */ jsx(AutocompleteItem, {
186
+ value: option,
187
+ disabled: option.disabled,
188
+ onMouseUp: (event) => event.preventBaseUIHandler(),
189
+ onClick: (event) => {
190
+ event.preventBaseUIHandler();
191
+ select(option);
192
+ },
193
+ className: cn(`data-highlighted:bg-accent
194
+ data-highlighted:text-accent-foreground cursor-default
195
+ rounded-sm px-2 py-1.5 text-sm [overflow-wrap:anywhere]
196
+ outline-none data-disabled:opacity-50`, classNames?.option),
197
+ children: option.label ?? option.value
198
+ }, option.value)
199
+ })]
200
+ })]
201
+ })
202
+ });
203
+ };
204
+ //#endregion
205
+ export { Mentions as default };
206
+
207
+ //# sourceMappingURL=Mentions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mentions.mjs","names":["autocomplete"],"sources":["../src/components/atoms/mentions.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ComponentPropsWithRef,\n type ReactNode,\n type Ref,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { useControllableState, useMergedRef } from '@jbpark/use-hooks';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { autocomplete } from '../../core';\nimport Input from './input';\nimport { findToken, insertToken } from './mentions-token';\n\nexport interface Option {\n /** Unique, non-empty token text without whitespace or the prefix. */\n value: string;\n label?: string;\n prefix?: string;\n disabled?: boolean;\n}\n\nexport interface Props extends Omit<\n ComponentPropsWithRef<'textarea'>,\n 'children' | 'value' | 'defaultValue' | 'onChange' | 'onSelect'\n> {\n options: readonly Option[];\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n onSelect?: (option: Option, prefix: string) => void;\n onSearch?: (query: string, prefix: string) => void;\n prefixes?: readonly string[];\n filterOption?: false | ((query: string, option: Option) => boolean);\n loading?: boolean;\n loadingText?: ReactNode;\n emptyText?: ReactNode;\n container?: HTMLElement;\n classNames?: {\n root?: string;\n content?: string;\n list?: string;\n option?: string;\n empty?: string;\n };\n}\n\nconst DEFAULT_PREFIXES = ['@'];\n\nfunction TextareaBridge({\n primitiveRef,\n ref,\n ...props\n}: ComponentPropsWithRef<'textarea'> & {\n primitiveRef?: Ref<HTMLTextAreaElement>;\n}) {\n const mergedRef = useMergedRef(primitiveRef, ref);\n\n return <Input.TextArea {...props} ref={mergedRef} />;\n}\n\nconst Mentions = ({\n options,\n value,\n defaultValue = '',\n onChange,\n onSelect,\n onSearch,\n prefixes = DEFAULT_PREFIXES,\n filterOption,\n loading = false,\n loadingText = 'Loading suggestions…',\n emptyText = 'No suggestions',\n container,\n disabled,\n readOnly,\n name,\n form,\n className,\n classNames,\n dir,\n ref,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n onKeyUp,\n onCompositionStart,\n onCompositionEnd,\n ...props\n}: Props) => {\n const { direction } = useConfig();\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const mergedRef = useMergedRef(ref, textareaRef);\n const composingRef = useRef(false);\n const pendingCaret = useRef<{ value: string; caret: number } | null>(null);\n const [text, setText] = useControllableState<string>({\n value,\n defaultValue,\n onChange,\n });\n const [focused, setFocused] = useState(false);\n const [composing, setComposing] = useState(false);\n const [selection, setSelection] = useState({ text: '', start: 0, end: 0 });\n const [dismissed, setDismissed] = useState<readonly (string | null)[]>([]);\n const token =\n focused && !composing && !disabled && !readOnly && selection.text === text\n ? findToken(text, selection.start, selection.end, prefixes)\n : null;\n const signature = token\n ? JSON.stringify([text, selection.start, selection.end, token.prefix])\n : null;\n const open = token !== null && !dismissed.includes(signature);\n const query = token?.query;\n const prefix = token?.prefix;\n const searchRef = useRef(onSearch);\n\n useEffect(() => {\n searchRef.current = onSearch;\n }, [onSearch]);\n\n useEffect(() => {\n if (query !== undefined && prefix !== undefined) {\n searchRef.current?.(query, prefix);\n }\n }, [query, prefix]);\n\n useEffect(() => {\n const pending = pendingCaret.current;\n const textarea = textareaRef.current;\n\n if (pending && textarea && text === pending.value) {\n pendingCaret.current = null;\n\n if (textarea.ownerDocument.activeElement === textarea) {\n textarea.setSelectionRange(pending.caret, pending.caret);\n }\n }\n });\n\n const syncSelection = (textarea: HTMLTextAreaElement) => {\n setSelection(previous => {\n const next = {\n text: textarea.value,\n start: textarea.selectionStart,\n end: textarea.selectionEnd,\n };\n\n return previous.text === next.text &&\n previous.start === next.start &&\n previous.end === next.end\n ? previous\n : next;\n });\n };\n const filtered = options.filter(option => {\n if (\n !option.value ||\n /\\s/u.test(option.value) ||\n prefixes.some(\n prefix => prefix.length > 0 && option.value.startsWith(prefix),\n ) ||\n (option.prefix !== undefined && option.prefix !== prefix)\n ) {\n return false;\n }\n\n if (filterOption === false) {\n return true;\n }\n\n return filterOption\n ? filterOption(query ?? '', option)\n : [option.value, option.label ?? ''].some(label =>\n label.toLowerCase().includes((query ?? '').toLowerCase()),\n );\n });\n const select = (option: Option) => {\n const textarea = textareaRef.current;\n\n if (\n !open ||\n !textarea ||\n composingRef.current ||\n option.disabled ||\n disabled ||\n readOnly ||\n textarea.value !== text\n ) {\n return;\n }\n\n const currentToken = findToken(\n text,\n textarea.selectionStart,\n textarea.selectionEnd,\n prefixes,\n );\n\n if (\n !currentToken ||\n currentToken.start !== token?.start ||\n currentToken.query !== token.query ||\n (currentToken.prefix !== option.prefix && option.prefix !== undefined)\n ) {\n return;\n }\n\n const next = insertToken(text, currentToken, option.value);\n\n pendingCaret.current = next;\n setDismissed([\n signature,\n JSON.stringify([next.value, next.caret, next.caret, currentToken.prefix]),\n ]);\n setText(next.value);\n onSelect?.(option, currentToken.prefix);\n };\n const {\n Autocomplete: Root,\n AutocompleteInput,\n AutocompleteContent,\n AutocompleteList,\n AutocompleteItem,\n } = autocomplete;\n\n return (\n <div\n data-slot=\"mentions\"\n dir={dir ?? direction}\n className={cn(\n 'relative min-w-0',\n classNames?.root, //\n )}\n >\n <Root\n items={loading ? [] : filtered}\n filter={null}\n value={text}\n defaultValue={defaultValue}\n onValueChange={(next, details) => {\n if (\n details.reason === 'item-press' ||\n details.reason === 'escape-key'\n ) {\n details.cancel();\n\n return;\n }\n\n pendingCaret.current = null;\n setText(next);\n\n if (textareaRef.current) {\n syncSelection(textareaRef.current);\n }\n }}\n disabled={disabled}\n readOnly={readOnly}\n name={name}\n form={form}\n open={open}\n onOpenChange={next => {\n if (!next) {\n setDismissed([signature]);\n }\n }}\n itemToStringValue={option => option.value}\n >\n <AutocompleteInput\n render={inputProps => {\n // Base UI's input handlers use the shared text-control DOM contract.\n // Adapt their input-only types while preserving the textarea atom.\n const native =\n inputProps as unknown as ComponentPropsWithRef<'textarea'>;\n\n return (\n <TextareaBridge\n {...native}\n {...props}\n ref={mergedRef}\n primitiveRef={native.ref}\n dir={dir ?? direction}\n data-slot=\"mentions-input\"\n className={cn(\n native.className,\n className, //\n )}\n onFocus={event => {\n onFocus?.(event);\n native.onFocus?.(event);\n setFocused(true);\n setDismissed([]);\n syncSelection(event.currentTarget);\n }}\n onBlur={event => {\n onBlur?.(event);\n native.onBlur?.(event);\n setFocused(false);\n }}\n onSelect={event => syncSelection(event.currentTarget)}\n onClick={event => {\n onClick?.(event);\n native.onClick?.(event);\n syncSelection(event.currentTarget);\n }}\n onKeyDown={event => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (\n !open ||\n composingRef.current ||\n event.nativeEvent.isComposing ||\n event.keyCode === 229 ||\n event.key === 'Home' ||\n event.key === 'End'\n ) {\n return;\n }\n\n native.onKeyDown?.(event);\n }}\n onKeyUp={event => {\n onKeyUp?.(event);\n native.onKeyUp?.(event);\n syncSelection(event.currentTarget);\n }}\n onCompositionStart={event => {\n composingRef.current = true;\n setComposing(true);\n onCompositionStart?.(event);\n native.onCompositionStart?.(event);\n }}\n onCompositionEnd={event => {\n composingRef.current = false;\n setComposing(false);\n onCompositionEnd?.(event);\n native.onCompositionEnd?.(event);\n syncSelection(event.currentTarget);\n }}\n />\n );\n }}\n />\n <AutocompleteContent\n container={container}\n dir={dir ?? direction}\n className={classNames?.content}\n >\n {(loading || filtered.length === 0) && (\n <div\n role=\"status\"\n className={cn(\n 'text-muted-foreground px-3 py-2 text-sm',\n classNames?.empty, //\n )}\n >\n {loading ? loadingText : emptyText}\n </div>\n )}\n <AutocompleteList\n className={cn(\n 'max-h-60 overflow-y-auto p-1',\n classNames?.list, //\n )}\n >\n {(option: Option) => (\n <AutocompleteItem\n key={option.value}\n value={option}\n disabled={option.disabled}\n onMouseUp={event => event.preventBaseUIHandler()}\n onClick={event => {\n event.preventBaseUIHandler();\n select(option);\n }}\n className={cn(\n `data-highlighted:bg-accent\n data-highlighted:text-accent-foreground cursor-default\n rounded-sm px-2 py-1.5 text-sm [overflow-wrap:anywhere]\n outline-none data-disabled:opacity-50`,\n classNames?.option, //\n )}\n >\n {option.label ?? option.value}\n </AutocompleteItem>\n )}\n </AutocompleteList>\n </AutocompleteContent>\n </Root>\n </div>\n );\n};\n\nexport default Mentions;\n"],"mappings":"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"}
package/dist/Menu.mjs CHANGED
@@ -1,2 +1 @@
1
- import Menu, { MENU_CLASSNAMES, buildSelectionMap, findKey } from "./components/molecules/menu/menu.mjs";
2
- export { MENU_CLASSNAMES, buildSelectionMap, Menu as default, findKey };
1
+ export { MENU_CLASSNAMES, buildSelectionMap, default, findKey } from "./components/molecules/menu/menu.mjs";
@@ -1,5 +1,5 @@
1
1
  //#region src/components/molecules/pagination.d.ts
2
- interface Props extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'children' | 'onChange'> {
2
+ export interface Props extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'children' | 'onChange'> {
3
3
  /** Total number of items, not pages. */
4
4
  total: number;
5
5
  /** Controlled number of items per page. */
@@ -49,5 +49,5 @@ interface Props extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'children' |
49
49
  }
50
50
  declare const Pagination: ({ total, pageSize, defaultPageSize, onPageSizeChange, pageSizeOptions, showSizeChanger, showTotal, showQuickJumper, page, defaultPage, onChange, siblingCount, boundaryCount, showFirstLast, hideOnSinglePage, getPageHref, disabled, size, labels, className, classNames, "aria-label": ariaLabel, ...props }: Props) => import("react").JSX.Element | null;
51
51
  //#endregion
52
- export { Props, Pagination as default };
52
+ export { Pagination as default };
53
53
  //# sourceMappingURL=Pagination.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.d.mts","names":[],"sources":["../src/components/molecules/pagination.tsx"],"mappings":";UAoBiB,cAAc,KAC7B,MAAM;;EAIN;;EAEA;EACA;EACA,oBAAoB;EACpB;EACA;;EAEA,aAAa,eAAe,4BAA4B,MAAM;EAC9D;;EAEA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;;EAEA,eAAe;EACf;EACA;EACA;IACE;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA;IACA;IACA;;EAEF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;cAkEE,eAAc,OAAA,UAAA,iBAAA,kBAAA,iBAAA,iBAAA,WAAA,iBAAA,MAAA,aAAA,UAAA,cAAA,eAAA,eAAA,kBAAA,aAAA,UAAA,MAAA,QAAA,WAAA,0BAAA,cAAA,SAwBjB,0BAAK,IAAA"}
1
+ {"version":3,"file":"Pagination.d.mts","names":[],"sources":["../src/components/molecules/pagination.tsx"],"mappings":";iBAoBiB,cAAc,KAC7B,MAAM;;EAIN;;EAEA;EACA;EACA,oBAAoB;EACpB;EACA;;EAEA,aAAa,eAAe,4BAA4B,MAAM;EAC9D;;EAEA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;;EAEA,eAAe;EACf;EACA;EACA;IACE;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA;IACA;IACA;;EAEF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;cAkEE,eAAc,OAAA,UAAA,iBAAA,kBAAA,iBAAA,iBAAA,WAAA,iBAAA,MAAA,aAAA,UAAA,cAAA,eAAA,eAAA,kBAAA,aAAA,UAAA,MAAA,QAAA,WAAA,0BAAA,cAAA,SAwBjB,0BAAK,IAAA"}
@@ -4,9 +4,9 @@ import { useConfig } from "./providers/config/context.mjs";
4
4
  import Button from "./Button.mjs";
5
5
  import Input from "./components/atoms/input/index.mjs";
6
6
  import Select from "./components/atoms/select.mjs";
7
- import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react";
8
7
  import { useState } from "react";
9
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react";
10
10
  //#region src/components/molecules/pagination.tsx
11
11
  const clampPage = (page, pageCount) => Math.min(Math.max(1, Number.isFinite(page) ? Math.floor(page) : 1), Math.max(1, pageCount));
12
12
  const normalizePageSize = (value) => Number.isFinite(value) && value >= 1 ? Math.floor(value) : 10;
@@ -0,0 +1,33 @@
1
+ import { Props as Props$1 } from "./Button.mjs";
2
+ import { Props as Props$2 } from "./components/atoms/popover.mjs";
3
+ import * as React$1 from "react";
4
+ //#region src/components/molecules/popconfirm.d.ts
5
+ type ActionProps = Omit<Props$1, 'children' | 'onClick' | 'loading' | 'disabled'>;
6
+ export interface Props extends Omit<Props$2, 'content' | 'title' | 'children'> {
7
+ children: React$1.ReactElement;
8
+ title: React$1.ReactNode;
9
+ description?: React$1.ReactNode;
10
+ /** A fulfilled promise closes the popup; a thrown error keeps it open. */
11
+ onConfirm?: () => void | Promise<void>;
12
+ /** Only the Cancel button invokes this callback. */
13
+ onCancel?: () => void;
14
+ onConfirmError?: (error: unknown) => void;
15
+ errorMessage?: React$1.ReactNode;
16
+ confirmText?: React$1.ReactNode;
17
+ cancelText?: React$1.ReactNode;
18
+ disabled?: boolean;
19
+ confirmButtonProps?: ActionProps;
20
+ cancelButtonProps?: ActionProps;
21
+ classNames?: {
22
+ title?: string;
23
+ description?: string;
24
+ actions?: string;
25
+ confirm?: string;
26
+ cancel?: string;
27
+ error?: string;
28
+ };
29
+ }
30
+ declare const Popconfirm: ({ children, title, description, onConfirm, onCancel, onConfirmError, errorMessage, confirmText, cancelText, disabled, confirmButtonProps, cancelButtonProps, className, classNames, open: controlledOpen, defaultOpen, onOpenChange, ...props }: Props) => React$1.JSX.Element;
31
+ //#endregion
32
+ export { Popconfirm as default };
33
+ //# sourceMappingURL=Popconfirm.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popconfirm.d.mts","names":["ButtonProps","PopoverProps","React"],"sources":["../src/components/molecules/popconfirm.tsx"],"mappings":";;;;KAYK,cAAc,KACjBA;iBAIe,cAAc,KAC7BC;EAGA,UAAUC,QAAM;EAChB,OAAOA,QAAM;EACb,cAAcA,QAAM;;EAEpB,yBAAyB;;EAEzB;EACA,kBAAkB;EAClB,eAAeA,QAAM;EACrB,cAAcA,QAAM;EACpB,aAAaA,QAAM;EACnB;EACA,qBAAqB;EACrB,oBAAoB;EACpB;IACE;IACA;IACA;IACA;IACA;IACA;;;cAIE,eAAc,UAAA,OAAA,aAAA,WAAA,UAAA,gBAAA,cAAA,aAAA,YAAA,UAAA,oBAAA,mBAAA,WAAA,YAAA,MAAA,gBAAA,aAAA,iBAAA,SAmBjB,UAAKA,QAAA,IAAA"}
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ import { cn } from "./utils.mjs";
3
+ import Button from "./Button.mjs";
4
+ import Typography from "./Typography.mjs";
5
+ import Popover from "./components/atoms/popover.mjs";
6
+ import * as React$1 from "react";
7
+ import { useControllableState } from "@jbpark/use-hooks";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/components/molecules/popconfirm.tsx
10
+ const Popconfirm = ({ children, title, description, onConfirm, onCancel, onConfirmError, errorMessage = "Unable to complete the action. Please try again.", confirmText = "Confirm", cancelText = "Cancel", disabled = false, confirmButtonProps, cancelButtonProps, className, classNames, open: controlledOpen, defaultOpen, onOpenChange, ...props }) => {
11
+ const [open, setOpen] = useControllableState({
12
+ value: controlledOpen,
13
+ defaultValue: defaultOpen ?? false,
14
+ onChange: onOpenChange
15
+ });
16
+ const [pending, setPending] = React$1.useState(false);
17
+ const [failed, setFailed] = React$1.useState(false);
18
+ const busy = React$1.useRef(false);
19
+ const mounted = React$1.useRef(false);
20
+ const generation = React$1.useRef(0);
21
+ const descriptionId = React$1.useId();
22
+ const titleId = React$1.useId();
23
+ React$1.useEffect(() => {
24
+ mounted.current = true;
25
+ return () => {
26
+ mounted.current = false;
27
+ generation.current += 1;
28
+ };
29
+ }, []);
30
+ React$1.useEffect(() => {
31
+ if (!open || disabled) generation.current += 1;
32
+ }, [open, disabled]);
33
+ const handleOpenChange = (nextOpen) => {
34
+ if (busy.current || disabled && nextOpen) return;
35
+ setFailed(false);
36
+ setOpen(nextOpen);
37
+ };
38
+ const handleConfirm = async () => {
39
+ if (busy.current || disabled) return;
40
+ busy.current = true;
41
+ setPending(true);
42
+ setFailed(false);
43
+ const request = generation.current;
44
+ try {
45
+ await onConfirm?.();
46
+ if (mounted.current && request === generation.current) setOpen(false);
47
+ } catch (error) {
48
+ if (mounted.current && request === generation.current) {
49
+ setFailed(true);
50
+ onConfirmError?.(error);
51
+ }
52
+ } finally {
53
+ busy.current = false;
54
+ if (mounted.current) setPending(false);
55
+ }
56
+ };
57
+ return /* @__PURE__ */ jsx(Popover, {
58
+ ...props,
59
+ open: open && !disabled,
60
+ onOpenChange: handleOpenChange,
61
+ className: cn("max-w-[calc(100vw-2rem)]", className),
62
+ "aria-labelledby": titleId,
63
+ "aria-describedby": description ? descriptionId : void 0,
64
+ content: /* @__PURE__ */ jsxs("div", {
65
+ "data-slot": "popconfirm",
66
+ "aria-busy": pending,
67
+ className: "space-y-3",
68
+ children: [
69
+ /* @__PURE__ */ jsx(Typography.Title, {
70
+ level: 6,
71
+ id: titleId,
72
+ className: classNames?.title,
73
+ children: title
74
+ }),
75
+ description && /* @__PURE__ */ jsx("div", {
76
+ id: descriptionId,
77
+ className: cn("text-muted-foreground text-sm", classNames?.description),
78
+ children: description
79
+ }),
80
+ failed && /* @__PURE__ */ jsx("div", {
81
+ role: "alert",
82
+ className: cn("text-destructive text-sm", classNames?.error),
83
+ children: errorMessage
84
+ }),
85
+ /* @__PURE__ */ jsxs("div", {
86
+ className: cn("flex justify-end gap-2", classNames?.actions),
87
+ children: [/* @__PURE__ */ jsx(Button, {
88
+ size: "small",
89
+ ...cancelButtonProps,
90
+ htmlType: "button",
91
+ disabled: pending,
92
+ className: cn(cancelButtonProps?.className, classNames?.cancel),
93
+ onClick: () => {
94
+ if (busy.current) return;
95
+ setFailed(false);
96
+ setOpen(false);
97
+ onCancel?.();
98
+ },
99
+ children: cancelText
100
+ }), /* @__PURE__ */ jsx(Button, {
101
+ size: "small",
102
+ type: "primary",
103
+ ...confirmButtonProps,
104
+ htmlType: "button",
105
+ loading: pending,
106
+ className: cn(confirmButtonProps?.className, classNames?.confirm),
107
+ onClick: () => void handleConfirm(),
108
+ children: confirmText
109
+ })]
110
+ })
111
+ ]
112
+ }),
113
+ children
114
+ });
115
+ };
116
+ //#endregion
117
+ export { Popconfirm as default };
118
+
119
+ //# sourceMappingURL=Popconfirm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popconfirm.mjs","names":["React"],"sources":["../src/components/molecules/popconfirm.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Button, { type Props as ButtonProps } from '../atoms/button';\nimport Popover, { type Props as PopoverProps } from '../atoms/popover';\nimport Typography from '../atoms/typography';\n\ntype ActionProps = Omit<\n ButtonProps,\n 'children' | 'onClick' | 'loading' | 'disabled'\n>;\n\nexport interface Props extends Omit<\n PopoverProps,\n 'content' | 'title' | 'children'\n> {\n children: React.ReactElement;\n title: React.ReactNode;\n description?: React.ReactNode;\n /** A fulfilled promise closes the popup; a thrown error keeps it open. */\n onConfirm?: () => void | Promise<void>;\n /** Only the Cancel button invokes this callback. */\n onCancel?: () => void;\n onConfirmError?: (error: unknown) => void;\n errorMessage?: React.ReactNode;\n confirmText?: React.ReactNode;\n cancelText?: React.ReactNode;\n disabled?: boolean;\n confirmButtonProps?: ActionProps;\n cancelButtonProps?: ActionProps;\n classNames?: {\n title?: string;\n description?: string;\n actions?: string;\n confirm?: string;\n cancel?: string;\n error?: string;\n };\n}\n\nconst Popconfirm = ({\n children,\n title,\n description,\n onConfirm,\n onCancel,\n onConfirmError,\n errorMessage = 'Unable to complete the action. Please try again.',\n confirmText = 'Confirm',\n cancelText = 'Cancel',\n disabled = false,\n confirmButtonProps,\n cancelButtonProps,\n className,\n classNames,\n open: controlledOpen,\n defaultOpen,\n onOpenChange,\n ...props\n}: Props) => {\n const [open, setOpen] = useControllableState<boolean>({\n value: controlledOpen,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const [pending, setPending] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const busy = React.useRef(false);\n const mounted = React.useRef(false);\n const generation = React.useRef(0);\n const descriptionId = React.useId();\n const titleId = React.useId();\n\n React.useEffect(() => {\n mounted.current = true;\n\n return () => {\n mounted.current = false;\n generation.current += 1;\n };\n }, []);\n\n React.useEffect(() => {\n if (!open || disabled) {\n generation.current += 1;\n }\n }, [open, disabled]);\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (busy.current || (disabled && nextOpen)) {\n return;\n }\n\n setFailed(false);\n setOpen(nextOpen);\n };\n\n const handleConfirm = async () => {\n if (busy.current || disabled) {\n return;\n }\n\n busy.current = true;\n setPending(true);\n setFailed(false);\n const request = generation.current;\n\n try {\n await onConfirm?.();\n\n if (mounted.current && request === generation.current) {\n setOpen(false);\n }\n } catch (error) {\n if (mounted.current && request === generation.current) {\n setFailed(true);\n onConfirmError?.(error);\n }\n } finally {\n busy.current = false;\n\n if (mounted.current) {\n setPending(false);\n }\n }\n };\n\n return (\n <Popover\n {...props}\n open={open && !disabled}\n onOpenChange={handleOpenChange}\n className={cn(\n 'max-w-[calc(100vw-2rem)]',\n className, //\n )}\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n content={\n <div data-slot=\"popconfirm\" aria-busy={pending} className=\"space-y-3\">\n <Typography.Title\n level={6}\n id={titleId}\n className={classNames?.title}\n >\n {title}\n </Typography.Title>\n {description && (\n <div\n id={descriptionId}\n className={cn(\n 'text-muted-foreground text-sm',\n classNames?.description, //\n )}\n >\n {description}\n </div>\n )}\n {failed && (\n <div\n role=\"alert\"\n className={cn(\n 'text-destructive text-sm',\n classNames?.error, //\n )}\n >\n {errorMessage}\n </div>\n )}\n <div\n className={cn(\n 'flex justify-end gap-2',\n classNames?.actions, //\n )}\n >\n <Button\n size=\"small\"\n {...cancelButtonProps}\n htmlType=\"button\"\n disabled={pending}\n className={cn(\n cancelButtonProps?.className,\n classNames?.cancel, //\n )}\n onClick={() => {\n if (busy.current) {\n return;\n }\n\n setFailed(false);\n setOpen(false);\n onCancel?.();\n }}\n >\n {cancelText}\n </Button>\n <Button\n size=\"small\"\n type=\"primary\"\n {...confirmButtonProps}\n htmlType=\"button\"\n loading={pending}\n className={cn(\n confirmButtonProps?.className,\n classNames?.confirm, //\n )}\n onClick={() => void handleConfirm()}\n >\n {confirmText}\n </Button>\n </div>\n </div>\n }\n >\n {children}\n </Popover>\n );\n};\n\nexport default Popconfirm;\n"],"mappings":";;;;;;;;;AA6CA,MAAM,cAAc,EAClB,UACA,OACA,aACA,WACA,UACA,gBACA,eAAe,oDACf,cAAc,WACd,aAAa,UACb,WAAW,OACX,oBACA,mBACA,WACA,YACA,MAAM,gBACN,aACA,cACA,GAAG,YACQ;CACX,MAAM,CAAC,MAAM,WAAW,qBAA8B;EACpD,OAAO;EACP,cAAc,eAAe;EAC7B,UAAU;CACZ,CAAC;CACD,MAAM,CAAC,SAAS,cAAcA,QAAM,SAAS,KAAK;CAClD,MAAM,CAAC,QAAQ,aAAaA,QAAM,SAAS,KAAK;CAChD,MAAM,OAAOA,QAAM,OAAO,KAAK;CAC/B,MAAM,UAAUA,QAAM,OAAO,KAAK;CAClC,MAAM,aAAaA,QAAM,OAAO,CAAC;CACjC,MAAM,gBAAgBA,QAAM,MAAM;CAClC,MAAM,UAAUA,QAAM,MAAM;CAE5B,QAAM,gBAAgB;EACpB,QAAQ,UAAU;EAElB,aAAa;GACX,QAAQ,UAAU;GAClB,WAAW,WAAW;EACxB;CACF,GAAG,CAAC,CAAC;CAEL,QAAM,gBAAgB;EACpB,IAAI,CAAC,QAAQ,UACX,WAAW,WAAW;CAE1B,GAAG,CAAC,MAAM,QAAQ,CAAC;CAEnB,MAAM,oBAAoB,aAAsB;EAC9C,IAAI,KAAK,WAAY,YAAY,UAC/B;EAGF,UAAU,KAAK;EACf,QAAQ,QAAQ;CAClB;CAEA,MAAM,gBAAgB,YAAY;EAChC,IAAI,KAAK,WAAW,UAClB;EAGF,KAAK,UAAU;EACf,WAAW,IAAI;EACf,UAAU,KAAK;EACf,MAAM,UAAU,WAAW;EAE3B,IAAI;GACF,MAAM,YAAY;GAElB,IAAI,QAAQ,WAAW,YAAY,WAAW,SAC5C,QAAQ,KAAK;EAEjB,SAAS,OAAO;GACd,IAAI,QAAQ,WAAW,YAAY,WAAW,SAAS;IACrD,UAAU,IAAI;IACd,iBAAiB,KAAK;GACxB;EACF,UAAU;GACR,KAAK,UAAU;GAEf,IAAI,QAAQ,SACV,WAAW,KAAK;EAEpB;CACF;CAEA,OACE,oBAAC,SAAD;EACE,GAAI;EACJ,MAAM,QAAQ,CAAC;EACf,cAAc;EACd,WAAW,GACT,4BACA,SACF;EACA,mBAAiB;EACjB,oBAAkB,cAAc,gBAAgB,KAAA;EAChD,SACE,qBAAC,OAAD;GAAK,aAAU;GAAa,aAAW;GAAS,WAAU;GAA1D,UAAA;IACE,oBAAC,WAAW,OAAZ;KACE,OAAO;KACP,IAAI;KACJ,WAAW,YAAY;KAEtB,UAAA;IACe,CAAA;IACjB,eACC,oBAAC,OAAD;KACE,IAAI;KACJ,WAAW,GACT,iCACA,YAAY,WACd;KAEC,UAAA;IACE,CAAA;IAEN,UACC,oBAAC,OAAD;KACE,MAAK;KACL,WAAW,GACT,4BACA,YAAY,KACd;KAEC,UAAA;IACE,CAAA;IAEP,qBAAC,OAAD;KACE,WAAW,GACT,0BACA,YAAY,OACd;KAJF,UAAA,CAME,oBAAC,QAAD;MACE,MAAK;MACL,GAAI;MACJ,UAAS;MACT,UAAU;MACV,WAAW,GACT,mBAAmB,WACnB,YAAY,MACd;MACA,eAAe;OACb,IAAI,KAAK,SACP;OAGF,UAAU,KAAK;OACf,QAAQ,KAAK;OACb,WAAW;MACb;MAEC,UAAA;KACK,CAAA,GACR,oBAAC,QAAD;MACE,MAAK;MACL,MAAK;MACL,GAAI;MACJ,UAAS;MACT,SAAS;MACT,WAAW,GACT,oBAAoB,WACpB,YAAY,OACd;MACA,eAAe,KAAK,cAAc;MAEjC,UAAA;KACK,CAAA,CACL;;GACF;;EAGN;CACM,CAAA;AAEb"}
@@ -0,0 +1,27 @@
1
+ import { ComponentPropsWithRef, ReactNode } from "react";
2
+ //#region src/components/atoms/rate.d.ts
3
+ export interface Props extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'value' | 'defaultValue' | 'onChange'> {
4
+ /** Positive whole-step count. Defaults to five. */
5
+ count?: number;
6
+ /** Zero means no rating. Values are rounded down and clamped to 0–count. */
7
+ value?: number;
8
+ defaultValue?: number;
9
+ onChange?: (value: number) => void;
10
+ /** Activating the selected score clears it to zero. Defaults to true. */
11
+ allowClear?: boolean;
12
+ disabled?: boolean;
13
+ readOnly?: boolean;
14
+ name?: string;
15
+ icon?: ReactNode;
16
+ getItemLabel?: (score: number, count: number) => string;
17
+ getValueText?: (value: number, count: number) => string;
18
+ classNames?: {
19
+ item?: string;
20
+ filledItem?: string;
21
+ icon?: string;
22
+ };
23
+ }
24
+ declare const Rate: ({ count, value, defaultValue, onChange, allowClear, disabled, readOnly, name, icon, getItemLabel, getValueText, className, classNames, dir, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: Props) => import("react").JSX.Element;
25
+ //#endregion
26
+ export { Rate as default };
27
+ //# sourceMappingURL=Rate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rate.d.mts","names":[],"sources":["../src/components/atoms/rate.tsx"],"mappings":";;iBAmBiB,cAAc,KAC7B;;EAIA;;EAEA;EACA;EACA,YAAY;;EAEZ;EACA;EACA;EACA;EACA,OAAO;EACP,gBAAgB,eAAe;EAC/B,gBAAgB,eAAe;EAC/B;IAAe;IAAe;IAAqB;;;cAG/C,SAAQ,OAAA,OAAA,cAAA,UAAA,YAAA,UAAA,UAAA,MAAA,MAAA,cAAA,cAAA,WAAA,YAAA,mBAAA,8BAAA,oCAAA,oBAAA,SAoBX,0BAAK,IAAA"}