@brumaombra/ui-vintage 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -0
- package/COMPONENTS.md +88 -17
- package/README.md +296 -262
- package/module.mjs +5 -11
- package/package.json +30 -12
- package/src/components/blog/BlogContentRenderer.vue +1 -1
- package/src/components/blog/BlogHeaderSection.vue +93 -19
- package/src/components/blog/BlogInfoSection.vue +39 -36
- package/src/components/blog/BlogPostHeader.vue +181 -0
- package/src/components/blog/BlogProgressBar.vue +3 -5
- package/src/components/blog/BlogSectionTitle.vue +8 -6
- package/src/components/blog/BlogTagsSection.vue +16 -7
- package/src/components/blog/CategoryCard.vue +18 -23
- package/src/components/blog/HeaderCarousel.vue +15 -6
- package/src/components/blog/PostCard.vue +13 -20
- package/src/components/blog/SocialShareSidebar.vue +24 -14
- package/src/components/blog/TableOfContents.vue +61 -28
- package/src/components/blog/index.ts +1 -0
- package/src/components/card-grid/CardGrid.vue +2 -2
- package/src/components/confirm-dialog/ConfirmDialog.vue +5 -0
- package/src/components/confirm-dialog/confirm-dialog-state.ts +22 -22
- package/src/components/content/BlogList.vue +28 -52
- package/src/components/content/BlogTable.vue +26 -30
- package/src/components/content/CodeBlock.vue +96 -22
- package/src/components/content/Flow.vue +29 -35
- package/src/components/content/ProseHr.vue +5 -5
- package/src/components/content/ProsePre.vue +9 -4
- package/src/components/content/Terminal.vue +42 -20
- package/src/components/cookie-consent/CookieConsent.vue +1 -1
- package/src/components/dashboard-shell/DashboardShell.vue +24 -7
- package/src/components/empty-state-card/EmptyStateCard.vue +2 -2
- package/src/components/error-page/ErrorPage.vue +3 -3
- package/src/components/info-card/InfoCard.vue +4 -4
- package/src/components/landing/landing-footer/LandingFooter.vue +16 -11
- package/src/components/landing/landing-navbar/LandingNavbar.vue +22 -6
- package/src/components/landing/landing-shell/LandingShell.vue +2 -7
- package/src/components/language-flag/index.ts +1 -0
- package/src/components/language-selector/LanguageSelector.vue +18 -10
- package/src/components/load-more-button/LoadMoreButton.vue +7 -12
- package/src/components/loading-state-card/LoadingStateCard.vue +2 -2
- package/src/components/message-dialog/MessageDialog.vue +11 -11
- package/src/components/message-dialog/message-dialog-state.ts +1 -4
- package/src/components/message-toast/MessageToast.vue +24 -9
- package/src/components/message-toast/message-toast-state.ts +20 -0
- package/src/components/page-header/PageHeader.vue +1 -1
- package/src/components/progress-component/ProgressComponent.vue +7 -3
- package/src/components/single-value-card/SingleValueCard.vue +37 -39
- package/src/components/slider-form-component/SliderFormComponent.vue +1 -1
- package/src/components/stat-strip/StatStrip.vue +36 -0
- package/src/components/stat-strip/index.ts +2 -0
- package/src/components/switch-form-component/SwitchFormComponent.vue +5 -5
- package/src/components/text-link/TextLink.vue +1 -1
- package/src/components/theme-selector/ThemeSelector.vue +2 -2
- package/src/components/theme-selector/theme-transition.ts +15 -3
- package/src/components/ui/accordion/Accordion.vue +18 -18
- package/src/components/ui/alert/AlertTitle.vue +1 -1
- package/src/components/ui/alert/index.ts +1 -1
- package/src/components/ui/avatar/AvatarFallback.vue +2 -1
- package/src/components/ui/avatar/AvatarGroup.vue +13 -3
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +2 -2
- package/src/components/ui/busy/Busy.vue +5 -7
- package/src/components/ui/button/Button.vue +4 -2
- package/src/components/ui/button/index.ts +1 -4
- package/src/components/ui/calendar/Calendar.vue +12 -7
- package/src/components/ui/calendar/CalendarCell.vue +1 -1
- package/src/components/ui/calendar/CalendarCellTrigger.vue +1 -1
- package/src/components/ui/calendar/CalendarHeadCell.vue +1 -1
- package/src/components/ui/calendar/CalendarNextButton.vue +1 -1
- package/src/components/ui/calendar/CalendarPrevButton.vue +1 -1
- package/src/components/ui/card/Card.vue +5 -15
- package/src/components/ui/checkbox/Checkbox.vue +5 -1
- package/src/components/ui/combobox/ComboboxInput.vue +5 -1
- package/src/components/ui/command/CommandGroup.vue +17 -3
- package/src/components/ui/command/CommandInput.vue +1 -1
- package/src/components/ui/command/CommandList.vue +5 -1
- package/src/components/ui/data-table/DataTable.vue +11 -3
- package/src/components/ui/date-picker/DatePicker.vue +7 -1
- package/src/components/ui/date-time-picker/DateTimePicker.vue +5 -1
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +1 -1
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +1 -1
- package/src/components/ui/dropdown-menu/classes.ts +2 -0
- package/src/components/ui/field/Field.vue +4 -0
- package/src/components/ui/field/FieldLabel.vue +6 -2
- package/src/components/ui/field/field-context.ts +62 -0
- package/src/components/ui/field/index.ts +1 -0
- package/src/components/ui/file-dropzone/FileDropzone.vue +4 -4
- package/src/components/ui/input/Input.vue +5 -1
- package/src/components/ui/native-select/NativeSelect.vue +6 -2
- package/src/components/ui/number-field/NumberField.vue +5 -1
- package/src/components/ui/pagination/PaginationItem.vue +1 -1
- package/src/components/ui/pin-input/PinInputInput.vue +2 -2
- package/src/components/ui/progress/Progress.vue +2 -2
- package/src/components/ui/radio-group/RadioGroupCard.vue +1 -1
- package/src/components/ui/select/SelectItem.vue +1 -1
- package/src/components/ui/select/SelectItemContent.vue +1 -1
- package/src/components/ui/select/SelectTrigger.vue +5 -1
- package/src/components/ui/sidebar/Sidebar.vue +1 -1
- package/src/components/ui/sidebar/SidebarGroupAction.vue +1 -1
- package/src/components/ui/sidebar/SidebarGroupLabel.vue +1 -1
- package/src/components/ui/sidebar/SidebarInset.vue +1 -1
- package/src/components/ui/sidebar/SidebarMenuAction.vue +1 -1
- package/src/components/ui/sidebar/SidebarMenuBadge.vue +1 -1
- package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +2 -2
- package/src/components/ui/sidebar/SidebarMenuSubButton.vue +1 -1
- package/src/components/ui/sidebar/SidebarProvider.vue +17 -6
- package/src/components/ui/sidebar/index.ts +2 -2
- package/src/components/ui/sidebar/utils.ts +1 -1
- package/src/components/ui/slider/Slider.vue +5 -4
- package/src/components/ui/spinner/Spinner.vue +3 -2
- package/src/components/ui/stepper/StepperDescription.vue +5 -3
- package/src/components/ui/stepper/StepperIndicator.vue +2 -2
- package/src/components/ui/stepper/StepperTitle.vue +5 -3
- package/src/components/ui/switch/Switch.vue +6 -2
- package/src/components/ui/tabs/TabsList.vue +1 -1
- package/src/components/ui/tabs/TabsTrigger.vue +1 -1
- package/src/components/ui/textarea/Textarea.vue +5 -1
- package/src/components/ui/time-picker/TimePicker.vue +2 -2
- package/src/components/ui/toggle-group/ToggleGroup.vue +1 -1
- package/src/components/ui/tooltip/TooltipContent.vue +1 -1
- package/src/i18n/de.json +16 -6
- package/src/i18n/en.json +16 -6
- package/src/i18n/es.json +16 -6
- package/src/i18n/fr.json +16 -6
- package/src/i18n/it.json +16 -6
- package/src/i18n/ja.json +16 -6
- package/src/i18n/pt.json +16 -6
- package/src/i18n/ru.json +16 -6
- package/src/i18n/zh.json +16 -6
- package/src/lib/color-tokens.ts +1 -1
- package/src/lib/i18n.ts +32 -4
- package/src/lib/utils.ts +21 -1
- package/src/runtime/ui-vintage-i18n-plugin.ts +11 -1
- package/src/styles.css +12 -16
- package/skills/ui-vintage/SKILL.md +0 -42
package/src/i18n/es.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "Navegación de migas de pan",
|
|
5
5
|
"more": "Más",
|
|
6
|
+
"home": "Inicio",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "Todavia no hay nada aqui",
|
|
8
9
|
"description": "No hay contenido para mostrar en este momento."
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "Cargando...",
|
|
12
13
|
"description": "Espera un momento mientras cargamos el contenido."
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "Logotipo de {name}"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "Quitar",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "Busca un comando para ejecutar..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "Elegir una fecha"
|
|
55
|
+
"placeholder": "Elegir una fecha",
|
|
56
|
+
"month": "Mes",
|
|
57
|
+
"year": "Año",
|
|
58
|
+
"time": "Hora"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "Terminal",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "Codigo",
|
|
62
67
|
"copy": "Copiar codigo",
|
|
63
|
-
"copied": "Codigo copiado"
|
|
68
|
+
"copied": "Codigo copiado",
|
|
69
|
+
"position": "Lín. {line}, col. {column}",
|
|
70
|
+
"plainText": "Texto sin formato"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "Hecho con",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "Progreso de lectura",
|
|
72
79
|
"readMore": "Leer mas",
|
|
73
80
|
"goToPost": "Ir al articulo",
|
|
81
|
+
"new": "Nuevo",
|
|
74
82
|
"tableOfContents": "Tabla de contenidos",
|
|
75
83
|
"tableOfContentsDescription": "Ir a una seccion de este articulo",
|
|
84
|
+
"tableOfContentsSections": "{count} seccion | {count} secciones",
|
|
76
85
|
"openTableOfContents": "Abrir tabla de contenidos",
|
|
77
86
|
"closeTableOfContents": "Cerrar tabla de contenidos",
|
|
78
87
|
"loadMoreWithNumbers": "Cargar mas ({current}/{total})",
|
|
79
88
|
"author": "Autor",
|
|
80
89
|
"publishedDate": "Publicado",
|
|
81
90
|
"lastUpdatedDate": "Actualizado",
|
|
91
|
+
"readingTime": "Tiempo de lectura",
|
|
92
|
+
"readingTimeValue": "{minutes} min",
|
|
93
|
+
"category": "Categoría",
|
|
94
|
+
"breadcrumbBlog": "Blog",
|
|
82
95
|
"carouselNavigation": "Navegacion del carrusel",
|
|
83
96
|
"goToSlide": "Ir a la diapositiva {index}",
|
|
84
97
|
"previousSlide": "Diapositiva anterior",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "Enlace copiado"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "Selecciona una opcion"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "Página no encontrada",
|
package/src/i18n/fr.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "Fil d'Ariane",
|
|
5
5
|
"more": "Plus",
|
|
6
|
+
"home": "Accueil",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "Rien ici pour le moment",
|
|
8
9
|
"description": "Il n'y a aucun contenu a afficher pour le moment."
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "Chargement...",
|
|
12
13
|
"description": "Veuillez patienter un instant pendant le chargement du contenu."
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "Logo de {name}"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "Retirer",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "Rechercher une commande à exécuter..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "Choisir une date"
|
|
55
|
+
"placeholder": "Choisir une date",
|
|
56
|
+
"month": "Mois",
|
|
57
|
+
"year": "Année",
|
|
58
|
+
"time": "Heure"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "Terminal",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "Code",
|
|
62
67
|
"copy": "Copier le code",
|
|
63
|
-
"copied": "Code copie"
|
|
68
|
+
"copied": "Code copie",
|
|
69
|
+
"position": "Ligne {line}, col. {column}",
|
|
70
|
+
"plainText": "Texte brut"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "Fait avec",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "Progression de lecture",
|
|
72
79
|
"readMore": "Lire la suite",
|
|
73
80
|
"goToPost": "Aller a l'article",
|
|
81
|
+
"new": "Nouveau",
|
|
74
82
|
"tableOfContents": "Table des matieres",
|
|
75
83
|
"tableOfContentsDescription": "Aller a une section de cet article",
|
|
84
|
+
"tableOfContentsSections": "{count} section | {count} sections",
|
|
76
85
|
"openTableOfContents": "Ouvrir la table des matieres",
|
|
77
86
|
"closeTableOfContents": "Fermer la table des matieres",
|
|
78
87
|
"loadMoreWithNumbers": "Charger plus ({current}/{total})",
|
|
79
88
|
"author": "Auteur",
|
|
80
89
|
"publishedDate": "Publie",
|
|
81
90
|
"lastUpdatedDate": "Mis a jour",
|
|
91
|
+
"readingTime": "Temps de lecture",
|
|
92
|
+
"readingTimeValue": "{minutes} min",
|
|
93
|
+
"category": "Catégorie",
|
|
94
|
+
"breadcrumbBlog": "Blog",
|
|
82
95
|
"carouselNavigation": "Navigation du carrousel",
|
|
83
96
|
"goToSlide": "Aller a la diapositive {index}",
|
|
84
97
|
"previousSlide": "Diapositive precedente",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "Lien copié"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "Selectionnez une option"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "Page introuvable",
|
package/src/i18n/it.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "Percorso di navigazione",
|
|
5
5
|
"more": "Altro",
|
|
6
|
+
"home": "Home",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "Non c'è ancora niente qui",
|
|
8
9
|
"description": "Al momento non c'è alcun contenuto da mostrare."
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "Caricamento...",
|
|
12
13
|
"description": "Attendi un momento mentre carichiamo il contenuto."
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "Logo di {name}"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "Rimuovi",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "Cerca un comando da eseguire..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "Scegli una data"
|
|
55
|
+
"placeholder": "Scegli una data",
|
|
56
|
+
"month": "Mese",
|
|
57
|
+
"year": "Anno",
|
|
58
|
+
"time": "Ora"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "Terminale",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "Codice",
|
|
62
67
|
"copy": "Copia codice",
|
|
63
|
-
"copied": "Codice copiato"
|
|
68
|
+
"copied": "Codice copiato",
|
|
69
|
+
"position": "Riga {line}, col. {column}",
|
|
70
|
+
"plainText": "Testo semplice"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "Fatto con",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "Avanzamento della lettura",
|
|
72
79
|
"readMore": "Leggi di piu",
|
|
73
80
|
"goToPost": "Vai all'articolo",
|
|
81
|
+
"new": "Novità",
|
|
74
82
|
"tableOfContents": "Indice dei contenuti",
|
|
75
83
|
"tableOfContentsDescription": "Vai a una sezione dell'articolo",
|
|
84
|
+
"tableOfContentsSections": "{count} sezione | {count} sezioni",
|
|
76
85
|
"openTableOfContents": "Apri l'indice dei contenuti",
|
|
77
86
|
"closeTableOfContents": "Chiudi l'indice dei contenuti",
|
|
78
87
|
"loadMoreWithNumbers": "Carica altro ({current}/{total})",
|
|
79
88
|
"author": "Autore",
|
|
80
89
|
"publishedDate": "Pubblicato",
|
|
81
90
|
"lastUpdatedDate": "Aggiornato",
|
|
91
|
+
"readingTime": "Tempo di lettura",
|
|
92
|
+
"readingTimeValue": "{minutes} min",
|
|
93
|
+
"category": "Categoria",
|
|
94
|
+
"breadcrumbBlog": "Blog",
|
|
82
95
|
"carouselNavigation": "Navigazione carosello",
|
|
83
96
|
"goToSlide": "Vai alla slide {index}",
|
|
84
97
|
"previousSlide": "Slide precedente",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "Link copiato"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "Seleziona un'opzione"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "Pagina non trovata",
|
package/src/i18n/ja.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "パンくずリスト",
|
|
5
5
|
"more": "もっと見る",
|
|
6
|
+
"home": "ホーム",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "まだ何もありません",
|
|
8
9
|
"description": "現在表示できるコンテンツはありません。"
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "読み込み中...",
|
|
12
13
|
"description": "コンテンツを読み込んでいます。しばらくお待ちください。"
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "{name} のロゴ"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "取り除く",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "実行するコマンドを検索..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "日付を選択"
|
|
55
|
+
"placeholder": "日付を選択",
|
|
56
|
+
"month": "月",
|
|
57
|
+
"year": "年",
|
|
58
|
+
"time": "時刻"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "ターミナル",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "コード",
|
|
62
67
|
"copy": "コードをコピー",
|
|
63
|
-
"copied": "コードをコピーしました"
|
|
68
|
+
"copied": "コードをコピーしました",
|
|
69
|
+
"position": "{line} 行、{column} 列",
|
|
70
|
+
"plainText": "プレーンテキスト"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "愛を込めて",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "読書の進捗",
|
|
72
79
|
"readMore": "続きを読む",
|
|
73
80
|
"goToPost": "記事を開く",
|
|
81
|
+
"new": "新着",
|
|
74
82
|
"tableOfContents": "目次",
|
|
75
83
|
"tableOfContentsDescription": "この記事のセクションに移動",
|
|
84
|
+
"tableOfContentsSections": "{count} セクション",
|
|
76
85
|
"openTableOfContents": "目次を開く",
|
|
77
86
|
"closeTableOfContents": "目次を閉じる",
|
|
78
87
|
"loadMoreWithNumbers": "さらに読み込む ({current}/{total})",
|
|
79
88
|
"author": "著者",
|
|
80
89
|
"publishedDate": "公開日",
|
|
81
90
|
"lastUpdatedDate": "更新日",
|
|
91
|
+
"readingTime": "読了時間",
|
|
92
|
+
"readingTimeValue": "{minutes}分",
|
|
93
|
+
"category": "カテゴリー",
|
|
94
|
+
"breadcrumbBlog": "ブログ",
|
|
82
95
|
"carouselNavigation": "カルーセルナビゲーション",
|
|
83
96
|
"goToSlide": "スライド {index} へ移動",
|
|
84
97
|
"previousSlide": "前のスライド",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "リンクをコピーしました"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "オプションを選択してください"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "ページが見つかりません",
|
package/src/i18n/pt.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "Navegação estrutural",
|
|
5
5
|
"more": "Mais",
|
|
6
|
+
"home": "Início",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "Ainda nao ha nada aqui",
|
|
8
9
|
"description": "Nao ha conteudo para mostrar neste momento."
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "Carregando...",
|
|
12
13
|
"description": "Aguarde um momento enquanto carregamos o conteudo."
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "Logótipo de {name}"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "Remover",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "Pesquise um comando para executar..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "Selecione uma data"
|
|
55
|
+
"placeholder": "Selecione uma data",
|
|
56
|
+
"month": "Mês",
|
|
57
|
+
"year": "Ano",
|
|
58
|
+
"time": "Hora"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "Terminal",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "Codigo",
|
|
62
67
|
"copy": "Copiar codigo",
|
|
63
|
-
"copied": "Codigo copiado"
|
|
68
|
+
"copied": "Codigo copiado",
|
|
69
|
+
"position": "Ln {line}, Col {column}",
|
|
70
|
+
"plainText": "Texto simples"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "Feito com",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "Progresso da leitura",
|
|
72
79
|
"readMore": "Ler mais",
|
|
73
80
|
"goToPost": "Ir para o artigo",
|
|
81
|
+
"new": "Novo",
|
|
74
82
|
"tableOfContents": "Indice",
|
|
75
83
|
"tableOfContentsDescription": "Ir para uma secao deste artigo",
|
|
84
|
+
"tableOfContentsSections": "{count} secao | {count} secoes",
|
|
76
85
|
"openTableOfContents": "Abrir indice",
|
|
77
86
|
"closeTableOfContents": "Fechar indice",
|
|
78
87
|
"loadMoreWithNumbers": "Carregar mais ({current}/{total})",
|
|
79
88
|
"author": "Autor",
|
|
80
89
|
"publishedDate": "Publicado",
|
|
81
90
|
"lastUpdatedDate": "Atualizado",
|
|
91
|
+
"readingTime": "Tempo de leitura",
|
|
92
|
+
"readingTimeValue": "{minutes} min",
|
|
93
|
+
"category": "Categoria",
|
|
94
|
+
"breadcrumbBlog": "Blog",
|
|
82
95
|
"carouselNavigation": "Navegacao do carrossel",
|
|
83
96
|
"goToSlide": "Ir para o slide {index}",
|
|
84
97
|
"previousSlide": "Slide anterior",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "Link copiado"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "Selecione uma opcao"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "Página não encontrada",
|
package/src/i18n/ru.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "Навигация по хлебным крошкам",
|
|
5
5
|
"more": "Ещё",
|
|
6
|
+
"home": "Главная",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "Здесь пока ничего нет",
|
|
8
9
|
"description": "Сейчас нет контента для отображения."
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "Загрузка...",
|
|
12
13
|
"description": "Подождите немного, пока мы загружаем содержимое."
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "Логотип {name}"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "Убрать",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "Найти команду для выполнения..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "Выберите дату"
|
|
55
|
+
"placeholder": "Выберите дату",
|
|
56
|
+
"month": "Месяц",
|
|
57
|
+
"year": "Год",
|
|
58
|
+
"time": "Время"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "Терминал",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "Код",
|
|
62
67
|
"copy": "Копировать код",
|
|
63
|
-
"copied": "Код скопирован"
|
|
68
|
+
"copied": "Код скопирован",
|
|
69
|
+
"position": "Стр. {line}, стлб. {column}",
|
|
70
|
+
"plainText": "Обычный текст"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "Сделано с",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "Прогресс чтения",
|
|
72
79
|
"readMore": "Читать далее",
|
|
73
80
|
"goToPost": "Перейти к статье",
|
|
81
|
+
"new": "Новое",
|
|
74
82
|
"tableOfContents": "Содержание",
|
|
75
83
|
"tableOfContentsDescription": "Перейти к разделу статьи",
|
|
84
|
+
"tableOfContentsSections": "Разделов: {count}",
|
|
76
85
|
"openTableOfContents": "Открыть содержание",
|
|
77
86
|
"closeTableOfContents": "Закрыть содержание",
|
|
78
87
|
"loadMoreWithNumbers": "Загрузить еще ({current}/{total})",
|
|
79
88
|
"author": "Автор",
|
|
80
89
|
"publishedDate": "Опубликовано",
|
|
81
90
|
"lastUpdatedDate": "Обновлено",
|
|
91
|
+
"readingTime": "Время чтения",
|
|
92
|
+
"readingTimeValue": "{minutes} мин",
|
|
93
|
+
"category": "Категория",
|
|
94
|
+
"breadcrumbBlog": "Блог",
|
|
82
95
|
"carouselNavigation": "Навигация карусели",
|
|
83
96
|
"goToSlide": "Перейти к слайду {index}",
|
|
84
97
|
"previousSlide": "Предыдущий слайд",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "Ссылка скопирована"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "Выберите вариант"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "Страница не найдена",
|
package/src/i18n/zh.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"common": {
|
|
4
4
|
"breadcrumb": "面包屑导航",
|
|
5
5
|
"more": "更多",
|
|
6
|
+
"home": "首页",
|
|
6
7
|
"empty": {
|
|
7
8
|
"title": "这里还没有内容",
|
|
8
9
|
"description": "当前没有可显示的内容。"
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
"loading": {
|
|
11
12
|
"title": "加载中...",
|
|
12
13
|
"description": "请稍候,正在加载内容。"
|
|
13
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"logo": "{name} 标志"
|
|
14
16
|
},
|
|
15
17
|
"buttons": {
|
|
16
18
|
"remove": "移除",
|
|
@@ -50,7 +52,10 @@
|
|
|
50
52
|
"description": "搜索要运行的命令..."
|
|
51
53
|
},
|
|
52
54
|
"datePicker": {
|
|
53
|
-
"placeholder": "选择日期"
|
|
55
|
+
"placeholder": "选择日期",
|
|
56
|
+
"month": "月份",
|
|
57
|
+
"year": "年份",
|
|
58
|
+
"time": "时间"
|
|
54
59
|
},
|
|
55
60
|
"terminal": {
|
|
56
61
|
"title": "终端",
|
|
@@ -60,7 +65,9 @@
|
|
|
60
65
|
"code": {
|
|
61
66
|
"title": "代码",
|
|
62
67
|
"copy": "复制代码",
|
|
63
|
-
"copied": "代码已复制"
|
|
68
|
+
"copied": "代码已复制",
|
|
69
|
+
"position": "第 {line} 行,第 {column} 列",
|
|
70
|
+
"plainText": "纯文本"
|
|
64
71
|
},
|
|
65
72
|
"footer": {
|
|
66
73
|
"madeWith": "用",
|
|
@@ -71,14 +78,20 @@
|
|
|
71
78
|
"readingProgress": "阅读进度",
|
|
72
79
|
"readMore": "阅读更多",
|
|
73
80
|
"goToPost": "前往文章",
|
|
81
|
+
"new": "最新",
|
|
74
82
|
"tableOfContents": "目录",
|
|
75
83
|
"tableOfContentsDescription": "跳转到本文的一个部分",
|
|
84
|
+
"tableOfContentsSections": "{count} 个章节",
|
|
76
85
|
"openTableOfContents": "打开目录",
|
|
77
86
|
"closeTableOfContents": "关闭目录",
|
|
78
87
|
"loadMoreWithNumbers": "加载更多 ({current}/{total})",
|
|
79
88
|
"author": "作者",
|
|
80
89
|
"publishedDate": "发布时间",
|
|
81
90
|
"lastUpdatedDate": "更新时间",
|
|
91
|
+
"readingTime": "阅读时间",
|
|
92
|
+
"readingTimeValue": "{minutes} 分钟",
|
|
93
|
+
"category": "分类",
|
|
94
|
+
"breadcrumbBlog": "博客",
|
|
82
95
|
"carouselNavigation": "轮播导航",
|
|
83
96
|
"goToSlide": "转到第 {index} 张幻灯片",
|
|
84
97
|
"previousSlide": "上一张幻灯片",
|
|
@@ -97,9 +110,6 @@
|
|
|
97
110
|
"copied": "链接已复制"
|
|
98
111
|
}
|
|
99
112
|
},
|
|
100
|
-
"select": {
|
|
101
|
-
"defaultPlaceholder": "请选择一个选项"
|
|
102
|
-
},
|
|
103
113
|
"errorPage": {
|
|
104
114
|
"notFound": {
|
|
105
115
|
"title": "找不到页面",
|
package/src/lib/color-tokens.ts
CHANGED
|
@@ -32,7 +32,7 @@ export const getInteractiveSurfaceToneClasses = (color: ToneColor) => {
|
|
|
32
32
|
// Return the list of classes for button variants
|
|
33
33
|
export const buttonVariantClasses: Record<ButtonVariantName, string> = {
|
|
34
34
|
// Custom button variants
|
|
35
|
-
primary: "bg-primary text-primary-foreground shadow-
|
|
35
|
+
primary: "bg-primary text-primary-foreground shadow-elevated-sm hover:bg-primary-hover",
|
|
36
36
|
secondary: "border border-border bg-secondary text-foreground shadow-elevated-sm hover:border-border-strong hover:bg-accent",
|
|
37
37
|
ghost: "text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
38
38
|
link: "text-primary underline-offset-4 decoration-2 hover:underline enabled:active:scale-100",
|
package/src/lib/i18n.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useI18n } from 'vue-i18n';
|
|
1
2
|
import en from '../i18n/en.json';
|
|
2
3
|
import it from '../i18n/it.json';
|
|
3
4
|
import fr from '../i18n/fr.json';
|
|
@@ -24,12 +25,23 @@ export const uiVintageMessages = {
|
|
|
24
25
|
// The type of the available locales based on the keys of the messages object
|
|
25
26
|
type UiVintageLocale = keyof typeof uiVintageMessages;
|
|
26
27
|
|
|
27
|
-
//
|
|
28
|
+
// Browser-only source of the app locale (set by the Nuxt plugin from the vue-i18n instance)
|
|
29
|
+
let runtimeLocaleSource: (() => string | undefined) | null = null;
|
|
30
|
+
|
|
31
|
+
// Let the app tell the imperatively mounted components which locale it uses
|
|
32
|
+
export const setUiVintageRuntimeLocaleSource = (source: (() => string | undefined) | null) => {
|
|
33
|
+
runtimeLocaleSource = source;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Resolve the current runtime locale from the app, the document or the navigator
|
|
28
37
|
const getUiVintageRuntimeLocale = (): UiVintageLocale => {
|
|
29
38
|
let browserLocale = 'en';
|
|
30
39
|
|
|
31
|
-
//
|
|
32
|
-
|
|
40
|
+
// Prefer the app locale, then try to detect the user's locale from the document or navigator
|
|
41
|
+
const appLocale = runtimeLocaleSource?.();
|
|
42
|
+
if (appLocale) {
|
|
43
|
+
browserLocale = appLocale.toLowerCase();
|
|
44
|
+
} else if (typeof document !== 'undefined' && document.documentElement?.lang) {
|
|
33
45
|
browserLocale = document.documentElement.lang?.toLowerCase();
|
|
34
46
|
} else if (typeof navigator !== 'undefined' && navigator.language) {
|
|
35
47
|
browserLocale = navigator.language?.toLowerCase();
|
|
@@ -77,4 +89,20 @@ export const getUiVintageRuntimeMessage = (path: string, fallback: string) => {
|
|
|
77
89
|
|
|
78
90
|
// If the final value is a string, return it; otherwise, return the fallback
|
|
79
91
|
return typeof currentValue === 'string' ? currentValue : fallback;
|
|
80
|
-
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Translate library messages inside components: use the app's vue-i18n when available (same locale on server and client),
|
|
95
|
+
// and fall back to the bundled messages in trees mounted outside the app (toasts, dialogs, busy indicator)
|
|
96
|
+
export const useUiVintageMessage = () => {
|
|
97
|
+
let translate: ((key: string) => string) | null = null;
|
|
98
|
+
try {
|
|
99
|
+
translate = useI18n({ useScope: 'global' }).t;
|
|
100
|
+
} catch {
|
|
101
|
+
translate = null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (path: string, fallback: string) => {
|
|
105
|
+
const message = translate?.(path);
|
|
106
|
+
return message && message !== path ? message : getUiVintageRuntimeMessage(path, fallback);
|
|
107
|
+
};
|
|
108
|
+
};
|
package/src/lib/utils.ts
CHANGED
|
@@ -26,4 +26,24 @@ export function formatDateLongItalyTimezone(date: string | number | Date | null
|
|
|
26
26
|
day: 'numeric',
|
|
27
27
|
timeZone: 'Europe/Rome'
|
|
28
28
|
}).format(parsedDate);
|
|
29
|
-
};
|
|
29
|
+
};
|
|
30
|
+
// Estimate the reading time in minutes from any text or content tree (about 220 words per minute)
|
|
31
|
+
export function getReadingMinutes(content: unknown, wordsPerMinute = 220) {
|
|
32
|
+
// Follow only the branches that hold readable text: tag names, props and the table of contents are skipped
|
|
33
|
+
const collectText = (node: unknown): string => {
|
|
34
|
+
if (typeof node === 'string') return node;
|
|
35
|
+
if (Array.isArray(node)) {
|
|
36
|
+
// Minimark elements are [tag, props, ...children]
|
|
37
|
+
const isElement = typeof node[0] === 'string' && !!node[1] && typeof node[1] === 'object' && !Array.isArray(node[1]);
|
|
38
|
+
return (isElement ? node.slice(2) : node).map(collectText).join(' ');
|
|
39
|
+
}
|
|
40
|
+
if (node && typeof node === 'object') {
|
|
41
|
+
// Documents keep the text in body, minimark bodies in value, AST nodes in children (or value for text nodes)
|
|
42
|
+
const record = node as Record<string, unknown>;
|
|
43
|
+
return ['body', 'value', 'children'].map(key => collectText(record[key])).join(' ');
|
|
44
|
+
}
|
|
45
|
+
return '';
|
|
46
|
+
};
|
|
47
|
+
const words = collectText(content).split(/\s+/).filter(Boolean).length;
|
|
48
|
+
return Math.max(1, Math.round(words / wordsPerMinute));
|
|
49
|
+
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { defineNuxtPlugin } from 'nuxt/app';
|
|
2
2
|
import type { NuxtApp } from 'nuxt/app';
|
|
3
|
-
import {
|
|
3
|
+
import { unref } from 'vue';
|
|
4
|
+
import { setUiVintageRuntimeLocaleSource, uiVintageMessages } from '../lib/i18n';
|
|
4
5
|
|
|
5
6
|
type MessageComposer = {
|
|
6
7
|
mergeLocaleMessage: (locale: string, messages: unknown) => void;
|
|
8
|
+
locale?: unknown;
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
type I18nInstance = {
|
|
@@ -56,6 +58,14 @@ const applyUiVintageMessages = (nuxtApp: NuxtApp): void => {
|
|
|
56
58
|
for (const [locale, messages] of Object.entries(uiVintageMessages)) {
|
|
57
59
|
composer.mergeLocaleMessage(locale, messages);
|
|
58
60
|
}
|
|
61
|
+
|
|
62
|
+
// In the browser, the toasts and dialogs mounted outside the app follow the app locale (never on the server, where state is shared across requests)
|
|
63
|
+
if (import.meta.client) {
|
|
64
|
+
setUiVintageRuntimeLocaleSource(() => {
|
|
65
|
+
const locale = unref(composer.locale);
|
|
66
|
+
return typeof locale === 'string' ? locale : undefined;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
59
69
|
};
|
|
60
70
|
|
|
61
71
|
// Define the Nuxt plugin
|