@brumaombra/ui-vintage 0.9.1 → 0.9.3

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 (344) hide show
  1. package/COMPONENTS.md +102 -2
  2. package/module.mjs +43 -43
  3. package/package.json +175 -175
  4. package/src/components/background-grid/BackgroundGrid.vue +4 -4
  5. package/src/components/blog/AllPostsSection.vue +33 -33
  6. package/src/components/blog/BlogCategoriesPage.vue +46 -0
  7. package/src/components/blog/BlogContentRenderer.vue +111 -111
  8. package/src/components/blog/BlogFAQSection.vue +19 -19
  9. package/src/components/blog/BlogHeaderSection.vue +80 -80
  10. package/src/components/blog/BlogIndexPage.vue +118 -0
  11. package/src/components/blog/BlogInfoSection.vue +47 -47
  12. package/src/components/blog/BlogPageBreadcrumbs.vue +43 -0
  13. package/src/components/blog/BlogPostHeader.vue +135 -135
  14. package/src/components/blog/BlogPostPage.vue +116 -0
  15. package/src/components/blog/BlogPostsPage.vue +74 -0
  16. package/src/components/blog/BlogProgressBar.vue +33 -33
  17. package/src/components/blog/BlogSectionTitle.vue +22 -22
  18. package/src/components/blog/BlogTagsPage.vue +46 -0
  19. package/src/components/blog/BlogTagsSection.vue +25 -25
  20. package/src/components/blog/BlogViewAllLink.vue +18 -0
  21. package/src/components/blog/CategoriesList.vue +14 -14
  22. package/src/components/blog/CategoriesSection.vue +11 -11
  23. package/src/components/blog/CategoryCard.vue +25 -25
  24. package/src/components/blog/HeaderCarousel.vue +97 -97
  25. package/src/components/blog/PostCard.vue +33 -33
  26. package/src/components/blog/PostsList.vue +15 -15
  27. package/src/components/blog/SocialShareSidebar.vue +84 -84
  28. package/src/components/blog/TableOfContents.vue +307 -307
  29. package/src/components/blog/blogPageUtils.ts +98 -0
  30. package/src/components/blog/index.ts +12 -1
  31. package/src/components/busy-indicator/BusyIndicator.vue +7 -7
  32. package/src/components/busy-indicator/busy-indicator-state.ts +56 -56
  33. package/src/components/card-grid/CardGrid.vue +34 -34
  34. package/src/components/chip/Chip.vue +15 -15
  35. package/src/components/confirm-dialog/ConfirmDialog.vue +50 -50
  36. package/src/components/confirm-dialog/confirm-dialog-state.ts +131 -131
  37. package/src/components/content/BlogList.vue +30 -30
  38. package/src/components/content/BlogTable.vue +36 -36
  39. package/src/components/content/CodeBlock.vue +136 -136
  40. package/src/components/content/Flow.vue +60 -60
  41. package/src/components/content/ProseHr.vue +15 -15
  42. package/src/components/content/ProsePre.vue +12 -12
  43. package/src/components/content/Terminal.vue +59 -59
  44. package/src/components/cookie-consent/CookieConsent.vue +36 -36
  45. package/src/components/cookie-consent/useCookieConsent.ts +37 -37
  46. package/src/components/dashboard-shell/DashboardShell.vue +171 -171
  47. package/src/components/data-list/DataList.vue +6 -6
  48. package/src/components/data-list/DataListItem.vue +4 -4
  49. package/src/components/data-list/DataListLabel.vue +4 -4
  50. package/src/components/data-list/DataListText.vue +4 -4
  51. package/src/components/data-list/DataListValue.vue +4 -4
  52. package/src/components/empty-state-card/EmptyStateCard.vue +40 -40
  53. package/src/components/error-page/ErrorPage.vue +72 -72
  54. package/src/components/info-card/InfoCard.vue +31 -31
  55. package/src/components/landing/landing-content/LandingContent.vue +4 -4
  56. package/src/components/landing/landing-footer/LandingFooter.vue +128 -128
  57. package/src/components/landing/landing-navbar/LandingNavbar.vue +50 -50
  58. package/src/components/landing/landing-shell/LandingShell.vue +36 -36
  59. package/src/components/language-flag/LanguageFlag.vue +25 -25
  60. package/src/components/language-flag/flags/ChineseFlag.vue +8 -8
  61. package/src/components/language-flag/flags/EnglishFlag.vue +7 -7
  62. package/src/components/language-flag/flags/FrenchFlag.vue +5 -5
  63. package/src/components/language-flag/flags/GermanFlag.vue +5 -5
  64. package/src/components/language-flag/flags/ItalianFlag.vue +7 -7
  65. package/src/components/language-flag/flags/JapaneseFlag.vue +4 -4
  66. package/src/components/language-flag/flags/PortugueseFlag.vue +57 -57
  67. package/src/components/language-flag/flags/RussianFlag.vue +5 -5
  68. package/src/components/language-flag/flags/SpanishFlag.vue +4 -4
  69. package/src/components/language-selector/LanguageSelector.vue +76 -76
  70. package/src/components/load-more-button/LoadMoreButton.vue +17 -17
  71. package/src/components/loading-state-card/LoadingStateCard.vue +28 -28
  72. package/src/components/message-dialog/MessageDialog.vue +59 -59
  73. package/src/components/message-dialog/message-dialog-state.ts +105 -105
  74. package/src/components/message-toast/MessageToast.vue +149 -149
  75. package/src/components/message-toast/message-toast-state.ts +146 -146
  76. package/src/components/page-header/PageHeader.vue +34 -34
  77. package/src/components/progress-component/ProgressComponent.vue +33 -33
  78. package/src/components/single-value-card/SingleValueCard.vue +57 -57
  79. package/src/components/slider-form-component/SliderFormComponent.vue +36 -36
  80. package/src/components/stat-strip/StatStrip.vue +22 -22
  81. package/src/components/switch-form-component/SwitchFormComponent.vue +20 -20
  82. package/src/components/text-link/TextLink.vue +14 -14
  83. package/src/components/theme-selector/ThemeSelector.vue +61 -61
  84. package/src/components/theme-selector/theme-transition.ts +63 -63
  85. package/src/components/ui/accordion/Accordion.vue +38 -38
  86. package/src/components/ui/alert/Alert.vue +5 -5
  87. package/src/components/ui/alert/AlertDescription.vue +4 -4
  88. package/src/components/ui/alert/AlertTitle.vue +4 -4
  89. package/src/components/ui/alert/index.ts +2 -2
  90. package/src/components/ui/alert-dialog/AlertDialog.vue +3 -3
  91. package/src/components/ui/alert-dialog/AlertDialogAction.vue +3 -3
  92. package/src/components/ui/alert-dialog/AlertDialogCancel.vue +3 -3
  93. package/src/components/ui/alert-dialog/AlertDialogContent.vue +7 -7
  94. package/src/components/ui/alert-dialog/AlertDialogDescription.vue +3 -3
  95. package/src/components/ui/alert-dialog/AlertDialogFooter.vue +4 -4
  96. package/src/components/ui/alert-dialog/AlertDialogHeader.vue +4 -4
  97. package/src/components/ui/alert-dialog/AlertDialogTitle.vue +3 -3
  98. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +3 -3
  99. package/src/components/ui/animated-number/AnimatedNumber.vue +49 -48
  100. package/src/components/ui/avatar/Avatar.vue +28 -28
  101. package/src/components/ui/avatar/AvatarFallback.vue +6 -6
  102. package/src/components/ui/avatar/AvatarGroup.vue +40 -40
  103. package/src/components/ui/avatar/AvatarImage.vue +3 -3
  104. package/src/components/ui/avatar/index.ts +17 -17
  105. package/src/components/ui/badge/Badge.vue +20 -20
  106. package/src/components/ui/breadcrumb/Breadcrumb.vue +4 -4
  107. package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +9 -9
  108. package/src/components/ui/breadcrumb/BreadcrumbItem.vue +4 -4
  109. package/src/components/ui/breadcrumb/BreadcrumbLink.vue +4 -4
  110. package/src/components/ui/breadcrumb/BreadcrumbList.vue +4 -4
  111. package/src/components/ui/breadcrumb/BreadcrumbPage.vue +4 -4
  112. package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +4 -4
  113. package/src/components/ui/busy/Busy.vue +33 -33
  114. package/src/components/ui/button/Button.vue +23 -23
  115. package/src/components/ui/button/index.ts +56 -56
  116. package/src/components/ui/calendar/Calendar.vue +138 -138
  117. package/src/components/ui/calendar/CalendarCell.vue +7 -7
  118. package/src/components/ui/calendar/CalendarCellTrigger.vue +18 -18
  119. package/src/components/ui/calendar/CalendarGrid.vue +3 -3
  120. package/src/components/ui/calendar/CalendarGridBody.vue +3 -3
  121. package/src/components/ui/calendar/CalendarGridHead.vue +3 -3
  122. package/src/components/ui/calendar/CalendarGridRow.vue +3 -3
  123. package/src/components/ui/calendar/CalendarHeadCell.vue +7 -7
  124. package/src/components/ui/calendar/CalendarHeader.vue +7 -7
  125. package/src/components/ui/calendar/CalendarHeading.vue +6 -6
  126. package/src/components/ui/calendar/CalendarNextButton.vue +15 -15
  127. package/src/components/ui/calendar/CalendarPrevButton.vue +15 -15
  128. package/src/components/ui/calendar/index.ts +4 -4
  129. package/src/components/ui/card/Card.vue +20 -20
  130. package/src/components/ui/card/CardAction.vue +8 -8
  131. package/src/components/ui/card/CardContent.vue +4 -4
  132. package/src/components/ui/card/CardDescription.vue +12 -12
  133. package/src/components/ui/card/CardFooter.vue +4 -4
  134. package/src/components/ui/card/CardHeader.vue +8 -8
  135. package/src/components/ui/card/CardText.vue +8 -8
  136. package/src/components/ui/card/CardTitle.vue +8 -8
  137. package/src/components/ui/checkbox/Checkbox.vue +27 -27
  138. package/src/components/ui/collapsible/Collapsible.vue +3 -3
  139. package/src/components/ui/collapsible/CollapsibleContent.vue +3 -3
  140. package/src/components/ui/collapsible/CollapsibleTrigger.vue +3 -3
  141. package/src/components/ui/combobox/Combobox.vue +4 -4
  142. package/src/components/ui/combobox/ComboboxAnchor.vue +16 -16
  143. package/src/components/ui/combobox/ComboboxEmpty.vue +3 -3
  144. package/src/components/ui/combobox/ComboboxGroup.vue +9 -9
  145. package/src/components/ui/combobox/ComboboxInput.vue +6 -6
  146. package/src/components/ui/combobox/ComboboxItem.vue +17 -17
  147. package/src/components/ui/combobox/ComboboxList.vue +19 -19
  148. package/src/components/ui/combobox/ComboboxSelect.vue +77 -77
  149. package/src/components/ui/combobox/ComboboxSeparator.vue +1 -1
  150. package/src/components/ui/combobox/ComboboxTrigger.vue +10 -10
  151. package/src/components/ui/combobox/types.ts +5 -5
  152. package/src/components/ui/command/Command.vue +48 -48
  153. package/src/components/ui/command/CommandDialog.vue +14 -14
  154. package/src/components/ui/command/CommandEmpty.vue +4 -4
  155. package/src/components/ui/command/CommandGroup.vue +23 -23
  156. package/src/components/ui/command/CommandInput.vue +9 -9
  157. package/src/components/ui/command/CommandItem.vue +40 -40
  158. package/src/components/ui/command/CommandList.vue +9 -9
  159. package/src/components/ui/command/CommandSeparator.vue +3 -3
  160. package/src/components/ui/command/CommandShortcut.vue +8 -8
  161. package/src/components/ui/command/index.ts +11 -11
  162. package/src/components/ui/data-table/DataTable.vue +145 -145
  163. package/src/components/ui/data-table/index.ts +11 -11
  164. package/src/components/ui/date-picker/DatePicker.vue +31 -31
  165. package/src/components/ui/date-time-picker/DateTimePicker.vue +97 -97
  166. package/src/components/ui/dialog/Dialog.vue +3 -3
  167. package/src/components/ui/dialog/DialogClose.vue +3 -3
  168. package/src/components/ui/dialog/DialogContent.vue +21 -21
  169. package/src/components/ui/dialog/DialogDescription.vue +7 -7
  170. package/src/components/ui/dialog/DialogFooter.vue +8 -8
  171. package/src/components/ui/dialog/DialogHeader.vue +4 -4
  172. package/src/components/ui/dialog/DialogOverlay.vue +7 -7
  173. package/src/components/ui/dialog/DialogScrollContent.vue +32 -32
  174. package/src/components/ui/dialog/DialogTitle.vue +3 -3
  175. package/src/components/ui/dialog/DialogTrigger.vue +3 -3
  176. package/src/components/ui/dropdown-menu/DropdownMenu.vue +3 -3
  177. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +11 -11
  178. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +15 -15
  179. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +3 -3
  180. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +12 -12
  181. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +9 -9
  182. package/src/components/ui/dropdown-menu/DropdownMenuPortal.vue +3 -3
  183. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +3 -3
  184. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +11 -11
  185. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +1 -1
  186. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +4 -4
  187. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +3 -3
  188. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +15 -15
  189. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +15 -15
  190. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +3 -3
  191. package/src/components/ui/dropdown-menu/classes.ts +16 -16
  192. package/src/components/ui/field/Field.vue +5 -5
  193. package/src/components/ui/field/FieldContent.vue +8 -8
  194. package/src/components/ui/field/FieldDescription.vue +10 -10
  195. package/src/components/ui/field/FieldError.vue +39 -39
  196. package/src/components/ui/field/FieldGroup.vue +8 -8
  197. package/src/components/ui/field/FieldLabel.vue +10 -10
  198. package/src/components/ui/field/FieldLegend.vue +11 -11
  199. package/src/components/ui/field/FieldSeparator.vue +11 -11
  200. package/src/components/ui/field/FieldSet.vue +9 -9
  201. package/src/components/ui/field/FieldTitle.vue +8 -8
  202. package/src/components/ui/field/field-context.ts +36 -36
  203. package/src/components/ui/field/index.ts +22 -22
  204. package/src/components/ui/file-dropzone/FileDropzone.vue +144 -144
  205. package/src/components/ui/file-dropzone/index.ts +19 -19
  206. package/src/components/ui/hover-card/HoverCard.vue +5 -5
  207. package/src/components/ui/hover-card/HoverCardContent.vue +13 -13
  208. package/src/components/ui/hover-card/HoverCardTrigger.vue +3 -3
  209. package/src/components/ui/input/Input.vue +13 -13
  210. package/src/components/ui/kbd/Kbd.vue +10 -10
  211. package/src/components/ui/kbd/KbdGroup.vue +49 -49
  212. package/src/components/ui/label/Label.vue +7 -7
  213. package/src/components/ui/native-select/NativeSelect.vue +16 -16
  214. package/src/components/ui/native-select/NativeSelectOptGroup.vue +3 -3
  215. package/src/components/ui/native-select/NativeSelectOption.vue +3 -3
  216. package/src/components/ui/number-field/NumberField.vue +88 -88
  217. package/src/components/ui/pagination/Pagination.vue +4 -4
  218. package/src/components/ui/pagination/PaginationContent.vue +4 -4
  219. package/src/components/ui/pagination/PaginationEllipsis.vue +9 -9
  220. package/src/components/ui/pagination/PaginationFirst.vue +8 -8
  221. package/src/components/ui/pagination/PaginationItem.vue +14 -14
  222. package/src/components/ui/pagination/PaginationLast.vue +8 -8
  223. package/src/components/ui/pagination/PaginationNext.vue +8 -8
  224. package/src/components/ui/pagination/PaginationPrevious.vue +8 -8
  225. package/src/components/ui/pagination/SimplePagination.vue +25 -25
  226. package/src/components/ui/pin-input/PinInput.vue +20 -20
  227. package/src/components/ui/pin-input/PinInputInput.vue +17 -17
  228. package/src/components/ui/pin-input/context.ts +1 -1
  229. package/src/components/ui/popover/Popover.vue +3 -3
  230. package/src/components/ui/popover/PopoverAnchor.vue +3 -3
  231. package/src/components/ui/popover/PopoverContent.vue +12 -12
  232. package/src/components/ui/popover/PopoverTrigger.vue +3 -3
  233. package/src/components/ui/progress/Progress.vue +16 -16
  234. package/src/components/ui/radio-group/RadioGroup.vue +7 -7
  235. package/src/components/ui/radio-group/RadioGroupCard.vue +39 -39
  236. package/src/components/ui/radio-group/RadioGroupItem.vue +20 -20
  237. package/src/components/ui/scroll-area/ScrollArea.vue +14 -14
  238. package/src/components/ui/scroll-area/ScrollBar.vue +12 -12
  239. package/src/components/ui/select/Select.vue +3 -3
  240. package/src/components/ui/select/SelectContent.vue +25 -25
  241. package/src/components/ui/select/SelectGroup.vue +3 -3
  242. package/src/components/ui/select/SelectItem.vue +24 -24
  243. package/src/components/ui/select/SelectItemContent.vue +32 -32
  244. package/src/components/ui/select/SelectItemText.vue +3 -3
  245. package/src/components/ui/select/SelectLabel.vue +3 -3
  246. package/src/components/ui/select/SelectScrollDownButton.vue +9 -9
  247. package/src/components/ui/select/SelectScrollUpButton.vue +9 -9
  248. package/src/components/ui/select/SelectSeparator.vue +2 -2
  249. package/src/components/ui/select/SelectTrigger.vue +14 -14
  250. package/src/components/ui/select/SelectValue.vue +3 -3
  251. package/src/components/ui/select/SelectValueContent.vue +39 -39
  252. package/src/components/ui/separator/Separator.vue +7 -7
  253. package/src/components/ui/sheet/Sheet.vue +3 -3
  254. package/src/components/ui/sheet/SheetClose.vue +3 -3
  255. package/src/components/ui/sheet/SheetContent.vue +22 -22
  256. package/src/components/ui/sheet/SheetDescription.vue +3 -3
  257. package/src/components/ui/sheet/SheetFooter.vue +3 -3
  258. package/src/components/ui/sheet/SheetHeader.vue +3 -3
  259. package/src/components/ui/sheet/SheetOverlay.vue +7 -7
  260. package/src/components/ui/sheet/SheetTitle.vue +3 -3
  261. package/src/components/ui/sheet/SheetTrigger.vue +3 -3
  262. package/src/components/ui/sidebar/Sidebar.vue +57 -57
  263. package/src/components/ui/sidebar/SidebarContent.vue +8 -8
  264. package/src/components/ui/sidebar/SidebarFooter.vue +8 -8
  265. package/src/components/ui/sidebar/SidebarGroup.vue +8 -8
  266. package/src/components/ui/sidebar/SidebarGroupAction.vue +9 -9
  267. package/src/components/ui/sidebar/SidebarGroupContent.vue +4 -4
  268. package/src/components/ui/sidebar/SidebarGroupLabel.vue +8 -8
  269. package/src/components/ui/sidebar/SidebarHeader.vue +8 -8
  270. package/src/components/ui/sidebar/SidebarInput.vue +8 -8
  271. package/src/components/ui/sidebar/SidebarInset.vue +9 -9
  272. package/src/components/ui/sidebar/SidebarMenu.vue +4 -4
  273. package/src/components/ui/sidebar/SidebarMenuAction.vue +18 -18
  274. package/src/components/ui/sidebar/SidebarMenuBadge.vue +14 -14
  275. package/src/components/ui/sidebar/SidebarMenuButton.vue +21 -21
  276. package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +10 -10
  277. package/src/components/ui/sidebar/SidebarMenuItem.vue +4 -4
  278. package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +10 -10
  279. package/src/components/ui/sidebar/SidebarMenuSub.vue +9 -9
  280. package/src/components/ui/sidebar/SidebarMenuSubButton.vue +17 -17
  281. package/src/components/ui/sidebar/SidebarMenuSubItem.vue +4 -4
  282. package/src/components/ui/sidebar/SidebarProvider.vue +46 -46
  283. package/src/components/ui/sidebar/SidebarRail.vue +13 -13
  284. package/src/components/ui/sidebar/SidebarSeparator.vue +4 -4
  285. package/src/components/ui/sidebar/SidebarTrigger.vue +5 -5
  286. package/src/components/ui/sidebar/index.ts +29 -29
  287. package/src/components/ui/sidebar/utils.ts +7 -7
  288. package/src/components/ui/skeleton/Skeleton.vue +6 -6
  289. package/src/components/ui/slider/Slider.vue +14 -14
  290. package/src/components/ui/spinner/Spinner.vue +21 -21
  291. package/src/components/ui/stepper/SimpleStepper.vue +26 -26
  292. package/src/components/ui/stepper/Stepper.vue +6 -6
  293. package/src/components/ui/stepper/StepperDescription.vue +5 -5
  294. package/src/components/ui/stepper/StepperIndicator.vue +17 -17
  295. package/src/components/ui/stepper/StepperItem.vue +4 -4
  296. package/src/components/ui/stepper/StepperSeparator.vue +7 -7
  297. package/src/components/ui/stepper/StepperTitle.vue +5 -5
  298. package/src/components/ui/stepper/StepperTrigger.vue +4 -4
  299. package/src/components/ui/stepper/index.ts +3 -3
  300. package/src/components/ui/switch/Switch.vue +15 -15
  301. package/src/components/ui/table/Table.vue +6 -6
  302. package/src/components/ui/table/TableBody.vue +4 -4
  303. package/src/components/ui/table/TableCaption.vue +4 -4
  304. package/src/components/ui/table/TableCell.vue +8 -8
  305. package/src/components/ui/table/TableEmpty.vue +14 -14
  306. package/src/components/ui/table/TableFooter.vue +8 -8
  307. package/src/components/ui/table/TableHead.vue +8 -8
  308. package/src/components/ui/table/TableHeader.vue +4 -4
  309. package/src/components/ui/table/TableRow.vue +8 -8
  310. package/src/components/ui/tabs/Tabs.vue +4 -4
  311. package/src/components/ui/tabs/TabsContent.vue +4 -4
  312. package/src/components/ui/tabs/TabsList.vue +15 -15
  313. package/src/components/ui/tabs/TabsTrigger.vue +10 -10
  314. package/src/components/ui/tags-input/TagsInput.vue +17 -17
  315. package/src/components/ui/tags-input/TagsInputInput.vue +6 -6
  316. package/src/components/ui/tags-input/TagsInputItem.vue +15 -15
  317. package/src/components/ui/tags-input/TagsInputItemDelete.vue +12 -12
  318. package/src/components/ui/tags-input/TagsInputItemText.vue +4 -4
  319. package/src/components/ui/textarea/Textarea.vue +12 -12
  320. package/src/components/ui/time-picker/TimePicker.vue +25 -25
  321. package/src/components/ui/toggle-group/Toggle.vue +10 -10
  322. package/src/components/ui/toggle-group/ToggleGroup.vue +38 -38
  323. package/src/components/ui/toggle-group/ToggleGroupItem.vue +9 -9
  324. package/src/components/ui/toggle-group/index.ts +46 -46
  325. package/src/components/ui/tooltip/Tooltip.vue +3 -3
  326. package/src/components/ui/tooltip/TooltipContent.vue +13 -13
  327. package/src/components/ui/tooltip/TooltipProvider.vue +4 -4
  328. package/src/components/ui/tooltip/TooltipTrigger.vue +3 -3
  329. package/src/i18n/de.json +206 -185
  330. package/src/i18n/en.json +206 -185
  331. package/src/i18n/es.json +206 -185
  332. package/src/i18n/fr.json +206 -185
  333. package/src/i18n/it.json +206 -185
  334. package/src/i18n/ja.json +206 -185
  335. package/src/i18n/pt.json +206 -185
  336. package/src/i18n/ru.json +206 -185
  337. package/src/i18n/zh.json +206 -185
  338. package/src/lib/color-tokens.ts +24 -24
  339. package/src/lib/i18n.ts +65 -65
  340. package/src/lib/utils.ts +33 -33
  341. package/src/nuxt-components.d.ts +2 -2
  342. package/src/runtime/ui-vintage-i18n-plugin.ts +49 -49
  343. package/src/shims-vue.d.ts +3 -3
  344. package/src/styles.css +377 -377
