mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 12:39:35 +01:00
Compare commits
23 Commits
feat/custo
...
deps/nuxt4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afcf86ac63 | ||
|
|
b13a4370da | ||
|
|
5b0ffeac5e | ||
|
|
55e06e97e7 | ||
|
|
a813ea700e | ||
|
|
a4d0ca7396 | ||
|
|
5ad7dabbdc | ||
|
|
d8160ba6ef | ||
|
|
fc24e03cc4 | ||
|
|
1902492cf2 | ||
|
|
0c525638d7 | ||
|
|
35f90b9920 | ||
|
|
836f74849b | ||
|
|
78f92a24f8 | ||
|
|
52908c19f1 | ||
|
|
513cca25f6 | ||
|
|
c1427a3264 | ||
|
|
6519a74de4 | ||
|
|
da05c37ffe | ||
|
|
ec569e427b | ||
|
|
1d052ec565 | ||
|
|
1ba8a55bcb | ||
|
|
63730d684b |
@@ -53,7 +53,7 @@ provide('navigation', mappedNavigation)
|
||||
<NuxtLoadingIndicator color="var(--ui-primary)" :height="2" />
|
||||
|
||||
<template v-if="!route.path.startsWith('/examples')">
|
||||
<!-- <Banner /> -->
|
||||
<Banner />
|
||||
|
||||
<Header :links="links" />
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<template>
|
||||
<UBanner
|
||||
id="ui3-launch"
|
||||
title="Nuxt UI v3 is officially released!"
|
||||
icon="i-lucide-rocket"
|
||||
:actions="[
|
||||
{
|
||||
label: 'Discover Nuxt UI Pro',
|
||||
to: '/pro/pricing',
|
||||
trailingIcon: 'i-lucide-arrow-right'
|
||||
}
|
||||
]"
|
||||
id="nuxtlabs-join-vercel"
|
||||
title="NuxtLabs is joining Vercel"
|
||||
icon="i-simple-icons-vercel"
|
||||
to="https://nuxtlabs.com/?utm_source=nuxt-ui&utm_medium=banner&utm_campaign=nuxtlabs-vercel"
|
||||
target="_blank"
|
||||
close
|
||||
:actions="[{
|
||||
label: 'Read the announcement',
|
||||
color: 'neutral',
|
||||
variant: 'outline',
|
||||
trailingIcon: 'i-lucide-arrow-right',
|
||||
to: 'https://nuxtlabs.com/?utm_source=nuxt-ui&utm_medium=banner&utm_campaign=nuxtlabs-vercel',
|
||||
target: '_blank',
|
||||
class: 'ring-0'
|
||||
}]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -34,7 +34,7 @@ const meta = await fetchComponentMeta(name as any)
|
||||
</ProseCode>
|
||||
</ProseTd>
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="slot.type" :type="slot.type" />
|
||||
<HighlightInlineType v-if="slot.type" :type="slot.type.replace(/ui:\s*\{[^}]*\}/g, 'ui: {}')" />
|
||||
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-toned mt-1" :cache-key="`${kebabCase(route.path)}-${slot.name}-description`" />
|
||||
</ProseTd>
|
||||
|
||||
@@ -14,8 +14,8 @@ const items = [
|
||||
v-slot="{ item }"
|
||||
orientation="vertical"
|
||||
:items="items"
|
||||
class="w-full max-w-xs mx-auto"
|
||||
:ui="{ container: 'h-[336px]' }"
|
||||
class="w-full max-w-xs mx-auto"
|
||||
>
|
||||
<img :src="item" width="320" height="320" class="rounded-lg">
|
||||
</UCarousel>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
const groups = [
|
||||
{
|
||||
id: 'actions',
|
||||
items: [
|
||||
{
|
||||
label: 'Add new file',
|
||||
suffix: 'Create a new file in the current directory',
|
||||
icon: 'i-lucide-file-plus',
|
||||
kbds: ['meta', 'N']
|
||||
},
|
||||
{
|
||||
label: 'Add new folder',
|
||||
suffix: 'Create a new folder in the current directory',
|
||||
icon: 'i-lucide-folder-plus',
|
||||
kbds: ['meta', 'F']
|
||||
},
|
||||
{
|
||||
label: 'Search files',
|
||||
suffix: 'Search across all files in the project',
|
||||
icon: 'i-lucide-search',
|
||||
kbds: ['meta', 'P']
|
||||
},
|
||||
{
|
||||
label: 'Settings',
|
||||
suffix: 'Open application settings',
|
||||
icon: 'i-lucide-settings',
|
||||
kbds: ['meta', ',']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'recent',
|
||||
label: 'Recent',
|
||||
items: [
|
||||
{
|
||||
label: 'project.vue',
|
||||
suffix: 'components/',
|
||||
icon: 'i-vscode-icons-file-type-vue'
|
||||
},
|
||||
{
|
||||
label: 'readme.md',
|
||||
suffix: 'docs/',
|
||||
icon: 'i-vscode-icons-file-type-markdown'
|
||||
},
|
||||
{
|
||||
label: 'package.json',
|
||||
suffix: 'root/',
|
||||
icon: 'i-vscode-icons-file-type-node'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette :groups="groups" class="flex-1 h-80">
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<UIcon name="i-simple-icons-nuxtdotjs" class="size-5 text-dimmed ml-1" />
|
||||
<div class="flex items-center gap-1">
|
||||
<UButton color="neutral" variant="ghost" label="Open Command" class="text-dimmed" size="xs">
|
||||
<template #trailing>
|
||||
<UKbd value="enter" />
|
||||
</template>
|
||||
</UButton>
|
||||
<USeparator orientation="vertical" class="h-4" />
|
||||
<UButton color="neutral" variant="ghost" label="Actions" class="text-dimmed" size="xs">
|
||||
<template #trailing>
|
||||
<UKbd value="meta" />
|
||||
<UKbd value="k" />
|
||||
</template>
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</UCommandPalette>
|
||||
</template>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-users-email',
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
email: user.email,
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
}))
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="users"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
:ui="{ content: 'min-w-fit' }"
|
||||
>
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -35,6 +35,7 @@ const items = ref([
|
||||
}
|
||||
}
|
||||
] satisfies InputMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ const text = computed(() => {
|
||||
placeholder="Password"
|
||||
:color="color"
|
||||
:type="show ? 'text' : 'password'"
|
||||
:ui="{ trailing: 'pe-1' }"
|
||||
:aria-invalid="score < 4"
|
||||
aria-describedby="password-strength"
|
||||
:ui="{ trailing: 'pe-1' }"
|
||||
class="w-full"
|
||||
>
|
||||
<template #trailing>
|
||||
|
||||
@@ -24,3 +24,10 @@ const password = ref('')
|
||||
</template>
|
||||
</UInput>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/* Hide the password reveal button in Edge */
|
||||
::-ms-reveal {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -62,13 +62,13 @@ const items = [
|
||||
<template>
|
||||
<UNavigationMenu
|
||||
:items="items"
|
||||
class="w-full justify-center"
|
||||
:ui="{
|
||||
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
|
||||
content: 'sm:w-auto',
|
||||
childList: 'sm:w-96',
|
||||
childLinkDescription: 'text-balance line-clamp-2'
|
||||
}"
|
||||
class="w-full justify-center"
|
||||
>
|
||||
<template #docs-content="{ item }">
|
||||
<ul class="grid gap-2 p-4 lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]">
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-users-email',
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
email: user.email,
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
}))
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<USelectMenu
|
||||
:items="users"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
:ui="{ content: 'min-w-fit' }"
|
||||
class="w-48"
|
||||
>
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
@@ -35,6 +35,7 @@ const items = ref([
|
||||
}
|
||||
}
|
||||
] satisfies SelectMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ const items = ref([
|
||||
}
|
||||
}
|
||||
] satisfies SelectMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ const items = ref([
|
||||
icon: 'i-lucide-circle-check'
|
||||
}
|
||||
] satisfies SelectMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
const value = ref<string>()
|
||||
|
||||
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-users-email',
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
email: user.email,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
}))
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<USelect
|
||||
v-model="value"
|
||||
:items="users"
|
||||
placeholder="Select user"
|
||||
value-key="value"
|
||||
:ui="{ content: 'min-w-fit' }"
|
||||
class="w-48"
|
||||
>
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
</USelect>
|
||||
</template>
|
||||
@@ -24,8 +24,8 @@ function getUserAvatar(value: string) {
|
||||
:loading="status === 'pending'"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
class="w-48"
|
||||
value-key="value"
|
||||
class="w-48"
|
||||
>
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
|
||||
@@ -35,6 +35,7 @@ const items = ref([
|
||||
}
|
||||
}
|
||||
] satisfies SelectItem[])
|
||||
|
||||
const value = ref(items.value[0]?.value)
|
||||
|
||||
const avatar = computed(() => items.value.find(item => item.value === value.value)?.avatar)
|
||||
|
||||
@@ -23,6 +23,7 @@ const items = ref([
|
||||
icon: 'i-lucide-circle-check'
|
||||
}
|
||||
] satisfies SelectItem[])
|
||||
|
||||
const value = ref(items.value[0]?.value)
|
||||
|
||||
const icon = computed(() => items.value.find(item => item.value === value.value)?.icon)
|
||||
|
||||
@@ -26,7 +26,7 @@ const state = reactive({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTabs :items="items" variant="link" class="gap-4 w-full" :ui="{ trigger: 'grow' }">
|
||||
<UTabs :items="items" variant="link" :ui="{ trigger: 'grow' }" class="gap-4 w-full">
|
||||
<template #account="{ item }">
|
||||
<p class="text-muted mb-4">
|
||||
{{ item.description }}
|
||||
|
||||
@@ -27,8 +27,8 @@ const items: TimelineItem[] = [{
|
||||
<template>
|
||||
<UTimeline
|
||||
:items="items"
|
||||
:ui="{ item: 'even:flex-row-reverse even:-translate-x-[calc(100%-2rem)] even:text-right' }"
|
||||
:default-value="2"
|
||||
:ui="{ item: 'even:flex-row-reverse even:-translate-x-[calc(100%-2rem)] even:text-right' }"
|
||||
class="translate-x-[calc(50%-1rem)]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -42,11 +42,11 @@ const items = [{
|
||||
<UTimeline
|
||||
:items="items"
|
||||
size="xs"
|
||||
class="w-96"
|
||||
:ui="{
|
||||
date: 'float-end ms-1',
|
||||
description: 'px-3 py-2 ring ring-default mt-2 rounded-md text-default'
|
||||
}"
|
||||
class="w-96"
|
||||
>
|
||||
<template #title="{ item }">
|
||||
<span>{{ item.username }}</span>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
const toast = useToast()
|
||||
|
||||
function showToast() {
|
||||
toast.add({
|
||||
title: 'Uh oh! Something went wrong.',
|
||||
description: 'There was a problem with your request.',
|
||||
icon: 'i-lucide-wifi',
|
||||
progress: false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
|
||||
</template>
|
||||
@@ -7,12 +7,12 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.duration"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
>
|
||||
<UInput
|
||||
v-model="appConfig.toaster.duration"
|
||||
|
||||
@@ -7,12 +7,12 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.expand"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="appConfig.toaster.expand"
|
||||
|
||||
@@ -10,12 +10,12 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.position"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="appConfig.toaster.position"
|
||||
|
||||
@@ -59,7 +59,7 @@ provide('navigation', mappedNavigation)
|
||||
<UApp>
|
||||
<NuxtLoadingIndicator color="#FFF" />
|
||||
|
||||
<!-- <Banner /> -->
|
||||
<Banner />
|
||||
|
||||
<Header :links="links" />
|
||||
|
||||
|
||||
@@ -5,6 +5,17 @@ pricing:
|
||||
title: Upgrade to Nuxt UI [Pro]{class="text-primary"}.
|
||||
description: On top of 40+ open source components from Nuxt UI, Pro gives you access to 50+ premium Vue components to create beautiful & responsive Nuxt applications in minutes. It includes all primitives to build landing pages, documentations, blogs, dashboards or entire SaaS products.
|
||||
freePlan:
|
||||
description: "**NuxtLabs is joining Vercel** :tada: As part of this transition, Nuxt UI is becoming even more accessible.<br><br> **In September, we're launching Nuxt UI v4**: a free, open-source library that unifies Nuxt UI and Nuxt UI Pro, offering 100+ components and a complete free Figma Kit for everyone."
|
||||
orientation: horizontal
|
||||
button:
|
||||
label: Read the announcement
|
||||
to: 'https://nuxtlabs.com/?utm_source=nuxt-ui&utm_medium=banner&utm_campaign=nuxtlabs-vercel'
|
||||
target: _blank
|
||||
color: 'neutral'
|
||||
trailingIcon: 'i-lucide-arrow-right'
|
||||
ui:
|
||||
trailingIcon: 'ms-0'
|
||||
devPlan:
|
||||
title: Free in development
|
||||
description: Try Nuxt UI Pro for free in development, no credit card required. Upgrade when ready to deploy.
|
||||
orientation: horizontal
|
||||
@@ -13,6 +24,9 @@ pricing:
|
||||
to: '/getting-started/installation/pro/nuxt'
|
||||
color: 'neutral'
|
||||
variant: 'subtle'
|
||||
trailingIcon: 'i-lucide-arrow-right'
|
||||
ui:
|
||||
trailingIcon: 'ms-0'
|
||||
figma:
|
||||
title: Figma Kit Pro
|
||||
description: Get all Nuxt UI Pro components in a Figma kit to design your next application before coding. Everything you need, from wire-framing to high-fidelity web integration.
|
||||
|
||||
@@ -34,10 +34,19 @@ useSeoMeta({
|
||||
<div class="flex flex-col bg-default gap-8 lg:gap-0">
|
||||
<UPricingPlan
|
||||
v-bind="page.pricing.freePlan"
|
||||
variant="naked"
|
||||
class="lg:rounded-none border-x border-default border-t border-b lg:border-b-0"
|
||||
class="lg:rounded-none ring-primary/15 ring-inset -mb-px bg-primary/5 z-[1]"
|
||||
:ui="{ description: 'mt-0 text-primary' }"
|
||||
>
|
||||
<template #description>
|
||||
<MDC :value="page.pricing.freePlan.description" unwrap="p" />
|
||||
</template>
|
||||
</UPricingPlan>
|
||||
|
||||
<UPricingPlan
|
||||
v-bind="page.pricing.devPlan"
|
||||
class="lg:rounded-none ring-inset -mb-px"
|
||||
/>
|
||||
<UPricingPlans compact>
|
||||
<UPricingPlans compact class="-space-x-px">
|
||||
<UPricingPlan
|
||||
v-for="(plan, index) in page.pricing.plans"
|
||||
:key="index"
|
||||
@@ -47,18 +56,17 @@ useSeoMeta({
|
||||
:discount="plan.discount"
|
||||
:billing-period="plan.billing_period"
|
||||
:billing-cycle="plan.billing_cycle"
|
||||
:variant="plan.highlight ? 'soft' : 'outline'"
|
||||
:class="['lg:rounded-none', { 'border-2 lg:border lg:border-x-0 border-primary lg:border-default': plan.highlight }]"
|
||||
:variant="plan.highlight ? 'subtle' : 'outline'"
|
||||
class="lg:rounded-none ring-inset -mb-px"
|
||||
:features="plan.features"
|
||||
:button="plan.button"
|
||||
/>
|
||||
</UPricingPlans>
|
||||
<UPricingPlan
|
||||
v-bind="page.pricing.figma"
|
||||
variant="naked"
|
||||
:billing-period="page.pricing.figma.billing_period"
|
||||
:billing-cycle="page.pricing.figma.billing_cycle"
|
||||
class="lg:rounded-none border lg:border-y-0 border-default"
|
||||
class="lg:rounded-none ring-inset -mb-px"
|
||||
>
|
||||
<template #features>
|
||||
<li v-for="(feature, index) in page.pricing.figma.features" :key="index" class="flex items-center gap-2 min-w-0">
|
||||
|
||||
@@ -225,6 +225,27 @@ export default defineNuxtConfig({
|
||||
This option adds the `transition-colors` class on components with hover or active states.
|
||||
::
|
||||
|
||||
### `theme.defaultVariants` :badge{label="Soon" class="align-text-top"}
|
||||
|
||||
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
|
||||
|
||||
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
|
||||
|
||||
```ts [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
modules: ['@nuxt/ui'],
|
||||
css: ['~/assets/css/main.css'],
|
||||
ui: {
|
||||
theme: {
|
||||
defaultVariants: {
|
||||
color: 'neutral',
|
||||
size: 'sm'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Continuous Releases
|
||||
|
||||
Nuxt UI uses [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) for continuous preview releases, providing developers with instant access to the latest features and bug fixes without waiting for official releases.
|
||||
|
||||
@@ -333,6 +333,32 @@ export default defineConfig({
|
||||
This option adds the `transition-colors` class on components with hover or active states.
|
||||
::
|
||||
|
||||
### `theme.defaultVariants` :badge{label="Soon" class="align-text-top"}
|
||||
|
||||
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
|
||||
|
||||
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
|
||||
|
||||
```ts [vite.config.ts]
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import ui from '@nuxt/ui/vite'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
ui({
|
||||
theme: {
|
||||
defaultVariants: {
|
||||
color: 'neutral',
|
||||
size: 'sm'
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
### `inertia`
|
||||
|
||||
Use the `inertia` option to enable compatibility with [Inertia.js](https://inertiajs.com/).
|
||||
|
||||
@@ -877,6 +877,20 @@ props:
|
||||
This can be useful when using the CommandPalette inside a [`Modal`](/components/modal) for example.
|
||||
::
|
||||
|
||||
### With footer slot :badge{label="Soon" class="align-text-top"}
|
||||
|
||||
Use the `#footer` slot to add custom content at the bottom of the CommandPalette, such as keyboard shortcuts help or additional actions.
|
||||
|
||||
::component-example
|
||||
---
|
||||
collapse: true
|
||||
name: 'command-palette-footer-slot-example'
|
||||
class: '!p-0'
|
||||
props:
|
||||
autofocus: false
|
||||
---
|
||||
::
|
||||
|
||||
### With custom slot
|
||||
|
||||
Use the `slot` property to customize a specific item or group.
|
||||
|
||||
@@ -757,6 +757,33 @@ name: 'input-menu-filter-fields-example'
|
||||
---
|
||||
::
|
||||
|
||||
### With full content width
|
||||
|
||||
You can expand the content to the full width of its items by using the `ui.content` key.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'input-menu-content-width-example'
|
||||
collapse: true
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can also change the content width globally in your `app.config.ts`:
|
||||
|
||||
```
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
inputMenu: {
|
||||
slots: {
|
||||
content: 'min-w-fit'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
::
|
||||
|
||||
### As a CountryPicker
|
||||
|
||||
This example demonstrates using the InputMenu as a country picker with lazy loading - countries are only fetched when the menu is opened.
|
||||
|
||||
@@ -790,6 +790,33 @@ name: 'select-menu-filter-fields-example'
|
||||
---
|
||||
::
|
||||
|
||||
### With full content width
|
||||
|
||||
You can expand the content to the full width of its items by using the `ui.content` key.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'select-menu-content-width-example'
|
||||
collapse: true
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can also change the content width globally in your `app.config.ts`:
|
||||
|
||||
```
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
selectMenu: {
|
||||
slots: {
|
||||
content: 'min-w-fit'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
::
|
||||
|
||||
### As a CountryPicker
|
||||
|
||||
This example demonstrates using the SelectMenu as a country picker with lazy loading - countries are only fetched when the menu is opened.
|
||||
@@ -801,6 +828,8 @@ name: 'select-menu-countries-example'
|
||||
---
|
||||
::
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
@@ -695,6 +695,33 @@ collapse: true
|
||||
---
|
||||
::
|
||||
|
||||
### With full content width
|
||||
|
||||
You can expand the content to the full width of its items by using the `ui.content` key.
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'select-content-width-example'
|
||||
collapse: true
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can also change the content width globally in your `app.config.ts`:
|
||||
|
||||
```
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
select: {
|
||||
slots: {
|
||||
content: 'min-w-fit'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
::
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
@@ -107,7 +107,7 @@ name: 'toast-color-example'
|
||||
|
||||
### Close
|
||||
|
||||
Pass a `close` field to customize or hide the close button (with `false` value).
|
||||
Pass a `close` field to customize or hide the close [Button](/components/button) (with `false` value).
|
||||
|
||||
::component-example
|
||||
---
|
||||
@@ -143,7 +143,7 @@ You can customize this icon globally in your `vite.config.ts` under `ui.icons.cl
|
||||
|
||||
### Actions
|
||||
|
||||
Pass an `actions` field to add some [Button](/components/button) actions to the Alert.
|
||||
Pass an `actions` field to add some [Button](/components/button) actions to the Toast.
|
||||
|
||||
::component-example
|
||||
---
|
||||
@@ -155,9 +155,23 @@ name: 'toast-actions-example'
|
||||
---
|
||||
::
|
||||
|
||||
### Progress :badge{label="Soon" class="align-text-top"}
|
||||
|
||||
Pass a `progress` field to customize or hide the [Progress](/components/progress) bar (with `false` value).
|
||||
|
||||
::tip
|
||||
The Progress bar inherits the Toast color by default, but you can override it using the `progress.color` field.
|
||||
::
|
||||
|
||||
::component-example
|
||||
---
|
||||
name: 'toast-progress-example'
|
||||
---
|
||||
::
|
||||
|
||||
### Orientation
|
||||
|
||||
Use the `orientation` prop to change the orientation of the Toast.
|
||||
Pass an `orientation` field to the `toast.add` method to change the orientation of the Toast.
|
||||
|
||||
::component-example
|
||||
---
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"@nuxt/content": "^3.6.3",
|
||||
"@nuxt/image": "^1.10.0",
|
||||
"@nuxt/ui": "workspace:*",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@22fdc5e",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@17684e4",
|
||||
"@nuxthub/core": "^0.9.0",
|
||||
"@nuxtjs/plausible": "^1.2.0",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
@@ -30,7 +30,7 @@
|
||||
"joi": "^17.13.3",
|
||||
"maska": "^3.2.0",
|
||||
"motion-v": "^1.5.0",
|
||||
"nuxt": "^3.17.6",
|
||||
"nuxt": "4.0.0-rc.0",
|
||||
"nuxt-component-meta": "^0.12.1",
|
||||
"nuxt-llms": "^0.1.3",
|
||||
"nuxt-og-image": "^5.1.9",
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
"@internationalized/number": "^3.6.3",
|
||||
"@nuxt/fonts": "^0.11.4",
|
||||
"@nuxt/icon": "^1.15.0",
|
||||
"@nuxt/kit": "^3.17.6",
|
||||
"@nuxt/schema": "^3.17.6",
|
||||
"@nuxt/kit": "4.0.0-rc.0",
|
||||
"@nuxt/schema": "4.0.0-rc.0",
|
||||
"@nuxtjs/color-mode": "^3.5.2",
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
@@ -163,7 +163,7 @@
|
||||
"embla-carousel": "^8.6.0",
|
||||
"eslint": "^9.30.1",
|
||||
"happy-dom": "^18.0.1",
|
||||
"nuxt": "^3.17.6",
|
||||
"nuxt": "4.0.0-rc.0",
|
||||
"release-it": "^19.0.3",
|
||||
"vitest": "^3.2.4",
|
||||
"vitest-environment-nuxt": "^1.0.1",
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
"zod": "^3.25.75"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vite": "^7.0.4",
|
||||
"vue-tsc": "^3.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ const open = ref(false)
|
||||
const searchTerm = ref('')
|
||||
// const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
const selected = ref([])
|
||||
const commandPalette = useTemplateRef('commandPalette')
|
||||
|
||||
const { data: _users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
// params: { q: searchTermDebounced },
|
||||
transform: (data: User[]) => {
|
||||
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
|
||||
@@ -23,6 +22,10 @@ const { data: _users, status } = await useFetch('https://jsonplaceholder.typicod
|
||||
const loading = ref(false)
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'users',
|
||||
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
|
||||
items: users.value || []
|
||||
}, {
|
||||
id: 'actions',
|
||||
items: [{
|
||||
label: 'Add new file',
|
||||
@@ -71,12 +74,6 @@ const groups = computed(() => [{
|
||||
toast.add({ title: 'Label added!' })
|
||||
},
|
||||
kbds: ['meta', 'L']
|
||||
}, {
|
||||
label: 'Set Wallpaper',
|
||||
suffix: 'Choose from beautiful wallpaper collection.',
|
||||
icon: 'i-lucide-image',
|
||||
view: 'wallpaper',
|
||||
placeholder: 'Search wallpapers...'
|
||||
}, {
|
||||
label: 'More actions',
|
||||
placeholder: 'Search actions...',
|
||||
@@ -143,116 +140,6 @@ const labels = [{
|
||||
}]
|
||||
const label = ref()
|
||||
|
||||
const wallpapers = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'red_distortion_1',
|
||||
gradient: 'from-red-500 via-orange-500 to-pink-500',
|
||||
category: 'Abstract',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'blue_distortion_1',
|
||||
gradient: 'from-blue-600 via-purple-600 to-indigo-600',
|
||||
category: 'Abstract',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'mono_dark_distortion_1',
|
||||
gradient: 'from-gray-900 via-gray-700 to-gray-800',
|
||||
category: 'Monochrome',
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'chromatic_dark_1',
|
||||
gradient: 'from-emerald-600 via-teal-600 to-cyan-600',
|
||||
category: 'Chromatic',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'red_distortion_2',
|
||||
gradient: 'from-rose-600 via-red-600 to-orange-600',
|
||||
category: 'Abstract',
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'purple_cosmic_1',
|
||||
gradient: 'from-violet-700 via-purple-700 to-fuchsia-700',
|
||||
category: 'Cosmic',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: 'golden_sunset_1',
|
||||
gradient: 'from-yellow-500 via-orange-500 to-red-500',
|
||||
category: 'Nature',
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: 'ocean_deep_1',
|
||||
gradient: 'from-blue-800 via-blue-900 to-indigo-900',
|
||||
category: 'Nature',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: 'mono_light_distortion_1',
|
||||
gradient: 'from-gray-200 via-gray-300 to-gray-400',
|
||||
category: 'Monochrome',
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'green_matrix_1',
|
||||
gradient: 'from-green-800 via-emerald-700 to-teal-700',
|
||||
category: 'Chromatic',
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: 'pink_dreams_1',
|
||||
gradient: 'from-pink-500 via-rose-500 to-purple-500',
|
||||
category: 'Abstract',
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: 'midnight_blue_1',
|
||||
gradient: 'from-slate-900 via-blue-900 to-indigo-900',
|
||||
category: 'Nature',
|
||||
featured: false
|
||||
}
|
||||
]
|
||||
|
||||
const filteredWallpapers = computed(() => {
|
||||
let filtered = wallpapers
|
||||
|
||||
// Filter by search term
|
||||
if (searchTerm.value.trim()) {
|
||||
const search = searchTerm.value.toLowerCase()
|
||||
filtered = filtered.filter(w =>
|
||||
w.name.toLowerCase().includes(search)
|
||||
|| w.category.toLowerCase().includes(search)
|
||||
)
|
||||
}
|
||||
|
||||
return filtered
|
||||
})
|
||||
|
||||
function setWallpaper(wallpaper: any) {
|
||||
toast.add({
|
||||
title: `Wallpaper set to ${wallpaper.name}!`,
|
||||
description: 'Your desktop wallpaper has been updated.',
|
||||
icon: 'i-lucide-image'
|
||||
})
|
||||
}
|
||||
|
||||
// function onSelect(item: typeof groups.value[number]['items'][number]) {
|
||||
function onSelect(item: any) {
|
||||
console.log('Selected', item)
|
||||
@@ -260,12 +147,6 @@ function onSelect(item: any) {
|
||||
|
||||
defineShortcuts({
|
||||
meta_k: () => open.value = !open.value,
|
||||
meta_shift_a: {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
commandPalette.value?.openView('askAI')
|
||||
}
|
||||
},
|
||||
...extractShortcuts(groups.value)
|
||||
})
|
||||
</script>
|
||||
@@ -273,7 +154,6 @@ defineShortcuts({
|
||||
<template>
|
||||
<DefineTemplate>
|
||||
<UCommandPalette
|
||||
ref="commandPalette"
|
||||
v-model="selected"
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
@@ -287,49 +167,25 @@ defineShortcuts({
|
||||
class="sm:max-h-80"
|
||||
@update:model-value="onSelect"
|
||||
>
|
||||
<template #wallpaper>
|
||||
<div class="flex-1 overflow-y-auto p-6">
|
||||
<div class="grid grid-cols-4 gap-4">
|
||||
<div
|
||||
v-for="wallpaper in filteredWallpapers"
|
||||
:key="wallpaper.id"
|
||||
class="group relative cursor-pointer"
|
||||
@click="setWallpaper(wallpaper)"
|
||||
>
|
||||
<div
|
||||
class="aspect-video rounded-lg bg-gradient-to-br shadow-lg ring-1 ring-black/5"
|
||||
:class="wallpaper.gradient"
|
||||
/>
|
||||
<div class="mt-2 px-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="text-sm font-medium text-highlighted truncate">
|
||||
{{ wallpaper.name }}
|
||||
</h3>
|
||||
<UChip
|
||||
v-if="wallpaper.featured"
|
||||
label="★"
|
||||
size="xs"
|
||||
color="primary"
|
||||
class="shrink-0"
|
||||
/>
|
||||
</div>
|
||||
<p class="text-xs text-dimmed">
|
||||
{{ wallpaper.category }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<UIcon name="i-simple-icons-nuxtdotjs" class="size-5 text-dimmed ml-1" />
|
||||
<div class="flex items-center gap-1">
|
||||
<UButton color="neutral" variant="ghost" label="Open Command" class="text-dimmed" size="xs">
|
||||
<template #trailing>
|
||||
<UKbd value="enter" />
|
||||
</template>
|
||||
</UButton>
|
||||
<USeparator orientation="vertical" class="h-4" />
|
||||
<UButton color="neutral" variant="ghost" label="Actions" class="text-dimmed" size="xs">
|
||||
<template #trailing>
|
||||
<UKbd value="meta" />
|
||||
<UKbd value="k" />
|
||||
</template>
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #askAI>
|
||||
<div class="flex flex-col items-center justify-center gap-4 p-6">
|
||||
<UIcon name="i-lucide-sparkles" class="size-8 text-primary" />
|
||||
<span class="text-lg font-semibold text-highlighted">
|
||||
Ask me anything...
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</UCommandPalette>
|
||||
</DefineTemplate>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"@internationalized/date": "^3.8.2",
|
||||
"@nuxt/ui": "workspace:*",
|
||||
"@nuxthub/core": "^0.9.0",
|
||||
"nuxt": "^3.17.6",
|
||||
"nuxt": "4.0.0-rc.0",
|
||||
"zod": "^3.25.75"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
1498
pnpm-lock.yaml
generated
1498
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,9 @@ import { name, version } from '../package.json'
|
||||
|
||||
export type * from './runtime/types'
|
||||
|
||||
type Color = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | (string & {})
|
||||
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {})
|
||||
|
||||
export interface ModuleOptions {
|
||||
/**
|
||||
* Prefix for components
|
||||
@@ -38,7 +41,7 @@ export interface ModuleOptions {
|
||||
* @defaultValue `['primary', 'secondary', 'success', 'info', 'warning', 'error']`
|
||||
* @link https://ui.nuxt.com/getting-started/installation/nuxt#themecolors
|
||||
*/
|
||||
colors?: string[]
|
||||
colors?: Color[]
|
||||
|
||||
/**
|
||||
* Enable or disable transitions on components
|
||||
@@ -46,6 +49,20 @@ export interface ModuleOptions {
|
||||
* @link https://ui.nuxt.com/getting-started/installation/nuxt#themetransitions
|
||||
*/
|
||||
transitions?: boolean
|
||||
|
||||
defaultVariants?: {
|
||||
/**
|
||||
* The default color variant to use for components
|
||||
* @defaultValue `'primary'`
|
||||
*/
|
||||
color?: Color
|
||||
|
||||
/**
|
||||
* The default size variant to use for components
|
||||
* @defaultValue `'md'`
|
||||
*/
|
||||
size?: Size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +102,7 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
|
||||
async function registerModule(name: string, key: string, options: Record<string, any>) {
|
||||
if (!hasNuxtModule(name)) {
|
||||
await installModule(name, options)
|
||||
await installModule(name, defu((nuxt.options as any)[key], options))
|
||||
} else {
|
||||
(nuxt.options as any)[key] = defu((nuxt.options as any)[key], options)
|
||||
}
|
||||
|
||||
@@ -256,6 +256,7 @@ const scrollSnaps = ref<number[]>([])
|
||||
function onInit(api: EmblaCarouselType) {
|
||||
scrollSnaps.value = api?.scrollSnapList() || []
|
||||
}
|
||||
|
||||
function onSelect(api: EmblaCarouselType) {
|
||||
canScrollNext.value = api?.canScrollNext() || false
|
||||
canScrollPrev.value = api?.canScrollPrev() || false
|
||||
@@ -300,8 +301,7 @@ defineExpose({
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
role="group"
|
||||
aria-roledescription="slide"
|
||||
v-bind="dots ? { role: 'tabpanel' } : { 'role': 'group', 'aria-roledescription': 'slide' }"
|
||||
:class="ui.item({ class: [props.ui?.item, isCarouselItem(item) && item.ui?.item, isCarouselItem(item) && item.class] })"
|
||||
>
|
||||
<slot :item="item" :index="index" />
|
||||
@@ -333,10 +333,13 @@ defineExpose({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="dots" :class="ui.dots({ class: props.ui?.dots })">
|
||||
<div v-if="dots" role="tablist" :aria-label="t('carousel.dots')" :class="ui.dots({ class: props.ui?.dots })">
|
||||
<template v-for="(_, index) in scrollSnaps" :key="index">
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
:aria-label="t('carousel.goto', { slide: index + 1 })"
|
||||
:aria-selected="selectedIndex === index"
|
||||
:class="ui.dot({ class: props.ui?.dot, active: selectedIndex === index })"
|
||||
:data-state="selectedIndex === index ? 'active' : undefined"
|
||||
@click="scrollTo(index)"
|
||||
|
||||
@@ -31,11 +31,6 @@ export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
|
||||
*/
|
||||
placeholder?: string
|
||||
children?: CommandPaletteItem[]
|
||||
/**
|
||||
* Custom view to display instead of children items.
|
||||
* When defined, clicking this item will show the custom view.
|
||||
*/
|
||||
view?: string
|
||||
onSelect?(e?: Event): void
|
||||
class?: any
|
||||
ui?: Pick<CommandPalette['slots'], 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemLabel' | 'itemLabelPrefix' | 'itemLabelBase' | 'itemLabelSuffix' | 'itemTrailing' | 'itemTrailingKbds' | 'itemTrailingKbdsSize' | 'itemTrailingHighlightedIcon' | 'itemTrailingIcon'>
|
||||
@@ -152,13 +147,14 @@ type SlotProps<T> = (props: { item: T, index: number }) => any
|
||||
|
||||
export type CommandPaletteSlots<G extends CommandPaletteGroup<T> = CommandPaletteGroup<any>, T extends CommandPaletteItem = CommandPaletteItem> = {
|
||||
'empty'(props: { searchTerm?: string }): any
|
||||
'footer'(props: { ui: { [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string } }): any
|
||||
'back'(props: { ui: { [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string } }): any
|
||||
'close'(props: { ui: { [K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string } }): any
|
||||
'item': SlotProps<T>
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
} & Record<string, SlotProps<G>> & Record<string, SlotProps<T>> & Record<string, (props: { current: any, searchTerm: string, navigateBack: () => void, close: () => void }) => any>
|
||||
} & Record<string, SlotProps<G>> & Record<string, SlotProps<T>>
|
||||
|
||||
</script>
|
||||
|
||||
@@ -213,17 +209,12 @@ const fuse = computed(() => defu({}, props.fuse, {
|
||||
matchAllWhenSearchEmpty: true
|
||||
}))
|
||||
|
||||
const history = ref<(CommandPaletteGroup & { placeholder?: string, view?: string })[]>([])
|
||||
const history = ref<(CommandPaletteGroup & { placeholder?: string })[]>([])
|
||||
|
||||
const placeholder = computed(() => history.value[history.value.length - 1]?.placeholder || props.placeholder || t('commandPalette.placeholder'))
|
||||
|
||||
const groups = computed(() => history.value?.length ? [history.value[history.value.length - 1] as G] : props.groups)
|
||||
|
||||
const currentView = computed(() => {
|
||||
const current = history.value[history.value.length - 1]
|
||||
return current?.view ? current : null
|
||||
})
|
||||
|
||||
const items = computed(() => groups.value?.filter((group) => {
|
||||
if (!group.id) {
|
||||
console.warn(`[@nuxt/ui] CommandPalette group is missing an \`id\` property`)
|
||||
@@ -289,33 +280,8 @@ const filteredGroups = computed(() => {
|
||||
|
||||
const listboxRootRef = useTemplateRef('listboxRootRef')
|
||||
|
||||
// Exposed methods for programmatic control
|
||||
function openView(viewName: string) {
|
||||
history.value.push({
|
||||
id: `view-${viewName}`,
|
||||
label: viewName,
|
||||
view: viewName,
|
||||
items: []
|
||||
} as any)
|
||||
|
||||
searchTerm.value = ''
|
||||
listboxRootRef.value?.highlightFirstItem()
|
||||
}
|
||||
|
||||
function closeView() {
|
||||
if (history.value.length > 0) {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openView,
|
||||
closeView,
|
||||
navigateBack
|
||||
})
|
||||
|
||||
function navigate(item: T) {
|
||||
if (!item.children?.length && !item.view) {
|
||||
if (!item.children?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -324,8 +290,7 @@ function navigate(item: T) {
|
||||
label: item.label,
|
||||
slot: item.slot,
|
||||
placeholder: item.placeholder,
|
||||
view: item.view,
|
||||
items: item.children || []
|
||||
items: item.children
|
||||
} as any)
|
||||
|
||||
searchTerm.value = ''
|
||||
@@ -352,7 +317,7 @@ function onBackspace() {
|
||||
}
|
||||
|
||||
function onSelect(e: Event, item: T) {
|
||||
if (item.children?.length || item.view) {
|
||||
if (item.children?.length) {
|
||||
e.preventDefault()
|
||||
|
||||
navigate(item)
|
||||
@@ -407,17 +372,7 @@ function onSelect(e: Event, item: T) {
|
||||
</ListboxFilter>
|
||||
|
||||
<ListboxContent :class="ui.content({ class: props.ui?.content })">
|
||||
<div v-if="currentView" :class="ui.viewport({ class: props.ui?.viewport })">
|
||||
<slot
|
||||
:name="currentView.view"
|
||||
:current="currentView"
|
||||
:search-term="searchTerm"
|
||||
:navigate-back="navigateBack"
|
||||
:close="closeView"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else-if="filteredGroups?.length" role="presentation" :class="ui.viewport({ class: props.ui?.viewport })">
|
||||
<div v-if="filteredGroups?.length" role="presentation" :class="ui.viewport({ class: props.ui?.viewport })">
|
||||
<ListboxGroup v-for="group in filteredGroups" :key="`group-${group.id}`" :class="ui.group({ class: props.ui?.group })">
|
||||
<ListboxGroupLabel v-if="get(group, props.labelKey as string)" :class="ui.label({ class: props.ui?.label })">
|
||||
{{ get(group, props.labelKey as string) }}
|
||||
@@ -461,7 +416,7 @@ function onSelect(e: Event, item: T) {
|
||||
<span :class="ui.itemTrailing({ class: [props.ui?.itemTrailing, item.ui?.itemTrailing] })">
|
||||
<slot :name="((item.slot ? `${item.slot}-trailing` : group.slot ? `${group.slot}-trailing` : `item-trailing`) as keyof CommandPaletteSlots<G, T>)" :item="(item as any)" :index="index">
|
||||
<UIcon
|
||||
v-if="(item.children && item.children.length > 0) || item.view"
|
||||
v-if="item.children && item.children.length > 0"
|
||||
:name="trailingIcon || appConfig.ui.icons.chevronRight"
|
||||
:class="ui.itemTrailingIcon({ class: [props.ui?.itemTrailingIcon, item.ui?.itemTrailingIcon] })"
|
||||
/>
|
||||
@@ -490,5 +445,9 @@ function onSelect(e: Event, item: T) {
|
||||
</slot>
|
||||
</div>
|
||||
</ListboxContent>
|
||||
|
||||
<div v-if="!!slots.footer" :class="ui.footer({ class: props.ui?.footer })">
|
||||
<slot name="footer" :ui="ui" />
|
||||
</div>
|
||||
</ListboxRoot>
|
||||
</template>
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface FormFieldProps {
|
||||
label?: string
|
||||
description?: string
|
||||
help?: string
|
||||
error?: string | boolean
|
||||
error?: boolean | string
|
||||
hint?: string
|
||||
/**
|
||||
* @defaultValue 'md'
|
||||
@@ -41,8 +41,8 @@ export interface FormFieldSlots {
|
||||
hint(props: { hint?: string }): any
|
||||
description(props: { description?: string }): any
|
||||
help(props: { help?: string }): any
|
||||
error(props: { error?: string | boolean }): any
|
||||
default(props: { error?: string | boolean }): any
|
||||
error(props: { error?: boolean | string }): any
|
||||
default(props: { error?: boolean | string }): any
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -177,6 +177,8 @@ import UBadge from './Badge.vue'
|
||||
import UPopover from './Popover.vue'
|
||||
import UTooltip from './Tooltip.vue'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
|
||||
const props = withDefaults(defineProps<NavigationMenuProps<T>>(), {
|
||||
orientation: 'horizontal',
|
||||
contentOrientation: 'horizontal',
|
||||
@@ -392,7 +394,7 @@ function getAccordionDefaultValue(list: NavigationMenuItem[], level = 0) {
|
||||
</component>
|
||||
</DefineItemTemplate>
|
||||
|
||||
<NavigationMenuRoot v-bind="rootProps" :data-collapsed="collapsed" :class="ui.root({ class: [props.ui?.root, props.class] })">
|
||||
<NavigationMenuRoot v-bind="{ ...rootProps, ...$attrs }" :data-collapsed="collapsed" :class="ui.root({ class: [props.ui?.root, props.class] })">
|
||||
<slot name="list-leading" />
|
||||
|
||||
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { ToastRootProps, ToastRootEmits } from 'reka-ui'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import theme from '#build/ui/toast'
|
||||
import type { AvatarProps, ButtonProps } from '../types'
|
||||
import type { AvatarProps, ButtonProps, ProgressProps } from '../types'
|
||||
import type { StringOrVNode, ComponentConfig } from '../types/utils'
|
||||
|
||||
type Toast = ComponentConfig<typeof theme, AppConfig, 'toast'>
|
||||
@@ -29,18 +29,6 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
|
||||
* @defaultValue 'vertical'
|
||||
*/
|
||||
orientation?: Toast['variants']['orientation']
|
||||
/**
|
||||
* Whether to show the progress bar.
|
||||
* @defaultValue true
|
||||
*/
|
||||
progress?: boolean
|
||||
/**
|
||||
* Display a list of actions:
|
||||
* - under the title and description when orientation is `vertical`
|
||||
* - next to the close button when orientation is `horizontal`
|
||||
* `{ size: 'xs' }`{lang="ts-type"}
|
||||
*/
|
||||
actions?: ButtonProps[]
|
||||
/**
|
||||
* Display a close button to dismiss the toast.
|
||||
* `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
|
||||
@@ -53,6 +41,19 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
|
||||
* @IconifyIcon
|
||||
*/
|
||||
closeIcon?: string
|
||||
/**
|
||||
* Display a list of actions:
|
||||
* - under the title and description when orientation is `vertical`
|
||||
* - next to the close button when orientation is `horizontal`
|
||||
* `{ size: 'xs' }`{lang="ts-type"}
|
||||
*/
|
||||
actions?: ButtonProps[]
|
||||
/**
|
||||
* Display a progress bar showing the toast's remaining duration.
|
||||
* `{ size: 'sm' }`{lang="ts-type"}
|
||||
* @defaultValue true
|
||||
*/
|
||||
progress?: boolean | Pick<ProgressProps, 'color'>
|
||||
class?: any
|
||||
ui?: Toast['slots']
|
||||
}
|
||||
@@ -78,10 +79,11 @@ import { tv } from '../utils/tv'
|
||||
import UIcon from './Icon.vue'
|
||||
import UAvatar from './Avatar.vue'
|
||||
import UButton from './Button.vue'
|
||||
import UProgress from './Progress.vue'
|
||||
|
||||
const props = withDefaults(defineProps<ToastProps>(), {
|
||||
close: true,
|
||||
orientation: 'vertical',
|
||||
close: true,
|
||||
progress: true
|
||||
})
|
||||
const emits = defineEmits<ToastEmits>()
|
||||
@@ -119,7 +121,7 @@ defineExpose({
|
||||
<template>
|
||||
<ToastRoot
|
||||
ref="el"
|
||||
v-slot="{ remaining, duration }"
|
||||
v-slot="{ remaining, duration, open }"
|
||||
v-bind="rootProps"
|
||||
:data-orientation="orientation"
|
||||
:class="ui.root({ class: [props.ui?.root, props.class] })"
|
||||
@@ -184,6 +186,13 @@ defineExpose({
|
||||
</ToastClose>
|
||||
</div>
|
||||
|
||||
<div v-if="progress && remaining > 0 && duration" :class="ui.progress({ class: props.ui?.progress })" :style="{ width: `${remaining / duration * 100}%` }" />
|
||||
<UProgress
|
||||
v-if="progress && open && remaining > 0 && duration"
|
||||
:model-value="remaining / duration * 100"
|
||||
:color="color"
|
||||
v-bind="(typeof progress === 'object' ? progress as Partial<ProgressProps> : {})"
|
||||
size="sm"
|
||||
:class="ui.progress({ class: props.ui?.progress })"
|
||||
/>
|
||||
</ToastRoot>
|
||||
</template>
|
||||
|
||||
@@ -107,6 +107,8 @@ import { get } from '../utils'
|
||||
import { tv } from '../utils/tv'
|
||||
import UIcon from './Icon.vue'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
|
||||
const props = withDefaults(defineProps<TreeProps<T, VK, M>>(), {
|
||||
labelKey: 'label' as never,
|
||||
valueKey: 'value' as never
|
||||
@@ -161,7 +163,7 @@ const defaultExpanded = computed(() =>
|
||||
@toggle="item.onToggle"
|
||||
@select="item.onSelect"
|
||||
>
|
||||
<button :disabled="item.disabled || disabled" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], selected: isSelected, disabled: item.disabled || disabled })">
|
||||
<button type="button" :disabled="item.disabled || disabled" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], selected: isSelected, disabled: item.disabled || disabled })">
|
||||
<slot :name="((item.slot || 'item') as keyof TreeSlots<T>)" v-bind="{ index, level, expanded: isExpanded, selected: isSelected }" :item="(item as Extract<NestedItem<T>, { slot: string; }>)">
|
||||
<slot :name="((item.slot ? `${item.slot}-leading`: 'item-leading') as keyof TreeSlots<T>)" v-bind="{ index, level, expanded: isExpanded, selected: isSelected }" :item="(item as Extract<NestedItem<T>, { slot: string; }>)">
|
||||
<UIcon
|
||||
@@ -199,7 +201,7 @@ const defaultExpanded = computed(() =>
|
||||
</DefineTreeTemplate>
|
||||
|
||||
<TreeRoot
|
||||
v-bind="(rootProps as unknown as TreeRootProps<NestedItem<T>>)"
|
||||
v-bind="{ ...(rootProps as unknown as TreeRootProps<NestedItem<T>>), ...$attrs }"
|
||||
:class="ui.root({ class: [props.ui?.root, props.class] })"
|
||||
:get-key="getItemValue"
|
||||
:default-expanded="defaultExpanded"
|
||||
|
||||
@@ -71,7 +71,7 @@ function _useOverlay() {
|
||||
isMounted: !!defaultOpen,
|
||||
destroyOnClose: !!destroyOnClose,
|
||||
originalProps: props || {},
|
||||
props: { ...(props || {}) }
|
||||
props: { ...props }
|
||||
})
|
||||
|
||||
overlays.push(options)
|
||||
@@ -87,11 +87,11 @@ function _useOverlay() {
|
||||
const open = <T extends Component>(id: symbol, props?: ComponentProps<T>): OpenedOverlay<T> => {
|
||||
const overlay = getOverlay(id)
|
||||
|
||||
// If props are provided, update the overlay's props
|
||||
// If props are provided, merge them with the original props, otherwise use the original props
|
||||
if (props) {
|
||||
patch(overlay.id, props)
|
||||
overlay.props = { ...overlay.originalProps, ...props }
|
||||
} else {
|
||||
patch(overlay.id, overlay.originalProps)
|
||||
overlay.props = { ...overlay.originalProps }
|
||||
}
|
||||
|
||||
overlay.isOpen = true
|
||||
@@ -135,7 +135,7 @@ function _useOverlay() {
|
||||
const patch = <T extends Component>(id: symbol, props: Partial<ComponentProps<T>>): void => {
|
||||
const overlay = getOverlay(id)
|
||||
|
||||
overlay.props = { ...props }
|
||||
overlay.props = { ...overlay.props, ...props }
|
||||
}
|
||||
|
||||
const getOverlay = (id: symbol): Overlay => {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { ref, onScopeDispose } from 'vue'
|
||||
import type { Ref, Plugin as VuePlugin } from 'vue'
|
||||
import { createHooks } from 'hookable'
|
||||
|
||||
import { usePage } from '@inertiajs/vue3'
|
||||
import { useColorMode as useColorModeVueUse } from '@vueuse/core'
|
||||
import appConfig from '#build/app.config'
|
||||
import type { NuxtApp } from '#app'
|
||||
import { useColorMode as useColorModeVueUse } from '@vueuse/core'
|
||||
import { usePage } from '@inertiajs/vue3'
|
||||
|
||||
export { useHead } from '@unhead/vue'
|
||||
|
||||
@@ -16,6 +15,7 @@ export { useLocale } from '../composables/useLocale'
|
||||
|
||||
export const useRoute = () => {
|
||||
const page = usePage()
|
||||
|
||||
return {
|
||||
fullPath: page.url
|
||||
}
|
||||
@@ -25,6 +25,10 @@ export const useRouter = () => {
|
||||
|
||||
}
|
||||
|
||||
export const clearError = () => {
|
||||
|
||||
}
|
||||
|
||||
export const useColorMode = () => {
|
||||
if (!appConfig.colorMode) {
|
||||
return {
|
||||
|
||||
@@ -40,7 +40,8 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'السابق',
|
||||
next: 'التالي',
|
||||
goto: 'الذهاب إلي شريحة {slide}'
|
||||
dots: 'اختر الشريحة المراد عرضها',
|
||||
goto: 'الذهاب إلى شريحة {slide}'
|
||||
},
|
||||
modal: {
|
||||
close: 'إغلاق'
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Əvvəlki',
|
||||
next: 'Növbəti',
|
||||
dots: 'Göstərmək üçün slayd seçin',
|
||||
goto: 'Slayd {slide} keç'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Назад',
|
||||
next: 'Напред',
|
||||
dots: 'Изберете слайд за показване',
|
||||
goto: 'Отидете на слайд {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'পূর্ববর্তী',
|
||||
next: 'পরবর্তী',
|
||||
dots: 'প্রদর্শনের জন্য স্লাইড নির্বাচন করুন',
|
||||
goto: 'স্লাইড {slide} এ যান'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Anterior',
|
||||
next: 'Següent',
|
||||
dots: 'Tria la diapositiva a mostrar',
|
||||
goto: 'Anar a la diapositiva {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -38,8 +38,9 @@ export default defineLocale<Messages>({
|
||||
close: 'داخستن'
|
||||
},
|
||||
carousel: {
|
||||
prev: 'پێشوو',
|
||||
prev: 'پێشووی',
|
||||
next: 'داهاتوو',
|
||||
dots: 'سلایدێک هەڵبژێرە بۆ پیشاندان',
|
||||
goto: 'بڕۆ بۆ سلایدی {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Předchozí',
|
||||
next: 'Další',
|
||||
dots: 'Vyberte snímek k zobrazení',
|
||||
goto: 'Přejít na {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Forrige',
|
||||
next: 'Næste',
|
||||
dots: 'Vælg dias til visning',
|
||||
goto: 'Gå til slide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Zurück',
|
||||
next: 'Weiter',
|
||||
dots: 'Folie zur Anzeige auswählen',
|
||||
goto: 'Gehe zu {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Προηγούμενο',
|
||||
next: 'Επόμενο',
|
||||
dots: 'Επιλέξτε διαφάνεια για εμφάνιση',
|
||||
goto: 'Μετάβαση στη διαφάνεια {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Prev',
|
||||
next: 'Next',
|
||||
dots: 'Choose slide to display',
|
||||
goto: 'Go to slide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Anterior',
|
||||
next: 'Siguiente',
|
||||
dots: 'Elegir diapositiva a mostrar',
|
||||
goto: 'Ir a la diapositiva {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Eel',
|
||||
next: 'Järg',
|
||||
dots: 'Valige kuvatav slaid',
|
||||
goto: 'Mine slaidile {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -40,6 +40,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'قبلی',
|
||||
next: 'بعدی',
|
||||
dots: 'اسلاید مورد نظر برای نمایش را انتخاب کنید',
|
||||
goto: 'رفتن به اسلاید {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Edellinen',
|
||||
next: 'Seuraava',
|
||||
dots: 'Valitse näytettävä dia',
|
||||
goto: 'Siirry sivulle {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Précédent',
|
||||
next: 'Suivant',
|
||||
dots: 'Choisir la diapositive à afficher',
|
||||
goto: 'Aller à {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -38,6 +38,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'הקודם',
|
||||
next: 'הבא',
|
||||
dots: 'בחר שקופית להצגה',
|
||||
goto: 'מעבר ל {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,7 +39,8 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'पिछला',
|
||||
next: 'अगला',
|
||||
goto: 'स्लाइड {slide} पर जाएँ'
|
||||
dots: 'प्रदर्शित करने के लिए स्लाइड चुनें',
|
||||
goto: 'स्लाइड {slide} पर जाएं'
|
||||
},
|
||||
modal: {
|
||||
close: 'बंद करें'
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Előző',
|
||||
next: 'Következő',
|
||||
dots: 'Válassza ki a megjelenítendő diát',
|
||||
goto: 'Ugrás ide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Հետ',
|
||||
next: 'Առաջ',
|
||||
dots: 'Ընտրեք ցուցադրելու սլայդը',
|
||||
goto: 'Անցնել {slide}-ին'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Sebelumnya',
|
||||
next: 'Berikutnya',
|
||||
dots: 'Pilih slide untuk ditampilkan',
|
||||
goto: 'Pergi ke slide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Precedente',
|
||||
next: 'Successiva',
|
||||
dots: 'Scegli diapositiva da visualizzare',
|
||||
goto: 'Vai alla slide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: '前へ',
|
||||
next: '次へ',
|
||||
dots: '表示するスライドを選択',
|
||||
goto: 'スライド {slide} に移動'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Алдыңғы',
|
||||
next: 'Келесі',
|
||||
dots: 'Көрсету үшін слайдты таңдаңыз',
|
||||
goto: '{slide} слайдқа өту'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,7 +39,8 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'មុន',
|
||||
next: 'បន្ទាប់',
|
||||
goto: 'លោតទៅកាន់ស្លាយ {slide}'
|
||||
dots: 'ជ្រើសរើសស្លាយដើម្បីបង្ហាញ',
|
||||
goto: 'ឡើងទៅស្លាយ {slide}'
|
||||
},
|
||||
modal: {
|
||||
close: 'បិទ'
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: '이전',
|
||||
next: '다음',
|
||||
dots: '표시할 슬라이드 선택',
|
||||
goto: '{slide} 페이지로 이동'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Алдыңкы',
|
||||
next: 'Кийинки',
|
||||
dots: 'Көрсөтүү үчүн слайдды тандаңыз',
|
||||
goto: '{slide} слайдга өтүү'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Präz.',
|
||||
next: 'Näch.',
|
||||
dots: 'Wielt Dia fir ze weisen',
|
||||
goto: 'Gitt op d\'Slide {Slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Atgal',
|
||||
next: 'Pirmyn',
|
||||
dots: 'Pasirinkite skaidrę rodymui',
|
||||
goto: 'Eiti į skaidrę {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Өмнөх',
|
||||
next: 'Дараах',
|
||||
dots: 'Харуулах слайдыг сонгоно уу',
|
||||
goto: '{slide}-р хуудсанд шилжих'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Sebelum',
|
||||
next: 'Seterusnya',
|
||||
dots: 'Pilih slaid untuk dipaparkan',
|
||||
goto: 'Pergi ke slaid {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Forrige',
|
||||
next: 'Neste',
|
||||
dots: 'Velg lysbilde som skal vises',
|
||||
goto: 'Gå til lysbilde {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Vorige',
|
||||
next: 'Volgende',
|
||||
dots: 'Kies dia om weer te geven',
|
||||
goto: 'Ga naar dia {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Poprzedni',
|
||||
next: 'Następny',
|
||||
dots: 'Wybierz slajd do wyświetlenia',
|
||||
goto: 'Idź do {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Anterior',
|
||||
next: 'Próximo',
|
||||
dots: 'Escolher slide para exibir',
|
||||
goto: 'Ir ao diapositivo {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Anterior',
|
||||
next: 'Próximo',
|
||||
dots: 'Escolher slide para exibir',
|
||||
goto: 'Ir para a slide {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Anterior',
|
||||
next: 'Următor',
|
||||
dots: 'Alegeți diapozitivul de afișat',
|
||||
goto: 'Mergi la diapozitivul {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Назад',
|
||||
next: 'Далее',
|
||||
dots: 'Выберите слайд для отображения',
|
||||
goto: 'Перейти к {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Predchádzajúci',
|
||||
next: 'Nasledujúci',
|
||||
dots: 'Vyberte snímku na zobrazenie',
|
||||
goto: 'Prejsť na {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Nazaj',
|
||||
next: 'Naprej',
|
||||
dots: 'Izberite diapozitiv za prikaz',
|
||||
goto: 'Pojdi na {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Föregående',
|
||||
next: 'Nästa',
|
||||
dots: 'Välj bild att visa',
|
||||
goto: 'Gå till {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'ย้อนกลับ',
|
||||
next: 'ถัดไป',
|
||||
dots: 'เลือกสไลด์ที่จะแสดง',
|
||||
goto: 'ไปที่ {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Қаблӣ',
|
||||
next: 'Баъдӣ',
|
||||
dots: 'Слайдро барои намоиш интихоб кунед',
|
||||
goto: 'Ба слайди {slide} гузаред'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Önceki',
|
||||
next: 'Sonraki',
|
||||
dots: 'Görüntülenecek slaydı seçin',
|
||||
goto: '{slide}. slayda git'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -40,6 +40,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'ئالدىنقى بەت',
|
||||
next: 'كېيىنكى بەت',
|
||||
dots: 'كۆرسىتىدىغان سلايدنى تاللاڭ',
|
||||
goto: '{slide}-بەتكە ئاتلاش'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Назад',
|
||||
next: 'Далі',
|
||||
dots: 'Виберіть слайд для відображення',
|
||||
goto: 'Перейти до {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -40,6 +40,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'پچھلا',
|
||||
next: 'اگلا',
|
||||
dots: 'دکھانے کے لیے سلائیڈ منتخب کریں',
|
||||
goto: 'سلائیڈ {slide} پر جائیں'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Ortga',
|
||||
next: 'Oldinga',
|
||||
dots: 'Koʻrsatish uchun slaydni tanlang',
|
||||
goto: '{slide}-slaydga o‘tish'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: 'Trước',
|
||||
next: 'Sau',
|
||||
dots: 'Chọn slide để hiển thị',
|
||||
goto: 'Đi tới ô {slide}'
|
||||
},
|
||||
modal: {
|
||||
|
||||
@@ -39,6 +39,7 @@ export default defineLocale<Messages>({
|
||||
carousel: {
|
||||
prev: '上一页',
|
||||
next: '下一页',
|
||||
dots: '选择要显示的幻灯片',
|
||||
goto: '跳转到第 {slide} 页'
|
||||
},
|
||||
modal: {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user