@brumaombra/ui-vintage 0.7.7 → 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 +49 -65
- 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/theme-selector/ThemeSelector.vue +4 -4
- package/src/components/ui/accordion/Accordion.vue +12 -15
- 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
|
@@ -4,35 +4,39 @@ import { useI18n } from 'vue-i18n';
|
|
|
4
4
|
import { Loading03Icon } from '@hugeicons/core-free-icons';
|
|
5
5
|
import { HugeiconsIcon } from '@hugeicons/vue';
|
|
6
6
|
import { Card, CardContent } from '../ui/card';
|
|
7
|
+
import type { HugeiconsIconDefinition } from '../../lib/common-types';
|
|
7
8
|
|
|
8
9
|
// Props
|
|
9
|
-
const props = defineProps
|
|
10
|
-
icon
|
|
11
|
-
title
|
|
12
|
-
description
|
|
10
|
+
const props = withDefaults(defineProps<{
|
|
11
|
+
icon?: HugeiconsIconDefinition;
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
}>(), {
|
|
15
|
+
icon: () => Loading03Icon,
|
|
16
|
+
title: '',
|
|
17
|
+
description: ''
|
|
13
18
|
});
|
|
14
19
|
|
|
15
20
|
const { t } = useI18n();
|
|
16
|
-
|
|
17
21
|
const resolvedTitle = computed(() => props.title || t('uiVintage.common.loading.title') || 'Loading...');
|
|
18
22
|
const resolvedDescription = computed(() => props.description || t('uiVintage.common.loading.description') || 'Please wait a moment while we load the content.');
|
|
19
23
|
</script>
|
|
20
24
|
|
|
21
25
|
<template>
|
|
22
26
|
<Card class="flex flex-col items-center justify-center px-4 py-8 text-center md:py-12">
|
|
23
|
-
<CardContent class="flex flex-col items-center justify-center
|
|
27
|
+
<CardContent class="flex flex-col items-center justify-center p-0! text-center">
|
|
24
28
|
<!-- Loading spinner icon -->
|
|
25
|
-
<div class="flex items-center justify-center text-4xl text-
|
|
29
|
+
<div class="flex items-center justify-center text-4xl text-(--text-secondary-light) opacity-60 dark:text-(--text-secondary-dark)">
|
|
26
30
|
<HugeiconsIcon :icon="props.icon" class="size-10 animate-spin" />
|
|
27
31
|
</div>
|
|
28
32
|
|
|
29
33
|
<!-- Title -->
|
|
30
|
-
<h3 v-if="resolvedTitle" class="text-sm font-bold text-
|
|
34
|
+
<h3 v-if="resolvedTitle" class="text-sm font-bold text-(--text-primary-light) dark:text-(--text-primary-dark) md:text-lg">
|
|
31
35
|
{{ resolvedTitle }}
|
|
32
36
|
</h3>
|
|
33
37
|
|
|
34
38
|
<!-- Description -->
|
|
35
|
-
<p v-if="resolvedDescription" class="max-w-md text-xs text-
|
|
39
|
+
<p v-if="resolvedDescription" class="max-w-md text-xs text-(--text-secondary-light) dark:text-(--text-secondary-dark) md:text-sm">
|
|
36
40
|
{{ resolvedDescription }}
|
|
37
41
|
</p>
|
|
38
42
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { HugeiconsIcon } from
|
|
3
|
-
import { computed } from
|
|
4
|
-
import { AlertCircleIcon, InformationCircleIcon, Tick02Icon } from
|
|
5
|
-
import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from
|
|
6
|
-
import { Button } from
|
|
7
|
-
import { getUiVintageRuntimeMessage } from
|
|
8
|
-
import { closeMessageDialog, messageDialogState, resolveActiveMessageDialog } from
|
|
2
|
+
import { HugeiconsIcon } from '@hugeicons/vue';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
import { AlertCircleIcon, InformationCircleIcon, Tick02Icon } 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 { getUiVintageRuntimeMessage } from '../../lib/i18n';
|
|
8
|
+
import { closeMessageDialog, messageDialogState, resolveActiveMessageDialog } from './message-dialog-state';
|
|
9
9
|
|
|
10
10
|
// Active dialog state
|
|
11
11
|
const currentDialog = computed(() => messageDialogState.current);
|
|
@@ -28,29 +28,29 @@ const resolvedCloseText = computed(() => {
|
|
|
28
28
|
const defaultMessageIcon = computed(() => {
|
|
29
29
|
const current = currentDialog.value;
|
|
30
30
|
if (!current) return InformationCircleIcon;
|
|
31
|
-
if (current.options.type ===
|
|
32
|
-
if (current.options.type ===
|
|
31
|
+
if (current.options.type === 'error' || current.options.type === 'warning') return AlertCircleIcon;
|
|
32
|
+
if (current.options.type === 'success') return Tick02Icon;
|
|
33
33
|
return InformationCircleIcon;
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
// Resolved container classes for the message icon
|
|
37
37
|
const messageIconClasses = computed(() => {
|
|
38
38
|
const current = currentDialog.value;
|
|
39
|
-
if (!current) return
|
|
40
|
-
if (current.options.type ===
|
|
41
|
-
if (current.options.type ===
|
|
42
|
-
if (current.options.type ===
|
|
43
|
-
return
|
|
39
|
+
if (!current) return 'border-(--border) bg-(--bg-surface-light) dark:bg-(--bg-surface-dark)';
|
|
40
|
+
if (current.options.type === 'error') return 'border-red-200 bg-red-50 dark:border-red-900/50 dark:bg-red-950/30';
|
|
41
|
+
if (current.options.type === 'warning') return 'border-amber-200 bg-amber-50 dark:border-amber-900/50 dark:bg-amber-950/30';
|
|
42
|
+
if (current.options.type === 'success') return 'border-green-200 bg-green-50 dark:border-green-900/50 dark:bg-green-950/30';
|
|
43
|
+
return 'border-(--border) bg-(--bg-surface-light) dark:bg-(--bg-surface-dark)';
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
// Resolved glyph color classes
|
|
47
47
|
const messageGlyphClasses = computed(() => {
|
|
48
48
|
const current = currentDialog.value;
|
|
49
|
-
if (!current) return
|
|
50
|
-
if (current.options.type ===
|
|
51
|
-
if (current.options.type ===
|
|
52
|
-
if (current.options.type ===
|
|
53
|
-
return
|
|
49
|
+
if (!current) return 'text-blue-600';
|
|
50
|
+
if (current.options.type === 'error') return 'text-red-600';
|
|
51
|
+
if (current.options.type === 'warning') return 'text-amber-600';
|
|
52
|
+
if (current.options.type === 'success') return 'text-green-600';
|
|
53
|
+
return 'text-blue-600';
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
// Close the dialog when the shell requests it
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
export { default as MessageDialog } from
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
messageDialogState,
|
|
5
|
-
resolveActiveMessageDialog,
|
|
6
|
-
showMessageDialog
|
|
7
|
-
} from "./message-dialog-state";
|
|
8
|
-
export type {
|
|
9
|
-
DialogMessageType,
|
|
10
|
-
ShowMessageDialogOptions
|
|
11
|
-
} from "./message-dialog-state";
|
|
1
|
+
export { default as MessageDialog } from './MessageDialog.vue';
|
|
2
|
+
export { closeMessageDialog, messageDialogState, resolveActiveMessageDialog, showMessageDialog } from './message-dialog-state';
|
|
3
|
+
export type { DialogMessageType, ShowMessageDialogOptions } from './message-dialog-state';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { h, markRaw, reactive, render } from
|
|
1
|
+
import { h, markRaw, reactive, render } from 'vue';
|
|
2
|
+
import type { HugeiconsIconDefinition } from '../../lib/common-types';
|
|
2
3
|
|
|
3
|
-
export type DialogMessageType =
|
|
4
|
-
export type
|
|
4
|
+
export type DialogMessageType = 'error' | 'success' | 'info' | 'warning';
|
|
5
|
+
export type { HugeiconsIconDefinition };
|
|
5
6
|
|
|
6
7
|
export interface ShowMessageDialogOptions {
|
|
7
8
|
type?: DialogMessageType;
|
|
@@ -14,7 +15,7 @@ export interface ShowMessageDialogOptions {
|
|
|
14
15
|
|
|
15
16
|
interface MessageDialogRequest {
|
|
16
17
|
id: number;
|
|
17
|
-
options: Omit<ShowMessageDialogOptions,
|
|
18
|
+
options: Omit<ShowMessageDialogOptions, 'icon' | 'closeButtonIcon'> & {
|
|
18
19
|
icon: HugeiconsIconDefinition | null;
|
|
19
20
|
closeButtonIcon: HugeiconsIconDefinition | null;
|
|
20
21
|
};
|
|
@@ -33,7 +34,7 @@ const DIALOG_CLOSE_DURATION_MS = 300;
|
|
|
33
34
|
let closeTimer: ReturnType<typeof setTimeout> | null = null;
|
|
34
35
|
let messageDialogMountPromise: Promise<void> | null = null;
|
|
35
36
|
|
|
36
|
-
const MESSAGE_DIALOG_ROOT_ID =
|
|
37
|
+
const MESSAGE_DIALOG_ROOT_ID = 'ui-vintage-message-dialog-root';
|
|
37
38
|
|
|
38
39
|
// Shared message dialog state
|
|
39
40
|
export const messageDialogState: MessageDialogState = reactive({
|
|
@@ -48,7 +49,7 @@ const markIcon = (icon: HugeiconsIconDefinition | null | undefined) => icon ? ma
|
|
|
48
49
|
// Mount the dialog once on demand
|
|
49
50
|
const ensureMessageDialogMounted = () => {
|
|
50
51
|
// Skip mounting during SSR
|
|
51
|
-
if (typeof document ===
|
|
52
|
+
if (typeof document === 'undefined') {
|
|
52
53
|
return Promise.resolve();
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -66,7 +67,7 @@ const ensureMessageDialogMounted = () => {
|
|
|
66
67
|
// Start the lazy mount
|
|
67
68
|
messageDialogMountPromise = (async () => {
|
|
68
69
|
// Load the component only when needed
|
|
69
|
-
const { default: MessageDialog } = await import(
|
|
70
|
+
const { default: MessageDialog } = await import('./MessageDialog.vue');
|
|
70
71
|
|
|
71
72
|
// Guard against a concurrent mount
|
|
72
73
|
if (document.getElementById(MESSAGE_DIALOG_ROOT_ID)) {
|
|
@@ -74,7 +75,7 @@ const ensureMessageDialogMounted = () => {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
// Create the host element and render the component
|
|
77
|
-
const container = document.createElement(
|
|
78
|
+
const container = document.createElement('div');
|
|
78
79
|
container.id = MESSAGE_DIALOG_ROOT_ID;
|
|
79
80
|
document.body.appendChild(container);
|
|
80
81
|
render(h(MessageDialog), container);
|
|
@@ -155,10 +156,10 @@ export const showMessageDialog = (options: ShowMessageDialogOptions) => {
|
|
|
155
156
|
enqueueMessageDialog({
|
|
156
157
|
id: nextMessageDialogId += 1,
|
|
157
158
|
options: {
|
|
158
|
-
type: options.type ??
|
|
159
|
-
title: options.title ??
|
|
159
|
+
type: options.type ?? 'info',
|
|
160
|
+
title: options.title ?? '',
|
|
160
161
|
message: options.message,
|
|
161
|
-
closeText: options.closeText ??
|
|
162
|
+
closeText: options.closeText ?? '',
|
|
162
163
|
icon: markIcon(options.icon),
|
|
163
164
|
closeButtonIcon: markIcon(options.closeButtonIcon)
|
|
164
165
|
},
|
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { AlertCircleIcon, Cancel01Icon, CheckmarkCircle02Icon, InformationCircleIcon } from
|
|
3
|
-
import { HugeiconsIcon } from
|
|
4
|
-
import { computed } from
|
|
5
|
-
import { getUiVintageRuntimeMessage } from
|
|
6
|
-
import { Button } from
|
|
7
|
-
import { closeMessageToast, messageToastState } from
|
|
2
|
+
import { AlertCircleIcon, Cancel01Icon, CheckmarkCircle02Icon, InformationCircleIcon } from '@hugeicons/core-free-icons';
|
|
3
|
+
import { HugeiconsIcon } from '@hugeicons/vue';
|
|
4
|
+
import { computed } from 'vue';
|
|
5
|
+
import { getUiVintageRuntimeMessage } from '../../lib/i18n';
|
|
6
|
+
import { Button } from '../ui/button';
|
|
7
|
+
import { closeMessageToast, messageToastState } from './message-toast-state';
|
|
8
8
|
|
|
9
9
|
// Current toast data
|
|
10
10
|
const currentToast = computed(() => messageToastState.current);
|
|
11
11
|
|
|
12
12
|
// Localized dismiss label resolved from bundled library messages
|
|
13
|
-
const closeAriaLabel = computed(() => getUiVintageRuntimeMessage(
|
|
13
|
+
const closeAriaLabel = computed(() => getUiVintageRuntimeMessage('uiVintage.buttons.close', 'Close'));
|
|
14
14
|
|
|
15
15
|
// Determine toast type for styling and icon selection
|
|
16
|
-
const toastType = computed(() => currentToast.value?.type ??
|
|
16
|
+
const toastType = computed(() => currentToast.value?.type ?? 'success');
|
|
17
17
|
|
|
18
18
|
// Resolved icon based on toast type
|
|
19
19
|
const toastIcon = computed(() => {
|
|
20
|
-
if (toastType.value ===
|
|
20
|
+
if (toastType.value === 'success') return CheckmarkCircle02Icon;
|
|
21
21
|
return toastType.value === "info" ? InformationCircleIcon : AlertCircleIcon;
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
// Resolved icon color classes based on toast type
|
|
25
25
|
const toastIconClasses = computed(() => {
|
|
26
|
-
if (toastType.value ===
|
|
27
|
-
if (toastType.value ===
|
|
28
|
-
if (toastType.value ===
|
|
29
|
-
return
|
|
26
|
+
if (toastType.value === 'error') return 'text-red-600 dark:text-red-400';
|
|
27
|
+
if (toastType.value === 'warning') return 'text-amber-600 dark:text-amber-400';
|
|
28
|
+
if (toastType.value === 'info') return 'text-blue-600 dark:text-blue-400';
|
|
29
|
+
return 'text-green-600 dark:text-green-400';
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
// Resolved aria-live politeness based on toast type
|
|
33
33
|
const toastAriaLive = computed(() => {
|
|
34
|
-
if (toastType.value ===
|
|
35
|
-
return
|
|
34
|
+
if (toastType.value === 'error' || toastType.value === 'warning') return 'assertive';
|
|
35
|
+
return 'polite';
|
|
36
36
|
});
|
|
37
37
|
</script>
|
|
38
38
|
|
|
39
39
|
<template>
|
|
40
40
|
<Transition name="toast">
|
|
41
|
-
<div v-if="messageToastState.current && messageToastState.isOpen" class="fixed inset-x-3 bottom-3 z-
|
|
41
|
+
<div v-if="messageToastState.current && messageToastState.isOpen" class="fixed inset-x-3 bottom-3 z-60 rounded border border-border bg-card p-4 text-card-foreground transition-colors duration-300 ease-in-out sm:inset-x-auto sm:right-6 sm:bottom-6 sm:max-w-87.5 sm:min-w-62.5" role="alert" :aria-live="toastAriaLive" aria-atomic="true">
|
|
42
42
|
<div class="flex items-center gap-4">
|
|
43
43
|
<!-- Leading type icon -->
|
|
44
44
|
<HugeiconsIcon :icon="toastIcon" class="size-5" :class="toastIconClasses" />
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
messageToastState,
|
|
4
|
-
showMessageToast
|
|
5
|
-
} from "./message-toast-state";
|
|
6
|
-
export type {
|
|
7
|
-
MessageToastType,
|
|
8
|
-
ShowMessageToastOptions
|
|
9
|
-
} from "./message-toast-state";
|
|
1
|
+
export { closeMessageToast, messageToastState, showMessageToast } from './message-toast-state';
|
|
2
|
+
export type { MessageToastType, ShowMessageToastOptions } from './message-toast-state';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { h, reactive, render } from
|
|
1
|
+
import { h, reactive, render } from 'vue';
|
|
2
2
|
|
|
3
|
-
export type MessageToastType =
|
|
3
|
+
export type MessageToastType = 'success' | 'info' | 'warning' | 'error';
|
|
4
4
|
|
|
5
5
|
export interface ShowMessageToastOptions {
|
|
6
6
|
message: string;
|
|
@@ -20,7 +20,7 @@ interface MessageToastState {
|
|
|
20
20
|
|
|
21
21
|
const TOAST_CLOSE_DURATION_MS = 300;
|
|
22
22
|
const DEFAULT_TOAST_DURATION_MS = 5000;
|
|
23
|
-
const MESSAGE_TOAST_ROOT_ID =
|
|
23
|
+
const MESSAGE_TOAST_ROOT_ID = 'ui-vintage-message-toast-root';
|
|
24
24
|
|
|
25
25
|
let dismissTimer: ReturnType<typeof setTimeout> | null = null;
|
|
26
26
|
let clearTimer: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -37,7 +37,7 @@ export const messageToastState: MessageToastState = reactive({
|
|
|
37
37
|
// Mount the toast once on demand
|
|
38
38
|
const ensureMessageToastMounted = () => {
|
|
39
39
|
// Skip mounting during SSR
|
|
40
|
-
if (typeof document ===
|
|
40
|
+
if (typeof document === 'undefined') {
|
|
41
41
|
return Promise.resolve();
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -55,7 +55,7 @@ const ensureMessageToastMounted = () => {
|
|
|
55
55
|
// Start the lazy mount
|
|
56
56
|
messageToastMountPromise = (async () => {
|
|
57
57
|
// Load the component only when needed
|
|
58
|
-
const { default: MessageToast } = await import(
|
|
58
|
+
const { default: MessageToast } = await import('./MessageToast.vue');
|
|
59
59
|
|
|
60
60
|
// Guard against a concurrent mount
|
|
61
61
|
if (document.getElementById(MESSAGE_TOAST_ROOT_ID)) {
|
|
@@ -63,7 +63,7 @@ const ensureMessageToastMounted = () => {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// Create the host element and render the component
|
|
66
|
-
const container = document.createElement(
|
|
66
|
+
const container = document.createElement('div');
|
|
67
67
|
container.id = MESSAGE_TOAST_ROOT_ID;
|
|
68
68
|
document.body.appendChild(container);
|
|
69
69
|
render(h(MessageToast), container);
|
|
@@ -90,7 +90,7 @@ const clearMessageToastTimers = () => {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// Clear any pending open frame from a previous toast
|
|
93
|
-
if (openFrame !== null && typeof cancelAnimationFrame !==
|
|
93
|
+
if (openFrame !== null && typeof cancelAnimationFrame !== 'undefined') {
|
|
94
94
|
cancelAnimationFrame(openFrame);
|
|
95
95
|
openFrame = null;
|
|
96
96
|
}
|
|
@@ -132,14 +132,14 @@ export const showMessageToast = (options: ShowMessageToastOptions) => {
|
|
|
132
132
|
// Update the toast state while keeping the shell closed until the renderer is mounted
|
|
133
133
|
messageToastState.current = {
|
|
134
134
|
message: options.message,
|
|
135
|
-
type: options.type ??
|
|
135
|
+
type: options.type ?? 'success'
|
|
136
136
|
};
|
|
137
137
|
messageToastState.isOpen = false;
|
|
138
138
|
|
|
139
139
|
// Mount first so the initial visible transition can run after the component exists
|
|
140
140
|
void ensureMessageToastMounted().then(() => {
|
|
141
141
|
// Guard against a toast change during the async mount
|
|
142
|
-
if (toastId !== activeToastId || !messageToastState.current || typeof requestAnimationFrame ===
|
|
142
|
+
if (toastId !== activeToastId || !messageToastState.current || typeof requestAnimationFrame === 'undefined') {
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
import { Comment, Text, computed, useSlots, type VNode } from 'vue';
|
|
3
3
|
|
|
4
4
|
// Props
|
|
5
|
-
const props = defineProps
|
|
6
|
-
title:
|
|
7
|
-
headingLevel
|
|
8
|
-
size
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
title: string;
|
|
7
|
+
headingLevel?: number;
|
|
8
|
+
size?: 'small' | 'medium' | 'large';
|
|
9
|
+
}>(), {
|
|
10
|
+
headingLevel: 1,
|
|
11
|
+
size: 'large'
|
|
9
12
|
});
|
|
10
13
|
|
|
11
14
|
const slots = useSlots();
|
|
@@ -24,7 +27,7 @@ const hasSlotContent = computed(() => {
|
|
|
24
27
|
|
|
25
28
|
// Get size classes based on size prop
|
|
26
29
|
const getSizeClasses = (size: string) => {
|
|
27
|
-
const baseClasses = 'font-bold text-
|
|
30
|
+
const baseClasses = 'font-bold text-(--text-primary-light) dark:text-(--text-primary-dark)';
|
|
28
31
|
|
|
29
32
|
// Return classes based on size
|
|
30
33
|
switch (size) {
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import { Progress } from '../ui/progress';
|
|
3
3
|
|
|
4
4
|
// Props
|
|
5
|
-
const props = defineProps
|
|
6
|
-
title:
|
|
7
|
-
bottomLeftLabel
|
|
8
|
-
bottomRightLabel
|
|
9
|
-
value:
|
|
10
|
-
max:
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
title: string;
|
|
7
|
+
bottomLeftLabel?: string;
|
|
8
|
+
bottomRightLabel?: string;
|
|
9
|
+
value: number;
|
|
10
|
+
max: number;
|
|
11
|
+
}>(), {
|
|
12
|
+
bottomLeftLabel: '',
|
|
13
|
+
bottomRightLabel: ''
|
|
11
14
|
});
|
|
12
15
|
</script>
|
|
13
16
|
|
|
@@ -16,12 +19,12 @@ const props = defineProps({
|
|
|
16
19
|
<!-- Header with icon and label -->
|
|
17
20
|
<div class="flex items-center justify-between">
|
|
18
21
|
<!-- Title of the progress bar -->
|
|
19
|
-
<span class="text-sm font-semibold text-
|
|
22
|
+
<span class="text-sm font-semibold text-(--text-primary-light) dark:text-(--text-primary-dark)">
|
|
20
23
|
{{ props.title }}
|
|
21
24
|
</span>
|
|
22
25
|
|
|
23
26
|
<!-- Current value / max -->
|
|
24
|
-
<span class="text-sm font-semibold text-
|
|
27
|
+
<span class="text-sm font-semibold text-(--text-primary-light) dark:text-(--text-primary-dark)">
|
|
25
28
|
{{ props.value }} / {{ props.max }}
|
|
26
29
|
</span>
|
|
27
30
|
</div>
|
|
@@ -32,12 +35,12 @@ const props = defineProps({
|
|
|
32
35
|
<!-- Bottom labels -->
|
|
33
36
|
<div v-if="props.bottomLeftLabel || props.bottomRightLabel" class="flex items-center justify-between text-xs">
|
|
34
37
|
<!-- Bottom left label -->
|
|
35
|
-
<span v-if="props.bottomLeftLabel" class="text-
|
|
38
|
+
<span v-if="props.bottomLeftLabel" class="text-(--text-secondary-light) dark:text-(--text-secondary-dark)">
|
|
36
39
|
{{ props.bottomLeftLabel }}
|
|
37
40
|
</span>
|
|
38
41
|
|
|
39
42
|
<!-- Bottom right label -->
|
|
40
|
-
<span v-if="props.bottomRightLabel" class="text-
|
|
43
|
+
<span v-if="props.bottomRightLabel" class="text-(--text-secondary-light) dark:text-(--text-secondary-dark)">
|
|
41
44
|
{{ props.bottomRightLabel }}
|
|
42
45
|
</span>
|
|
43
46
|
</div>
|
|
@@ -1,43 +1,46 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed } from
|
|
3
|
-
import { HugeiconsIcon } from
|
|
4
|
-
import { Card, CardContent } from
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { HugeiconsIcon } from '@hugeicons/vue';
|
|
4
|
+
import { Card, CardContent } from '../ui/card';
|
|
5
|
+
import type { HugeiconsIconDefinition } from '../../lib/common-types';
|
|
5
6
|
|
|
6
7
|
// Props
|
|
7
|
-
const props = defineProps
|
|
8
|
-
value:
|
|
9
|
-
label:
|
|
10
|
-
icon:
|
|
11
|
-
valueColor
|
|
8
|
+
const props = withDefaults(defineProps<{
|
|
9
|
+
value: string | number;
|
|
10
|
+
label: string;
|
|
11
|
+
icon: HugeiconsIconDefinition;
|
|
12
|
+
valueColor?: 'default' | 'green' | 'red' | 'gray';
|
|
13
|
+
}>(), {
|
|
14
|
+
valueColor: 'default'
|
|
12
15
|
});
|
|
13
16
|
|
|
14
17
|
// Value classes
|
|
15
18
|
const valueClass = computed(() => {
|
|
16
19
|
switch (props.valueColor) {
|
|
17
|
-
case
|
|
18
|
-
return
|
|
19
|
-
case
|
|
20
|
-
return
|
|
21
|
-
case
|
|
22
|
-
return
|
|
20
|
+
case 'green':
|
|
21
|
+
return 'text-green-600 dark:text-green-400';
|
|
22
|
+
case 'red':
|
|
23
|
+
return 'text-red-600 dark:text-red-400';
|
|
24
|
+
case 'gray':
|
|
25
|
+
return 'text-gray-600 dark:text-gray-400';
|
|
23
26
|
default:
|
|
24
|
-
return
|
|
27
|
+
return 'text-(--text-primary-light) dark:text-(--text-primary-dark)';
|
|
25
28
|
}
|
|
26
29
|
});
|
|
27
30
|
</script>
|
|
28
31
|
|
|
29
32
|
<template>
|
|
30
|
-
<Card class="flex-row items-center
|
|
31
|
-
<CardContent class="
|
|
33
|
+
<Card class="flex-row items-center p-4!">
|
|
34
|
+
<CardContent class="flex-row items-center gap-0 p-0!">
|
|
32
35
|
<!-- Icon -->
|
|
33
|
-
<Card color="gray" class="mr-4 flex h-12 w-12
|
|
36
|
+
<Card color="gray" class="mr-4 flex h-12 w-12 shrink-0 items-center justify-center p-0!">
|
|
34
37
|
<HugeiconsIcon :icon="props.icon" class="size-5" />
|
|
35
38
|
</Card>
|
|
36
39
|
|
|
37
40
|
<!-- Content -->
|
|
38
41
|
<div class="flex flex-col">
|
|
39
42
|
<!-- Label -->
|
|
40
|
-
<span class="mb-1 text-xs font-semibold text-
|
|
43
|
+
<span class="mb-1 text-xs font-semibold text-(--text-secondary-light) dark:text-(--text-secondary-dark)">
|
|
41
44
|
{{ props.label }}
|
|
42
45
|
</span>
|
|
43
46
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed } from
|
|
3
|
-
import { Card } from
|
|
4
|
-
import { Slider } from
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import { Card } from '../ui/card';
|
|
4
|
+
import { Slider } from '../ui/slider';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Props
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
7
8
|
id?: string;
|
|
8
9
|
label: string;
|
|
9
10
|
description?: string;
|
|
@@ -12,21 +13,18 @@ interface SliderFormComponentProps {
|
|
|
12
13
|
max?: number;
|
|
13
14
|
step?: number;
|
|
14
15
|
valueText?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Props
|
|
18
|
-
const props = withDefaults(defineProps<SliderFormComponentProps>(), {
|
|
16
|
+
}>(), {
|
|
19
17
|
id: undefined,
|
|
20
|
-
description:
|
|
18
|
+
description: '',
|
|
21
19
|
min: 0,
|
|
22
20
|
max: 100,
|
|
23
21
|
step: 1,
|
|
24
|
-
valueText:
|
|
22
|
+
valueText: ''
|
|
25
23
|
});
|
|
26
24
|
|
|
27
25
|
// Emits
|
|
28
26
|
const emits = defineEmits<{
|
|
29
|
-
(e:
|
|
27
|
+
(e: 'update:modelValue', value: number): void;
|
|
30
28
|
}>();
|
|
31
29
|
|
|
32
30
|
const sliderValue = computed(() => [props.modelValue]);
|
|
@@ -34,7 +32,7 @@ const resolvedValueText = computed(() => props.valueText || String(props.modelVa
|
|
|
34
32
|
|
|
35
33
|
// Emit the first slider value back to the parent
|
|
36
34
|
const handleUpdateModelValue = (value?: number[]) => {
|
|
37
|
-
emits(
|
|
35
|
+
emits('update:modelValue', value?.[0] ?? props.min);
|
|
38
36
|
};
|
|
39
37
|
</script>
|
|
40
38
|
|
|
@@ -59,13 +57,6 @@ const handleUpdateModelValue = (value?: number[]) => {
|
|
|
59
57
|
</div>
|
|
60
58
|
|
|
61
59
|
<!-- Slider control -->
|
|
62
|
-
<Slider
|
|
63
|
-
:id="props.id"
|
|
64
|
-
:model-value="sliderValue"
|
|
65
|
-
:min="props.min"
|
|
66
|
-
:max="props.max"
|
|
67
|
-
:step="props.step"
|
|
68
|
-
@update:model-value="handleUpdateModelValue"
|
|
69
|
-
/>
|
|
60
|
+
<Slider :id="props.id" :model-value="sliderValue" :min="props.min" :max="props.max" :step="props.step" @update:model-value="handleUpdateModelValue" />
|
|
70
61
|
</Card>
|
|
71
62
|
</template>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from
|
|
2
|
-
export { default as SliderFormComponent } from
|
|
1
|
+
export { default } from './SliderFormComponent.vue';
|
|
2
|
+
export { default as SliderFormComponent } from './SliderFormComponent.vue';
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { Card } from
|
|
3
|
-
import { Switch } from
|
|
2
|
+
import { Card } from '../ui/card';
|
|
3
|
+
import { Switch } from '../ui/switch';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// Props
|
|
6
|
+
const props = defineProps<{
|
|
6
7
|
id: string;
|
|
7
8
|
label: string;
|
|
8
9
|
description: string;
|
|
9
10
|
modelValue: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Props
|
|
13
|
-
const props = defineProps<SwitchFormComponentProps>();
|
|
11
|
+
}>();
|
|
14
12
|
|
|
15
13
|
// Emits
|
|
16
14
|
const emits = defineEmits<{
|
|
17
|
-
(e:
|
|
15
|
+
(e: 'update:modelValue', value: boolean): void;
|
|
18
16
|
}>();
|
|
19
17
|
</script>
|
|
20
18
|
|
|
21
19
|
<template>
|
|
22
|
-
<Card class="flex flex-col gap-2
|
|
20
|
+
<Card class="flex flex-col gap-2 px-4 py-3 sm:gap-3!">
|
|
23
21
|
<!-- Switch label and control -->
|
|
24
22
|
<div class="flex items-center justify-between gap-4">
|
|
25
23
|
<!-- Switch label -->
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from
|
|
2
|
-
export { default as SwitchFormComponent } from
|
|
1
|
+
export { default } from './SwitchFormComponent.vue';
|
|
2
|
+
export { default as SwitchFormComponent } from './SwitchFormComponent.vue';
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type { Component
|
|
2
|
+
import type { Component } from 'vue';
|
|
3
3
|
|
|
4
4
|
// Props
|
|
5
|
-
const props = defineProps
|
|
6
|
-
to:
|
|
7
|
-
text:
|
|
8
|
-
linkComponent
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
to: string;
|
|
7
|
+
text: string;
|
|
8
|
+
linkComponent?: Component | string;
|
|
9
|
+
}>(), {
|
|
10
|
+
linkComponent: 'a'
|
|
9
11
|
});
|
|
10
12
|
|
|
11
13
|
// Emits
|
|
12
|
-
const emits = defineEmits
|
|
14
|
+
const emits = defineEmits<{
|
|
15
|
+
click: [event: MouseEvent];
|
|
16
|
+
}>();
|
|
13
17
|
|
|
14
18
|
// Get link props based on the type of link component
|
|
15
19
|
const getLinkProps = () => {
|
|
@@ -27,7 +31,7 @@ const handleClick = (event: MouseEvent) => {
|
|
|
27
31
|
</script>
|
|
28
32
|
|
|
29
33
|
<template>
|
|
30
|
-
<component :is="props.linkComponent" v-bind="getLinkProps()" class="cursor-pointer font-semibold text-
|
|
34
|
+
<component :is="props.linkComponent" v-bind="getLinkProps()" class="cursor-pointer font-semibold text-(--text-primary-light) hover:underline dark:text-(--text-primary-dark)" @click="handleClick">
|
|
31
35
|
{{ props.text }}
|
|
32
36
|
</component>
|
|
33
37
|
</template>
|