@polymarbot/nuxt-layer-shadcn-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. package/app/assets/styles/animate.css +71 -0
  2. package/app/assets/styles/colors.css +116 -0
  3. package/app/assets/styles/globals.css +43 -0
  4. package/app/assets/styles/index.stories.ts +211 -0
  5. package/app/assets/styles/transition.css +34 -0
  6. package/app/assets/styles/utilities.css +26 -0
  7. package/app/components/shadcn/accordion/Accordion.vue +18 -0
  8. package/app/components/shadcn/accordion/AccordionContent.vue +23 -0
  9. package/app/components/shadcn/accordion/AccordionItem.vue +24 -0
  10. package/app/components/shadcn/accordion/AccordionTrigger.vue +37 -0
  11. package/app/components/shadcn/accordion/index.ts +4 -0
  12. package/app/components/shadcn/alert/Alert.vue +21 -0
  13. package/app/components/shadcn/alert/AlertDescription.vue +17 -0
  14. package/app/components/shadcn/alert/AlertTitle.vue +17 -0
  15. package/app/components/shadcn/alert/index.ts +24 -0
  16. package/app/components/shadcn/avatar/Avatar.vue +18 -0
  17. package/app/components/shadcn/avatar/AvatarFallback.vue +21 -0
  18. package/app/components/shadcn/avatar/AvatarImage.vue +16 -0
  19. package/app/components/shadcn/avatar/index.ts +3 -0
  20. package/app/components/shadcn/badge/Badge.vue +26 -0
  21. package/app/components/shadcn/badge/index.ts +26 -0
  22. package/app/components/shadcn/breadcrumb/Breadcrumb.vue +17 -0
  23. package/app/components/shadcn/breadcrumb/BreadcrumbEllipsis.vue +23 -0
  24. package/app/components/shadcn/breadcrumb/BreadcrumbItem.vue +17 -0
  25. package/app/components/shadcn/breadcrumb/BreadcrumbLink.vue +21 -0
  26. package/app/components/shadcn/breadcrumb/BreadcrumbList.vue +17 -0
  27. package/app/components/shadcn/breadcrumb/BreadcrumbPage.vue +20 -0
  28. package/app/components/shadcn/breadcrumb/BreadcrumbSeparator.vue +22 -0
  29. package/app/components/shadcn/breadcrumb/index.ts +7 -0
  30. package/app/components/shadcn/button/Button.vue +31 -0
  31. package/app/components/shadcn/button/index.ts +38 -0
  32. package/app/components/shadcn/card/Card.vue +22 -0
  33. package/app/components/shadcn/card/CardAction.vue +17 -0
  34. package/app/components/shadcn/card/CardContent.vue +17 -0
  35. package/app/components/shadcn/card/CardDescription.vue +17 -0
  36. package/app/components/shadcn/card/CardFooter.vue +17 -0
  37. package/app/components/shadcn/card/CardHeader.vue +17 -0
  38. package/app/components/shadcn/card/CardTitle.vue +17 -0
  39. package/app/components/shadcn/card/index.ts +7 -0
  40. package/app/components/shadcn/checkbox/Checkbox.vue +35 -0
  41. package/app/components/shadcn/checkbox/index.ts +1 -0
  42. package/app/components/shadcn/collapsible/Collapsible.vue +19 -0
  43. package/app/components/shadcn/collapsible/CollapsibleContent.vue +15 -0
  44. package/app/components/shadcn/collapsible/CollapsibleTrigger.vue +15 -0
  45. package/app/components/shadcn/collapsible/index.ts +3 -0
  46. package/app/components/shadcn/command/Command.vue +87 -0
  47. package/app/components/shadcn/command/CommandDialog.vue +31 -0
  48. package/app/components/shadcn/command/CommandEmpty.vue +27 -0
  49. package/app/components/shadcn/command/CommandGroup.vue +45 -0
  50. package/app/components/shadcn/command/CommandInput.vue +39 -0
  51. package/app/components/shadcn/command/CommandItem.vue +76 -0
  52. package/app/components/shadcn/command/CommandList.vue +25 -0
  53. package/app/components/shadcn/command/CommandSeparator.vue +21 -0
  54. package/app/components/shadcn/command/CommandShortcut.vue +17 -0
  55. package/app/components/shadcn/command/index.ts +25 -0
  56. package/app/components/shadcn/dialog/Dialog.vue +19 -0
  57. package/app/components/shadcn/dialog/DialogClose.vue +15 -0
  58. package/app/components/shadcn/dialog/DialogContent.vue +53 -0
  59. package/app/components/shadcn/dialog/DialogDescription.vue +23 -0
  60. package/app/components/shadcn/dialog/DialogFooter.vue +27 -0
  61. package/app/components/shadcn/dialog/DialogHeader.vue +17 -0
  62. package/app/components/shadcn/dialog/DialogOverlay.vue +21 -0
  63. package/app/components/shadcn/dialog/DialogScrollContent.vue +59 -0
  64. package/app/components/shadcn/dialog/DialogTitle.vue +23 -0
  65. package/app/components/shadcn/dialog/DialogTrigger.vue +15 -0
  66. package/app/components/shadcn/dialog/index.ts +10 -0
  67. package/app/components/shadcn/dropdown-menu/DropdownMenu.vue +19 -0
  68. package/app/components/shadcn/dropdown-menu/DropdownMenuCheckboxItem.vue +39 -0
  69. package/app/components/shadcn/dropdown-menu/DropdownMenuContent.vue +39 -0
  70. package/app/components/shadcn/dropdown-menu/DropdownMenuGroup.vue +15 -0
  71. package/app/components/shadcn/dropdown-menu/DropdownMenuItem.vue +31 -0
  72. package/app/components/shadcn/dropdown-menu/DropdownMenuLabel.vue +23 -0
  73. package/app/components/shadcn/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  74. package/app/components/shadcn/dropdown-menu/DropdownMenuRadioItem.vue +40 -0
  75. package/app/components/shadcn/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  76. package/app/components/shadcn/dropdown-menu/DropdownMenuShortcut.vue +17 -0
  77. package/app/components/shadcn/dropdown-menu/DropdownMenuSub.vue +18 -0
  78. package/app/components/shadcn/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  79. package/app/components/shadcn/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
  80. package/app/components/shadcn/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  81. package/app/components/shadcn/dropdown-menu/index.ts +16 -0
  82. package/app/components/shadcn/field/Field.vue +25 -0
  83. package/app/components/shadcn/field/FieldContent.vue +20 -0
  84. package/app/components/shadcn/field/FieldDescription.vue +22 -0
  85. package/app/components/shadcn/field/FieldError.vue +53 -0
  86. package/app/components/shadcn/field/FieldGroup.vue +20 -0
  87. package/app/components/shadcn/field/FieldLabel.vue +23 -0
  88. package/app/components/shadcn/field/FieldLegend.vue +24 -0
  89. package/app/components/shadcn/field/FieldSeparator.vue +29 -0
  90. package/app/components/shadcn/field/FieldSet.vue +21 -0
  91. package/app/components/shadcn/field/FieldTitle.vue +20 -0
  92. package/app/components/shadcn/field/index.ts +39 -0
  93. package/app/components/shadcn/input/Input.vue +33 -0
  94. package/app/components/shadcn/input/index.ts +1 -0
  95. package/app/components/shadcn/input-group/InputGroup.vue +35 -0
  96. package/app/components/shadcn/input-group/InputGroupAddon.vue +36 -0
  97. package/app/components/shadcn/input-group/InputGroupButton.vue +29 -0
  98. package/app/components/shadcn/input-group/InputGroupInput.vue +19 -0
  99. package/app/components/shadcn/input-group/InputGroupText.vue +19 -0
  100. package/app/components/shadcn/input-group/InputGroupTextarea.vue +19 -0
  101. package/app/components/shadcn/input-group/index.ts +51 -0
  102. package/app/components/shadcn/label/Label.vue +26 -0
  103. package/app/components/shadcn/label/index.ts +1 -0
  104. package/app/components/shadcn/number-field/NumberField.vue +20 -0
  105. package/app/components/shadcn/number-field/NumberFieldContent.vue +14 -0
  106. package/app/components/shadcn/number-field/NumberFieldDecrement.vue +22 -0
  107. package/app/components/shadcn/number-field/NumberFieldIncrement.vue +22 -0
  108. package/app/components/shadcn/number-field/NumberFieldInput.vue +16 -0
  109. package/app/components/shadcn/number-field/index.ts +5 -0
  110. package/app/components/shadcn/pagination/Pagination.vue +26 -0
  111. package/app/components/shadcn/pagination/PaginationContent.vue +22 -0
  112. package/app/components/shadcn/pagination/PaginationEllipsis.vue +25 -0
  113. package/app/components/shadcn/pagination/PaginationFirst.vue +33 -0
  114. package/app/components/shadcn/pagination/PaginationItem.vue +34 -0
  115. package/app/components/shadcn/pagination/PaginationLast.vue +33 -0
  116. package/app/components/shadcn/pagination/PaginationNext.vue +33 -0
  117. package/app/components/shadcn/pagination/PaginationPrevious.vue +33 -0
  118. package/app/components/shadcn/pagination/index.ts +8 -0
  119. package/app/components/shadcn/pin-input/PinInput.vue +26 -0
  120. package/app/components/shadcn/pin-input/PinInputGroup.vue +21 -0
  121. package/app/components/shadcn/pin-input/PinInputSeparator.vue +19 -0
  122. package/app/components/shadcn/pin-input/PinInputSlot.vue +21 -0
  123. package/app/components/shadcn/pin-input/index.ts +4 -0
  124. package/app/components/shadcn/popover/Popover.vue +19 -0
  125. package/app/components/shadcn/popover/PopoverAnchor.vue +15 -0
  126. package/app/components/shadcn/popover/PopoverContent.vue +45 -0
  127. package/app/components/shadcn/popover/PopoverTrigger.vue +15 -0
  128. package/app/components/shadcn/popover/index.ts +4 -0
  129. package/app/components/shadcn/progress/Progress.vue +38 -0
  130. package/app/components/shadcn/progress/index.ts +1 -0
  131. package/app/components/shadcn/radio-group/RadioGroup.vue +25 -0
  132. package/app/components/shadcn/radio-group/RadioGroupItem.vue +40 -0
  133. package/app/components/shadcn/radio-group/index.ts +2 -0
  134. package/app/components/shadcn/scroll-area/ScrollArea.vue +33 -0
  135. package/app/components/shadcn/scroll-area/ScrollBar.vue +32 -0
  136. package/app/components/shadcn/scroll-area/index.ts +2 -0
  137. package/app/components/shadcn/select/Select.vue +19 -0
  138. package/app/components/shadcn/select/SelectContent.vue +51 -0
  139. package/app/components/shadcn/select/SelectGroup.vue +15 -0
  140. package/app/components/shadcn/select/SelectItem.vue +44 -0
  141. package/app/components/shadcn/select/SelectItemText.vue +15 -0
  142. package/app/components/shadcn/select/SelectLabel.vue +17 -0
  143. package/app/components/shadcn/select/SelectScrollDownButton.vue +26 -0
  144. package/app/components/shadcn/select/SelectScrollUpButton.vue +26 -0
  145. package/app/components/shadcn/select/SelectSeparator.vue +19 -0
  146. package/app/components/shadcn/select/SelectTrigger.vue +33 -0
  147. package/app/components/shadcn/select/SelectValue.vue +15 -0
  148. package/app/components/shadcn/select/index.ts +11 -0
  149. package/app/components/shadcn/separator/Separator.vue +29 -0
  150. package/app/components/shadcn/separator/index.ts +1 -0
  151. package/app/components/shadcn/sheet/Sheet.vue +19 -0
  152. package/app/components/shadcn/sheet/SheetClose.vue +15 -0
  153. package/app/components/shadcn/sheet/SheetContent.vue +62 -0
  154. package/app/components/shadcn/sheet/SheetDescription.vue +21 -0
  155. package/app/components/shadcn/sheet/SheetFooter.vue +16 -0
  156. package/app/components/shadcn/sheet/SheetHeader.vue +15 -0
  157. package/app/components/shadcn/sheet/SheetOverlay.vue +21 -0
  158. package/app/components/shadcn/sheet/SheetTitle.vue +21 -0
  159. package/app/components/shadcn/sheet/SheetTrigger.vue +15 -0
  160. package/app/components/shadcn/sheet/index.ts +8 -0
  161. package/app/components/shadcn/sidebar/Sidebar.vue +96 -0
  162. package/app/components/shadcn/sidebar/SidebarContent.vue +18 -0
  163. package/app/components/shadcn/sidebar/SidebarFooter.vue +18 -0
  164. package/app/components/shadcn/sidebar/SidebarGroup.vue +18 -0
  165. package/app/components/shadcn/sidebar/SidebarGroupAction.vue +27 -0
  166. package/app/components/shadcn/sidebar/SidebarGroupContent.vue +18 -0
  167. package/app/components/shadcn/sidebar/SidebarGroupLabel.vue +25 -0
  168. package/app/components/shadcn/sidebar/SidebarHeader.vue +18 -0
  169. package/app/components/shadcn/sidebar/SidebarInput.vue +22 -0
  170. package/app/components/shadcn/sidebar/SidebarInset.vue +21 -0
  171. package/app/components/shadcn/sidebar/SidebarMenu.vue +18 -0
  172. package/app/components/shadcn/sidebar/SidebarMenuAction.vue +35 -0
  173. package/app/components/shadcn/sidebar/SidebarMenuBadge.vue +26 -0
  174. package/app/components/shadcn/sidebar/SidebarMenuButton.vue +48 -0
  175. package/app/components/shadcn/sidebar/SidebarMenuButtonChild.vue +36 -0
  176. package/app/components/shadcn/sidebar/SidebarMenuItem.vue +18 -0
  177. package/app/components/shadcn/sidebar/SidebarMenuSkeleton.vue +35 -0
  178. package/app/components/shadcn/sidebar/SidebarMenuSub.vue +22 -0
  179. package/app/components/shadcn/sidebar/SidebarMenuSubButton.vue +36 -0
  180. package/app/components/shadcn/sidebar/SidebarMenuSubItem.vue +18 -0
  181. package/app/components/shadcn/sidebar/SidebarProvider.vue +82 -0
  182. package/app/components/shadcn/sidebar/SidebarRail.vue +33 -0
  183. package/app/components/shadcn/sidebar/SidebarSeparator.vue +19 -0
  184. package/app/components/shadcn/sidebar/SidebarTrigger.vue +27 -0
  185. package/app/components/shadcn/sidebar/index.ts +60 -0
  186. package/app/components/shadcn/sidebar/utils.ts +19 -0
  187. package/app/components/shadcn/skeleton/Skeleton.vue +17 -0
  188. package/app/components/shadcn/skeleton/index.ts +1 -0
  189. package/app/components/shadcn/slider/Slider.vue +43 -0
  190. package/app/components/shadcn/slider/index.ts +1 -0
  191. package/app/components/shadcn/sonner/Sonner.vue +42 -0
  192. package/app/components/shadcn/sonner/index.ts +1 -0
  193. package/app/components/shadcn/switch/Switch.vue +38 -0
  194. package/app/components/shadcn/switch/index.ts +1 -0
  195. package/app/components/shadcn/table/Table.vue +16 -0
  196. package/app/components/shadcn/table/TableBody.vue +17 -0
  197. package/app/components/shadcn/table/TableCaption.vue +17 -0
  198. package/app/components/shadcn/table/TableCell.vue +22 -0
  199. package/app/components/shadcn/table/TableEmpty.vue +34 -0
  200. package/app/components/shadcn/table/TableFooter.vue +17 -0
  201. package/app/components/shadcn/table/TableHead.vue +17 -0
  202. package/app/components/shadcn/table/TableHeader.vue +17 -0
  203. package/app/components/shadcn/table/TableRow.vue +17 -0
  204. package/app/components/shadcn/table/index.ts +9 -0
  205. package/app/components/shadcn/table/utils.ts +10 -0
  206. package/app/components/shadcn/tabs/Tabs.vue +24 -0
  207. package/app/components/shadcn/tabs/TabsContent.vue +21 -0
  208. package/app/components/shadcn/tabs/TabsList.vue +24 -0
  209. package/app/components/shadcn/tabs/TabsTrigger.vue +26 -0
  210. package/app/components/shadcn/tabs/index.ts +4 -0
  211. package/app/components/shadcn/textarea/Textarea.vue +28 -0
  212. package/app/components/shadcn/textarea/index.ts +1 -0
  213. package/app/components/shadcn/toggle/Toggle.vue +35 -0
  214. package/app/components/shadcn/toggle/index.ts +28 -0
  215. package/app/components/shadcn/toggle-group/ToggleGroup.vue +49 -0
  216. package/app/components/shadcn/toggle-group/ToggleGroupItem.vue +46 -0
  217. package/app/components/shadcn/toggle-group/index.ts +2 -0
  218. package/app/components/shadcn/tooltip/Tooltip.vue +19 -0
  219. package/app/components/shadcn/tooltip/TooltipContent.vue +34 -0
  220. package/app/components/shadcn/tooltip/TooltipProvider.vue +14 -0
  221. package/app/components/shadcn/tooltip/TooltipTrigger.vue +15 -0
  222. package/app/components/shadcn/tooltip/index.ts +4 -0
  223. package/app/components/ui/Accordion/index.stories.ts +108 -0
  224. package/app/components/ui/Accordion/index.vue +80 -0
  225. package/app/components/ui/Accordion/types.ts +27 -0
  226. package/app/components/ui/Alert/index.stories.ts +53 -0
  227. package/app/components/ui/Alert/index.vue +61 -0
  228. package/app/components/ui/Alert/types.ts +9 -0
  229. package/app/components/ui/AlertDialog/index.stories.ts +108 -0
  230. package/app/components/ui/AlertDialog/index.vue +25 -0
  231. package/app/components/ui/AsyncDataTable/en.json +3 -0
  232. package/app/components/ui/AsyncDataTable/index.stories.ts +141 -0
  233. package/app/components/ui/AsyncDataTable/index.vue +312 -0
  234. package/app/components/ui/AsyncDataTable/types.ts +53 -0
  235. package/app/components/ui/Avatar/index.stories.ts +84 -0
  236. package/app/components/ui/Avatar/index.vue +52 -0
  237. package/app/components/ui/Avatar/types.ts +8 -0
  238. package/app/components/ui/Badge/index.stories.ts +67 -0
  239. package/app/components/ui/Badge/index.vue +12 -0
  240. package/app/components/ui/Badge/types.ts +3 -0
  241. package/app/components/ui/Breadcrumb/index.stories.ts +52 -0
  242. package/app/components/ui/Breadcrumb/index.vue +61 -0
  243. package/app/components/ui/Breadcrumb/types.ts +11 -0
  244. package/app/components/ui/Button/index.stories.ts +145 -0
  245. package/app/components/ui/Button/index.vue +63 -0
  246. package/app/components/ui/Button/types.ts +14 -0
  247. package/app/components/ui/ButtonGroup/index.stories.ts +75 -0
  248. package/app/components/ui/ButtonGroup/index.vue +22 -0
  249. package/app/components/ui/ButtonGroup/types.ts +3 -0
  250. package/app/components/ui/Card/index.stories.ts +65 -0
  251. package/app/components/ui/Card/index.vue +28 -0
  252. package/app/components/ui/Card/types.ts +3 -0
  253. package/app/components/ui/Checkbox/index.stories.ts +68 -0
  254. package/app/components/ui/Checkbox/index.vue +23 -0
  255. package/app/components/ui/Checkbox/types.ts +3 -0
  256. package/app/components/ui/CopyButton/en.json +4 -0
  257. package/app/components/ui/CopyButton/index.stories.ts +55 -0
  258. package/app/components/ui/CopyButton/index.vue +98 -0
  259. package/app/components/ui/CopyButton/types.ts +10 -0
  260. package/app/components/ui/DataTable/en.json +3 -0
  261. package/app/components/ui/DataTable/index.stories.ts +231 -0
  262. package/app/components/ui/DataTable/index.vue +505 -0
  263. package/app/components/ui/DataTable/types.ts +42 -0
  264. package/app/components/ui/DatePicker/en.json +9 -0
  265. package/app/components/ui/DatePicker/index.stories.ts +70 -0
  266. package/app/components/ui/DatePicker/index.vue +127 -0
  267. package/app/components/ui/DatePicker/style.css +88 -0
  268. package/app/components/ui/DatePicker/types.ts +41 -0
  269. package/app/components/ui/DateRangePicker/en.json +5 -0
  270. package/app/components/ui/DateRangePicker/index.stories.ts +67 -0
  271. package/app/components/ui/DateRangePicker/index.vue +138 -0
  272. package/app/components/ui/DateRangePicker/types.ts +31 -0
  273. package/app/components/ui/Divider/index.stories.ts +42 -0
  274. package/app/components/ui/Divider/index.vue +16 -0
  275. package/app/components/ui/Divider/types.ts +3 -0
  276. package/app/components/ui/Drawer/index.stories.ts +124 -0
  277. package/app/components/ui/Drawer/index.vue +197 -0
  278. package/app/components/ui/Drawer/types.ts +22 -0
  279. package/app/components/ui/Dropdown/index.stories.ts +145 -0
  280. package/app/components/ui/Dropdown/index.vue +258 -0
  281. package/app/components/ui/Dropdown/types.ts +87 -0
  282. package/app/components/ui/FormItem/index.stories.ts +70 -0
  283. package/app/components/ui/FormItem/index.vue +56 -0
  284. package/app/components/ui/FormItem/types.ts +14 -0
  285. package/app/components/ui/Help/index.stories.ts +54 -0
  286. package/app/components/ui/Help/index.vue +35 -0
  287. package/app/components/ui/Help/types.ts +8 -0
  288. package/app/components/ui/Icon/index.stories.ts +68 -0
  289. package/app/components/ui/Icon/index.vue +30 -0
  290. package/app/components/ui/Icon/types.ts +5 -0
  291. package/app/components/ui/Input/index.stories.ts +73 -0
  292. package/app/components/ui/Input/index.vue +92 -0
  293. package/app/components/ui/Input/types.ts +9 -0
  294. package/app/components/ui/InputCurrency/index.stories.ts +75 -0
  295. package/app/components/ui/InputCurrency/index.vue +31 -0
  296. package/app/components/ui/InputCurrency/types.ts +4 -0
  297. package/app/components/ui/InputNumber/index.stories.ts +56 -0
  298. package/app/components/ui/InputNumber/index.vue +76 -0
  299. package/app/components/ui/InputNumber/types.ts +10 -0
  300. package/app/components/ui/InputOtp/index.stories.ts +39 -0
  301. package/app/components/ui/InputOtp/index.vue +45 -0
  302. package/app/components/ui/InputOtp/types.ts +5 -0
  303. package/app/components/ui/InputPercent/index.stories.ts +32 -0
  304. package/app/components/ui/InputPercent/index.vue +8 -0
  305. package/app/components/ui/InputRange/index.stories.ts +37 -0
  306. package/app/components/ui/InputRange/index.vue +49 -0
  307. package/app/components/ui/InputRange/types.ts +8 -0
  308. package/app/components/ui/Loading/index.stories.ts +36 -0
  309. package/app/components/ui/Loading/index.vue +15 -0
  310. package/app/components/ui/Loading/types.ts +3 -0
  311. package/app/components/ui/Markdown/index.stories.ts +52 -0
  312. package/app/components/ui/Markdown/index.vue +22 -0
  313. package/app/components/ui/Markdown/themes/github.css +1248 -0
  314. package/app/components/ui/Markdown/types.ts +3 -0
  315. package/app/components/ui/Modal/index.stories.ts +124 -0
  316. package/app/components/ui/Modal/index.vue +202 -0
  317. package/app/components/ui/Modal/types.ts +23 -0
  318. package/app/components/ui/ModalContent/index.stories.ts +47 -0
  319. package/app/components/ui/ModalContent/index.vue +79 -0
  320. package/app/components/ui/ModalContent/types.ts +9 -0
  321. package/app/components/ui/PageCard/index.stories.ts +106 -0
  322. package/app/components/ui/PageCard/index.vue +135 -0
  323. package/app/components/ui/PageCard/types.ts +16 -0
  324. package/app/components/ui/Pagination/en.json +3 -0
  325. package/app/components/ui/Pagination/index.stories.ts +82 -0
  326. package/app/components/ui/Pagination/index.vue +173 -0
  327. package/app/components/ui/Pagination/types.ts +18 -0
  328. package/app/components/ui/Popover/index.stories.ts +67 -0
  329. package/app/components/ui/Popover/index.vue +21 -0
  330. package/app/components/ui/Popover/types.ts +5 -0
  331. package/app/components/ui/Qrcode/index.stories.ts +57 -0
  332. package/app/components/ui/Qrcode/index.vue +40 -0
  333. package/app/components/ui/Qrcode/types.ts +3 -0
  334. package/app/components/ui/Radio/index.stories.ts +71 -0
  335. package/app/components/ui/Radio/index.vue +10 -0
  336. package/app/components/ui/Radio/types.ts +3 -0
  337. package/app/components/ui/RadioCardGroup/index.stories.ts +90 -0
  338. package/app/components/ui/RadioCardGroup/index.vue +64 -0
  339. package/app/components/ui/RadioCardGroup/types.ts +13 -0
  340. package/app/components/ui/ScrollArea/index.stories.ts +66 -0
  341. package/app/components/ui/ScrollArea/index.vue +64 -0
  342. package/app/components/ui/ScrollArea/types.ts +5 -0
  343. package/app/components/ui/SearchSelect/en.json +5 -0
  344. package/app/components/ui/SearchSelect/index.stories.ts +126 -0
  345. package/app/components/ui/SearchSelect/index.vue +259 -0
  346. package/app/components/ui/SearchSelect/types.ts +39 -0
  347. package/app/components/ui/Select/en.json +6 -0
  348. package/app/components/ui/Select/index.stories.ts +128 -0
  349. package/app/components/ui/Select/index.vue +267 -0
  350. package/app/components/ui/Select/types.ts +34 -0
  351. package/app/components/ui/Skeleton/index.stories.ts +56 -0
  352. package/app/components/ui/Skeleton/index.vue +12 -0
  353. package/app/components/ui/Skeleton/types.ts +4 -0
  354. package/app/components/ui/Slider/index.stories.ts +60 -0
  355. package/app/components/ui/Slider/index.vue +27 -0
  356. package/app/components/ui/Slider/types.ts +5 -0
  357. package/app/components/ui/Surface/index.stories.ts +50 -0
  358. package/app/components/ui/Surface/index.vue +108 -0
  359. package/app/components/ui/Surface/types.ts +8 -0
  360. package/app/components/ui/Switch/index.stories.ts +32 -0
  361. package/app/components/ui/Switch/index.vue +10 -0
  362. package/app/components/ui/Switch/types.ts +3 -0
  363. package/app/components/ui/Tabs/index.stories.ts +116 -0
  364. package/app/components/ui/Tabs/index.vue +94 -0
  365. package/app/components/ui/Tabs/types.ts +19 -0
  366. package/app/components/ui/Tag/index.stories.ts +51 -0
  367. package/app/components/ui/Tag/index.vue +108 -0
  368. package/app/components/ui/Tag/types.ts +8 -0
  369. package/app/components/ui/Textarea/index.stories.ts +35 -0
  370. package/app/components/ui/Textarea/index.vue +50 -0
  371. package/app/components/ui/Textarea/types.ts +8 -0
  372. package/app/components/ui/Toast/index.stories.ts +48 -0
  373. package/app/components/ui/Toast/index.vue +21 -0
  374. package/app/components/ui/Toast/types.ts +5 -0
  375. package/app/components/ui/Tooltip/index.stories.ts +62 -0
  376. package/app/components/ui/Tooltip/index.vue +72 -0
  377. package/app/components/ui/Tooltip/types.ts +7 -0
  378. package/app/components/ui/WebLink/index.stories.ts +59 -0
  379. package/app/components/ui/WebLink/index.vue +61 -0
  380. package/app/components/ui/WebLink/types.ts +11 -0
  381. package/app/composables/index.ts +9 -0
  382. package/app/composables/useDialog.ts +76 -0
  383. package/app/composables/useToast.ts +49 -0
  384. package/app/en.json +23 -0
  385. package/app/types/index.ts +7 -0
  386. package/app/utils/index.ts +6 -0
  387. package/i18n/messages/ar.json +65 -0
  388. package/i18n/messages/de.json +65 -0
  389. package/i18n/messages/en.json +65 -0
  390. package/i18n/messages/es.json +65 -0
  391. package/i18n/messages/fr.json +65 -0
  392. package/i18n/messages/hi.json +65 -0
  393. package/i18n/messages/id.json +65 -0
  394. package/i18n/messages/it.json +65 -0
  395. package/i18n/messages/ja.json +65 -0
  396. package/i18n/messages/ko.json +65 -0
  397. package/i18n/messages/nl.json +65 -0
  398. package/i18n/messages/pl.json +65 -0
  399. package/i18n/messages/pt.json +65 -0
  400. package/i18n/messages/ru.json +65 -0
  401. package/i18n/messages/th.json +65 -0
  402. package/i18n/messages/tr.json +65 -0
  403. package/i18n/messages/vi.json +65 -0
  404. package/i18n/messages/zh-CN.json +65 -0
  405. package/i18n/messages/zh-TW.json +65 -0
  406. package/i18n.config.ts +19 -0
  407. package/nuxt.config.ts +62 -0
  408. package/package.json +46 -0
