mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 07:21:46 +01:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6736d1efd | ||
|
|
f6e695ffc8 | ||
|
|
e8898d15a6 | ||
|
|
f65aefb706 | ||
|
|
9b9ccdb59e | ||
|
|
688232215d | ||
|
|
ebfb835033 | ||
|
|
838d6c832f | ||
|
|
e7c2f7856c | ||
|
|
1d5bd89d58 | ||
|
|
6c124bb1ac | ||
|
|
49174b7628 | ||
|
|
50ad14f9df | ||
|
|
6e2678d1d8 | ||
|
|
831c560a96 | ||
|
|
06990beabf | ||
|
|
3ebff4d133 | ||
|
|
d66cfa9d7d | ||
|
|
75c0d9e31f | ||
|
|
6033872ef8 | ||
|
|
838cb7212a | ||
|
|
c8dd71c4f5 | ||
|
|
4f0d00f7a6 | ||
|
|
3b975634e8 | ||
|
|
249bbd49dc | ||
|
|
3c1602af37 | ||
|
|
e1ca6e0cde | ||
|
|
3b3bd16afe | ||
|
|
fab9cbebd8 | ||
|
|
581b470cc7 | ||
|
|
24d30cd1f3 |
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,5 +1,30 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.17.0](https://github.com/nuxt/ui/compare/v2.16.0...v2.17.0) (2024-06-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Alert:** add `actions` slot ([#1785](https://github.com/nuxt/ui/issues/1785)) ([c8dd71c](https://github.com/nuxt/ui/commit/c8dd71c4f5a5239811b07b50f1dc802101af07d5))
|
||||||
|
* **Form:** update and migrate `valibot` to v0.31.0 ([#1848](https://github.com/nuxt/ui/issues/1848)) ([1d5bd89](https://github.com/nuxt/ui/commit/1d5bd89d5881163fc6dc917e138b9d8304dff6c4))
|
||||||
|
* **Notification:** allow ring customization with `{color}` ([#1830](https://github.com/nuxt/ui/issues/1830)) ([3ebff4d](https://github.com/nuxt/ui/commit/3ebff4d133372e339e2c4c439576e9e192b29cc3))
|
||||||
|
* **Slideover:** handle `top` and `bottom` side ([#1834](https://github.com/nuxt/ui/issues/1834)) ([50ad14f](https://github.com/nuxt/ui/commit/50ad14f9dffe4f76bef888cd10d30b417c75bca5))
|
||||||
|
* **Tabs:** add `content` prop to avoid the render of the HTML markup ([#1831](https://github.com/nuxt/ui/issues/1831)) ([6e2678d](https://github.com/nuxt/ui/commit/6e2678d1d8a498322eb3eff909ccbba55e40a2b7))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Alert/Notification:** use `div` for description ([e8898d1](https://github.com/nuxt/ui/commit/e8898d15a667ba66e78828315e3cc4e92845cd3f)), closes [#1551](https://github.com/nuxt/ui/issues/1551)
|
||||||
|
* **Alert:** base style not applied on icon ([#1859](https://github.com/nuxt/ui/issues/1859)) ([f65aefb](https://github.com/nuxt/ui/commit/f65aefb7067c1c64c1355b5d699129e716ef1281))
|
||||||
|
* **Breadcrumb:** allow `aria-current` to be overrideable ([ebfb835](https://github.com/nuxt/ui/commit/ebfb8350339725c0a6f88c73f16bff01d61538c2)), closes [#1856](https://github.com/nuxt/ui/issues/1856)
|
||||||
|
* **Carousel:** prevent mouse click when dragging ([#1781](https://github.com/nuxt/ui/issues/1781)) ([4f0d00f](https://github.com/nuxt/ui/commit/4f0d00f7a6eebf05adceaf1e7c2869ad91949cf3))
|
||||||
|
* **CommandPalette:** hide `empty-state` when `null` ([249bbd4](https://github.com/nuxt/ui/commit/249bbd49dc8420603e8d561543d237abeb400908)), closes [#1787](https://github.com/nuxt/ui/issues/1787)
|
||||||
|
* **Form:** maintain other errors when using `setErrors` with a path ([#1818](https://github.com/nuxt/ui/issues/1818)) ([06990be](https://github.com/nuxt/ui/commit/06990beabf67f668322b4d3fb2ec93cc4f3bdcd4))
|
||||||
|
* **Input:** hide wrapper when type is `hidden` ([#1797](https://github.com/nuxt/ui/issues/1797)) ([e7c2f78](https://github.com/nuxt/ui/commit/e7c2f7856c05ed96f48c83d64d8e1d3f41ab58fe))
|
||||||
|
* **Link:** typo in `exactHash` type ([581b470](https://github.com/nuxt/ui/commit/581b470cc79c2315bb2d56e02a7c134a7861c616)), closes [#1767](https://github.com/nuxt/ui/issues/1767)
|
||||||
|
* **SelectMenu:** wrong placeholder color when `modelValue` is an empty string ([9b9ccdb](https://github.com/nuxt/ui/commit/9b9ccdb59e98fed096dd18809af646b10de46b9f)), closes [#1862](https://github.com/nuxt/ui/issues/1862)
|
||||||
|
* **Select:** remove defaults for `value` and `text` ([6c124bb](https://github.com/nuxt/ui/commit/6c124bb1ac2fef116161da56a3a8e5f92144ce3a)), closes [#1702](https://github.com/nuxt/ui/issues/1702)
|
||||||
|
|
||||||
## [2.16.0](https://github.com/nuxt/ui/compare/v2.15.2...v2.16.0) (2024-05-07)
|
## [2.16.0](https://github.com/nuxt/ui/compare/v2.15.2...v2.16.0) (2024-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useMouse, useWindowScroll } from '@vueuse/core'
|
||||||
|
|
||||||
const { x, y } = useMouse()
|
const { x, y } = useMouse()
|
||||||
const { y: windowY } = useWindowScroll()
|
const { y: windowY } = useWindowScroll()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useMouse, useWindowScroll } from '@vueuse/core'
|
||||||
|
|
||||||
const { x, y } = useMouse()
|
const { x, y } = useMouse()
|
||||||
const { y: windowY } = useWindowScroll()
|
const { y: windowY } = useWindowScroll()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useMouse, useWindowScroll } from '@vueuse/core'
|
||||||
|
|
||||||
const { x, y } = useMouse()
|
const { x, y } = useMouse()
|
||||||
const { y: windowY } = useWindowScroll()
|
const { y: windowY } = useWindowScroll()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useMouse, useWindowScroll } from '@vueuse/core'
|
||||||
|
|
||||||
const { x, y } = useMouse()
|
const { x, y } = useMouse()
|
||||||
const { y: windowY } = useWindowScroll()
|
const { y: windowY } = useWindowScroll()
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { string, objectAsync, email, minLength, type Input } from 'valibot'
|
import * as v from 'valibot'
|
||||||
import type { FormSubmitEvent } from '#ui/types'
|
import type { FormSubmitEvent } from '#ui/types'
|
||||||
|
|
||||||
const schema = objectAsync({
|
const schema = v.object({
|
||||||
email: string([email('Invalid email')]),
|
email: v.pipe(v.string(), v.email('Invalid email')),
|
||||||
password: string([minLength(8, 'Must be at least 8 characters')])
|
password: v.pipe(v.string(), v.minLength(8, 'Must be at least 8 characters'))
|
||||||
})
|
})
|
||||||
|
|
||||||
type Schema = Input<typeof schema>
|
type Schema = v.InferOutput<typeof schema>
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
email: '',
|
email: '',
|
||||||
@@ -21,7 +21,7 @@ async function onSubmit (event: FormSubmitEvent<Schema>) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
<UForm :schema="v.safeParser(schema)" :state="state" class="space-y-4" @submit="onSubmit">
|
||||||
<UFormGroup label="Email" name="email">
|
<UFormGroup label="Email" name="email">
|
||||||
<UInput v-model="state.email" />
|
<UInput v-model="state.email" />
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ const isOpen = ref(false)
|
|||||||
|
|
||||||
<USlideover v-model="isOpen">
|
<USlideover v-model="isOpen">
|
||||||
<div class="p-4 flex-1">
|
<div class="p-4 flex-1">
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
icon="i-heroicons-x-mark-20-solid"
|
||||||
|
class="flex sm:hidden absolute end-5 top-5 z-10"
|
||||||
|
square
|
||||||
|
padded
|
||||||
|
@click="isOpen = false"
|
||||||
|
/>
|
||||||
<Placeholder class="h-full" />
|
<Placeholder class="h-full" />
|
||||||
</div>
|
</div>
|
||||||
</USlideover>
|
</USlideover>
|
||||||
|
|||||||
@@ -7,8 +7,22 @@ const isOpen = ref(false)
|
|||||||
<UButton label="Open" @click="isOpen = true" />
|
<UButton label="Open" @click="isOpen = true" />
|
||||||
|
|
||||||
<USlideover v-model="isOpen">
|
<USlideover v-model="isOpen">
|
||||||
<UCard class="flex flex-col flex-1" :ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
|
<UCard
|
||||||
|
class="flex flex-col flex-1"
|
||||||
|
:ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }"
|
||||||
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
icon="i-heroicons-x-mark-20-solid"
|
||||||
|
class="flex sm:hidden absolute end-5 top-5 z-10"
|
||||||
|
square
|
||||||
|
padded
|
||||||
|
@click="isOpen = false"
|
||||||
|
/>
|
||||||
|
|
||||||
<Placeholder class="h-8" />
|
<Placeholder class="h-8" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,17 @@ const isOpen = ref(false)
|
|||||||
|
|
||||||
<USlideover v-model="isOpen" :overlay="false">
|
<USlideover v-model="isOpen" :overlay="false">
|
||||||
<div class="p-4 flex-1">
|
<div class="p-4 flex-1">
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
icon="i-heroicons-x-mark-20-solid"
|
||||||
|
class="flex sm:hidden absolute end-5 top-5 z-10"
|
||||||
|
square
|
||||||
|
padded
|
||||||
|
@click="isOpen = false"
|
||||||
|
/>
|
||||||
|
|
||||||
<Placeholder class="h-full" />
|
<Placeholder class="h-full" />
|
||||||
</div>
|
</div>
|
||||||
</USlideover>
|
</USlideover>
|
||||||
|
|||||||
@@ -8,6 +8,17 @@ const isOpen = ref(false)
|
|||||||
|
|
||||||
<USlideover v-model="isOpen" :transition="false">
|
<USlideover v-model="isOpen" :transition="false">
|
||||||
<div class="p-4 flex-1">
|
<div class="p-4 flex-1">
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
icon="i-heroicons-x-mark-20-solid"
|
||||||
|
class="flex sm:hidden absolute end-5 top-5 z-10"
|
||||||
|
square
|
||||||
|
padded
|
||||||
|
@click="isOpen = false"
|
||||||
|
/>
|
||||||
|
|
||||||
<Placeholder class="h-full" />
|
<Placeholder class="h-full" />
|
||||||
</div>
|
</div>
|
||||||
</USlideover>
|
</USlideover>
|
||||||
|
|||||||
@@ -175,6 +175,10 @@ Use the `#avatar` slot to customize the displayable avatar.
|
|||||||
|
|
||||||
:component-example{component="alert-example-avatar"}
|
:component-example{component="alert-example-avatar"}
|
||||||
|
|
||||||
|
### `actions` :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
|
||||||
|
|
||||||
|
Use the `#actions` slot to add custom user interaction elements.
|
||||||
|
|
||||||
## Props
|
## Props
|
||||||
|
|
||||||
:component-props
|
:component-props
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ links:
|
|||||||
|
|
||||||
Use the Form component to validate form data using schema libraries such as [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi), [Valibot](https://valibot.dev/), or your own validation logic.
|
Use the Form component to validate form data using schema libraries such as [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi), [Valibot](https://valibot.dev/), or your own validation logic.
|
||||||
|
|
||||||
It works with the [FormGroup](/components/input) component to display error messages around form elements automatically.
|
It works with the [FormGroup](/components/form-group) component to display error messages around form elements automatically.
|
||||||
|
|
||||||
The form component requires two props:
|
The form component requires two props:
|
||||||
- `state` - a reactive object holding the form's state.
|
- `state` - a reactive object holding the form's state.
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ extraClass: 'overflow-hidden'
|
|||||||
padding: false
|
padding: false
|
||||||
component: 'table-example-columns-selectable'
|
component: 'table-example-columns-selectable'
|
||||||
componentProps:
|
componentProps:
|
||||||
class: 'flex-1'
|
class: 'flex-1 flex-col overflow-hidden'
|
||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ extraClass: 'overflow-hidden'
|
|||||||
padding: false
|
padding: false
|
||||||
component: 'table-example-searchable'
|
component: 'table-example-searchable'
|
||||||
componentProps:
|
componentProps:
|
||||||
class: 'flex-1'
|
class: 'flex-1 flex-col overflow-hidden'
|
||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ extraClass: 'overflow-hidden'
|
|||||||
padding: false
|
padding: false
|
||||||
component: 'table-example-paginable'
|
component: 'table-example-paginable'
|
||||||
componentProps:
|
componentProps:
|
||||||
class: 'flex-1'
|
class: 'flex-1 flex-col overflow-hidden'
|
||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ componentProps:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
You can use the `content` prop and set it to `false` to avoid the rendering of the HTML content if you don't need it.
|
||||||
|
|
||||||
### Control the selected index
|
### Control the selected index
|
||||||
|
|
||||||
Use a `v-model` to control the selected index.
|
Use a `v-model` to control the selected index.
|
||||||
|
|||||||
@@ -4,29 +4,29 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/heroicons": "^1.1.21",
|
"@iconify-json/heroicons": "^1.1.21",
|
||||||
"@iconify-json/simple-icons": "^1.1.101",
|
"@iconify-json/simple-icons": "^1.1.105",
|
||||||
"@nuxt/content": "^2.12.1",
|
"@nuxt/content": "^2.12.1",
|
||||||
"@nuxt/eslint-config": "^0.3.10",
|
"@nuxt/eslint-config": "^0.3.13",
|
||||||
"@nuxt/fonts": "^0.7.0",
|
"@nuxt/fonts": "^0.7.0",
|
||||||
"@nuxt/image": "^1.7.0",
|
"@nuxt/image": "^1.7.0",
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@1.1.0-28584604.9227c85",
|
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@1.2.0-28637819.42c6d9b",
|
||||||
"@nuxtjs/plausible": "^1.0.0",
|
"@nuxtjs/plausible": "^1.0.0",
|
||||||
"@octokit/rest": "^20.1.1",
|
"@octokit/rest": "^20.1.1",
|
||||||
"@vueuse/nuxt": "^10.9.0",
|
"@vueuse/nuxt": "^10.11.0",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"joi": "^17.13.1",
|
"joi": "^17.13.1",
|
||||||
"nuxt": "^3.11.2",
|
"nuxt": "^3.12.1",
|
||||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||||
"nuxt-component-meta": "^0.6.4",
|
"nuxt-component-meta": "^0.6.4",
|
||||||
"nuxt-og-image": "^2.2.4",
|
"nuxt-og-image": "^2.2.4",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.3.2",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"ufo": "^1.5.3",
|
"ufo": "^1.5.3",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"valibot": "^0.30.0",
|
"valibot": "^0.31.1",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"zod": "^3.23.6"
|
"zod": "^3.23.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
35
package.json
35
package.json
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/ui",
|
"name": "@nuxt/ui",
|
||||||
"version": "2.16.0",
|
"version": "2.17.0",
|
||||||
|
"packageManager": "pnpm@9.1.1",
|
||||||
"repository": "nuxt/ui",
|
"repository": "nuxt/ui",
|
||||||
"homepage": "https://ui.nuxt.com",
|
"homepage": "https://ui.nuxt.com",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -33,11 +34,11 @@
|
|||||||
"test": "vitest"
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@egoist/tailwindcss-icons": "^1.8.0",
|
"@egoist/tailwindcss-icons": "^1.8.1",
|
||||||
"@headlessui/tailwindcss": "^0.2.0",
|
"@headlessui/tailwindcss": "^0.2.1",
|
||||||
"@headlessui/vue": "^1.7.21",
|
"@headlessui/vue": "^1.7.22",
|
||||||
"@iconify-json/heroicons": "^1.1.21",
|
"@iconify-json/heroicons": "^1.1.21",
|
||||||
"@nuxt/kit": "^3.11.2",
|
"@nuxt/kit": "^3.12.1",
|
||||||
"@nuxtjs/color-mode": "^3.4.1",
|
"@nuxtjs/color-mode": "^3.4.1",
|
||||||
"@nuxtjs/tailwindcss": "^6.12.0",
|
"@nuxtjs/tailwindcss": "^6.12.0",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
@@ -45,9 +46,9 @@
|
|||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/forms": "^0.5.7",
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.11.0",
|
||||||
"@vueuse/integrations": "^10.9.0",
|
"@vueuse/integrations": "^10.11.0",
|
||||||
"@vueuse/math": "^10.9.0",
|
"@vueuse/math": "^10.11.0",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"nuxt-icon": "^0.6.10",
|
"nuxt-icon": "^0.6.10",
|
||||||
@@ -55,30 +56,32 @@
|
|||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"scule": "^1.3.0",
|
"scule": "^1.3.0",
|
||||||
"tailwind-merge": "^2.3.0",
|
"tailwind-merge": "^2.3.0",
|
||||||
"tailwindcss": "^3.4.3"
|
"tailwindcss": "^3.4.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^0.3.10",
|
"@nuxt/eslint-config": "^0.3.13",
|
||||||
"@nuxt/module-builder": "^0.5.5",
|
"@nuxt/module-builder": "^0.5.5",
|
||||||
"@nuxt/test-utils": "^3.12.1",
|
"@nuxt/test-utils": "^3.13.1",
|
||||||
"@release-it/conventional-changelog": "^8.0.1",
|
"@release-it/conventional-changelog": "^8.0.1",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"happy-dom": "^14.10.1",
|
"happy-dom": "^14.10.1",
|
||||||
"joi": "^17.13.1",
|
"joi": "^17.13.1",
|
||||||
"nuxt": "^3.11.2",
|
"nuxt": "^3.12.1",
|
||||||
"release-it": "^17.2.1",
|
"release-it": "^17.3.0",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"unbuild": "^2.0.0",
|
"unbuild": "^2.0.0",
|
||||||
"valibot": "^0.30.0",
|
"valibot30": "npm:valibot@0.30.0",
|
||||||
|
"valibot": "^0.31.1",
|
||||||
"vitest": "^1.6.0",
|
"vitest": "^1.6.0",
|
||||||
"vitest-environment-nuxt": "^1.0.0",
|
"vitest-environment-nuxt": "^1.0.0",
|
||||||
"vue-tsc": "^2.0.16",
|
"vue-tsc": "^2.0.16",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"zod": "^3.23.6"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@nuxt/ui": "workspace:*",
|
"@nuxt/ui": "workspace:*",
|
||||||
"@nuxt/module-builder": "0.5.5"
|
"@nuxt/module-builder": "0.5.5",
|
||||||
|
"vue-tsc": "2.0.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"nuxt": "^3.11.2"
|
"nuxt": "^3.12.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7596
pnpm-lock.yaml
generated
7596
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
<div :class="alertClass" v-bind="attrs">
|
<div :class="alertClass" v-bind="attrs">
|
||||||
<div class="flex" :class="[ui.gap, { 'items-start': (description || $slots.description), 'items-center': !description && !$slots.description }]">
|
<div class="flex" :class="[ui.gap, { 'items-start': (description || $slots.description), 'items-center': !description && !$slots.description }]">
|
||||||
<slot name="icon" :icon="icon">
|
<slot name="icon" :icon="icon">
|
||||||
<UIcon v-if="icon" :name="icon" :ui="ui.icon.base" />
|
<UIcon v-if="icon" :name="icon" :class="ui.icon.base" />
|
||||||
</slot>
|
</slot>
|
||||||
<slot name="avatar" :avatar="avatar">
|
<slot name="avatar" :avatar="avatar">
|
||||||
<UAvatar v-if="avatar" v-bind="{ size: ui.avatar.size, ...avatar }" :class="ui.avatar.base" />
|
<UAvatar v-if="avatar" v-bind="{ size: ui.avatar.size, ...avatar }" :class="ui.avatar.base" />
|
||||||
@@ -14,19 +14,23 @@
|
|||||||
{{ title }}
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="description || $slots.description" :class="twMerge(ui.description, !(title && $slots.title) && 'mt-0 leading-5')">
|
<div v-if="description || $slots.description" :class="twMerge(ui.description, !(title && $slots.title) && 'mt-0 leading-5')">
|
||||||
<slot name="description" :description="description">
|
<slot name="description" :description="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
<div v-if="(description || $slots.description) && actions.length" :class="ui.actions">
|
<div v-if="(description || $slots.description) && (actions.length || $slots.actions)" :class="ui.actions">
|
||||||
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
<slot name="actions">
|
||||||
|
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="closeButton || (!description && !$slots.description && actions.length)" :class="twMerge(ui.actions, 'mt-0')">
|
<div v-if="closeButton || (!description && !$slots.description && actions.length)" :class="twMerge(ui.actions, 'mt-0')">
|
||||||
<template v-if="!description && !$slots.description && actions.length">
|
<template v-if="!description && !$slots.description && (actions.length || $slots.actions)">
|
||||||
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
<slot name="actions">
|
||||||
|
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<UButton v-if="closeButton" aria-label="Close" v-bind="{ ...(ui.default.closeButton || {}), ...closeButton }" @click.stop="$emit('close')" />
|
<UButton v-if="closeButton" aria-label="Close" v-bind="{ ...(ui.default.closeButton || {}), ...closeButton }" @click.stop="$emit('close')" />
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import { useEventBus } from '@vueuse/core'
|
|||||||
import type { ZodSchema } from 'zod'
|
import type { ZodSchema } from 'zod'
|
||||||
import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi'
|
import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi'
|
||||||
import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup'
|
import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup'
|
||||||
import type { ObjectSchemaAsync as ValibotObjectSchema } from 'valibot'
|
import type { BaseSchema as ValibotSchema30, BaseSchemaAsync as ValibotSchemaAsync30 } from 'valibot30'
|
||||||
|
import type { GenericSchema as ValibotSchema, GenericSchemaAsync as ValibotSchemaAsync, SafeParser as ValibotSafeParser, SafeParserAsync as ValibotSafeParserAsync } from 'valibot'
|
||||||
import type { FormError, FormEvent, FormEventType, FormSubmitEvent, FormErrorEvent, Form } from '../../types/form'
|
import type { FormError, FormEvent, FormEventType, FormSubmitEvent, FormErrorEvent, Form } from '../../types/form'
|
||||||
import { useId } from '#imports'
|
import { useId } from '#imports'
|
||||||
|
|
||||||
@@ -25,11 +26,13 @@ class FormException extends Error {
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
schema: {
|
schema: {
|
||||||
type: Object as
|
type: [Object, Function] as
|
||||||
| PropType<ZodSchema>
|
| PropType<ZodSchema>
|
||||||
| PropType<YupObjectSchema<any>>
|
| PropType<YupObjectSchema<any>>
|
||||||
| PropType<JoiSchema>
|
| PropType<JoiSchema>
|
||||||
| PropType<ValibotObjectSchema<any>>,
|
| PropType<ValibotSchema30 | ValibotSchemaAsync30>
|
||||||
|
| PropType<ValibotSchema | ValibotSchemaAsync>
|
||||||
|
| PropType<ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>>,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
state: {
|
state: {
|
||||||
@@ -151,7 +154,6 @@ export default defineComponent({
|
|||||||
validate,
|
validate,
|
||||||
errors,
|
errors,
|
||||||
setErrors (errs: FormError[], path?: string) {
|
setErrors (errs: FormError[], path?: string) {
|
||||||
errors.value = errs
|
|
||||||
if (path) {
|
if (path) {
|
||||||
errors.value = errors.value.filter(
|
errors.value = errors.value.filter(
|
||||||
(error) => error.path !== path
|
(error) => error.path !== path
|
||||||
@@ -256,21 +258,19 @@ async function getJoiErrors (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValibotSchema (schema: any): schema is ValibotObjectSchema<any> {
|
function isValibotSchema (schema: any): schema is ValibotSchema30 | ValibotSchemaAsync30 | ValibotSchema | ValibotSchemaAsync | ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any> {
|
||||||
return schema._parse !== undefined
|
return '_parse' in schema || '_run' in schema || (typeof schema === 'function' && 'schema' in schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getValibotError (
|
async function getValibotError (
|
||||||
state: any,
|
state: any,
|
||||||
schema: ValibotObjectSchema<any>
|
schema: ValibotSchema30 | ValibotSchemaAsync30 | ValibotSchema | ValibotSchemaAsync | ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>
|
||||||
): Promise<FormError[]> {
|
): Promise<FormError[]> {
|
||||||
const result = await schema._parse(state)
|
const result = await ('_parse' in schema ? schema._parse(state) : '_run' in schema ? schema._run({ typed: false, value: state }, {}) : schema(state))
|
||||||
if (result.issues) {
|
return result.issues?.map((issue) => ({
|
||||||
return result.issues.map((issue) => ({
|
// We know that the key for a form schema is always a string or a number
|
||||||
path: issue.path?.map(p => p.key).join('.') || '',
|
path: issue.path?.map((item) => item.key).join('.') || '',
|
||||||
message: issue.message
|
message: issue.message
|
||||||
}))
|
})) || []
|
||||||
}
|
|
||||||
return []
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="ui.wrapper">
|
<div :class="(type === 'hidden') ? 'hidden' : ui.wrapper">
|
||||||
<input
|
<input
|
||||||
:id="inputId"
|
:id="inputId"
|
||||||
ref="input"
|
ref="input"
|
||||||
|
|||||||
@@ -199,11 +199,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const guessOptionValue = (option: any) => {
|
const guessOptionValue = (option: any) => {
|
||||||
return get(option, props.valueAttribute, get(option, props.optionAttribute))
|
return get(option, props.valueAttribute, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
const guessOptionText = (option: any) => {
|
const guessOptionText = (option: any) => {
|
||||||
return get(option, props.optionAttribute, get(option, props.valueAttribute))
|
return get(option, props.optionAttribute, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizeOption = (option: any) => {
|
const normalizeOption = (option: any) => {
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ export default defineComponent({
|
|||||||
variant?.replaceAll('{color}', color.value),
|
variant?.replaceAll('{color}', color.value),
|
||||||
(isLeading.value || slots.leading) && ui.value.leading.padding[size.value],
|
(isLeading.value || slots.leading) && ui.value.leading.padding[size.value],
|
||||||
(isTrailing.value || slots.trailing) && ui.value.trailing.padding[size.value]
|
(isTrailing.value || slots.trailing) && ui.value.trailing.padding[size.value]
|
||||||
), props.placeholder && (props.modelValue === undefined && props.modelValue === null) && ui.value.placeholder, props.selectClass)
|
), props.placeholder && !props.modelValue && ui.value.placeholder, props.selectClass)
|
||||||
})
|
})
|
||||||
|
|
||||||
const isLeading = computed(() => {
|
const isLeading = computed(() => {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<ULink
|
<ULink
|
||||||
as="span"
|
as="span"
|
||||||
:class="[ui.base, index === links.length - 1 ? ui.active : !!link.to ? ui.inactive : '']"
|
:class="[ui.base, index === links.length - 1 ? ui.active : !!link.to ? ui.inactive : '']"
|
||||||
v-bind="getULinkProps(link)"
|
|
||||||
:aria-current="index === links.length - 1 ? 'page' : undefined"
|
:aria-current="index === links.length - 1 ? 'page' : undefined"
|
||||||
|
v-bind="getULinkProps(link)"
|
||||||
@click="link.click"
|
@click="link.click"
|
||||||
>
|
>
|
||||||
<slot name="icon" :link="link" :index="index" :is-active="index === links.length - 1">
|
<slot name="icon" :link="link" :index="index" :is-active="index === links.length - 1">
|
||||||
|
|||||||
@@ -321,7 +321,10 @@ export default defineComponent({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const emptyState = computed(() => ({ ...ui.value.default.emptyState, ...props.emptyState }))
|
const emptyState = computed(() => {
|
||||||
|
if (props.emptyState === null) return null
|
||||||
|
return { ...ui.value.default.emptyState, ...props.emptyState }
|
||||||
|
})
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</HTab>
|
</HTab>
|
||||||
</HTabList>
|
</HTabList>
|
||||||
|
|
||||||
<HTabPanels :class="ui.container">
|
<HTabPanels v-if="content" :class="ui.container">
|
||||||
<HTabPanel v-for="(item, index) of items" :key="index" v-slot="{ selected }" :class="ui.base" :unmount="unmount">
|
<HTabPanel v-for="(item, index) of items" :key="index" v-slot="{ selected }" :class="ui.base" :unmount="unmount">
|
||||||
<slot :name="item.slot || 'item'" :item="item" :index="index" :selected="selected">
|
<slot :name="item.slot || 'item'" :item="item" :index="index" :selected="selected">
|
||||||
{{ item.content }}
|
{{ item.content }}
|
||||||
@@ -88,6 +88,10 @@ export default defineComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
content: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
class: {
|
class: {
|
||||||
type: [String, Object, Array] as PropType<any>,
|
type: [String, Object, Array] as PropType<any>,
|
||||||
default: () => ''
|
default: () => ''
|
||||||
|
|||||||
@@ -18,11 +18,11 @@
|
|||||||
{{ title }}
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="(description || $slots.description)" :class="twMerge(ui.description, !(title && $slots.title) && 'mt-0 leading-5')">
|
<div v-if="(description || $slots.description)" :class="twMerge(ui.description, !(title && $slots.title) && 'mt-0 leading-5')">
|
||||||
<slot name="description" :description="description">
|
<slot name="description" :description="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
<div v-if="(description || $slots.description) && actions.length" :class="ui.actions">
|
<div v-if="(description || $slots.description) && actions.length" :class="ui.actions">
|
||||||
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
<UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...(ui.default.actionButton || {}), ...action }" @click.stop="onAction(action)" />
|
||||||
@@ -131,7 +131,8 @@ export default defineComponent({
|
|||||||
ui.value.wrapper,
|
ui.value.wrapper,
|
||||||
ui.value.background?.replaceAll('{color}', props.color),
|
ui.value.background?.replaceAll('{color}', props.color),
|
||||||
ui.value.rounded,
|
ui.value.rounded,
|
||||||
ui.value.shadow
|
ui.value.shadow,
|
||||||
|
ui.value.ring?.replaceAll('{color}', props.color)
|
||||||
), props.class)
|
), props.class)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<TransitionRoot as="template" :appear="appear" :show="isOpen" @after-leave="onAfterLeave">
|
<TransitionRoot as="template" :appear="appear" :show="isOpen" @after-leave="onAfterLeave">
|
||||||
<HDialog :class="[ui.wrapper, { 'justify-end': side === 'right' }]" v-bind="attrs" @close="close">
|
<HDialog :class="[ui.wrapper, { 'justify-end': side === 'right' }, { 'items-end': side === 'bottom' }]" v-bind="attrs" @close="close">
|
||||||
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
||||||
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
||||||
</TransitionChild>
|
</TransitionChild>
|
||||||
|
|
||||||
<TransitionChild as="template" :appear="appear" v-bind="transitionClass">
|
<TransitionChild as="template" :appear="appear" v-bind="transitionClass">
|
||||||
<HDialogPanel :class="[ui.base, ui.width, ui.background, ui.ring, ui.padding]">
|
<HDialogPanel :class="[ui.base, sideType === 'horizontal' ? [ui.width, 'h-full'] : [ui.height, 'w-full'], ui.background, ui.ring, ui.padding]">
|
||||||
<slot />
|
<slot />
|
||||||
</HDialogPanel>
|
</HDialogPanel>
|
||||||
</TransitionChild>
|
</TransitionChild>
|
||||||
@@ -46,9 +46,9 @@ export default defineComponent({
|
|||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
side: {
|
side: {
|
||||||
type: String as PropType<'left' | 'right'>,
|
type: String as PropType<'left' | 'right' | 'top' | 'bottom'>,
|
||||||
default: 'right',
|
default: 'right',
|
||||||
validator: (value: string) => ['left', 'right'].includes(value)
|
validator: (value: string) => ['left', 'right', 'top', 'bottom'].includes(value)
|
||||||
},
|
},
|
||||||
overlay: {
|
overlay: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -89,14 +89,52 @@ export default defineComponent({
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let enterFrom, leaveTo
|
||||||
|
switch (props.side) {
|
||||||
|
case 'left':
|
||||||
|
enterFrom = ui.value.translate.left
|
||||||
|
leaveTo = ui.value.translate.left
|
||||||
|
break
|
||||||
|
case 'right':
|
||||||
|
enterFrom = ui.value.translate.right
|
||||||
|
leaveTo = ui.value.translate.right
|
||||||
|
break
|
||||||
|
case 'top':
|
||||||
|
enterFrom = ui.value.translate.top
|
||||||
|
leaveTo = ui.value.translate.top
|
||||||
|
break
|
||||||
|
case 'bottom':
|
||||||
|
enterFrom = ui.value.translate.bottom
|
||||||
|
leaveTo = ui.value.translate.bottom
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
enterFrom = ui.value.translate.right
|
||||||
|
leaveTo = ui.value.translate.right
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...ui.value.transition,
|
...ui.value.transition,
|
||||||
enterFrom: props.side === 'left' ? ui.value.translate.left : ui.value.translate.right,
|
enterFrom,
|
||||||
enterTo: ui.value.translate.base,
|
enterTo: ui.value.translate.base,
|
||||||
leaveFrom: ui.value.translate.base,
|
leaveFrom: ui.value.translate.base,
|
||||||
leaveTo: props.side === 'left' ? ui.value.translate.left : ui.value.translate.right
|
leaveTo
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const sideType = computed(() => {
|
||||||
|
switch (props.side) {
|
||||||
|
case 'left':
|
||||||
|
return 'horizontal'
|
||||||
|
case 'right':
|
||||||
|
return 'horizontal'
|
||||||
|
case 'top':
|
||||||
|
return 'vertical'
|
||||||
|
case 'bottom':
|
||||||
|
return 'vertical'
|
||||||
|
default:
|
||||||
|
return 'right'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
function close (value: boolean) {
|
function close (value: boolean) {
|
||||||
if (props.preventClose) {
|
if (props.preventClose) {
|
||||||
@@ -121,6 +159,7 @@ export default defineComponent({
|
|||||||
attrs,
|
attrs,
|
||||||
isOpen,
|
isOpen,
|
||||||
transitionClass,
|
transitionClass,
|
||||||
|
sideType,
|
||||||
onAfterLeave,
|
onAfterLeave,
|
||||||
close
|
close
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export const useCarouselScroll = (el: Ref<HTMLElement>) => {
|
|||||||
function onMouseUp () {
|
function onMouseUp () {
|
||||||
el.value.style.removeProperty('scroll-behavior')
|
el.value.style.removeProperty('scroll-behavior')
|
||||||
el.value.style.removeProperty('scroll-snap-type')
|
el.value.style.removeProperty('scroll-snap-type')
|
||||||
|
el.value.style.removeProperty('pointer-events')
|
||||||
|
|
||||||
window.removeEventListener('mousemove', onMouseMove)
|
window.removeEventListener('mousemove', onMouseMove)
|
||||||
window.removeEventListener('mouseup', onMouseUp)
|
window.removeEventListener('mouseup', onMouseUp)
|
||||||
@@ -24,6 +25,8 @@ export const useCarouselScroll = (el: Ref<HTMLElement>) => {
|
|||||||
function onMouseMove (e) {
|
function onMouseMove (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
|
el.value.style.pointerEvents = 'none'
|
||||||
|
|
||||||
const delta = e.pageX - x.value
|
const delta = e.pageX - x.value
|
||||||
|
|
||||||
x.value = e.pageX
|
x.value = e.pageX
|
||||||
|
|||||||
2
src/runtime/types/link.d.ts
vendored
2
src/runtime/types/link.d.ts
vendored
@@ -7,6 +7,6 @@ export interface Link extends NuxtLinkProps {
|
|||||||
active?: boolean
|
active?: boolean
|
||||||
exact?: boolean
|
exact?: boolean
|
||||||
exactQuery?: boolean
|
exactQuery?: boolean
|
||||||
exactMatch?: boolean
|
exactHash?: boolean
|
||||||
inactiveClass?: string
|
inactiveClass?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ export default {
|
|||||||
padding: '',
|
padding: '',
|
||||||
shadow: 'shadow-xl',
|
shadow: 'shadow-xl',
|
||||||
width: 'w-screen max-w-md',
|
width: 'w-screen max-w-md',
|
||||||
|
height: 'h-screen max-h-96',
|
||||||
translate: {
|
translate: {
|
||||||
base: 'translate-x-0',
|
base: 'translate-x-0',
|
||||||
left: '-translate-x-full rtl:translate-x-full',
|
left: '-translate-x-full rtl:translate-x-full',
|
||||||
right: 'translate-x-full rtl:-translate-x-full'
|
right: 'translate-x-full rtl:-translate-x-full',
|
||||||
|
top: '-translate-y-full',
|
||||||
|
bottom: 'translate-y-full'
|
||||||
},
|
},
|
||||||
// Syntax for `<TransitionRoot>` component https://headlessui.com/vue/transition#basic-example
|
// Syntax for `<TransitionRoot>` component https://headlessui.com/vue/transition#basic-example
|
||||||
transition: {
|
transition: {
|
||||||
|
|||||||
Reference in New Issue
Block a user