@brumaombra/ui-vintage 0.7.8 → 0.7.10

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 (275) hide show
  1. package/README.md +308 -48
  2. package/module.mjs +1 -1
  3. package/package.json +2 -1
  4. package/src/components/background-grid/BackgroundGrid.vue +11 -2
  5. package/src/components/background-grid/index.ts +2 -2
  6. package/src/components/blog/AllPostsSection.vue +25 -9
  7. package/src/components/blog/BlogContentRenderer.vue +133 -0
  8. package/src/components/blog/BlogFAQSection.vue +8 -3
  9. package/src/components/blog/BlogHeaderSection.vue +14 -11
  10. package/src/components/blog/BlogInfoSection.vue +13 -11
  11. package/src/components/blog/BlogProgressBar.vue +77 -0
  12. package/src/components/blog/BlogSectionTitle.vue +5 -5
  13. package/src/components/blog/CategoriesList.vue +11 -3
  14. package/src/components/blog/CategoriesSection.vue +11 -3
  15. package/src/components/blog/CategoryCard.vue +10 -8
  16. package/src/components/blog/HeaderCarousel.vue +24 -15
  17. package/src/components/blog/PostCard.vue +16 -11
  18. package/src/components/blog/PostsList.vue +12 -3
  19. package/src/components/blog/SocialShareSidebar.vue +43 -41
  20. package/src/components/blog/TableOfContents.vue +29 -13
  21. package/src/components/blog/index.ts +1 -0
  22. package/src/components/busy-indicator/BusyIndicator.vue +2 -2
  23. package/src/components/busy-indicator/busy-indicator-state.ts +11 -12
  24. package/src/components/busy-indicator/index.ts +3 -3
  25. package/src/components/card-grid/CardGrid.vue +25 -11
  26. package/src/components/chip/Chip.vue +15 -15
  27. package/src/components/chip/index.ts +2 -2
  28. package/src/components/confirm-dialog/ConfirmDialog.vue +9 -9
  29. package/src/components/confirm-dialog/confirm-dialog-state.ts +15 -14
  30. package/src/components/confirm-dialog/index.ts +3 -12
  31. package/src/components/content/BlogList.vue +11 -8
  32. package/src/components/content/BlogTable.vue +18 -14
  33. package/src/components/content/ProseHr.vue +10 -7
  34. package/src/components/content/Terminal.vue +70 -0
  35. package/src/components/content/index.ts +2 -1
  36. package/src/components/dashboard-shell/DashboardShell.vue +43 -64
  37. package/src/components/dashboard-shell/index.ts +2 -2
  38. package/src/components/data-list/DataList.vue +11 -13
  39. package/src/components/data-list/DataListItem.vue +9 -11
  40. package/src/components/data-list/DataListLabel.vue +9 -11
  41. package/src/components/data-list/DataListText.vue +9 -11
  42. package/src/components/data-list/DataListValue.vue +9 -11
  43. package/src/components/data-list/index.ts +5 -5
  44. package/src/components/empty-state-card/EmptyStateCard.vue +21 -11
  45. package/src/components/error-page/ErrorPage.vue +24 -27
  46. package/src/components/error-page/index.ts +2 -2
  47. package/src/components/info-card/InfoCard.vue +17 -11
  48. package/src/components/landing/index.ts +6 -6
  49. package/src/components/landing/landing-content/LandingContent.vue +5 -7
  50. package/src/components/landing/landing-content/index.ts +2 -2
  51. package/src/components/landing/landing-footer/LandingFooter.vue +26 -29
  52. package/src/components/landing/landing-footer/index.ts +3 -3
  53. package/src/components/landing/landing-navbar/LandingNavbar.vue +51 -19
  54. package/src/components/landing/landing-navbar/index.ts +2 -2
  55. package/src/components/landing/landing-shell/LandingShell.vue +12 -15
  56. package/src/components/landing/landing-shell/index.ts +2 -2
  57. package/src/components/language-flag/LanguageFlag.vue +6 -5
  58. package/src/components/language-flag/index.ts +1 -0
  59. package/src/components/language-selector/LanguageSelector.vue +20 -21
  60. package/src/components/load-more-button/LoadMoreButton.vue +18 -14
  61. package/src/components/loading-state-card/LoadingStateCard.vue +13 -9
  62. package/src/components/message-dialog/MessageDialog.vue +19 -19
  63. package/src/components/message-dialog/index.ts +3 -11
  64. package/src/components/message-dialog/message-dialog-state.ts +12 -11
  65. package/src/components/message-toast/MessageToast.vue +16 -16
  66. package/src/components/message-toast/index.ts +2 -9
  67. package/src/components/message-toast/message-toast-state.ts +9 -9
  68. package/src/components/page-header/PageHeader.vue +8 -5
  69. package/src/components/progress-component/ProgressComponent.vue +13 -10
  70. package/src/components/single-value-card/SingleValueCard.vue +22 -19
  71. package/src/components/slider-form-component/SliderFormComponent.vue +11 -20
  72. package/src/components/slider-form-component/index.ts +2 -2
  73. package/src/components/switch-form-component/SwitchFormComponent.vue +7 -9
  74. package/src/components/switch-form-component/index.ts +2 -2
  75. package/src/components/text-link/TextLink.vue +11 -7
  76. package/src/components/ui/accordion/Accordion.vue +10 -13
  77. package/src/components/ui/accordion/index.ts +1 -1
  78. package/src/components/ui/alert/Alert.vue +11 -10
  79. package/src/components/ui/alert/AlertDescription.vue +9 -8
  80. package/src/components/ui/alert/AlertTitle.vue +9 -8
  81. package/src/components/ui/alert/index.ts +10 -10
  82. package/src/components/ui/alert-dialog/AlertDialog.vue +13 -9
  83. package/src/components/ui/alert-dialog/AlertDialogAction.vue +14 -12
  84. package/src/components/ui/alert-dialog/AlertDialogCancel.vue +14 -16
  85. package/src/components/ui/alert-dialog/AlertDialogContent.vue +24 -27
  86. package/src/components/ui/alert-dialog/AlertDialogDescription.vue +13 -13
  87. package/src/components/ui/alert-dialog/AlertDialogFooter.vue +9 -12
  88. package/src/components/ui/alert-dialog/AlertDialogHeader.vue +9 -8
  89. package/src/components/ui/alert-dialog/AlertDialogTitle.vue +13 -11
  90. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +8 -7
  91. package/src/components/ui/alert-dialog/index.ts +9 -9
  92. package/src/components/ui/badge/Badge.vue +11 -12
  93. package/src/components/ui/badge/index.ts +1 -1
  94. package/src/components/ui/breadcrumb/Breadcrumb.vue +9 -12
  95. package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +15 -19
  96. package/src/components/ui/breadcrumb/BreadcrumbItem.vue +10 -12
  97. package/src/components/ui/breadcrumb/BreadcrumbLink.vue +13 -17
  98. package/src/components/ui/breadcrumb/BreadcrumbList.vue +10 -12
  99. package/src/components/ui/breadcrumb/BreadcrumbPage.vue +10 -15
  100. package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +14 -18
  101. package/src/components/ui/breadcrumb/index.ts +7 -7
  102. package/src/components/ui/busy/Busy.vue +36 -29
  103. package/src/components/ui/busy/index.ts +1 -1
  104. package/src/components/ui/button/Button.vue +18 -19
  105. package/src/components/ui/button/index.ts +54 -35
  106. package/src/components/ui/calendar/Calendar.vue +167 -121
  107. package/src/components/ui/calendar/CalendarCell.vue +18 -17
  108. package/src/components/ui/calendar/CalendarCellTrigger.vue +31 -33
  109. package/src/components/ui/calendar/CalendarGrid.vue +14 -17
  110. package/src/components/ui/calendar/CalendarGridBody.vue +9 -11
  111. package/src/components/ui/calendar/CalendarGridHead.vue +10 -12
  112. package/src/components/ui/calendar/CalendarGridRow.vue +14 -16
  113. package/src/components/ui/calendar/CalendarHeadCell.vue +18 -17
  114. package/src/components/ui/calendar/CalendarHeader.vue +18 -17
  115. package/src/components/ui/calendar/CalendarHeading.vue +18 -22
  116. package/src/components/ui/calendar/CalendarNextButton.vue +29 -26
  117. package/src/components/ui/calendar/CalendarPrevButton.vue +29 -26
  118. package/src/components/ui/calendar/index.ts +17 -13
  119. package/src/components/ui/card/Card.vue +21 -13
  120. package/src/components/ui/card/CardAction.vue +12 -7
  121. package/src/components/ui/card/CardContent.vue +8 -7
  122. package/src/components/ui/card/CardDescription.vue +16 -7
  123. package/src/components/ui/card/CardFooter.vue +8 -7
  124. package/src/components/ui/card/CardHeader.vue +12 -7
  125. package/src/components/ui/card/CardText.vue +12 -7
  126. package/src/components/ui/card/CardTitle.vue +9 -7
  127. package/src/components/ui/card/index.ts +8 -8
  128. package/src/components/ui/command/Command.vue +71 -61
  129. package/src/components/ui/command/CommandDialog.vue +33 -23
  130. package/src/components/ui/command/CommandEmpty.vue +19 -20
  131. package/src/components/ui/command/CommandGroup.vue +32 -35
  132. package/src/components/ui/command/CommandInput.vue +25 -21
  133. package/src/components/ui/command/CommandItem.vue +62 -59
  134. package/src/components/ui/command/CommandList.vue +21 -18
  135. package/src/components/ui/command/CommandSeparator.vue +13 -11
  136. package/src/components/ui/command/CommandShortcut.vue +13 -8
  137. package/src/components/ui/command/index.ts +24 -20
  138. package/src/components/ui/date-picker/DatePicker.vue +46 -37
  139. package/src/components/ui/date-picker/index.ts +2 -2
  140. package/src/components/ui/date-time-picker/DateTimePicker.vue +99 -95
  141. package/src/components/ui/date-time-picker/index.ts +2 -2
  142. package/src/components/ui/dialog/Dialog.vue +12 -9
  143. package/src/components/ui/dialog/DialogClose.vue +8 -10
  144. package/src/components/ui/dialog/DialogContent.vue +36 -42
  145. package/src/components/ui/dialog/DialogDescription.vue +16 -11
  146. package/src/components/ui/dialog/DialogFooter.vue +13 -12
  147. package/src/components/ui/dialog/DialogHeader.vue +9 -8
  148. package/src/components/ui/dialog/DialogOverlay.vue +16 -11
  149. package/src/components/ui/dialog/DialogScrollContent.vue +47 -45
  150. package/src/components/ui/dialog/DialogTitle.vue +13 -12
  151. package/src/components/ui/dialog/DialogTrigger.vue +8 -7
  152. package/src/components/ui/dialog/index.ts +10 -10
  153. package/src/components/ui/field/Field.vue +12 -14
  154. package/src/components/ui/field/FieldContent.vue +13 -11
  155. package/src/components/ui/field/FieldDescription.vue +15 -13
  156. package/src/components/ui/field/FieldError.vue +43 -40
  157. package/src/components/ui/field/FieldGroup.vue +13 -11
  158. package/src/components/ui/field/FieldLabel.vue +16 -14
  159. package/src/components/ui/field/FieldLegend.vue +16 -14
  160. package/src/components/ui/field/FieldSeparator.vue +17 -15
  161. package/src/components/ui/field/FieldSet.vue +14 -12
  162. package/src/components/ui/field/FieldTitle.vue +13 -11
  163. package/src/components/ui/field/index.ts +36 -36
  164. package/src/components/ui/input/Input.vue +23 -20
  165. package/src/components/ui/input/index.ts +1 -1
  166. package/src/components/ui/label/Label.vue +16 -15
  167. package/src/components/ui/label/index.ts +1 -1
  168. package/src/components/ui/native-select/NativeSelect.vue +31 -41
  169. package/src/components/ui/native-select/NativeSelectOptGroup.vue +8 -7
  170. package/src/components/ui/native-select/NativeSelectOption.vue +8 -7
  171. package/src/components/ui/native-select/index.ts +3 -3
  172. package/src/components/ui/popover/Popover.vue +12 -9
  173. package/src/components/ui/popover/PopoverAnchor.vue +8 -7
  174. package/src/components/ui/popover/PopoverContent.vue +27 -31
  175. package/src/components/ui/popover/PopoverTrigger.vue +8 -7
  176. package/src/components/ui/popover/index.ts +4 -4
  177. package/src/components/ui/progress/Progress.vue +18 -32
  178. package/src/components/ui/progress/index.ts +1 -1
  179. package/src/components/ui/scroll-area/ScrollArea.vue +23 -26
  180. package/src/components/ui/scroll-area/ScrollBar.vue +22 -26
  181. package/src/components/ui/scroll-area/index.ts +2 -2
  182. package/src/components/ui/select/Select.vue +12 -9
  183. package/src/components/ui/select/SelectContent.vue +39 -40
  184. package/src/components/ui/select/SelectGroup.vue +8 -7
  185. package/src/components/ui/select/SelectItem.vue +36 -41
  186. package/src/components/ui/select/SelectItemContent.vue +22 -15
  187. package/src/components/ui/select/SelectItemText.vue +8 -7
  188. package/src/components/ui/select/SelectLabel.vue +10 -9
  189. package/src/components/ui/select/SelectScrollDownButton.vue +21 -17
  190. package/src/components/ui/select/SelectScrollUpButton.vue +21 -17
  191. package/src/components/ui/select/SelectSeparator.vue +11 -9
  192. package/src/components/ui/select/SelectTrigger.vue +27 -25
  193. package/src/components/ui/select/SelectValue.vue +8 -7
  194. package/src/components/ui/select/SelectValueContent.vue +30 -18
  195. package/src/components/ui/select/index.ts +13 -13
  196. package/src/components/ui/separator/Separator.vue +17 -18
  197. package/src/components/ui/separator/index.ts +1 -1
  198. package/src/components/ui/sheet/Sheet.vue +12 -9
  199. package/src/components/ui/sheet/SheetClose.vue +8 -7
  200. package/src/components/ui/sheet/SheetContent.vue +36 -37
  201. package/src/components/ui/sheet/SheetDescription.vue +12 -11
  202. package/src/components/ui/sheet/SheetFooter.vue +8 -7
  203. package/src/components/ui/sheet/SheetHeader.vue +8 -7
  204. package/src/components/ui/sheet/SheetOverlay.vue +16 -11
  205. package/src/components/ui/sheet/SheetTitle.vue +12 -11
  206. package/src/components/ui/sheet/SheetTrigger.vue +8 -7
  207. package/src/components/ui/sheet/index.ts +8 -8
  208. package/src/components/ui/sidebar/Sidebar.vue +68 -61
  209. package/src/components/ui/sidebar/SidebarContent.vue +13 -8
  210. package/src/components/ui/sidebar/SidebarFooter.vue +13 -8
  211. package/src/components/ui/sidebar/SidebarGroup.vue +13 -8
  212. package/src/components/ui/sidebar/SidebarGroupAction.vue +16 -16
  213. package/src/components/ui/sidebar/SidebarGroupContent.vue +9 -8
  214. package/src/components/ui/sidebar/SidebarGroupLabel.vue +15 -14
  215. package/src/components/ui/sidebar/SidebarHeader.vue +13 -8
  216. package/src/components/ui/sidebar/SidebarInput.vue +14 -12
  217. package/src/components/ui/sidebar/SidebarInset.vue +14 -12
  218. package/src/components/ui/sidebar/SidebarMenu.vue +9 -8
  219. package/src/components/ui/sidebar/SidebarMenuAction.vue +25 -23
  220. package/src/components/ui/sidebar/SidebarMenuBadge.vue +19 -17
  221. package/src/components/ui/sidebar/SidebarMenuButton.vue +33 -32
  222. package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +19 -18
  223. package/src/components/ui/sidebar/SidebarMenuItem.vue +9 -8
  224. package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +17 -12
  225. package/src/components/ui/sidebar/SidebarMenuSub.vue +14 -12
  226. package/src/components/ui/sidebar/SidebarMenuSubButton.vue +24 -21
  227. package/src/components/ui/sidebar/SidebarMenuSubItem.vue +9 -8
  228. package/src/components/ui/sidebar/SidebarProvider.vue +63 -53
  229. package/src/components/ui/sidebar/SidebarRail.vue +20 -18
  230. package/src/components/ui/sidebar/SidebarSeparator.vue +10 -9
  231. package/src/components/ui/sidebar/SidebarTrigger.vue +15 -14
  232. package/src/components/ui/sidebar/index.ts +62 -58
  233. package/src/components/ui/sidebar/utils.ts +16 -16
  234. package/src/components/ui/skeleton/Skeleton.vue +12 -9
  235. package/src/components/ui/skeleton/index.ts +1 -1
  236. package/src/components/ui/slider/Slider.vue +24 -19
  237. package/src/components/ui/slider/index.ts +1 -1
  238. package/src/components/ui/switch/Switch.vue +26 -23
  239. package/src/components/ui/switch/index.ts +1 -1
  240. package/src/components/ui/table/Table.vue +11 -10
  241. package/src/components/ui/table/TableBody.vue +9 -11
  242. package/src/components/ui/table/TableCaption.vue +9 -11
  243. package/src/components/ui/table/TableCell.vue +13 -16
  244. package/src/components/ui/table/TableEmpty.vue +22 -25
  245. package/src/components/ui/table/TableFooter.vue +13 -11
  246. package/src/components/ui/table/TableHead.vue +13 -11
  247. package/src/components/ui/table/TableHeader.vue +9 -11
  248. package/src/components/ui/table/TableRow.vue +13 -11
  249. package/src/components/ui/table/index.ts +9 -9
  250. package/src/components/ui/tabs/Tabs.vue +18 -18
  251. package/src/components/ui/tabs/TabsContent.vue +14 -15
  252. package/src/components/ui/tabs/TabsList.vue +18 -18
  253. package/src/components/ui/tabs/TabsTrigger.vue +19 -20
  254. package/src/components/ui/tabs/index.ts +4 -4
  255. package/src/components/ui/textarea/Textarea.vue +23 -20
  256. package/src/components/ui/textarea/index.ts +1 -1
  257. package/src/components/ui/time-picker/TimePicker.vue +33 -38
  258. package/src/components/ui/time-picker/index.ts +2 -2
  259. package/src/components/ui/tooltip/Tooltip.vue +12 -9
  260. package/src/components/ui/tooltip/TooltipContent.vue +28 -20
  261. package/src/components/ui/tooltip/TooltipProvider.vue +9 -8
  262. package/src/components/ui/tooltip/TooltipTrigger.vue +8 -7
  263. package/src/components/ui/tooltip/index.ts +4 -4
  264. package/src/i18n/de.json +5 -0
  265. package/src/i18n/en.json +5 -0
  266. package/src/i18n/es.json +5 -0
  267. package/src/i18n/fr.json +5 -0
  268. package/src/i18n/it.json +5 -0
  269. package/src/i18n/ja.json +5 -0
  270. package/src/i18n/pt.json +5 -0
  271. package/src/i18n/ru.json +5 -0
  272. package/src/i18n/zh.json +5 -0
  273. package/src/lib/common-types.ts +2 -0
  274. package/src/lib/i18n.ts +0 -5
  275. package/src/runtime/{ui-vintage-i18n-plugin.js → ui-vintage-i18n-plugin.ts} +30 -8