@@ -0,0 +1,70 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import Input from '../Input/index.vue'
3
+ import FormItem from './index.vue'
4
+
5
+ const meta = {
6
+ title: 'UI/FormItem',
7
+ component: FormItem,
8
+ } satisfies Meta<typeof FormItem>
9
+
10
+ export default meta
11
+ type Story = StoryObj<typeof meta>
12
+
13
+ export const Default: Story = {
14
+ render: () => ({
15
+ components: { FormItem, Input },
16
+ setup () {
17
+ const name = ref('')
18
+ const email = ref('')
19
+ return { name, email }
20
+ },
21
+ template: `
22
+ <div class="space-y-10 max-w-md">
23
+ <section>
24
+ <h3 class="mb-4 text-lg font-medium">Basic</h3>
25
+ <FormItem label="Name">
26
+ <Input v-model="name" placeholder="Enter your name" />
27
+ </FormItem>
28
+ </section>
29
+
30
+ <section>
31
+ <h3 class="mb-4 text-lg font-medium">Required</h3>
32
+ <FormItem label="Email" required>
33
+ <Input v-model="email" placeholder="Enter your email" />
34
+ </FormItem>
35
+ </section>
36
+
37
+ <section>
38
+ <h3 class="mb-4 text-lg font-medium">With Error</h3>
39
+ <FormItem label="Username" required error="Username is already taken">
40
+ <Input model-value="admin" />
41
+ </FormItem>
42
+ </section>
43
+
44
+ <section>
45
+ <h3 class="mb-4 text-lg font-medium">With Description</h3>
46
+ <FormItem label="Password" description="Must be at least 8 characters long">
47
+ <Input type="password" placeholder="Enter password" />
48
+ </FormItem>
49
+ </section>
50
+
51
+ <section>
52
+ <h3 class="mb-4 text-lg font-medium">Horizontal Orientation</h3>
53
+ <FormItem label="Display Name" orientation="horizontal">
54
+ <Input placeholder="Enter display name" />
55
+ </FormItem>
56
+ </section>
57
+
58
+ <section>
59
+ <h3 class="mb-4 text-lg font-medium">Responsive Orientation</h3>
60
+ <p class="mb-2 text-sm text-muted-foreground">Drag the right edge to resize ↔</p>
61
+ <div class="@container/field-group resize-x overflow-auto rounded border border-dashed border-border bg-card p-4" style="min-width: 200px;">
62
+ <FormItem label="Address" orientation="responsive" description="Your mailing address">
63
+ <Input placeholder="Enter address" />
64
+ </FormItem>
65
+ </div>
66
+ </section>
67
+ </div>
68
+ `,
69
+ }),
70
+ }
@@ -0,0 +1,56 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ Field,
4
+ FieldContent,
5
+ FieldDescription,
6
+ FieldError,
7
+ FieldLabel,
8
+ } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/field'
9
+ import type { FormItemProps } from './types'
10
+
11
+ const props = defineProps<FormItemProps>()
12
+
13
+ const errorArray = computed(() => {
14
+ if (!props.error) return undefined
15
+ return [{ message: props.error }]
16
+ })
17
+
18
+ const labelClass = computed(() => {
19
+ if (props.orientation === 'horizontal') return '!flex-initial mt-2'
20
+ if (props.orientation === 'responsive') return '@md/field-group:!flex-initial @md/field-group:mt-2'
21
+ return undefined
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <Field
27
+ :orientation="orientation"
28
+ :class="props.class"
29
+ :data-invalid="!!error || undefined"
30
+ >
31
+ <FieldLabel
32
+ v-if="label"
33
+ :class="labelClass"
34
+ >
35
+ <div>
36
+ {{ label }}
37
+ <span
38
+ v-if="required"
39
+ class="text-danger"
40
+ aria-hidden="true"
41
+ >
42
+ *
43
+ </span>
44
+ </div>
45
+ </FieldLabel>
46
+ <FieldContent>
47
+ <slot />
48
+ <FieldDescription v-if="description || $slots.description">
49
+ <slot name="description">
50
+ {{ description }}
51
+ </slot>
52
+ </FieldDescription>
53
+ <FieldError :errors="errorArray" />
54
+ </FieldContent>
55
+ </Field>
56
+ </template>
@@ -0,0 +1,14 @@
1
+ export interface FormItemProps {
2
+ /** Label text */
3
+ label?: string
4
+ /** Error message to display */
5
+ error?: string
6
+ /** Description / help text below the input */
7
+ description?: string
8
+ /** Whether the field is required (shows red asterisk) */
9
+ required?: boolean
10
+ /** Field layout orientation */
11
+ orientation?: 'vertical' | 'horizontal' | 'responsive'
12
+ /** Custom class for the root Field */
13
+ class?: ClassValue
14
+ }
@@ -0,0 +1,54 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import Help from './index.vue'
3
+
4
+ const meta = {
5
+ title: 'UI/Help',
6
+ component: Help,
7
+ } satisfies Meta<typeof Help>
8
+
9
+ export default meta
10
+ type Story = StoryObj<typeof meta>
11
+
12
+ export const Default: Story = {
13
+ render: () => ({
14
+ components: { Help },
15
+ template: `
16
+ <div class="space-y-10">
17
+ <section>
18
+ <h3 class="mb-4 text-lg font-medium">Basic</h3>
19
+ <Help text="This is a helpful tooltip" />
20
+ </section>
21
+
22
+ <section>
23
+ <h3 class="mb-4 text-lg font-medium">Positions</h3>
24
+ <div class="flex items-center gap-8 py-10 justify-center">
25
+ <div class="flex flex-col items-center gap-2">
26
+ <Help text="Top tooltip" position="top" />
27
+ <span class="text-sm text-muted-foreground">Top</span>
28
+ </div>
29
+ <div class="flex flex-col items-center gap-2">
30
+ <Help text="Bottom tooltip" position="bottom" />
31
+ <span class="text-sm text-muted-foreground">Bottom</span>
32
+ </div>
33
+ <div class="flex flex-col items-center gap-2">
34
+ <Help text="Left tooltip" position="left" />
35
+ <span class="text-sm text-muted-foreground">Left</span>
36
+ </div>
37
+ <div class="flex flex-col items-center gap-2">
38
+ <Help text="Right tooltip" position="right" />
39
+ <span class="text-sm text-muted-foreground">Right</span>
40
+ </div>
41
+ </div>
42
+ </section>
43
+
44
+ <section>
45
+ <h3 class="mb-4 text-lg font-medium">Inline with Label</h3>
46
+ <div class="flex items-center gap-1">
47
+ <span class="text-sm font-medium">API Key</span>
48
+ <Help text="Your unique API key for authentication" />
49
+ </div>
50
+ </section>
51
+ </div>
52
+ `,
53
+ }),
54
+ }
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ import type { HelpProps } from './types'
3
+
4
+ const props = withDefaults(defineProps<HelpProps>(), {
5
+ text: undefined,
6
+ position: 'top',
7
+ class: undefined,
8
+ })
9
+
10
+ const mergedClass = computed(() =>
11
+ cn(
12
+ `
13
+ flex items-center justify-center text-muted-foreground transition-colors
14
+ hover:text-foreground
15
+ `,
16
+ props.class,
17
+ ),
18
+ )
19
+ </script>
20
+
21
+ <template>
22
+ <Tooltip
23
+ :text="text"
24
+ :position="position"
25
+ >
26
+ <div :class="mergedClass">
27
+ <slot>
28
+ <Icon
29
+ name="circle-question-mark"
30
+ class="cursor-help"
31
+ />
32
+ </slot>
33
+ </div>
34
+ </Tooltip>
35
+ </template>
@@ -0,0 +1,8 @@
1
+ export interface HelpProps {
2
+ /** Tooltip content text */
3
+ text?: string
4
+ /** Tooltip position */
5
+ position?: 'top' | 'bottom' | 'left' | 'right'
6
+ /** Custom class */
7
+ class?: ClassValue
8
+ }
@@ -0,0 +1,68 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import Icon from './index.vue'
3
+
4
+ const meta = {
5
+ title: 'UI/Icon',
6
+ component: Icon,
7
+ argTypes: {
8
+ name: { control: 'text' },
9
+ },
10
+ args: {
11
+ name: 'house',
12
+ },
13
+ } satisfies Meta<typeof Icon>
14
+
15
+ export default meta
16
+ type Story = StoryObj<typeof meta>
17
+
18
+ const commonIcons = [
19
+ 'house', 'search', 'settings', 'user', 'mail', 'bell',
20
+ 'heart', 'star', 'plus', 'minus', 'check', 'x',
21
+ 'chevron-left', 'chevron-right', 'chevron-up', 'chevron-down',
22
+ 'arrow-left', 'arrow-right', 'arrow-up', 'arrow-down',
23
+ 'eye', 'eye-off', 'trash-2', 'pencil', 'copy', 'download',
24
+ 'upload', 'share', 'link', 'external-link', 'info', 'triangle-alert',
25
+ ]
26
+
27
+ export const Default: Story = {
28
+ render: args => ({
29
+ components: { Icon },
30
+ setup: () => ({ args, commonIcons }),
31
+ template: `
32
+ <div class="space-y-10">
33
+ <!-- Controlled -->
34
+ <section>
35
+ <h3 class="mb-4 text-lg font-medium">Controlled</h3>
36
+ <Icon v-bind="args" />
37
+ </section>
38
+
39
+ <!-- Common Icons -->
40
+ <section>
41
+ <h3 class="mb-4 text-lg font-medium">Common Icons</h3>
42
+ <div class="grid grid-cols-8 gap-4">
43
+ <div
44
+ v-for="name in commonIcons"
45
+ :key="name"
46
+ class="flex flex-col items-center gap-2 rounded-md border p-3"
47
+ >
48
+ <Icon :name="name" class="size-5" />
49
+ <span class="text-xs text-muted-foreground">{{ name }}</span>
50
+ </div>
51
+ </div>
52
+ </section>
53
+
54
+ <!-- Sizes -->
55
+ <section>
56
+ <h3 class="mb-4 text-lg font-medium">Sizes</h3>
57
+ <div class="flex items-end gap-4">
58
+ <Icon name="star" class="size-3" />
59
+ <Icon name="star" class="size-4" />
60
+ <Icon name="star" class="size-5" />
61
+ <Icon name="star" class="size-6" />
62
+ <Icon name="star" class="size-8" />
63
+ </div>
64
+ </section>
65
+ </div>
66
+ `,
67
+ }),
68
+ }
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { icons } from 'lucide-vue-next'
3
+ import type { Component } from 'vue'
4
+ import type { IconProps } from './types'
5
+
6
+ const props = defineProps<IconProps>()
7
+
8
+ // Convert kebab-case to PascalCase: "alarm-clock" -> "AlarmClock"
9
+ function toPascalCase (str: string): string {
10
+ return str
11
+ .split('-')
12
+ .map(s => s.charAt(0).toUpperCase() + s.slice(1))
13
+ .join('')
14
+ }
15
+
16
+ const iconComponent = computed<Component | undefined>(() => {
17
+ const pascalName = toPascalCase(props.name)
18
+ return (icons as Record<string, Component>)[pascalName]
19
+ })
20
+
21
+ const mergedClass = computed(() => cn('size-4', props.class))
22
+ </script>
23
+
24
+ <template>
25
+ <component
26
+ :is="iconComponent"
27
+ v-if="iconComponent"
28
+ :class="mergedClass"
29
+ />
30
+ </template>
@@ -0,0 +1,5 @@
1
+ export interface IconProps {
2
+ /** Icon name in kebab-case (e.g. "mail", "arrow-left", "circle-question-mark") */
3
+ name: string
4
+ class?: ClassValue
5
+ }
@@ -0,0 +1,73 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import Icon from '../Icon/index.vue'
3
+ import Input from './index.vue'
4
+
5
+ const meta = {
6
+ title: 'UI/Input',
7
+ component: Input,
8
+ argTypes: {
9
+ disabled: { control: 'boolean' },
10
+ readonly: { control: 'boolean' },
11
+ invalid: { control: 'boolean' },
12
+ },
13
+ args: {
14
+ disabled: false,
15
+ readonly: false,
16
+ invalid: false,
17
+ },
18
+ } satisfies Meta
19
+
20
+ export default meta
21
+ type Story = StoryObj<typeof meta>
22
+
23
+ export const Default: Story = {
24
+ render: args => ({
25
+ components: { Input, Icon },
26
+ setup () {
27
+ const value = ref('')
28
+ const withPrefix = ref('')
29
+ const withSuffix = ref('')
30
+ const password = ref('')
31
+ return { args, value, withPrefix, withSuffix, password }
32
+ },
33
+ template: `
34
+ <div class="space-y-10 max-w-sm">
35
+ <!-- Controlled -->
36
+ <section>
37
+ <h3 class="mb-4 text-lg font-medium">Controlled</h3>
38
+ <Input v-model="value" v-bind="args" placeholder="Enter your name..." />
39
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ value }}</div>
40
+ </section>
41
+
42
+ <!-- With Prefix Icon -->
43
+ <section>
44
+ <h3 class="mb-4 text-lg font-medium">With Prefix Icon</h3>
45
+ <Input v-model="withPrefix" placeholder="Search...">
46
+ <template #prefix>
47
+ <Icon name="search" />
48
+ </template>
49
+ </Input>
50
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ withPrefix }}</div>
51
+ </section>
52
+
53
+ <!-- With Suffix Icon -->
54
+ <section>
55
+ <h3 class="mb-4 text-lg font-medium">With Suffix Icon</h3>
56
+ <Input v-model="withSuffix" placeholder="Email">
57
+ <template #suffix>
58
+ <Icon name="mail" />
59
+ </template>
60
+ </Input>
61
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ withSuffix }}</div>
62
+ </section>
63
+
64
+ <!-- Password -->
65
+ <section>
66
+ <h3 class="mb-4 text-lg font-medium">Password</h3>
67
+ <Input v-model="password" type="password" placeholder="Password" />
68
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ password }}</div>
69
+ </section>
70
+ </div>
71
+ `,
72
+ }),
73
+ }
@@ -0,0 +1,92 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ InputGroup,
4
+ InputGroupAddon,
5
+ InputGroupButton,
6
+ InputGroupInput,
7
+ } from '@polymarbot/nuxt-layer-shadcn-ui/app/components/shadcn/input-group'
8
+ import type { InputProps } from './types'
9
+
10
+ defineOptions({ inheritAttrs: false })
11
+
12
+ const props = defineProps<InputProps>()
13
+
14
+ const emit = defineEmits<{
15
+ 'update:modelValue': [value: string | undefined]
16
+ 'change': [value: string | undefined]
17
+ }>()
18
+
19
+ const $slots = defineSlots<{
20
+ prefix?: () => unknown
21
+ suffix?: () => unknown
22
+ }>()
23
+
24
+ // Internal value tracks the actual input content, independent of parent's modelValue
25
+ const internalValue = ref(props.modelValue)
26
+
27
+ // Sync internal value when parent updates modelValue
28
+ watch(() => props.modelValue, value => {
29
+ internalValue.value = value
30
+ })
31
+
32
+ const showClearButton = computed(() => !!internalValue.value && !props.readonly && !props.disabled)
33
+
34
+ function handleChange (event: Event) {
35
+ const target = event.target as HTMLInputElement
36
+ emit('change', target.value)
37
+ }
38
+
39
+ function handleInput (event: Event) {
40
+ const target = event.target as HTMLInputElement
41
+ internalValue.value = target.value
42
+ emit('update:modelValue', target.value)
43
+ }
44
+
45
+ function clearInput () {
46
+ internalValue.value = undefined
47
+ emit('update:modelValue', undefined)
48
+ emit('change', undefined)
49
+ }
50
+ </script>
51
+
52
+ <template>
53
+ <InputGroup
54
+ :class="props.class"
55
+ :data-disabled="disabled || undefined"
56
+ >
57
+ <InputGroupAddon
58
+ v-if="$slots.prefix"
59
+ align="inline-start"
60
+ >
61
+ <slot name="prefix" />
62
+ </InputGroupAddon>
63
+ <InputGroupInput
64
+ :modelValue="internalValue"
65
+ v-bind="$attrs"
66
+ :readonly="readonly"
67
+ :disabled="disabled"
68
+ :aria-invalid="invalid || undefined"
69
+ :data-1p-ignore="autocomplete === 'off' || !autocomplete ? true : undefined"
70
+ :autocomplete="autocomplete || 'off'"
71
+ @input="handleInput"
72
+ @change="handleChange"
73
+ />
74
+ <InputGroupAddon
75
+ v-if="showClearButton"
76
+ align="inline-end"
77
+ >
78
+ <InputGroupButton
79
+ size="icon-xs"
80
+ @click="clearInput"
81
+ >
82
+ <Icon name="x" />
83
+ </InputGroupButton>
84
+ </InputGroupAddon>
85
+ <InputGroupAddon
86
+ v-if="$slots.suffix"
87
+ align="inline-end"
88
+ >
89
+ <slot name="suffix" />
90
+ </InputGroupAddon>
91
+ </InputGroup>
92
+ </template>
@@ -0,0 +1,9 @@
1
+ export interface InputProps {
2
+ modelValue?: string
3
+ /** Set to enable browser/password-manager autofill (e.g. 'email', 'current-password'). Defaults to 'off'. */
4
+ autocomplete?: string
5
+ readonly?: boolean
6
+ disabled?: boolean
7
+ invalid?: boolean
8
+ class?: ClassValue
9
+ }
@@ -0,0 +1,75 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import InputCurrency from './index.vue'
3
+
4
+ const meta = {
5
+ title: 'UI/InputCurrency',
6
+ component: InputCurrency,
7
+ argTypes: {
8
+ disabled: { control: 'boolean' },
9
+ },
10
+ args: {
11
+ disabled: false,
12
+ },
13
+ } satisfies Meta
14
+
15
+ export default meta
16
+ type Story = StoryObj<typeof meta>
17
+
18
+ export const Default: Story = {
19
+ render: args => ({
20
+ components: { InputCurrency },
21
+ setup () {
22
+ const jpy = ref(1000)
23
+ const usd = ref(49.99)
24
+ const eurCode = ref(29.99)
25
+ const cadSymbol = ref(79.99)
26
+ const cadNarrow = ref(79.99)
27
+ const jpyName = ref(5000)
28
+ return { args, jpy, usd, eurCode, cadSymbol, cadNarrow, jpyName }
29
+ },
30
+ template: `
31
+ <div class="space-y-10 max-w-xs">
32
+ <!-- Controlled -->
33
+ <section>
34
+ <h3 class="mb-4 text-lg font-medium">Controlled</h3>
35
+ <InputCurrency v-model="jpy" v-bind="args" />
36
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ jpy }}</div>
37
+ </section>
38
+
39
+ <!-- USD (symbol) -->
40
+ <section>
41
+ <h3 class="mb-4 text-lg font-medium">USD (symbol)</h3>
42
+ <InputCurrency v-model="usd" currency="USD" />
43
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ usd }}</div>
44
+ </section>
45
+
46
+ <!-- EUR (code display) -->
47
+ <section>
48
+ <h3 class="mb-4 text-lg font-medium">EUR (code display)</h3>
49
+ <InputCurrency v-model="eurCode" currency="EUR" currencyDisplay="code" />
50
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ eurCode }}</div>
51
+ </section>
52
+
53
+ <!-- CAD symbol vs narrowSymbol -->
54
+ <section>
55
+ <h3 class="mb-4 text-lg font-medium">CAD (symbol → CA$)</h3>
56
+ <InputCurrency v-model="cadSymbol" currency="CAD" currencyDisplay="symbol" />
57
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ cadSymbol }}</div>
58
+ </section>
59
+
60
+ <section>
61
+ <h3 class="mb-4 text-lg font-medium">CAD (narrowSymbol → $)</h3>
62
+ <InputCurrency v-model="cadNarrow" currency="CAD" currencyDisplay="narrowSymbol" />
63
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ cadNarrow }}</div>
64
+ </section>
65
+
66
+ <!-- JPY (name display) -->
67
+ <section>
68
+ <h3 class="mb-4 text-lg font-medium">JPY (name display)</h3>
69
+ <InputCurrency v-model="jpyName" currencyDisplay="name" />
70
+ <div class="mt-2 text-sm text-muted-foreground">Value: {{ jpyName }}</div>
71
+ </section>
72
+ </div>
73
+ `,
74
+ }),
75
+ }
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ import type { InputCurrencyProps } from './types'
3
+
4
+ const props = withDefaults(defineProps<InputCurrencyProps>(), {
5
+ currency: 'JPY',
6
+ currencyDisplay: 'symbol',
7
+ })
8
+
9
+ const formatOptions = computed<Intl.NumberFormatOptions>(() => ({
10
+ style: 'currency',
11
+ currency: props.currency,
12
+ currencyDisplay: props.currencyDisplay,
13
+ }))
14
+
15
+ // Derive step from currency's minor unit (e.g. JPY→1, USD→0.01, BHD→0.001)
16
+ const defaultStep = computed(() => {
17
+ const { minimumFractionDigits } = new Intl.NumberFormat('en', {
18
+ style: 'currency',
19
+ currency: props.currency,
20
+ }).resolvedOptions()
21
+ return 1 / (10 ** (minimumFractionDigits ?? 0))
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <InputNumber
27
+ :formatOptions="formatOptions"
28
+ :min="0"
29
+ :step="defaultStep"
30
+ />
31
+ </template>
@@ -0,0 +1,4 @@
1
+ export interface InputCurrencyProps {
2
+ currency?: string
3
+ currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name'
4
+ }