@@ -0,0 +1,98 @@
1
+ // Post fields read by the blog page helpers (a Nuxt Content blog collection entry)
2
+ export interface BlogPostData {
3
+ path?: string;
4
+ title?: string;
5
+ description?: string;
6
+ image?: string;
7
+ categoryText?: string;
8
+ categorySlug?: string;
9
+ tags?: string[];
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ // Category card data built from the posts
14
+ export interface BlogCategoryData {
15
+ name: string;
16
+ slug: string;
17
+ path: string;
18
+ count: number;
19
+ image?: string;
20
+ }
21
+
22
+ // Tag badge data built from the posts
23
+ export interface BlogTagData {
24
+ name: string;
25
+ slug: string;
26
+ count: number;
27
+ }
28
+
29
+ // Turn a label into a URL slug (e.g. "Dark Mode" -> "dark-mode")
30
+ export const slugify = (value: unknown) => {
31
+ return String(value || '')
32
+ .trim()
33
+ .toLowerCase()
34
+ .replace(/[^a-z0-9]+/g, '-')
35
+ .replace(/^-+|-+$/g, '');
36
+ };
37
+
38
+ // Remove the trailing slashes of a route path, since content paths never have one ("/blog/post/" -> "/blog/post")
39
+ export const normalizeContentPath = (path: string) => path.replace(/(.)\/+$/, '$1');
40
+
41
+ // Build the unique categories of the posts, with their post count and the image of their first post
42
+ export const buildCategoriesFromPosts = (posts: BlogPostData[], getPath: (slug: string) => string): BlogCategoryData[] => {
43
+ const categoriesList = posts.map(post => post.categorySlug);
44
+ const uniqueCategories = categoriesList.filter((category, index, self): category is string => !!category && self.indexOf(category) === index);
45
+
46
+ // Map unique categories to category data
47
+ return uniqueCategories.map(category => {
48
+ const firstPost = posts.find(post => post.categorySlug === category);
49
+
50
+ // Return category data
51
+ return {
52
+ name: firstPost?.categoryText || category,
53
+ slug: category,
54
+ path: getPath(category),
55
+ count: categoriesList.filter(item => item === category).length,
56
+ image: firstPost?.image
57
+ };
58
+ });
59
+ };
60
+
61
+ // Build the unique tags of the posts, with their number of uses (the first label wins for tags that share a slug)
62
+ export const buildTagsFromPosts = (posts: BlogPostData[]): BlogTagData[] => {
63
+ const tagsBySlug = new Map<string, BlogTagData>();
64
+
65
+ // Loop through each post and tag
66
+ for (const post of posts) {
67
+ for (const tag of post.tags || []) {
68
+ const slug = slugify(tag);
69
+ if (!slug) continue; // Skip tags that cannot produce a URL slug
70
+
71
+ // Preserve the first label while counting the duplicates
72
+ const existingTag = tagsBySlug.get(slug);
73
+ tagsBySlug.set(slug, {
74
+ name: existingTag?.name || tag,
75
+ slug,
76
+ count: (existingTag?.count || 0) + 1
77
+ });
78
+ }
79
+ }
80
+
81
+ // Return unique tags with their post counts
82
+ return [...tagsBySlug.values()];
83
+ };
84
+
85
+ // Create a deterministic hash for stable related content ordering (FNV-1a: a linear hash would give every seed the same order)
86
+ const hashString = (value: string) => {
87
+ let hash = 2166136261;
88
+ for (let index = 0; index < value.length; index++) {
89
+ hash ^= value.charCodeAt(index);
90
+ hash = Math.imul(hash, 16777619);
91
+ }
92
+ return hash >>> 0;
93
+ };
94
+
95
+ // Sort a list by a deterministic score derived from a seed (the same post always shows the same related items, on the server and in the browser)
96
+ export const sortByStableSeed = <T>(items: T[], seed: string, getKey: (item: T) => string) => {
97
+ return [...items].sort((itemA, itemB) => hashString(`${seed}-${getKey(itemA)}`) - hashString(`${seed}-${getKey(itemB)}`));
98
+ };
@@ -13,4 +13,15 @@ export { default as HeaderCarousel } from './HeaderCarousel.vue';
13
13
  export { default as PostCard } from './PostCard.vue';
14
14
  export { default as PostsList } from './PostsList.vue';
15
15
  export { default as SocialShareSidebar } from './SocialShareSidebar.vue';
16
- export { default as TableOfContents } from './TableOfContents.vue';
16
+ export { default as TableOfContents } from './TableOfContents.vue';
17
+ // Complete blog pages (the app fetches the content and sets the SEO, these render the page)
18
+ export { default as BlogIndexPage } from './BlogIndexPage.vue';
19
+ export { default as BlogPostPage } from './BlogPostPage.vue';
20
+ export { default as BlogCategoriesPage } from './BlogCategoriesPage.vue';
21
+ export { default as BlogTagsPage } from './BlogTagsPage.vue';
22
+ export { default as BlogPostsPage } from './BlogPostsPage.vue';
23
+ export { default as BlogViewAllLink } from './BlogViewAllLink.vue';
24
+
25
+ // Helpers for the data of the blog pages
26
+ export { slugify, normalizeContentPath, buildCategoriesFromPosts, buildTagsFromPosts, sortByStableSeed } from './blogPageUtils';
27
+ export type { BlogPostData, BlogCategoryData, BlogTagData } from './blogPageUtils';
@@ -4,11 +4,11 @@ import { busyIndicatorState } from './busy-indicator-state';
4
4
  </script>
5
5
 
6
6
  <template>
7
- <!-- Busy overlay -->
8
- <Busy
9
- :show="busyIndicatorState.show"
10
- :label="busyIndicatorState.label"
11
- :class="busyIndicatorState.class"
12
- :overlay-class="busyIndicatorState.overlayClass"
13
- />
7
+ <!-- Busy overlay -->
8
+ <Busy
9
+ :show="busyIndicatorState.show"
10
+ :label="busyIndicatorState.label"
11
+ :class="busyIndicatorState.class"
12
+ :overlay-class="busyIndicatorState.overlayClass"
13
+ />
14
14
  </template>
@@ -2,16 +2,16 @@ import { h, reactive, render, type HTMLAttributes } from 'vue';
2
2
  import { getUiVintageRuntimeMessage } from '../../lib/i18n';
3
3
 
4
4
  export interface SetBusyOptions {
5
- label?: string;
6
- class?: HTMLAttributes['class'];
7
- overlayClass?: HTMLAttributes['class'];
5
+ label?: string;
6
+ class?: HTMLAttributes['class'];
7
+ overlayClass?: HTMLAttributes['class'];
8
8
  }
9
9
 
10
10
  interface BusyIndicatorState {
11
- show: boolean;
12
- label: string;
13
- class: HTMLAttributes['class'];
14
- overlayClass: HTMLAttributes['class'];
11
+ show: boolean;
12
+ label: string;
13
+ class: HTMLAttributes['class'];
14
+ overlayClass: HTMLAttributes['class'];
15
15
  }
16
16
 
17
17
  const BUSY_INDICATOR_ROOT_ID = 'ui-vintage-busy-indicator-root';
@@ -20,69 +20,69 @@ let busyIndicatorMountPromise: Promise<void> | null = null;
20
20
 
21
21
  // Shared busy state
22
22
  export const busyIndicatorState: BusyIndicatorState = reactive({
23
- show: false,
24
- label: getUiVintageRuntimeMessage('uiVintage.common.loading.title', 'Loading...'),
25
- class: undefined,
26
- overlayClass: undefined
23
+ show: false,
24
+ label: getUiVintageRuntimeMessage('uiVintage.common.loading.title', 'Loading...'),
25
+ class: undefined,
26
+ overlayClass: undefined
27
27
  });
28
28
 
29
29
  // Mount the busy indicator once on demand
30
30
  const ensureBusyIndicatorMounted = () => {
31
- // Skip mounting during SSR
32
- if (typeof document === 'undefined') {
33
- return Promise.resolve();
34
- }
31
+ // Skip mounting during SSR
32
+ if (typeof document === 'undefined') {
33
+ return Promise.resolve();
34
+ }
35
35
 
36
- // Reuse the existing mount root
37
- const existingRoot = document.getElementById(BUSY_INDICATOR_ROOT_ID);
38
- if (existingRoot) {
39
- return Promise.resolve();
40
- }
36
+ // Reuse the existing mount root
37
+ const existingRoot = document.getElementById(BUSY_INDICATOR_ROOT_ID);
38
+ if (existingRoot) {
39
+ return Promise.resolve();
40
+ }
41
41
 
42
- // Reuse the in-flight mount
43
- if (busyIndicatorMountPromise) {
44
- return busyIndicatorMountPromise;
45
- }
42
+ // Reuse the in-flight mount
43
+ if (busyIndicatorMountPromise) {
44
+ return busyIndicatorMountPromise;
45
+ }
46
46
 
47
- // Start the lazy mount
48
- busyIndicatorMountPromise = (async () => {
49
- // Load the component only when needed
50
- const { default: BusyIndicator } = await import('./BusyIndicator.vue');
47
+ // Start the lazy mount
48
+ busyIndicatorMountPromise = (async () => {
49
+ // Load the component only when needed
50
+ const { default: BusyIndicator } = await import('./BusyIndicator.vue');
51
51
 
52
- // Guard against a concurrent mount
53
- if (document.getElementById(BUSY_INDICATOR_ROOT_ID)) {
54
- return;
55
- }
52
+ // Guard against a concurrent mount
53
+ if (document.getElementById(BUSY_INDICATOR_ROOT_ID)) {
54
+ return;
55
+ }
56
56
 
57
- // Create the host element and render the component
58
- const container = document.createElement('div');
59
- container.id = BUSY_INDICATOR_ROOT_ID;
60
- document.body.appendChild(container);
61
- render(h(BusyIndicator), container);
62
- })().finally(() => {
63
- busyIndicatorMountPromise = null;
64
- });
57
+ // Create the host element and render the component
58
+ const container = document.createElement('div');
59
+ container.id = BUSY_INDICATOR_ROOT_ID;
60
+ document.body.appendChild(container);
61
+ render(h(BusyIndicator), container);
62
+ })().finally(() => {
63
+ busyIndicatorMountPromise = null;
64
+ });
65
65
 
66
- // Let callers await the mount
67
- return busyIndicatorMountPromise;
66
+ // Let callers await the mount
67
+ return busyIndicatorMountPromise;
68
68
  };
69
69
 
70
70
  // Toggle the global busy overlay
71
71
  export const setBusy = (show: boolean, options: SetBusyOptions = {}) => {
72
- // Prepare the overlay before showing it
73
- if (show) {
74
- busyIndicatorState.label = options.label ?? getUiVintageRuntimeMessage('uiVintage.common.loading.title', 'Loading...');
75
- busyIndicatorState.class = options.class;
76
- busyIndicatorState.overlayClass = options.overlayClass;
77
- void ensureBusyIndicatorMounted();
78
- }
72
+ // Prepare the overlay before showing it
73
+ if (show) {
74
+ busyIndicatorState.label = options.label ?? getUiVintageRuntimeMessage('uiVintage.common.loading.title', 'Loading...');
75
+ busyIndicatorState.class = options.class;
76
+ busyIndicatorState.overlayClass = options.overlayClass;
77
+ void ensureBusyIndicatorMounted();
78
+ }
79
79
 
80
- // Toggle the overlay visibility
81
- busyIndicatorState.show = show;
80
+ // Toggle the overlay visibility
81
+ busyIndicatorState.show = show;
82
82
 
83
- // Reset transient styling after hiding
84
- if (!show) {
85
- busyIndicatorState.class = undefined;
86
- busyIndicatorState.overlayClass = undefined;
87
- }
83
+ // Reset transient styling after hiding
84
+ if (!show) {
85
+ busyIndicatorState.class = undefined;
86
+ busyIndicatorState.overlayClass = undefined;
87
+ }
88
88
  };
@@ -7,55 +7,55 @@ import type { HugeiconsIconDefinition } from '../../lib/common-types';
7
7
 
8
8
  // Props
9
9
  const props = withDefaults(defineProps<{
10
- items?: T[];
11
- busy?: boolean;
12
- loadMoreBusy?: boolean;
13
- hasMore?: boolean;
14
- emptyMessage: string;
15
- emptyIcon?: HugeiconsIconDefinition;
10
+ items?: T[];
11
+ busy?: boolean;
12
+ loadMoreBusy?: boolean;
13
+ hasMore?: boolean;
14
+ emptyMessage: string;
15
+ emptyIcon?: HugeiconsIconDefinition;
16
16
  }>(), {
17
- items: () => [],
18
- busy: false,
19
- loadMoreBusy: false,
20
- hasMore: false,
21
- emptyIcon: () => PackageIcon
17
+ items: () => [],
18
+ busy: false,
19
+ loadMoreBusy: false,
20
+ hasMore: false,
21
+ emptyIcon: () => PackageIcon
22
22
  });
23
23
 
24
24
  // Emits
25
25
  const emits = defineEmits<{
26
- 'load-more': [];
26
+ 'load-more': [];
27
27
  }>();
28
28
 
29
29
  // Slots
30
30
  defineSlots<{
31
- card(props: { item: T; key?: PropertyKey }): unknown;
31
+ card(props: { item: T; key?: PropertyKey }): unknown;
32
32
  }>();
33
33
 
34
34
  // Handle load more
35
35
  const handleLoadMore = () => {
36
- emits('load-more');
36
+ emits('load-more');
37
37
  };
38
38
  </script>
39
39
 
40
40
  <template>
41
- <div>
42
- <!-- Busy state for initial loading -->
43
- <LoadingStateCard v-if="props.busy" />
44
-
45
- <!-- Empty state -->
46
- <EmptyStateCard v-else-if="props.items.length === 0"
47
- :description="props.emptyMessage"
48
- :icon="props.emptyIcon" />
49
-
50
- <!-- Cards grid -->
51
- <div v-else class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-6 xl:gap-4">
52
- <slot name="card" v-for="item in props.items" :item="item" :key="item.id" />
53
- </div>
54
-
55
- <!-- Load more button (only under a grid, never under the loading or empty state) -->
56
- <div v-if="!props.busy && props.items.length > 0 && (props.hasMore || props.loadMoreBusy)" class="flex justify-center mt-6">
57
- <LoadMoreButton :busy="props.loadMoreBusy"
58
- @load-more="handleLoadMore" />
59
- </div>
60
- </div>
41
+ <div>
42
+ <!-- Busy state for initial loading -->
43
+ <LoadingStateCard v-if="props.busy" />
44
+
45
+ <!-- Empty state -->
46
+ <EmptyStateCard v-else-if="props.items.length === 0"
47
+ :description="props.emptyMessage"
48
+ :icon="props.emptyIcon" />
49
+
50
+ <!-- Cards grid -->
51
+ <div v-else class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 md:gap-6 xl:gap-4">
52
+ <slot name="card" v-for="item in props.items" :item="item" :key="item.id" />
53
+ </div>
54
+
55
+ <!-- Load more button (only under a grid, never under the loading or empty state) -->
56
+ <div v-if="!props.busy && props.items.length > 0 && (props.hasMore || props.loadMoreBusy)" class="flex justify-center mt-6">
57
+ <LoadMoreButton :busy="props.loadMoreBusy"
58
+ @load-more="handleLoadMore" />
59
+ </div>
60
+ </div>
61
61
  </template>
@@ -9,12 +9,12 @@ import { cn } from '../../lib/utils';
9
9
 
10
10
  // Props
11
11
  const props = withDefaults(defineProps<{
12
- text: string;
13
- color?: ToneColor;
14
- removeLabel?: string;
15
- class?: HTMLAttributes['class'];
12
+ text: string;
13
+ color?: ToneColor;
14
+ removeLabel?: string;
15
+ class?: HTMLAttributes['class'];
16
16
  }>(), {
17
- color: 'gray'
17
+ color: 'gray'
18
18
  });
19
19
 
20
20
  const { t } = useI18n();
@@ -22,23 +22,23 @@ const resolvedRemoveLabel = computed(() => props.removeLabel || t('uiVintage.but
22
22
 
23
23
  // Emits
24
24
  const emits = defineEmits<{
25
- remove: []
25
+ remove: []
26
26
  }>();
27
27
 
28
28
  // Handle remove button click
29
29
  const handleRemove = () => {
30
- emits('remove');
30
+ emits('remove');
31
31
  };
32
32
  </script>
33
33
 
34
34
  <template>
35
- <div data-slot="chip" :class="cn('inline-flex items-center gap-2 rounded border px-3 py-2 text-sm font-semibold transition-colors duration-150', getSurfaceToneClasses(props.color), props.class)">
36
- <!-- Text content -->
37
- <span class="leading-none">{{ props.text }}</span>
35
+ <div data-slot="chip" :class="cn('inline-flex items-center gap-2 rounded border px-3 py-2 text-sm font-semibold transition-colors duration-150', getSurfaceToneClasses(props.color), props.class)">
36
+ <!-- Text content -->
37
+ <span class="leading-none">{{ props.text }}</span>
38
38
 
39
- <!-- Remove button -->
40
- <button type="button" :aria-label="resolvedRemoveLabel" class="group/remove inline-flex size-4 cursor-pointer items-center justify-center rounded-sm opacity-70 [transition:opacity_150ms,background-color_150ms,scale_300ms_var(--ease-spring)] hover:bg-black/5 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current/20 active:scale-75 dark:hover:bg-white/10" @click="handleRemove">
41
- <HugeiconsIcon :icon="Cancel01Icon" class="size-3 transition-transform duration-300 ease-spring group-hover/remove:rotate-90" />
42
- </button>
43
- </div>
39
+ <!-- Remove button -->
40
+ <button type="button" :aria-label="resolvedRemoveLabel" class="group/remove inline-flex size-4 cursor-pointer items-center justify-center rounded-sm opacity-70 [transition:opacity_150ms,background-color_150ms,scale_300ms_var(--ease-spring)] hover:bg-black/5 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current/20 active:scale-75 dark:hover:bg-white/10" @click="handleRemove">
41
+ <HugeiconsIcon :icon="Cancel01Icon" class="size-3 transition-transform duration-300 ease-spring group-hover/remove:rotate-90" />
42
+ </button>
43
+ </div>
44
44
  </template>
@@ -11,66 +11,66 @@ const pendingAction = ref<'confirm' | 'cancel' | null>(null);
11
11
 
12
12
  // Run an action while showing a spinner on the button that triggered it
13
13
  const runAction = async (action: 'confirm' | 'cancel') => {
14
- // Ignore clicks while another action is still running
15
- if (pendingAction.value) {
16
- return;
17
- }
14
+ // Ignore clicks while another action is still running
15
+ if (pendingAction.value) {
16
+ return;
17
+ }
18
18
 
19
- pendingAction.value = action;
20
- try {
21
- await (action === 'confirm' ? confirmActiveDialog() : cancelActiveConfirmDialog());
22
- } finally {
23
- pendingAction.value = null;
24
- }
19
+ pendingAction.value = action;
20
+ try {
21
+ await (action === 'confirm' ? confirmActiveDialog() : cancelActiveConfirmDialog());
22
+ } finally {
23
+ pendingAction.value = null;
24
+ }
25
25
  };
26
26
 
27
27
  // Close the dialog when the shell requests it
28
28
  const handleOpenChange = (open: boolean) => {
29
- if (!open) {
30
- closeConfirmDialog();
31
- }
29
+ if (!open) {
30
+ closeConfirmDialog();
31
+ }
32
32
  };
33
33
  </script>
34
34
 
35
35
  <template>
36
- <!-- Dialog shell -->
37
- <AlertDialog :open="confirmDialogState.isOpen" @update:open="handleOpenChange">
38
- <!-- Dialog content -->
39
- <AlertDialogContent v-if="currentDialog">
40
- <div class="px-5 pb-5 pt-5 sm:px-6 sm:pb-4 sm:pt-6">
41
- <div class="flex flex-col gap-4 sm:flex-row sm:items-start">
42
- <!-- Dialog icon -->
43
- <div class="flex size-12 shrink-0 self-center items-center justify-center rounded border border-primary/30 bg-primary/10 sm:size-10 sm:self-start">
44
- <HugeiconsIcon v-if="currentDialog.options.icon" :icon="currentDialog.options.icon" :stroke-width="1.8" class="size-6 animate-uv-pop text-primary [animation-delay:140ms]" />
45
- <HugeiconsIcon v-else :icon="InformationCircleIcon" :stroke-width="1.8" class="size-6 animate-uv-pop text-primary [animation-delay:140ms]" />
46
- </div>
36
+ <!-- Dialog shell -->
37
+ <AlertDialog :open="confirmDialogState.isOpen" @update:open="handleOpenChange">
38
+ <!-- Dialog content -->
39
+ <AlertDialogContent v-if="currentDialog">
40
+ <div class="px-5 pb-5 pt-5 sm:px-6 sm:pb-4 sm:pt-6">
41
+ <div class="flex flex-col gap-4 sm:flex-row sm:items-start">
42
+ <!-- Dialog icon -->
43
+ <div class="flex size-12 shrink-0 self-center items-center justify-center rounded border border-primary/30 bg-primary/10 sm:size-10 sm:self-start">
44
+ <HugeiconsIcon v-if="currentDialog.options.icon" :icon="currentDialog.options.icon" :stroke-width="1.8" class="size-6 animate-uv-pop text-primary [animation-delay:140ms]" />
45
+ <HugeiconsIcon v-else :icon="InformationCircleIcon" :stroke-width="1.8" class="size-6 animate-uv-pop text-primary [animation-delay:140ms]" />
46
+ </div>
47
47
 
48
- <!-- Dialog header -->
49
- <AlertDialogHeader class="sm:pt-0">
50
- <AlertDialogTitle>
51
- {{ currentDialog.options.title }}
52
- </AlertDialogTitle>
53
- <AlertDialogDescription>
54
- {{ currentDialog.options.message }}
55
- </AlertDialogDescription>
56
- </AlertDialogHeader>
57
- </div>
58
- </div>
48
+ <!-- Dialog header -->
49
+ <AlertDialogHeader class="sm:pt-0">
50
+ <AlertDialogTitle>
51
+ {{ currentDialog.options.title }}
52
+ </AlertDialogTitle>
53
+ <AlertDialogDescription>
54
+ {{ currentDialog.options.message }}
55
+ </AlertDialogDescription>
56
+ </AlertDialogHeader>
57
+ </div>
58
+ </div>
59
59
 
60
- <!-- Dialog actions -->
61
- <AlertDialogFooter>
62
- <!-- Cancel button -->
63
- <Button :variant="currentDialog.options.cancelButtonType" :disabled="confirmDialogState.busy && pendingAction !== 'cancel'" :loading="pendingAction === 'cancel'" @click="runAction('cancel')">
64
- <HugeiconsIcon v-if="currentDialog.options.cancelButtonIcon" :icon="currentDialog.options.cancelButtonIcon" class="size-4" />
65
- {{ currentDialog.options.cancelText }}
66
- </Button>
60
+ <!-- Dialog actions -->
61
+ <AlertDialogFooter>
62
+ <!-- Cancel button -->
63
+ <Button :variant="currentDialog.options.cancelButtonType" :disabled="confirmDialogState.busy && pendingAction !== 'cancel'" :loading="pendingAction === 'cancel'" @click="runAction('cancel')">
64
+ <HugeiconsIcon v-if="currentDialog.options.cancelButtonIcon" :icon="currentDialog.options.cancelButtonIcon" class="size-4" />
65
+ {{ currentDialog.options.cancelText }}
66
+ </Button>
67
67
 
68
- <!-- Confirm button -->
69
- <Button :variant="currentDialog.options.confirmButtonType" :disabled="confirmDialogState.busy && pendingAction !== 'confirm'" :loading="pendingAction === 'confirm'" @click="runAction('confirm')">
70
- <HugeiconsIcon v-if="currentDialog.options.confirmButtonIcon" :icon="currentDialog.options.confirmButtonIcon" class="size-4" />
71
- {{ currentDialog.options.confirmText }}
72
- </Button>
73
- </AlertDialogFooter>
74
- </AlertDialogContent>
75
- </AlertDialog>
68
+ <!-- Confirm button -->
69
+ <Button :variant="currentDialog.options.confirmButtonType" :disabled="confirmDialogState.busy && pendingAction !== 'confirm'" :loading="pendingAction === 'confirm'" @click="runAction('confirm')">
70
+ <HugeiconsIcon v-if="currentDialog.options.confirmButtonIcon" :icon="currentDialog.options.confirmButtonIcon" class="size-4" />
71
+ {{ currentDialog.options.confirmText }}
72
+ </Button>
73
+ </AlertDialogFooter>
74
+ </AlertDialogContent>
75
+ </AlertDialog>
76
76
  </template>