@@ -1,4 +1,5 @@
1
1
  export { default as AllPostsSection } from './AllPostsSection.vue';
2
+ export { default as BlogContentRenderer } from './BlogContentRenderer.vue';
2
3
  export { default as BlogFAQSection } from './BlogFAQSection.vue';
3
4
  export { default as BlogInfoSection } from './BlogInfoSection.vue';
4
5
  export { default as BlogHeaderSection } from './BlogHeaderSection.vue';
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { Busy } from "../ui/busy";
3
- import { busyIndicatorState } from "./busy-indicator-state";
2
+ import { Busy } from '../ui/busy';
3
+ import { busyIndicatorState } from './busy-indicator-state';
4
4
  </script>
5
5
 
6
6
  <template>
@@ -1,27 +1,26 @@
1
- import { h, reactive, render } from "vue";
2
- import type { HTMLAttributes } from "vue";
1
+ import { h, reactive, render, type HTMLAttributes } from 'vue';
3
2
 
4
3
  export interface SetBusyOptions {
5
4
  label?: string;
6
- class?: HTMLAttributes["class"];
7
- overlayClass?: HTMLAttributes["class"];
5
+ class?: HTMLAttributes['class'];
6
+ overlayClass?: HTMLAttributes['class'];
8
7
  }
