@brumaombra/ui-vintage 0.7.8 → 0.7.9
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.
- package/README.md +308 -48
- package/module.mjs +1 -1
- package/package.json +2 -1
- package/src/components/background-grid/BackgroundGrid.vue +11 -2
- package/src/components/background-grid/index.ts +2 -2
- package/src/components/blog/AllPostsSection.vue +25 -9
- package/src/components/blog/BlogFAQSection.vue +8 -3
- package/src/components/blog/BlogHeaderSection.vue +14 -11
- package/src/components/blog/BlogInfoSection.vue +13 -11
- package/src/components/blog/BlogSectionTitle.vue +5 -5
- package/src/components/blog/CategoriesList.vue +11 -3
- package/src/components/blog/CategoriesSection.vue +11 -3
- package/src/components/blog/CategoryCard.vue +10 -8
- package/src/components/blog/HeaderCarousel.vue +24 -15
- package/src/components/blog/PostCard.vue +16 -11
- package/src/components/blog/PostsList.vue +12 -3
- package/src/components/blog/SocialShareSidebar.vue +11 -11
- package/src/components/blog/TableOfContents.vue +29 -13
- package/src/components/busy-indicator/BusyIndicator.vue +2 -2
- package/src/components/busy-indicator/busy-indicator-state.ts +11 -12
- package/src/components/busy-indicator/index.ts +3 -3
- package/src/components/card-grid/CardGrid.vue +25 -11
- package/src/components/chip/Chip.vue +15 -15
- package/src/components/chip/index.ts +2 -2
- package/src/components/confirm-dialog/ConfirmDialog.vue +9 -9
- package/src/components/confirm-dialog/confirm-dialog-state.ts +15 -14
- package/src/components/confirm-dialog/index.ts +3 -12
- package/src/components/content/BlogList.vue +11 -8
- package/src/components/content/BlogTable.vue +18 -14
- package/src/components/content/ProseHr.vue +10 -7
- package/src/components/content/Terminal.vue +70 -0
- package/src/components/content/index.ts +2 -1
- package/src/components/dashboard-shell/DashboardShell.vue +43 -64
- package/src/components/dashboard-shell/index.ts +2 -2
- package/src/components/data-list/DataList.vue +11 -13
- package/src/components/data-list/DataListItem.vue +9 -11
- package/src/components/data-list/DataListLabel.vue +9 -11
- package/src/components/data-list/DataListText.vue +9 -11
- package/src/components/data-list/DataListValue.vue +9 -11
- package/src/components/data-list/index.ts +5 -5
- package/src/components/empty-state-card/EmptyStateCard.vue +21 -11
- package/src/components/error-page/ErrorPage.vue +24 -27
- package/src/components/error-page/index.ts +2 -2
- package/src/components/info-card/InfoCard.vue +17 -11
- package/src/components/landing/index.ts +6 -6
- package/src/components/landing/landing-content/LandingContent.vue +5 -7
- package/src/components/landing/landing-content/index.ts +2 -2
- package/src/components/landing/landing-footer/LandingFooter.vue +26 -29
- package/src/components/landing/landing-footer/index.ts +3 -3
- package/src/components/landing/landing-navbar/LandingNavbar.vue +15 -17
- package/src/components/landing/landing-navbar/index.ts +2 -2
- package/src/components/landing/landing-shell/LandingShell.vue +10 -13
- package/src/components/landing/landing-shell/index.ts +2 -2
- package/src/components/language-flag/LanguageFlag.vue +6 -5
- package/src/components/language-flag/index.ts +1 -0
- package/src/components/language-selector/LanguageSelector.vue +20 -21
- package/src/components/load-more-button/LoadMoreButton.vue +18 -14
- package/src/components/loading-state-card/LoadingStateCard.vue +13 -9
- package/src/components/message-dialog/MessageDialog.vue +19 -19
- package/src/components/message-dialog/index.ts +3 -11
- package/src/components/message-dialog/message-dialog-state.ts +12 -11
- package/src/components/message-toast/MessageToast.vue +16 -16
- package/src/components/message-toast/index.ts +2 -9
- package/src/components/message-toast/message-toast-state.ts +9 -9
- package/src/components/page-header/PageHeader.vue +8 -5
- package/src/components/progress-component/ProgressComponent.vue +13 -10
- package/src/components/single-value-card/SingleValueCard.vue +22 -19
- package/src/components/slider-form-component/SliderFormComponent.vue +11 -20
- package/src/components/slider-form-component/index.ts +2 -2
- package/src/components/switch-form-component/SwitchFormComponent.vue +7 -9
- package/src/components/switch-form-component/index.ts +2 -2
- package/src/components/text-link/TextLink.vue +11 -7
- package/src/components/ui/accordion/Accordion.vue +10 -13
- package/src/components/ui/accordion/index.ts +1 -1
- package/src/components/ui/alert/Alert.vue +11 -10
- package/src/components/ui/alert/AlertDescription.vue +9 -8
- package/src/components/ui/alert/AlertTitle.vue +9 -8
- package/src/components/ui/alert/index.ts +10 -10
- package/src/components/ui/alert-dialog/AlertDialog.vue +13 -9
- package/src/components/ui/alert-dialog/AlertDialogAction.vue +14 -12
- package/src/components/ui/alert-dialog/AlertDialogCancel.vue +14 -16
- package/src/components/ui/alert-dialog/AlertDialogContent.vue +24 -27
- package/src/components/ui/alert-dialog/AlertDialogDescription.vue +13 -13
- package/src/components/ui/alert-dialog/AlertDialogFooter.vue +9 -12
- package/src/components/ui/alert-dialog/AlertDialogHeader.vue +9 -8
- package/src/components/ui/alert-dialog/AlertDialogTitle.vue +13 -11
- package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +8 -7
- package/src/components/ui/alert-dialog/index.ts +9 -9
- package/src/components/ui/badge/Badge.vue +11 -12
- package/src/components/ui/badge/index.ts +1 -1
- package/src/components/ui/breadcrumb/Breadcrumb.vue +9 -12
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +15 -19
- package/src/components/ui/breadcrumb/BreadcrumbItem.vue +10 -12
- package/src/components/ui/breadcrumb/BreadcrumbLink.vue +13 -17
- package/src/components/ui/breadcrumb/BreadcrumbList.vue +10 -12
- package/src/components/ui/breadcrumb/BreadcrumbPage.vue +10 -15
- package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +14 -18
- package/src/components/ui/breadcrumb/index.ts +7 -7
- package/src/components/ui/busy/Busy.vue +36 -29
- package/src/components/ui/busy/index.ts +1 -1
- package/src/components/ui/button/Button.vue +18 -19
- package/src/components/ui/button/index.ts +54 -35
- package/src/components/ui/calendar/Calendar.vue +167 -121
- package/src/components/ui/calendar/CalendarCell.vue +18 -17
- package/src/components/ui/calendar/CalendarCellTrigger.vue +31 -33
- package/src/components/ui/calendar/CalendarGrid.vue +14 -17
- package/src/components/ui/calendar/CalendarGridBody.vue +9 -11
- package/src/components/ui/calendar/CalendarGridHead.vue +10 -12
- package/src/components/ui/calendar/CalendarGridRow.vue +14 -16
- package/src/components/ui/calendar/CalendarHeadCell.vue +18 -17
- package/src/components/ui/calendar/CalendarHeader.vue +18 -17
- package/src/components/ui/calendar/CalendarHeading.vue +18 -22
- package/src/components/ui/calendar/CalendarNextButton.vue +29 -26
- package/src/components/ui/calendar/CalendarPrevButton.vue +29 -26
- package/src/components/ui/calendar/index.ts +17 -13
- package/src/components/ui/card/Card.vue +21 -13
- package/src/components/ui/card/CardAction.vue +12 -7
- package/src/components/ui/card/CardContent.vue +8 -7
- package/src/components/ui/card/CardDescription.vue +16 -7
- package/src/components/ui/card/CardFooter.vue +8 -7
- package/src/components/ui/card/CardHeader.vue +12 -7
- package/src/components/ui/card/CardText.vue +12 -7
- package/src/components/ui/card/CardTitle.vue +9 -7
- package/src/components/ui/card/index.ts +8 -8
- package/src/components/ui/command/Command.vue +71 -61
- package/src/components/ui/command/CommandDialog.vue +33 -23
- package/src/components/ui/command/CommandEmpty.vue +19 -20
- package/src/components/ui/command/CommandGroup.vue +32 -35
- package/src/components/ui/command/CommandInput.vue +25 -21
- package/src/components/ui/command/CommandItem.vue +62 -59
- package/src/components/ui/command/CommandList.vue +21 -18
- package/src/components/ui/command/CommandSeparator.vue +13 -11
- package/src/components/ui/command/CommandShortcut.vue +13 -8
- package/src/components/ui/command/index.ts +24 -20
- package/src/components/ui/date-picker/DatePicker.vue +46 -37
- package/src/components/ui/date-picker/index.ts +2 -2
- package/src/components/ui/date-time-picker/DateTimePicker.vue +99 -95
- package/src/components/ui/date-time-picker/index.ts +2 -2
- package/src/components/ui/dialog/Dialog.vue +12 -9
- package/src/components/ui/dialog/DialogClose.vue +8 -10
- package/src/components/ui/dialog/DialogContent.vue +36 -42
- package/src/components/ui/dialog/DialogDescription.vue +16 -11
- package/src/components/ui/dialog/DialogFooter.vue +13 -12
- package/src/components/ui/dialog/DialogHeader.vue +9 -8
- package/src/components/ui/dialog/DialogOverlay.vue +16 -11
- package/src/components/ui/dialog/DialogScrollContent.vue +47 -45
- package/src/components/ui/dialog/DialogTitle.vue +13 -12
- package/src/components/ui/dialog/DialogTrigger.vue +8 -7
- package/src/components/ui/dialog/index.ts +10 -10
- package/src/components/ui/field/Field.vue +12 -14
- package/src/components/ui/field/FieldContent.vue +13 -11
- package/src/components/ui/field/FieldDescription.vue +15 -13
- package/src/components/ui/field/FieldError.vue +43 -40
- package/src/components/ui/field/FieldGroup.vue +13 -11
- package/src/components/ui/field/FieldLabel.vue +16 -14
- package/src/components/ui/field/FieldLegend.vue +16 -14
- package/src/components/ui/field/FieldSeparator.vue +17 -15
- package/src/components/ui/field/FieldSet.vue +14 -12
- package/src/components/ui/field/FieldTitle.vue +13 -11
- package/src/components/ui/field/index.ts +36 -36
- package/src/components/ui/input/Input.vue +23 -20
- package/src/components/ui/input/index.ts +1 -1
- package/src/components/ui/label/Label.vue +16 -15
- package/src/components/ui/label/index.ts +1 -1
- package/src/components/ui/native-select/NativeSelect.vue +31 -41
- package/src/components/ui/native-select/NativeSelectOptGroup.vue +8 -7
- package/src/components/ui/native-select/NativeSelectOption.vue +8 -7
- package/src/components/ui/native-select/index.ts +3 -3
- package/src/components/ui/popover/Popover.vue +12 -9
- package/src/components/ui/popover/PopoverAnchor.vue +8 -7
- package/src/components/ui/popover/PopoverContent.vue +27 -31
- package/src/components/ui/popover/PopoverTrigger.vue +8 -7
- package/src/components/ui/popover/index.ts +4 -4
- package/src/components/ui/progress/Progress.vue +18 -32
- package/src/components/ui/progress/index.ts +1 -1
- package/src/components/ui/scroll-area/ScrollArea.vue +23 -26
- package/src/components/ui/scroll-area/ScrollBar.vue +22 -26
- package/src/components/ui/scroll-area/index.ts +2 -2
- package/src/components/ui/select/Select.vue +12 -9
- package/src/components/ui/select/SelectContent.vue +39 -40
- package/src/components/ui/select/SelectGroup.vue +8 -7
- package/src/components/ui/select/SelectItem.vue +36 -41
- package/src/components/ui/select/SelectItemContent.vue +22 -15
- package/src/components/ui/select/SelectItemText.vue +8 -7
- package/src/components/ui/select/SelectLabel.vue +10 -9
- package/src/components/ui/select/SelectScrollDownButton.vue +21 -17
- package/src/components/ui/select/SelectScrollUpButton.vue +21 -17
- package/src/components/ui/select/SelectSeparator.vue +11 -9
- package/src/components/ui/select/SelectTrigger.vue +27 -25
- package/src/components/ui/select/SelectValue.vue +8 -7
- package/src/components/ui/select/SelectValueContent.vue +30 -18
- package/src/components/ui/select/index.ts +13 -13
- package/src/components/ui/separator/Separator.vue +17 -18
- package/src/components/ui/separator/index.ts +1 -1
- package/src/components/ui/sheet/Sheet.vue +12 -9
- package/src/components/ui/sheet/SheetClose.vue +8 -7
- package/src/components/ui/sheet/SheetContent.vue +36 -37
- package/src/components/ui/sheet/SheetDescription.vue +12 -11
- package/src/components/ui/sheet/SheetFooter.vue +8 -7
- package/src/components/ui/sheet/SheetHeader.vue +8 -7
- package/src/components/ui/sheet/SheetOverlay.vue +16 -11
- package/src/components/ui/sheet/SheetTitle.vue +12 -11
- package/src/components/ui/sheet/SheetTrigger.vue +8 -7
- package/src/components/ui/sheet/index.ts +8 -8
- package/src/components/ui/sidebar/Sidebar.vue +68 -61
- package/src/components/ui/sidebar/SidebarContent.vue +13 -8
- package/src/components/ui/sidebar/SidebarFooter.vue +13 -8
- package/src/components/ui/sidebar/SidebarGroup.vue +13 -8
- package/src/components/ui/sidebar/SidebarGroupAction.vue +16 -16
- package/src/components/ui/sidebar/SidebarGroupContent.vue +9 -8
- package/src/components/ui/sidebar/SidebarGroupLabel.vue +15 -14
- package/src/components/ui/sidebar/SidebarHeader.vue +13 -8
- package/src/components/ui/sidebar/SidebarInput.vue +14 -12
- package/src/components/ui/sidebar/SidebarInset.vue +14 -12
- package/src/components/ui/sidebar/SidebarMenu.vue +9 -8
- package/src/components/ui/sidebar/SidebarMenuAction.vue +25 -23
- package/src/components/ui/sidebar/SidebarMenuBadge.vue +19 -17
- package/src/components/ui/sidebar/SidebarMenuButton.vue +33 -32
- package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +19 -18
- package/src/components/ui/sidebar/SidebarMenuItem.vue +9 -8
- package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +17 -12
- package/src/components/ui/sidebar/SidebarMenuSub.vue +14 -12
- package/src/components/ui/sidebar/SidebarMenuSubButton.vue +24 -21
- package/src/components/ui/sidebar/SidebarMenuSubItem.vue +9 -8
- package/src/components/ui/sidebar/SidebarProvider.vue +63 -53
- package/src/components/ui/sidebar/SidebarRail.vue +20 -18
- package/src/components/ui/sidebar/SidebarSeparator.vue +10 -9
- package/src/components/ui/sidebar/SidebarTrigger.vue +15 -14
- package/src/components/ui/sidebar/index.ts +62 -58
- package/src/components/ui/sidebar/utils.ts +16 -16
- package/src/components/ui/skeleton/Skeleton.vue +12 -9
- package/src/components/ui/skeleton/index.ts +1 -1
- package/src/components/ui/slider/Slider.vue +24 -19
- package/src/components/ui/slider/index.ts +1 -1
- package/src/components/ui/switch/Switch.vue +26 -23
- package/src/components/ui/switch/index.ts +1 -1
- package/src/components/ui/table/Table.vue +11 -10
- package/src/components/ui/table/TableBody.vue +9 -11
- package/src/components/ui/table/TableCaption.vue +9 -11
- package/src/components/ui/table/TableCell.vue +13 -16
- package/src/components/ui/table/TableEmpty.vue +22 -25
- package/src/components/ui/table/TableFooter.vue +13 -11
- package/src/components/ui/table/TableHead.vue +13 -11
- package/src/components/ui/table/TableHeader.vue +9 -11
- package/src/components/ui/table/TableRow.vue +13 -11
- package/src/components/ui/table/index.ts +9 -9
- package/src/components/ui/tabs/Tabs.vue +18 -18
- package/src/components/ui/tabs/TabsContent.vue +14 -15
- package/src/components/ui/tabs/TabsList.vue +18 -18
- package/src/components/ui/tabs/TabsTrigger.vue +19 -20
- package/src/components/ui/tabs/index.ts +4 -4
- package/src/components/ui/textarea/Textarea.vue +23 -20
- package/src/components/ui/textarea/index.ts +1 -1
- package/src/components/ui/time-picker/TimePicker.vue +33 -38
- package/src/components/ui/time-picker/index.ts +2 -2
- package/src/components/ui/tooltip/Tooltip.vue +12 -9
- package/src/components/ui/tooltip/TooltipContent.vue +28 -20
- package/src/components/ui/tooltip/TooltipProvider.vue +9 -8
- package/src/components/ui/tooltip/TooltipTrigger.vue +8 -7
- package/src/components/ui/tooltip/index.ts +4 -4
- package/src/i18n/de.json +5 -0
- package/src/i18n/en.json +5 -0
- package/src/i18n/es.json +5 -0
- package/src/i18n/fr.json +5 -0
- package/src/i18n/it.json +5 -0
- package/src/i18n/ja.json +5 -0
- package/src/i18n/pt.json +5 -0
- package/src/i18n/ru.json +5 -0
- package/src/i18n/zh.json +5 -0
- package/src/lib/common-types.ts +2 -0
- package/src/lib/i18n.ts +0 -5
- package/src/runtime/{ui-vintage-i18n-plugin.js → ui-vintage-i18n-plugin.ts} +30 -8
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import CategoriesList from './CategoriesList.vue';
|
|
3
3
|
|
|
4
4
|
// Props
|
|
5
|
-
const props = defineProps
|
|
6
|
-
categories
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
categories?: Array<{
|
|
7
|
+
path: string;
|
|
8
|
+
slug?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
image?: string;
|
|
11
|
+
count: number;
|
|
12
|
+
}>;
|
|
13
|
+
}>(), {
|
|
14
|
+
categories: () => []
|
|
7
15
|
});
|
|
8
16
|
</script>
|
|
9
17
|
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { NuxtImg } from '#components';
|
|
3
3
|
import { Badge } from '../ui/badge';
|
|
4
4
|
import { Card, CardContent } from '../ui/card';
|
|
5
5
|
|
|
6
6
|
// Props
|
|
7
|
-
const props = defineProps
|
|
8
|
-
name:
|
|
9
|
-
image
|
|
10
|
-
count:
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
name: string;
|
|
9
|
+
image?: string;
|
|
10
|
+
count: number;
|
|
11
|
+
}>(), {
|
|
12
|
+
image: ''
|
|
11
13
|
});
|
|
12
14
|
</script>
|
|
13
15
|
|
|
14
16
|
<template>
|
|
15
|
-
<Card class="
|
|
16
|
-
<CardContent class="gap-0
|
|
17
|
+
<Card class="p-0! overflow-hidden group cursor-pointer transition-transform duration-300 ease-out hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
|
|
18
|
+
<CardContent class="gap-0 p-0!">
|
|
17
19
|
<!-- Background Image -->
|
|
18
20
|
<div v-if="props.image" class="relative w-full h-36 overflow-hidden">
|
|
19
21
|
<NuxtImg :src="props.image" :alt="props.name" height="225" width="400" format="avif" quality="35" :sizes="{ 480: '480px', 1280: '400px' }" loading="lazy" decoding="async" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" />
|
|
@@ -22,7 +24,7 @@ const props = defineProps({
|
|
|
22
24
|
<!-- Content -->
|
|
23
25
|
<div class="p-4 flex items-center justify-between">
|
|
24
26
|
<!-- Name -->
|
|
25
|
-
<span class="text-sm font-bold text-
|
|
27
|
+
<span class="text-sm font-bold text-(--text-primary-light) dark:text-(--text-primary-dark) truncate mr-3">
|
|
26
28
|
{{ props.name }}
|
|
27
29
|
</span>
|
|
28
30
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { NuxtImg } from '#components';
|
|
3
3
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
|
4
4
|
import { useI18n } from 'vue-i18n';
|
|
@@ -11,15 +11,24 @@ import { Card, CardContent } from '../ui/card';
|
|
|
11
11
|
const { t } = useI18n();
|
|
12
12
|
|
|
13
13
|
// Props
|
|
14
|
-
const props = defineProps
|
|
15
|
-
featuredPosts
|
|
14
|
+
const props = withDefaults(defineProps<{
|
|
15
|
+
featuredPosts?: Array<{
|
|
16
|
+
path: string;
|
|
17
|
+
title: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
image?: string;
|
|
20
|
+
categoryText?: string;
|
|
21
|
+
categoryPath?: string;
|
|
22
|
+
}>;
|
|
23
|
+
}>(), {
|
|
24
|
+
featuredPosts: () => []
|
|
16
25
|
});
|
|
17
26
|
|
|
18
27
|
// Carousel state
|
|
19
28
|
const currentSlide = ref(0);
|
|
20
29
|
const slideCount = computed(() => props.featuredPosts.length || 0);
|
|
21
|
-
const intervalId = ref(null);
|
|
22
|
-
const direction = ref('forward');
|
|
30
|
+
const intervalId = ref<ReturnType<typeof setInterval> | null>(null);
|
|
31
|
+
const direction = ref<'forward' | 'backward'>('forward');
|
|
23
32
|
|
|
24
33
|
// Start auto-play functionality
|
|
25
34
|
const startAutoPlay = () => {
|
|
@@ -44,7 +53,7 @@ const prevSlide = () => {
|
|
|
44
53
|
};
|
|
45
54
|
|
|
46
55
|
// Go to specific slide
|
|
47
|
-
const goToSlide = index => {
|
|
56
|
+
const goToSlide = (index: number) => {
|
|
48
57
|
// Determine direction
|
|
49
58
|
if (index > currentSlide.value) {
|
|
50
59
|
direction.value = 'forward';
|
|
@@ -73,8 +82,8 @@ onUnmounted(() => {
|
|
|
73
82
|
<div class="relative overflow-hidden rounded">
|
|
74
83
|
<TransitionGroup name="slide">
|
|
75
84
|
<div v-for="(post, index) in props.featuredPosts" :id="`carousel-slide-${index}`" :key="post.path || post.title || index" v-show="currentSlide === index" class="w-full" :data-direction="direction">
|
|
76
|
-
<Card class="
|
|
77
|
-
<CardContent class="gap-0
|
|
85
|
+
<Card class="p-0! overflow-hidden cursor-pointer">
|
|
86
|
+
<CardContent class="gap-0 p-0!">
|
|
78
87
|
<!-- Slide image -->
|
|
79
88
|
<NuxtLink :to="post.path">
|
|
80
89
|
<div class="relative w-full h-56 md:h-80 overflow-hidden">
|
|
@@ -91,13 +100,13 @@ onUnmounted(() => {
|
|
|
91
100
|
|
|
92
101
|
<!-- Title -->
|
|
93
102
|
<NuxtLink :to="post.path">
|
|
94
|
-
<h3 class="text-base md:text-3xl font-bold text-
|
|
103
|
+
<h3 class="text-base md:text-3xl font-bold text-(--text-primary-light) dark:text-(--text-primary-dark) mb-3 line-clamp-2 hover:opacity-75 transition-opacity duration-200">
|
|
95
104
|
{{ post.title }}
|
|
96
105
|
</h3>
|
|
97
106
|
</NuxtLink>
|
|
98
107
|
|
|
99
108
|
<!-- Description -->
|
|
100
|
-
<p class="text-xs md
|
|
109
|
+
<p class="text-xs md:text-base! text-(--text-secondary-light) dark:text-(--text-secondary-dark) mb-6 line-clamp-2 leading-relaxed">
|
|
101
110
|
{{ post.description }}
|
|
102
111
|
</p>
|
|
103
112
|
|
|
@@ -116,7 +125,7 @@ onUnmounted(() => {
|
|
|
116
125
|
<button v-for="(_, idx) in props.featuredPosts"
|
|
117
126
|
:key="idx"
|
|
118
127
|
@click="goToSlide(idx)"
|
|
119
|
-
:class="['h-5 w-5 sm
|
|
128
|
+
:class="['h-5 w-5 sm:h-4! sm:w-4! shrink-0 rounded-[2px] transition-all duration-300 cursor-pointer bg-(--border-light) dark:bg-(--border-dark)', currentSlide === idx ? 'w-8! sm:w-7! bg-(--text-primary-light)! dark:bg-(--text-primary-dark)!' : '']"
|
|
120
129
|
:aria-label="t('uiVintage.blog.goToSlide', { index: idx + 1 })"
|
|
121
130
|
:aria-current="currentSlide === idx"
|
|
122
131
|
role="tab"
|
|
@@ -135,16 +144,16 @@ onUnmounted(() => {
|
|
|
135
144
|
<button v-if="props.featuredPosts.length > 1"
|
|
136
145
|
@click="prevSlide"
|
|
137
146
|
:aria-label="t('uiVintage.blog.previousSlide')"
|
|
138
|
-
class="absolute left-2 top-[calc(50%-4rem)] -translate-y-1/2 z-10 border border-
|
|
139
|
-
<HugeiconsIcon :icon="ArrowLeft01Icon" class="size-4 text-
|
|
147
|
+
class="absolute left-2 top-[calc(50%-4rem)] -translate-y-1/2 z-10 border border-(--border-light) dark:border-(--border-dark) bg-(--bg-card-light) dark:bg-(--bg-card-dark) px-3 py-3 rounded-none transition-colors duration-200 hover:border-(--border-hover-light) dark:hover:border-(--border-hover-dark) cursor-pointer">
|
|
148
|
+
<HugeiconsIcon :icon="ArrowLeft01Icon" class="size-4 text-(--text-secondary-light) dark:text-(--text-secondary-dark)" />
|
|
140
149
|
</button>
|
|
141
150
|
|
|
142
151
|
<!-- Next slide -->
|
|
143
152
|
<button v-if="props.featuredPosts.length > 1"
|
|
144
153
|
@click="nextSlide"
|
|
145
154
|
:aria-label="t('uiVintage.blog.nextSlide')"
|
|
146
|
-
class="absolute right-2 top-[calc(50%-4rem)] -translate-y-1/2 z-10 border border-
|
|
147
|
-
<HugeiconsIcon :icon="ArrowRight01Icon" class="size-4 text-
|
|
155
|
+
class="absolute right-2 top-[calc(50%-4rem)] -translate-y-1/2 z-10 border border-(--border-light) dark:border-(--border-dark) bg-(--bg-card-light) dark:bg-(--bg-card-dark) px-3 py-3 rounded-none transition-colors duration-200 hover:border-(--border-hover-light) dark:hover:border-(--border-hover-dark) cursor-pointer">
|
|
156
|
+
<HugeiconsIcon :icon="ArrowRight01Icon" class="size-4 text-(--text-secondary-light) dark:text-(--text-secondary-dark)" />
|
|
148
157
|
</button>
|
|
149
158
|
</div>
|
|
150
159
|
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { NuxtImg } from '#components';
|
|
3
3
|
import { useI18n } from 'vue-i18n';
|
|
4
4
|
import { ArrowRight01Icon } from '@hugeicons/core-free-icons';
|
|
@@ -10,36 +10,41 @@ import { Card, CardContent } from '../ui/card';
|
|
|
10
10
|
const { t } = useI18n();
|
|
11
11
|
|
|
12
12
|
// Props
|
|
13
|
-
const props = defineProps
|
|
14
|
-
image
|
|
15
|
-
category
|
|
16
|
-
title
|
|
17
|
-
description
|
|
13
|
+
const props = withDefaults(defineProps<{
|
|
14
|
+
image?: string;
|
|
15
|
+
category?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
}>(), {
|
|
19
|
+
image: '',
|
|
20
|
+
category: '',
|
|
21
|
+
title: '',
|
|
22
|
+
description: ''
|
|
18
23
|
});
|
|
19
24
|
</script>
|
|
20
25
|
|
|
21
26
|
<template>
|
|
22
|
-
<Card class="
|
|
23
|
-
<CardContent class="h-full gap-0
|
|
27
|
+
<Card class="p-0! overflow-hidden group cursor-pointer transition-transform duration-300 ease-out hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
|
|
28
|
+
<CardContent class="h-full gap-0 p-0!">
|
|
24
29
|
<!-- Featured image -->
|
|
25
30
|
<div v-if="props.image" class="relative w-full h-48 overflow-hidden">
|
|
26
31
|
<NuxtImg :src="props.image" :alt="props.title" height="225" width="400" format="avif" quality="35" :sizes="{ 480: '480px', 1280: '400px' }" loading="lazy" decoding="async" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" />
|
|
27
32
|
</div>
|
|
28
33
|
|
|
29
34
|
<!-- Content -->
|
|
30
|
-
<div class="p-6 flex flex-col
|
|
35
|
+
<div class="p-6 flex flex-col grow">
|
|
31
36
|
<!-- Category Badge -->
|
|
32
37
|
<div v-if="props.category" class="mb-3">
|
|
33
38
|
<Badge color="gray" :text="props.category" />
|
|
34
39
|
</div>
|
|
35
40
|
|
|
36
41
|
<!-- Post Title -->
|
|
37
|
-
<h2 class="text-base font-bold text-
|
|
42
|
+
<h2 class="text-base font-bold text-(--text-primary-light) dark:text-(--text-primary-dark) mb-2 line-clamp-2">
|
|
38
43
|
{{ props.title }}
|
|
39
44
|
</h2>
|
|
40
45
|
|
|
41
46
|
<!-- Post Description -->
|
|
42
|
-
<p class="text-xs md:text-sm text-
|
|
47
|
+
<p class="text-xs md:text-sm text-(--text-secondary-light) dark:text-(--text-secondary-dark) leading-relaxed mb-4 line-clamp-3 grow">
|
|
43
48
|
{{ props.description }}
|
|
44
49
|
</p>
|
|
45
50
|
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import PostCard from './PostCard.vue';
|
|
3
3
|
|
|
4
4
|
// Props
|
|
5
|
-
const props = defineProps
|
|
6
|
-
posts
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
posts?: Array<{
|
|
7
|
+
path: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
image?: string;
|
|
11
|
+
categoryText?: string;
|
|
12
|
+
categoryPath?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}>(), {
|
|
15
|
+
posts: () => []
|
|
7
16
|
});
|
|
8
17
|
</script>
|
|
9
18
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue';
|
|
3
3
|
import { useI18n } from 'vue-i18n';
|
|
4
4
|
import { Facebook01Icon, Linkedin01Icon, NewTwitterIcon, Share08Icon, TelegramIcon, WhatsappIcon } from '@hugeicons/core-free-icons';
|
|
@@ -6,10 +6,10 @@ import { HugeiconsIcon } from '@hugeicons/vue';
|
|
|
6
6
|
import { Card, CardContent } from '../ui/card';
|
|
7
7
|
|
|
8
8
|
// Props
|
|
9
|
-
const props = defineProps
|
|
10
|
-
title:
|
|
11
|
-
url:
|
|
12
|
-
});
|
|
9
|
+
const props = defineProps<{
|
|
10
|
+
title: string;
|
|
11
|
+
url: string;
|
|
12
|
+
}>();
|
|
13
13
|
|
|
14
14
|
const { t } = useI18n();
|
|
15
15
|
|
|
@@ -54,11 +54,11 @@ const socialPlatforms = computed(() => {
|
|
|
54
54
|
|
|
55
55
|
<template>
|
|
56
56
|
<!-- Desktop sidebar on the right -->
|
|
57
|
-
<div class="fixed right-[calc(50%-600px)] top-
|
|
58
|
-
<Card class="
|
|
59
|
-
<CardContent class="
|
|
57
|
+
<div class="fixed right-[calc(50%-600px)] top-35 z-10 hidden xl:block">
|
|
58
|
+
<Card class="p-5! flex flex-col space-y-4 items-center">
|
|
59
|
+
<CardContent class="p-0! gap-4 items-center">
|
|
60
60
|
<!-- Share icon -->
|
|
61
|
-
<HugeiconsIcon :icon="Share08Icon" class="size-5 text-
|
|
61
|
+
<HugeiconsIcon :icon="Share08Icon" class="size-5 text-(--text-secondary-light) dark:text-(--text-secondary-dark) mb-2" />
|
|
62
62
|
|
|
63
63
|
<!-- Social share links (desktop) -->
|
|
64
64
|
<template v-for="platform in socialPlatforms" :key="platform.name">
|
|
@@ -76,8 +76,8 @@ const socialPlatforms = computed(() => {
|
|
|
76
76
|
|
|
77
77
|
<!-- Mobile view (floating bar at bottom) -->
|
|
78
78
|
<div class="fixed bottom-4 left-1/2 z-10 -translate-x-1/2 xl:hidden">
|
|
79
|
-
<Card class="
|
|
80
|
-
<CardContent class="
|
|
79
|
+
<Card class="p-3! w-fit">
|
|
80
|
+
<CardContent class="flex-row! p-0! items-center justify-center gap-3">
|
|
81
81
|
<!-- Social share links (mobile) -->
|
|
82
82
|
<template v-for="platform in socialPlatforms" :key="platform.name">
|
|
83
83
|
<NuxtLink :to="platform.url"
|
|
@@ -1,13 +1,29 @@
|
|
|
1
|
-
<script setup>
|
|
1
|
+
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue';
|
|
3
3
|
import { useI18n } from 'vue-i18n';
|
|
4
4
|
import { Bookmark01Icon } from '@hugeicons/core-free-icons';
|
|
5
5
|
import { Accordion } from '../ui/accordion';
|
|
6
6
|
|
|
7
|
+
interface BlogTocLink {
|
|
8
|
+
id?: string;
|
|
9
|
+
text?: string;
|
|
10
|
+
depth?: number;
|
|
11
|
+
children?: BlogTocLink[];
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
// Props
|
|
8
|
-
const props = defineProps
|
|
9
|
-
content: {
|
|
10
|
-
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
content: {
|
|
17
|
+
body?: {
|
|
18
|
+
toc?: {
|
|
19
|
+
links?: BlogTocLink[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
toc?: {
|
|
23
|
+
links?: BlogTocLink[];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}>();
|
|
11
27
|
|
|
12
28
|
const { t } = useI18n();
|
|
13
29
|
|
|
@@ -16,13 +32,13 @@ const headings = computed(() => {
|
|
|
16
32
|
const tocLinks = props.content?.body?.toc?.links || props.content?.toc?.links || [];
|
|
17
33
|
|
|
18
34
|
// Recursive function to flatten the nested links
|
|
19
|
-
const flattenLinks = links => {
|
|
35
|
+
const flattenLinks = (links: BlogTocLink[]): Array<{ id: string; text: string; level: number }> => {
|
|
20
36
|
return links.flatMap(link => {
|
|
21
37
|
// Extract the current heading
|
|
22
38
|
const currentHeading = {
|
|
23
|
-
id: link.id,
|
|
24
|
-
text: link.text,
|
|
25
|
-
level: link.depth
|
|
39
|
+
id: link.id ?? '',
|
|
40
|
+
text: link.text ?? '',
|
|
41
|
+
level: link.depth ?? 0
|
|
26
42
|
};
|
|
27
43
|
|
|
28
44
|
// Recursively flatten the children links
|
|
@@ -36,7 +52,7 @@ const headings = computed(() => {
|
|
|
36
52
|
});
|
|
37
53
|
|
|
38
54
|
// Smooth scroll to heading
|
|
39
|
-
const scrollToHeading = id => {
|
|
55
|
+
const scrollToHeading = (id: string) => {
|
|
40
56
|
const element = document.getElementById(id);
|
|
41
57
|
if (element) {
|
|
42
58
|
element.scrollIntoView({
|
|
@@ -48,16 +64,16 @@ const scrollToHeading = id => {
|
|
|
48
64
|
};
|
|
49
65
|
|
|
50
66
|
// Get classes for heading button
|
|
51
|
-
const getHeadingButtonClasses =
|
|
67
|
+
const getHeadingButtonClasses = (level: number) => {
|
|
52
68
|
// Base classes for all titles
|
|
53
69
|
const baseClasses = 'block w-full text-left px-0 py-2 md:px-3 md:py-2 rounded transition-all duration-200 hover:bg-(--bg-selected-light) dark:hover:bg-(--bg-selected-dark) cursor-pointer';
|
|
54
70
|
|
|
55
71
|
// Add classes based on heading level
|
|
56
72
|
let levelClasses = '';
|
|
57
|
-
if (
|
|
73
|
+
if (level === 2) {
|
|
58
74
|
levelClasses = 'text-(--text-primary-light) dark:text-(--text-primary-dark) font-semibold text-xs md:text-sm';
|
|
59
75
|
} else {
|
|
60
|
-
levelClasses = 'text-(--text-secondary-light) dark:text-(--text-secondary-dark)
|
|
76
|
+
levelClasses = 'text-(--text-secondary-light) dark:text-(--text-secondary-dark) pl-6! text-xs md:text-sm';
|
|
61
77
|
}
|
|
62
78
|
|
|
63
79
|
// Return combined classes
|
|
@@ -68,7 +84,7 @@ const getHeadingButtonClasses = heading => {
|
|
|
68
84
|
<template>
|
|
69
85
|
<Accordion v-if="headings.length > 0" :title="t('uiVintage.blog.tableOfContents')" :icon="Bookmark01Icon">
|
|
70
86
|
<nav class="space-y-1">
|
|
71
|
-
<button v-for="heading in headings" :key="heading.id" @click="scrollToHeading(heading.id)" :class="getHeadingButtonClasses(heading)">
|
|
87
|
+
<button v-for="heading in headings" :key="heading.id" @click="scrollToHeading(heading.id)" :class="getHeadingButtonClasses(heading.level)">
|
|
72
88
|
{{ heading.text }}
|
|
73
89
|
</button>
|
|
74
90
|
</nav>
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import { h, reactive, render } from
|
|
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[
|
|
7
|
-
overlayClass?: HTMLAttributes[
|
|
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[
|
|
14
|
-
overlayClass: HTMLAttributes[
|
|
12
|
+
class: HTMLAttributes['class'];
|
|
13
|
+
overlayClass: HTMLAttributes['class'];
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
const BUSY_INDICATOR_ROOT_ID =
|
|
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:
|
|
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 ===
|
|
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(
|
|
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(
|
|
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 ??
|
|
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
|
|
2
|
-
export { busyIndicatorState, setBusy } from
|
|
3
|
-
export type { SetBusyOptions } from
|
|
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
|
|
10
|
-
busy
|
|
11
|
-
loadMoreBusy
|
|
12
|
-
hasMore
|
|
13
|
-
emptyMessage:
|
|
14
|
-
emptyIcon
|
|
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
|
|
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="
|
|
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="
|
|
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
|
|
3
|
-
import { HugeiconsIcon } from
|
|
4
|
-
import type { HTMLAttributes } from
|
|
5
|
-
import { getSurfaceToneClasses, type ToneColor } from
|
|
6
|
-
import { cn } from
|
|
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[
|
|
10
|
+
text: string;
|
|
11
|
+
color?: ToneColor;
|
|
12
|
+
removeLabel?: string;
|
|
13
|
+
class?: HTMLAttributes['class'];
|
|
14
14
|
}>(), {
|
|
15
|
-
color:
|
|
16
|
-
removeLabel:
|
|
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(
|
|
27
|
-
}
|
|
26
|
+
emits('remove');
|
|
27
|
+
};
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<template>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from
|
|
2
|
-
export { default as Chip } from
|
|
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
|
|
3
|
-
import { computed } from
|
|
4
|
-
import { InformationCircleIcon } from
|
|
5
|
-
import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from
|
|
6
|
-
import { Button } from
|
|
7
|
-
import { cancelActiveConfirmDialog, closeConfirmDialog, confirmActiveDialog, confirmDialogState } from
|
|
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-
|
|
28
|
-
<HugeiconsIcon v-if="currentDialog.options.icon" :icon="currentDialog.options.icon" :stroke-width="1.8" class="size-6 text-
|
|
29
|
-
<HugeiconsIcon v-else :icon="InformationCircleIcon" :stroke-width="1.8" class="size-6 text-
|
|
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 -->
|