9
8
 
10
9
  interface BusyIndicatorState {
11
10
  show: boolean;
12
11
  label: string;
13
- class: HTMLAttributes["class"];
14
- overlayClass: HTMLAttributes["class"];
12
+ class: HTMLAttributes['class'];
13
+ overlayClass: HTMLAttributes['class'];
15
14
  }
16
15
 
17
- const BUSY_INDICATOR_ROOT_ID = "ui-vintage-busy-indicator-root";
16
+ const BUSY_INDICATOR_ROOT_ID = 'ui-vintage-busy-indicator-root';
18
17
 
19
18
  let busyIndicatorMountPromise: Promise<void> | null = null;
20
19
 
21
20
  // Shared busy state
22
21
  export const busyIndicatorState: BusyIndicatorState = reactive({
23
22
  show: false,
24
- label: "Loading...",
23
+ label: 'Loading...',
25
24
  class: undefined,
26
25
  overlayClass: undefined
27
26
  });
@@ -29,7 +28,7 @@ export const busyIndicatorState: BusyIndicatorState = reactive({
29
28
  // Mount the busy indicator once on demand
30
29
  const ensureBusyIndicatorMounted = () => {
31
30
  // Skip mounting during SSR
32
- if (typeof document === "undefined") {
31
+ if (typeof document === 'undefined') {
33
32
  return Promise.resolve();
34
33
  }
35
34
 
@@ -47,7 +46,7 @@ const ensureBusyIndicatorMounted = () => {
47
46
  // Start the lazy mount
48
47
  busyIndicatorMountPromise = (async () => {
49
48
  // Load the component only when needed
50
- const { default: BusyIndicator } = await import("./BusyIndicator.vue");
49
+ const { default: BusyIndicator } = await import('./BusyIndicator.vue');
51
50
 
52
51
  // Guard against a concurrent mount
53
52
  if (document.getElementById(BUSY_INDICATOR_ROOT_ID)) {
@@ -55,7 +54,7 @@ const ensureBusyIndicatorMounted = () => {
55
54
  }
56
55
 
57
56
  // Create the host element and render the component
58
- const container = document.createElement("div");
57
+ const container = document.createElement('div');
59
58
  container.id = BUSY_INDICATOR_ROOT_ID;
60
59
  document.body.appendChild(container);
61
60
  render(h(BusyIndicator), container);
@@ -71,7 +70,7 @@ const ensureBusyIndicatorMounted = () => {
71
70
  export const setBusy = (show: boolean, options: SetBusyOptions = {}) => {
72
71
  // Prepare the overlay before showing it
73
72
  if (show) {
74
- busyIndicatorState.label = options.label ?? busyIndicatorState.label ?? "Loading...";
73
+ busyIndicatorState.label = options.label ?? busyIndicatorState.label ?? 'Loading...';
75
74
  busyIndicatorState.class = options.class;
76
75
  busyIndicatorState.overlayClass = options.overlayClass;
77
76
  void ensureBusyIndicatorMounted();
@@ -1,3 +1,3 @@
1
- export { default as BusyIndicator } from "./BusyIndicator.vue";
2
- export { busyIndicatorState, setBusy } from "./busy-indicator-state";
3
- export type { SetBusyOptions } from "./busy-indicator-state";
1
+ export { default as BusyIndicator } from './BusyIndicator.vue';
2
+ export { busyIndicatorState, setBusy } from './busy-indicator-state';
3
+ export type { SetBusyOptions } from './busy-indicator-state';
@@ -1,21 +1,35 @@
1
- <script setup lang="ts">
1
+ <script setup lang="ts" generic="T extends { id: PropertyKey }">
2
2
  import { PackageIcon } from '@hugeicons/core-free-icons';
3
3
  import { EmptyStateCard } from '../empty-state-card';
4
4
  import { LoadMoreButton } from '../load-more-button';
5
5
  import { LoadingStateCard } from '../loading-state-card';
6
+ import type { HugeiconsIconDefinition } from '../../lib/common-types';
6
7
 
7
8
  // Props
8
- const props = defineProps({
9
- items: { type: Array, default: () => [] },
10
- busy: { type: Boolean, default: false },
11
- loadMoreBusy: { type: Boolean, default: false },
12
- hasMore: { type: Boolean, default: false },
13
- emptyMessage: { type: String, required: true },
14
- emptyIcon: { type: Object, default: () => PackageIcon }
9
+ const props = withDefaults(defineProps<{
10
+ items?: T[];
11
+ busy?: boolean;
12
+ loadMoreBusy?: boolean;
13
+ hasMore?: boolean;
14
+ emptyMessage: string;
15
+ emptyIcon?: HugeiconsIconDefinition;
16
+ }>(), {
17
+ items: () => [],
18
+ busy: false,
19
+ loadMoreBusy: false,
20
+ hasMore: false,
21
+ emptyIcon: () => PackageIcon
15
22
  });
16
23
 
17
24
  // Emits
18
- const emits = defineEmits(['load-more']);
25
+ const emits = defineEmits<{
26
+ 'load-more': [];
27
+ }>();
28
+
29
+ // Slots
30
+ defineSlots<{
31
+ card(props: { item: T; key?: PropertyKey }): unknown;
32
+ }>();
19
33
 
20
34
  // Handle load more
21
35
  const handleLoadMore = () => {
@@ -29,13 +43,13 @@ const handleLoadMore = () => {
29
43
  <LoadingStateCard v-if="props.busy" />
30
44
 
31
45
  <!-- Empty state -->
32
- <EmptyStateCard v-else-if="!props.items || props.items.length === 0"
46
+ <EmptyStateCard v-else-if="props.items.length === 0"
33
47
  :description="props.emptyMessage"
34
48
  :icon="props.emptyIcon" />
35
49
 
36
50
  <!-- Cards grid -->
37
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">
38
- <slot name="card" v-for="item in props.items" :item="item" :key="(item as any).id" />
52
+ <slot name="card" v-for="item in props.items" :item="item" :key="item.id" />
39
53
  </div>
40
54
 
41
55
  <!-- Load more button -->
@@ -1,30 +1,30 @@
1
1
  <script setup lang="ts">
2
- import { Cancel01Icon } from "@hugeicons/core-free-icons"
3
- import { HugeiconsIcon } from "@hugeicons/vue"
4
- import type { HTMLAttributes } from "vue"
5
- import { getSurfaceToneClasses, type ToneColor } from "../../lib/color-tokens"
6
- import { cn } from "../../lib/utils"
2
+ import { Cancel01Icon } from '@hugeicons/core-free-icons';
3
+ import { HugeiconsIcon } from '@hugeicons/vue';
4
+ import type { HTMLAttributes } from 'vue';
5
+ import { getSurfaceToneClasses, type ToneColor } from '../../lib/color-tokens';
6
+ import { cn } from '../../lib/utils';
7
7
 
8
8
  // Props
9
9
  const props = withDefaults(defineProps<{
10
- text: string
11
- color?: ToneColor
12
- removeLabel?: string
13
- class?: HTMLAttributes["class"]
10
+ text: string;
11
+ color?: ToneColor;
12
+ removeLabel?: string;
13
+ class?: HTMLAttributes['class'];
14
14
  }>(), {
15
- color: "gray",
16
- removeLabel: "Remove"
17
- })
15
+ color: 'gray',
16
+ removeLabel: 'Remove'
17
+ });
18
18
 
19
19
  // Emits
20
20
  const emits = defineEmits<{
21
21
  remove: []
22
- }>()
22
+ }>();
23
23
 
24
24
  // Handle remove button click
25
25
  const handleRemove = () => {
26
- emits("remove")
27
- }
26
+ emits('remove');
27
+ };
28
28
  </script>
29
29
 
30
30
  <template>
@@ -1,2 +1,2 @@
1
- export { default } from "./Chip.vue"
2
- export { default as Chip } from "./Chip.vue"
1
+ export { default } from './Chip.vue';
2
+ export { default as Chip } from './Chip.vue';
@@ -1,10 +1,10 @@
1
1
  <script setup lang="ts">
2
- import { HugeiconsIcon } from "@hugeicons/vue";
3
- import { computed } from "vue";
4
- import { InformationCircleIcon } from "@hugeicons/core-free-icons";
5
- import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "../ui/alert-dialog";
6
- import { Button } from "../ui/button";
7
- import { cancelActiveConfirmDialog, closeConfirmDialog, confirmActiveDialog, confirmDialogState } from "./confirm-dialog-state";
2
+ import { HugeiconsIcon } from '@hugeicons/vue';
3
+ import { computed } from 'vue';
4
+ import { InformationCircleIcon } from '@hugeicons/core-free-icons';
5
+ import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '../ui/alert-dialog';
6
+ import { Button } from '../ui/button';
7
+ import { cancelActiveConfirmDialog, closeConfirmDialog, confirmActiveDialog, confirmDialogState } from './confirm-dialog-state';
8
8
 
9
9
  const currentDialog = computed(() => confirmDialogState.current);
10
10
 
@@ -24,9 +24,9 @@ const handleOpenChange = (open: boolean) => {
24
24
  <div class="px-5 pb-5 pt-5 sm:px-6 sm:pb-4 sm:pt-6">
25
25
  <div class="flex flex-col gap-4 sm:flex-row sm:items-start">
26
26
  <!-- Dialog icon -->
27
- <div class="flex size-12 shrink-0 self-center items-center justify-center rounded border border-[var(--border-light)] bg-[var(--bg-surface-light)] sm:size-10 sm:self-start dark:border-[var(--border-dark)] dark:bg-[var(--bg-surface-dark)]">
28
- <HugeiconsIcon v-if="currentDialog.options.icon" :icon="currentDialog.options.icon" :stroke-width="1.8" class="size-6 text-[var(--button-primary-light)] dark:text-[var(--button-primary-dark)]" />
29
- <HugeiconsIcon v-else :icon="InformationCircleIcon" :stroke-width="1.8" class="size-6 text-[var(--button-primary-light)] dark:text-[var(--button-primary-dark)]" />
27
+ <div class="flex size-12 shrink-0 self-center items-center justify-center rounded border border-(--border-light) bg-(--bg-surface-light) sm:size-10 sm:self-start dark:border-(--border-dark) dark:bg-(--bg-surface-dark)">
28
+ <HugeiconsIcon v-if="currentDialog.options.icon" :icon="currentDialog.options.icon" :stroke-width="1.8" class="size-6 text-(--button-primary-light) dark:text-(--button-primary-dark)" />
29
+ <HugeiconsIcon v-else :icon="InformationCircleIcon" :stroke-width="1.8" class="size-6 text-(--button-primary-light) dark:text-(--button-primary-dark)" />
30
30
  </div>
31
31
 
32
32
  <!-- Dialog header -->
@@ -1,8 +1,9 @@
1
- import { h, markRaw, reactive, render } from "vue";
2
- import type { ButtonVariants } from "../ui/button";
1
+ import { h, markRaw, reactive, render } from 'vue';
2
+ import type { ButtonVariants } from '../ui/button';
3
+ import type { HugeiconsIconDefinition } from '../../lib/common-types';
3
4
 
4
- export type DialogButtonVariant = NonNullable<ButtonVariants["variant"]>;
5
- export type HugeiconsIconDefinition = readonly (readonly [string, { readonly [key: string]: string | number }])[];
5
+ export type DialogButtonVariant = NonNullable<ButtonVariants['variant']>;
6
+ export type { HugeiconsIconDefinition };
6
7
 
7
8
  export interface ShowConfirmDialogOptions {
8
9
  title?: string;
@@ -20,7 +21,7 @@ export interface ShowConfirmDialogOptions {
20
21
 
21
22
  interface ConfirmDialogRequest {
22
23
  id: number;
23
- options: Required<Omit<ShowConfirmDialogOptions, "icon" | "confirmButtonIcon" | "cancelButtonIcon" | "onConfirm" | "onCancel">> & {
24
+ options: Required<Omit<ShowConfirmDialogOptions, 'icon' | 'confirmButtonIcon' | 'cancelButtonIcon' | 'onConfirm' | 'onCancel'>> & {
24
25
  icon: HugeiconsIconDefinition | null;
25
26
  confirmButtonIcon: HugeiconsIconDefinition | null;
26
27
  cancelButtonIcon: HugeiconsIconDefinition | null;
@@ -42,7 +43,7 @@ const DIALOG_CLOSE_DURATION_MS = 300;
42
43
  let closeTimer: ReturnType<typeof setTimeout> | null = null;
43
44
  let confirmDialogMountPromise: Promise<void> | null = null;
44
45
 
45
- const CONFIRM_DIALOG_ROOT_ID = "ui-vintage-confirm-dialog-root";
46
+ const CONFIRM_DIALOG_ROOT_ID = 'ui-vintage-confirm-dialog-root';
46
47
 
47
48
  // Shared confirm dialog state
48
49
  export const confirmDialogState: ConfirmDialogState = reactive({
@@ -57,7 +58,7 @@ const markIcon = (icon: HugeiconsIconDefinition | null | undefined) => icon ? ma
57
58
  // Mount the dialog once on demand
58
59
  const ensureConfirmDialogMounted = () => {
59
60
  // Skip mounting during SSR
60
- if (typeof document === "undefined") {
61
+ if (typeof document === 'undefined') {
61
62
  return Promise.resolve();
62
63
  }
63
64
 
@@ -75,7 +76,7 @@ const ensureConfirmDialogMounted = () => {
75
76
  // Start the lazy mount
76
77
  confirmDialogMountPromise = (async () => {
77
78
  // Load the component only when needed
78
- const { default: ConfirmDialog } = await import("./ConfirmDialog.vue");
79
+ const { default: ConfirmDialog } = await import('./ConfirmDialog.vue');
79
80
 
80
81
  // Guard against a concurrent mount
81
82
  if (document.getElementById(CONFIRM_DIALOG_ROOT_ID)) {
@@ -83,7 +84,7 @@ const ensureConfirmDialogMounted = () => {
83
84
  }
84
85
 
85
86
  // Create the host element and render the component
86
- const container = document.createElement("div");
87
+ const container = document.createElement('div');
87
88
  container.id = CONFIRM_DIALOG_ROOT_ID;
88
89
  document.body.appendChild(container);
89
90
  render(h(ConfirmDialog), container);
@@ -182,12 +183,12 @@ export const showConfirmDialog = (options: ShowConfirmDialogOptions) => {
182
183
  enqueueConfirmDialog({
183
184
  id: nextConfirmDialogId += 1,
184
185
  options: {
185
- title: options.title ?? "Confirm",
186
+ title: options.title ?? 'Confirm',
186
187
  message: options.message,
187
- confirmText: options.confirmText ?? "Confirm",
188
- cancelText: options.cancelText ?? "Cancel",
189
- confirmButtonType: options.confirmButtonType ?? "primary",
190
- cancelButtonType: options.cancelButtonType ?? "secondary",
188
+ confirmText: options.confirmText ?? 'Confirm',
189
+ cancelText: options.cancelText ?? 'Cancel',
190
+ confirmButtonType: options.confirmButtonType ?? 'primary',
191
+ cancelButtonType: options.cancelButtonType ?? 'secondary',
191
192
  icon: markIcon(options.icon),
192
193
  confirmButtonIcon: markIcon(options.confirmButtonIcon),
193
194
  cancelButtonIcon: markIcon(options.cancelButtonIcon),
@@ -1,12 +1,3 @@
1
- export { default as ConfirmDialog } from "./ConfirmDialog.vue";
2
- export {
3
- cancelActiveConfirmDialog,
4
- closeConfirmDialog,
5
- confirmActiveDialog,
6
- confirmDialogState,
7
- showConfirmDialog
8
- } from "./confirm-dialog-state";
9
- export type {
10
- DialogButtonVariant,
11
- ShowConfirmDialogOptions
12
- } from "./confirm-dialog-state";
1
+ export { default as ConfirmDialog } from './ConfirmDialog.vue';
2
+ export { cancelActiveConfirmDialog, closeConfirmDialog, confirmActiveDialog, confirmDialogState, showConfirmDialog } from './confirm-dialog-state';
3
+ export type { DialogButtonVariant, ShowConfirmDialogOptions } from './confirm-dialog-state';
@@ -1,22 +1,25 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { Cancel01Icon, CheckmarkCircle02Icon, CircleSmallIcon } from '@hugeicons/core-free-icons';
3
3
  import { HugeiconsIcon } from '@hugeicons/vue';
4
4
  import { Card, CardContent } from '../ui/card';
5
5
 
6
6
  // Props
7
- const props = defineProps({
8
- items: { type: Array, default: () => [] },
9
- variant: { type: String, default: 'checkmark', validator: value => ['circle', 'checkmark', 'numbered', 'cross'].includes(value) }
7
+ const props = withDefaults(defineProps<{
8
+ items?: string[];
9
+ variant?: 'circle' | 'checkmark' | 'numbered' | 'cross';
10
+ }>(), {
11
+ items: () => [],
12
+ variant: 'checkmark'
10
13
  });
11
14
 
12
15
  // Icon container classes
13
16
  const getIconContainerClasses = () => {
14
- return 'flex items-center justify-center w-8 h-8 bg-[var(--bg-card-light)] dark:bg-[var(--bg-card-dark)] border border-[var(--border-light)] dark:border-[var(--border-dark)] rounded mr-4 flex-shrink-0';
17
+ return 'flex items-center justify-center w-8 h-8 bg-(--bg-card-light) dark:bg-(--bg-card-dark) border border-(--border-light) dark:border-(--border-dark) rounded mr-4 shrink-0';
15
18
  };
16
19
 
17
20
  // Icon color classes
18
21
  const getIconClasses = () => {
19
- return 'text-[var(--text-secondary-light)] dark:text-[var(--text-secondary-dark)] text-xs';
22
+ return 'text-(--text-secondary-light) dark:text-(--text-secondary-dark) text-xs';
20
23
  };
21
24
  </script>
22
25
 
@@ -24,7 +27,7 @@ const getIconClasses = () => {
24
27
  <div class="not-prose my-6 sm:my-12">
25
28
  <Card>
26
29
  <CardContent class="gap-0">
27
- <ul class="text-xs md:text-sm !p-0 !space-y-6">
30
+ <ul class="text-xs md:text-sm p-0! space-y-6!">
28
31
  <li v-for="(item, index) in props.items" :key="index" class="flex items-center">
29
32
  <!-- Circle -->
30
33
  <div v-if="props.variant === 'circle'" :class="getIconContainerClasses()">
@@ -48,7 +51,7 @@ const getIconClasses = () => {
48
51
 
49
52
  <!-- Content -->
50
53
  <div class="flex-1">
51
- <div class="text-[var(--text-primary-light)] dark:text-[var(--text-primary-dark)] leading-relaxed">
54
+ <div class="text-(--text-primary-light) dark:text-(--text-primary-dark) leading-relaxed">
52
55
  {{ item }}
53
56
  </div>
54
57
  </div>
@@ -1,26 +1,30 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { Card, CardContent } from '../ui/card';
3
3
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
4
4
 
5
5
  // Props
6
- const props = defineProps({
7
- headers: { type: Array, default: () => [] },
8
- rows: { type: Array, default: () => [] },
9
- highlightCol: { type: Number, default: -1 }
6
+ const props = withDefaults(defineProps<{
7
+ headers?: string[];
8
+ rows?: string[][];
9
+ highlightCol?: number;
10
+ }>(), {
11
+ headers: () => [],
12
+ rows: () => [],
13
+ highlightCol: -1
10
14
  });
11
15
 
12
16
  // Header cell classes
13
- const getHeaderClasses = colIndex => {
14
- const baseClasses = 'text-left font-semibold text-[var(--text-primary-light)] dark:text-[var(--text-primary-dark)]';
15
- const highlightClass = props.highlightCol === colIndex ? 'bg-[var(--bg-selected-light)] dark:bg-[var(--bg-selected-dark)]' : '';
17
+ const getHeaderClasses = (colIndex: number) => {
18
+ const baseClasses = 'text-left font-semibold text-(--text-primary-light) dark:text-(--text-primary-dark)';
19
+ const highlightClass = props.highlightCol === colIndex ? 'bg-(--bg-selected-light) dark:bg-(--bg-selected-dark)' : '';
16
20
  return [baseClasses, highlightClass];
17
21
  };
18
22
 
19
23
  // Body cell classes
20
- const getCellClasses = colIndex => {
21
- const baseClasses = 'align-top text-[var(--text-primary-light)] dark:text-[var(--text-primary-dark)] leading-relaxed whitespace-normal';
22
- const firstColClass = colIndex === 0 ? 'font-semibold text-[var(--text-secondary-light)] dark:text-[var(--text-secondary-dark)]' : '';
23
- const highlightClass = props.highlightCol === colIndex ? 'bg-[var(--bg-selected-light)] dark:bg-[var(--bg-selected-dark)]' : '';
24
+ const getCellClasses = (colIndex: number) => {
25
+ const baseClasses = 'align-top text-(--text-primary-light) dark:text-(--text-primary-dark) leading-relaxed whitespace-normal';
26
+ const firstColClass = colIndex === 0 ? 'font-semibold text-(--text-secondary-light) dark:text-(--text-secondary-dark)' : '';
27
+ const highlightClass = props.highlightCol === colIndex ? 'bg-(--bg-selected-light) dark:bg-(--bg-selected-dark)' : '';
24
28
  return [baseClasses, firstColClass, highlightClass];
25
29
  };
26
30
  </script>
@@ -33,7 +37,7 @@ const getCellClasses = colIndex => {
33
37
  <Table class="w-full text-sm text-left">
34
38
  <!-- Table header -->
35
39
  <TableHeader>
36
- <TableRow class="bg-transparent text-sm text-[var(--text-secondary-light)] dark:text-[var(--text-secondary-dark)] hover:bg-transparent">
40
+ <TableRow class="bg-transparent text-sm text-(--text-secondary-light) dark:text-(--text-secondary-dark) hover:bg-transparent">
37
41
  <TableHead v-for="(header, colIndex) in props.headers" :key="colIndex" :class="getHeaderClasses(colIndex)">
38
42
  {{ header }}
39
43
  </TableHead>
@@ -42,7 +46,7 @@ const getCellClasses = colIndex => {
42
46
 
43
47
  <!-- Table body -->
44
48
  <TableBody>
45
- <TableRow v-for="(row, rowIndex) in props.rows" :key="rowIndex" class="text-[var(--text-secondary-light)] dark:text-[var(--text-secondary-dark)] hover:bg-transparent">
49
+ <TableRow v-for="(row, rowIndex) in props.rows" :key="rowIndex" class="text-(--text-secondary-light) dark:text-(--text-secondary-dark) hover:bg-transparent">
46
50
  <TableCell v-for="(cell, colIndex) in row" :key="colIndex" :class="getCellClasses(colIndex)">
47
51
  {{ cell }}
48
52
  </TableCell>
@@ -1,10 +1,13 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { ChartLineData02Icon } from '@hugeicons/core-free-icons';
3
3
  import { HugeiconsIcon } from '@hugeicons/vue';
4
+ import type { HugeiconsIconDefinition } from '../../lib/common-types';
4
5
 
5
6
  // Props
6
- const props = defineProps({
7
- icon: { type: Object, default: () => ChartLineData02Icon }
7
+ const props = withDefaults(defineProps<{
8
+ icon?: HugeiconsIconDefinition;
9
+ }>(), {
10
+ icon: () => ChartLineData02Icon
8
11
  });
9
12
  </script>
10
13
 
@@ -12,15 +15,15 @@ const props = defineProps({
12
15
  <div aria-hidden="true" class="not-prose my-6 sm:my-12">
13
16
  <div class="flex items-center gap-3 sm:gap-4">
14
17
  <!-- Left line -->
15
- <div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--border-light)] to-[var(--border-light)] dark:via-[var(--border-dark)] dark:to-[var(--border-dark)]" />
18
+ <div class="h-px flex-1 bg-linear-to-r from-transparent via-(--border-light) to-(--border-light) dark:via-(--border-dark) dark:to-(--border-dark)" />
16
19
 
17
20
  <!-- Icon in the middle -->
18
- <div class="flex h-9 w-9 items-center justify-center rounded bg-[var(--bg-card-light)] dark:bg-[var(--bg-card-dark)] border border-[var(--border-light)] dark:border-[var(--border-dark)]">
19
- <HugeiconsIcon :icon="props.icon" class="size-4 text-[var(--text-secondary-light)] dark:text-[var(--text-secondary-dark)]" />
21
+ <div class="flex h-9 w-9 items-center justify-center rounded bg-(--bg-card-light) dark:bg-(--bg-card-dark) border border-(--border-light) dark:border-(--border-dark)">
22
+ <HugeiconsIcon :icon="props.icon" class="size-4 text-(--text-secondary-light) dark:text-(--text-secondary-dark)" />
20
23
  </div>
21
24
 
22
25
  <!-- Right line -->
23
- <div class="h-px flex-1 bg-gradient-to-l from-transparent via-[var(--border-light)] to-[var(--border-light)] dark:via-[var(--border-dark)] dark:to-[var(--border-dark)]" />
26
+ <div class="h-px flex-1 bg-linear-to-l from-transparent via-(--border-light) to-(--border-light) dark:via-(--border-dark) dark:to-(--border-dark)" />
24
27
  </div>
25
28
  </div>
26
29
  </template>
@@ -0,0 +1,70 @@
1
+ <script setup lang="ts">
2
+ import { CheckmarkCircle02Icon, Copy01Icon, TerminalIcon } from '@hugeicons/core-free-icons';
3
+ import { HugeiconsIcon } from '@hugeicons/vue';
4
+ import { computed, ref } from 'vue';
5
+ import { useI18n } from 'vue-i18n';
6
+ import { Button } from '../ui/button';
7
+ import { Card } from '../ui/card';
8
+
9
+ // Props
10
+ const props = withDefaults(defineProps<{
11
+ commands?: string[];
12
+ title?: string;
13
+ prompt?: string;
14
+ copyable?: boolean;
15
+ }>(), {
16
+ commands: () => [],
17
+ title: '',
18
+ prompt: '$',
19
+ copyable: true
20
+ });
21
+
22
+ const { t } = useI18n();
23
+ const copied = ref(false);
24
+ const commandText = computed(() => props.commands.join('\n'));
25
+ const resolvedTitle = computed(() => props.title || t('uiVintage.terminal.title'));
26
+
27
+ // Copy all command lines to the clipboard
28
+ const copyCommands = async () => {
29
+ // Check if copy is enabled
30
+ if (!props.copyable || !commandText.value || !navigator.clipboard) {
31
+ return;
32
+ }
33
+
34
+ // Copy the command text to the clipboard
35
+ await navigator.clipboard.writeText(commandText.value);
36
+ copied.value = true;
37
+ window.setTimeout(() => {
38
+ copied.value = false;
39
+ }, 1800);
40
+ };
41
+ </script>
42
+
43
+ <template>
44
+ <div class="not-prose my-6 sm:my-12">
45
+ <Card class="gap-0! sm:gap-0! overflow-hidden p-0! text-(--text-primary-light) dark:text-(--text-primary-dark)">
46
+ <!-- Terminal header -->
47
+ <div class="flex items-center justify-between gap-3 border-b border-(--border-light) bg-(--bg-card-light) px-3 py-2 sm:px-4 dark:border-(--border-dark) dark:bg-(--bg-card-dark)">
48
+ <div class="flex min-w-0 items-center gap-2">
49
+ <HugeiconsIcon :icon="TerminalIcon" class="size-4 shrink-0 text-(--text-secondary-light) dark:text-(--text-secondary-dark)" />
50
+ <span class="truncate text-xs font-semibold text-(--text-secondary-light) dark:text-(--text-secondary-dark)">{{ resolvedTitle }}</span>
51
+ </div>
52
+
53
+ <!-- Copy command button -->
54
+ <Button v-if="props.copyable"
55
+ variant="ghost"
56
+ size="icon"
57
+ class="size-7 text-(--text-secondary-light) hover:bg-(--bg-selected-light) hover:text-(--text-primary-light) dark:text-(--text-secondary-dark) dark:hover:bg-(--bg-selected-dark) dark:hover:text-(--text-primary-dark)"
58
+ :aria-label="t('uiVintage.terminal.copy')"
59
+ :title="t('uiVintage.terminal.copy')"
60
+ :disabled="!commandText"
61
+ @click="copyCommands">
62
+ <HugeiconsIcon :icon="copied ? CheckmarkCircle02Icon : Copy01Icon" class="size-4" />
63
+ </Button>
64
+ </div>
65
+
66
+ <!-- Terminal commands -->
67
+ <pre class="overflow-x-auto bg-(--bg-surface-light) px-4 py-3 text-xs leading-6 dark:bg-(--bg-surface-dark) sm:px-5 sm:py-4 sm:text-sm"><code><span v-for="(command, index) in props.commands" :key="`${command}-${index}`" class="flex min-w-max"><span class="mr-3 select-none text-(--text-secondary-light) dark:text-(--text-secondary-dark)" aria-hidden="true">{{ props.prompt }}</span><span>{{ command }}</span></span></code></pre>
68
+ </Card>
69
+ </div>
70
+ </template>
@@ -1,3 +1,4 @@
1
1
  export { default as BlogList } from './BlogList.vue';
2
2
  export { default as BlogTable } from './BlogTable.vue';
3
- export { default as ProseHr } from './ProseHr.vue';
3
+ export { default as ProseHr } from './ProseHr.vue';
4
+ export { default as Terminal } from './Terminal.vue';