Compare commits

..

3 Commits

Author SHA1 Message Date
Benjamin Canac
723065afa7 up 2025-03-07 15:19:38 +01:00
Benjamin Canac
e67305e412 up 2025-03-07 15:11:17 +01:00
Benjamin Canac
33ed3935a3 fix(vue): stub vue-router 2025-03-07 15:00:10 +01:00
82 changed files with 2077 additions and 2214 deletions

View File

@@ -1,36 +1,5 @@
# Changelog # Changelog
## [3.0.0](https://github.com/nuxt/ui/compare/v3.0.0-beta.4...v3.0.0) (2025-03-12)
## [3.0.0-beta.4](https://github.com/nuxt/ui/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2025-03-12)
### Features
* **Form:** global errors ([#3482](https://github.com/nuxt/ui/issues/3482)) ([6e03d9c](https://github.com/nuxt/ui/commit/6e03d9c6efc8f4cfc306813e733d7d3e03706323))
* **Input/Textarea:** allow `null` value in model ([#3415](https://github.com/nuxt/ui/issues/3415)) ([cfe9b2e](https://github.com/nuxt/ui/commit/cfe9b2ecf34827bc11a5281a069988ab96030047))
* **useLocale:** handle generic messages ([#3100](https://github.com/nuxt/ui/issues/3100)) ([a9c8eb3](https://github.com/nuxt/ui/commit/a9c8eb3f60a10d1a71632991c9db594716b0fba1))
### Bug Fixes
* **Button:** missing import ([21dbf01](https://github.com/nuxt/ui/commit/21dbf01888a161a9d8ac6eb0d957c1342f6cc30d)), closes [nuxt/ui#3417](https://github.com/nuxt/ui/issues/3417)
* **Form:** input blur validation on submit ([#3504](https://github.com/nuxt/ui/issues/3504)) ([97c8098](https://github.com/nuxt/ui/commit/97c8098d4a35c392719ae179d36aa008d6f8f78a))
* **vue:** prevent calling `useHead` in colors ([5ecd227](https://github.com/nuxt/ui/commit/5ecd2271ca86087cb805548397d75c38763ad412))
## [3.0.0-beta.3](https://github.com/nuxt/ui/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2025-03-07)
### Features
* **Button:** handle `active` state ([bd2d484](https://github.com/nuxt/ui/commit/bd2d4848d246a3d5930f8059913f5a1a0abe29fd)), closes [#3417](https://github.com/nuxt/ui/issues/3417)
* **Table:** add `loading` slot ([99e531d](https://github.com/nuxt/ui/commit/99e531d8dfb7954322b7ab7feda3d8814c6d8d02)), closes [#3444](https://github.com/nuxt/ui/issues/3444)
### Bug Fixes
* **InputMenu/SelectMenu:** proxy `required` in root props ([60b7e2d](https://github.com/nuxt/ui/commit/60b7e2d69e80afa7e221855dcec46479d0ca5c6c))
* **InputMenu:** wrong `required` in multiple mode ([01fa230](https://github.com/nuxt/ui/commit/01fa230eae4b6623c5fd71cc218d114d9f6f0f25)), closes [#2741](https://github.com/nuxt/ui/issues/2741)
* **Pagination:** add missing slots ([a47c5ff](https://github.com/nuxt/ui/commit/a47c5ff46616eafee3158cb9801183965f5f9874)), closes [#3441](https://github.com/nuxt/ui/issues/3441)
* **Pagination:** wrong next link ([e823022](https://github.com/nuxt/ui/commit/e823022b19bb172d2e5fabb9144b4a4286a25a5f)), closes [#3008](https://github.com/nuxt/ui/issues/3008)
* **templates:** prevent overriding existing colors ([ccbd89c](https://github.com/nuxt/ui/commit/ccbd89c908fe8af54c7d723dd12da5b7f3906c8f)), closes [#3426](https://github.com/nuxt/ui/issues/3426)
## [3.0.0-beta.2](https://github.com/nuxt/ui/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2025-02-28) ## [3.0.0-beta.2](https://github.com/nuxt/ui/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2025-02-28)
### Bug Fixes ### Bug Fixes

View File

@@ -14,7 +14,7 @@
We're thrilled to introduce Nuxt UI v3, a significant upgrade to our UI library that delivers extensive improvements and robust new capabilities. This major update harnesses the combined strengths of [Reka UI](https://reka-ui.com/), [Tailwind CSS v4](https://tailwindcss.com/), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces. We're thrilled to introduce Nuxt UI v3, a significant upgrade to our UI library that delivers extensive improvements and robust new capabilities. This major update harnesses the combined strengths of [Reka UI](https://reka-ui.com/), [Tailwind CSS v4](https://tailwindcss.com/), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces.
> [!NOTE] > [!NOTE]
> You are on the `v3` development branch, check out the [v2 branch](https://github.com/nuxt/ui/tree/v2) for Nuxt UI v2. > You are on the `v3` development branch, check out the [dev branch](https://github.com/nuxt/ui/tree/dev) for Nuxt UI v2.
## Documentation ## Documentation

View File

@@ -275,14 +275,16 @@ faq:
content: As the Figma Pro Kit is a digital product packaged as a zip file, we cannot offer refunds once the purchase is made. content: As the Figma Pro Kit is a digital product packaged as a zip file, we cannot offer refunds once the purchase is made.
- label: Do you have a Figma to Code plugin? - label: Do you have a Figma to Code plugin?
content: > content: >
We recommend the open source [TemPad Dev](https://github.com/ecomfe/tempad-dev) inspect panel with the [TemPad Dev Nuxt UI Plugin](https://github.com/Justineo/tempad-dev-plugin-nuxt-ui): We recommend the open source [TeamPad Dev](https://github.com/ecomfe/tempad-dev) inspect panel with the [TeamPad Dev Nuxt UI Plugin](https://github.com/Justineo/tempad-dev-plugin-nuxt-ui):
1. Install the [TemPad Dev Chrome Extension](https://chromewebstore.google.com/detail/tempad-dev/lgoeakbaikpkihoiphamaeopmliaimpc) 1. Install the [TeamPad Dev Chrome Extension](https://chromewebstore.google.com/detail/tempad-dev/lgoeakbaikpkihoiphamaeopmliaimpc)
2. Open your Figma file with Nuxt UI components (reload the page if you don't see the TemPad Dev panel) 2. Open your Figma file with Nuxt UI components (reload the page if you don't see the TeamPad Dev panel)
3. Install the `@nuxt` (or `@nuxt/pro` for Nuxt UI Pro) in TemPad Dev's plugins section 3. Install the `@nuxt` in TeamPad Dev's plugins section
4. Select any Nuxt UI component and inspect the code it generates 4. Select any Nuxt UI component and inspect the code it generates
![TemPad Dev Nuxt UI Plugin](/pro/figma/teampad-dev-nuxt-ui-plugin.gif){.w-full .rounded .mb-2 .max-w-[636px]} ![TeamPad Dev Nuxt UI Plugin](/pro/figma/teampad-dev-nuxt-ui-plugin.gif){.w-full .rounded .mb-2 .max-w-[636px]}
*Right now, only Nuxt UI components are supported, but the code of the plugin is [open source](https://github.com/Justineo/tempad-dev-plugin-nuxt-ui) and anyone can contribute to it.*

View File

@@ -189,7 +189,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
:links="page.design_system.links" :links="page.design_system.links"
orientation="horizontal" orientation="horizontal"
> >
<MDC :value="page.design_system.code" cache-key="index-design-system-code" /> <MDC :value="page.design_system.code" />
</UPageSection> </UPageSection>
<USeparator /> <USeparator />
@@ -201,10 +201,10 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
orientation="horizontal" orientation="horizontal"
> >
<template #description> <template #description>
<MDC :value="page.component_customization.description" cache-key="index-component-customization-description" /> <MDC :value="page.component_customization.description" />
</template> </template>
<MDC :value="page.component_customization.code" cache-key="index-component-customization-code" /> <MDC :value="page.component_customization.code" />
</UPageSection> </UPageSection>
<USeparator /> <USeparator />

View File

@@ -227,17 +227,28 @@ This option adds the `transition-colors` class on components with hover or activ
Nuxt UI v3 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. Nuxt UI v3 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.
Automatic preview releases are created for all commits and PRs to the `v3` branch. Use them by replacing your package version with the specific commit hash or PR number. Preview releases are automatically generated for every commit to the `v3` branch and pull requests targeting the `v3` branch. To use it into your project, use the installation command below by replacing `5385f84` with any commit hash or pull request number.
```diff [package.json] ::code-group{sync="pm"}
{
"dependencies": { ```bash [pnpm]
- "@nuxt/ui": "^3.0.0-beta.3", pnpm add https://pkg.pr.new/@nuxt/ui@5385f84
+ "@nuxt/ui": "https://pkg.pr.new/@nuxt/ui@83725ac",
}
}
``` ```
```bash [yarn]
yarn add https://pkg.pr.new/@nuxt/ui@5385f84
```
```bash [npm]
npm install https://pkg.pr.new/@nuxt/ui@5385f84
```
```bash [bun]
bun add https://pkg.pr.new/@nuxt/ui@5385f84
```
::
::note ::note
**pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes.
:: ::

View File

@@ -315,17 +315,28 @@ This option adds the `transition-colors` class on components with hover or activ
Nuxt UI v3 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. Nuxt UI v3 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.
Automatic preview releases are created for all commits and PRs to the `v3` branch. Use them by replacing your package version with the specific commit hash or PR number. Preview releases are automatically generated for every commit to the `v3` branch and pull requests targeting the `v3` branch. To use it into your project, use the installation command below by replacing `5385f84` with any commit hash or pull request number.
```diff [package.json] ::code-group{sync="pm"}
{
"dependencies": { ```bash [pnpm]
- "@nuxt/ui": "^3.0.0-beta.3", pnpm add https://pkg.pr.new/@nuxt/ui@5385f84
+ "@nuxt/ui": "https://pkg.pr.new/@nuxt/ui@83725ac",
}
}
``` ```
```bash [yarn]
yarn add https://pkg.pr.new/@nuxt/ui@5385f84
```
```bash [npm]
npm install https://pkg.pr.new/@nuxt/ui@5385f84
```
```bash [bun]
bun add https://pkg.pr.new/@nuxt/ui@5385f84
```
::
::note ::note
**pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes.
:: ::

View File

@@ -439,10 +439,7 @@ This change affects the following components: `Modal`, `Popover`, `Slideover`, `
This change affects the following components: `Modal`, `Slideover`. This change affects the following components: `Modal`, `Slideover`.
:: ::
6. The `Toast` component `timeout` prop has been renamed to `duration`:
### Changed composables
1. The `useToast()` composable `timeout` prop has been renamed to `duration`:
```diff ```diff
<script setup lang="ts"> <script setup lang="ts">
@@ -453,79 +450,6 @@ const toast = useToast()
</script> </script>
``` ```
2. The `useModal` and `useSlideover` composables have been removed in favor of a more generic `useOverlay` composable:
Some important differences:
- The `useOverlay` composable is now used to create overlay instances
- Overlays that are opened, can be awaited for their result
- Overlays can no longer be closed using `modal.close()` or `slideover.close()`, rather, they close automatically: either when a `closed` event is fired explicitly from the opened component OR when the overlay closes itself (clicking on backdrop, pressing the ESC key, etc)
- To capture the return value in the parent component you must explictly emit a `closed` event with the desired value
```diff
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
- modal.open(ModalExampleComponent)
+ const modal = overlay.create(ModalExampleComponent)
</script>
```
Props are now passed through a props attribute:
```diff
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
const count = ref(0)
- modal.open(ModalExampleComponent, {
- count: count.value
- })
+ const modal = overlay.create(ModalExampleComponent, {
+ props: {
+ count: count.value
+ }
+ })
</script>
```
Closing a modal is now done through the `closed` event. The `modal.open` method now returns a promise that resolves to the result of the modal whenever the modal is closed:
```diff
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
- const modal = useModal()
+ const overlay = useOverlay()
+ const modal = overlay.create(ModalExampleComponent)
- function openModal() {
- modal.open(ModalExampleComponent, {
- onSuccess() {
- toast.add({ title: 'Success!' })
- }
- })
- }
+ async function openModal() {
+ const result = await modal.open(ModalExampleComponent, {
+ count: count.value
+ })
+
+ if (result) {
+ toast.add({ title: 'Success!' })
+ }
+ }
</script>
```
--- ---
::warning ::warning

View File

@@ -17,11 +17,6 @@ Nuxt UI provides an **App** component that wraps your app to provide global conf
### Locale ### Locale
::module-only
#ui
:::div
Use the `locale` prop with the locale you want to use from `@nuxt/ui/locale`: Use the `locale` prop with the locale you want to use from `@nuxt/ui/locale`:
```vue [app.vue] ```vue [app.vue]
@@ -36,42 +31,13 @@ import { fr } from '@nuxt/ui/locale'
</template> </template>
``` ```
:::
#ui-pro
:::div
Use the `locale` prop with the locale you want to use from `@nuxt/ui-pro/locale`:
```vue [app.vue]
<script setup lang="ts">
import { fr } from '@nuxt/ui-pro/locale'
</script>
<template>
<UApp :locale="fr">
<NuxtPage />
</UApp>
</template>
```
:::
::
### Custom locale ### Custom locale
You also have the option to add your own locale using `defineLocale`: You also have the option to add your own locale using `defineLocale`:
::module-only
#ui
:::div
```vue [app.vue] ```vue [app.vue]
<script setup lang="ts"> <script setup lang="ts">
import type { Messages } from '@nuxt/ui' const locale = defineLocale({
const locale = defineLocale<Messages>({
name: 'My custom locale', name: 'My custom locale',
code: 'en', code: 'en',
dir: 'ltr', dir: 'ltr',
@@ -88,35 +54,6 @@ const locale = defineLocale<Messages>({
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [app.vue]
<script setup lang="ts">
import type { Messages } from '@nuxt/ui-pro'
const locale = defineLocale<Messages>({
name: 'My custom locale',
code: 'en',
dir: 'ltr',
messages: {
// implement pairs
}
})
</script>
<template>
<UApp :locale="locale">
<NuxtPage />
</UApp>
</template>
```
:::
::
::tip ::tip
Look at the `code` parameter, there you need to pass the iso code of the language. Example: Look at the `code` parameter, there you need to pass the iso code of the language. Example:
@@ -179,11 +116,6 @@ export default defineNuxtConfig({
#### Set the `locale` prop using `useI18n` #### Set the `locale` prop using `useI18n`
::module-only
#ui
:::div
```vue [app.vue] ```vue [app.vue]
<script setup lang="ts"> <script setup lang="ts">
import * as locales from '@nuxt/ui/locale' import * as locales from '@nuxt/ui/locale'
@@ -198,28 +130,6 @@ const { locale } = useI18n()
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [app.vue]
<script setup lang="ts">
import * as locales from '@nuxt/ui-pro/locale'
const { locale } = useI18n()
</script>
<template>
<UApp :locale="locales[locale]">
<NuxtPage />
</UApp>
</template>
```
:::
::
:: ::
### Dynamic direction ### Dynamic direction
@@ -228,11 +138,6 @@ Each locale has a `dir` property which will be used by the `App` component to se
In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://nuxt.com/docs/api/composables/use-head) composable: In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://nuxt.com/docs/api/composables/use-head) composable:
::module-only
#ui
:::div
```vue [app.vue] ```vue [app.vue]
<script setup lang="ts"> <script setup lang="ts">
import * as locales from '@nuxt/ui/locale' import * as locales from '@nuxt/ui/locale'
@@ -257,38 +162,6 @@ useHead({
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [app.vue]
<script setup lang="ts">
import * as locales from '@nuxt/ui-pro/locale'
const { locale } = useI18n()
const lang = computed(() => locales[locale.value].code)
const dir = computed(() => locales[locale.value].dir)
useHead({
htmlAttrs: {
lang,
dir
}
})
</script>
<template>
<UApp :locale="locales[locale]">
<NuxtPage />
</UApp>
</template>
```
:::
::
## Supported languages ## Supported languages
:supported-languages :supported-languages

View File

@@ -17,11 +17,6 @@ Nuxt UI provides an **App** component that wraps your app to provide global conf
### Locale ### Locale
::module-only
#ui
:::div
Use the `locale` prop with the locale you want to use from `@nuxt/ui/locale`: Use the `locale` prop with the locale you want to use from `@nuxt/ui/locale`:
```vue [App.vue] ```vue [App.vue]
@@ -36,43 +31,15 @@ import { fr } from '@nuxt/ui/locale'
</template> </template>
``` ```
:::
#ui-pro
:::div
Use the `locale` prop with the locale you want to use from `@nuxt/ui-pro/locale`:
```vue [App.vue]
<script setup lang="ts">
import { fr } from '@nuxt/ui-pro/locale'
</script>
<template>
<UApp :locale="fr">
<RouterView />
</UApp>
</template>
```
:::
::
### Custom locale ### Custom locale
You also have the option to add your locale using `defineLocale`: You also have the option to add your locale using `defineLocale`:
::module-only
#ui
:::div
```vue [App.vue] ```vue [App.vue]
<script setup lang="ts"> <script setup lang="ts">
import type { Messages } from '@nuxt/ui' import { defineLocale } from '@nuxt/ui/composables/defineLocale'
import { defineLocale } from '@nuxt/ui/composables/defineLocale.js'
const locale = defineLocale<Messages>({ const locale = defineLocale({
name: 'My custom locale', name: 'My custom locale',
code: 'en', code: 'en',
dir: 'ltr', dir: 'ltr',
@@ -89,36 +56,6 @@ const locale = defineLocale<Messages>({
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [App.vue]
<script setup lang="ts">
import type { Messages } from '@nuxt/ui-pro'
import { defineLocale } from '@nuxt/ui/composables/defineLocale.js'
const locale = defineLocale<Messages>({
name: 'My custom locale',
code: 'en',
dir: 'ltr',
messages: {
// implement pairs
}
})
</script>
<template>
<UApp :locale="locale">
<RouterView />
</UApp>
</template>
```
:::
::
::tip ::tip
Look at the `code` parameter, there you need to pass the iso code of the language. Example: Look at the `code` parameter, there you need to pass the iso code of the language. Example:
@@ -194,11 +131,6 @@ app.mount('#app')
#### Set the `locale` prop using `useI18n` #### Set the `locale` prop using `useI18n`
::module-only
#ui
:::div
```vue [App.vue] ```vue [App.vue]
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@@ -214,29 +146,6 @@ const { locale } = useI18n()
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [App.vue]
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import * as locales from '@nuxt/ui-pro/locale'
const { locale } = useI18n()
</script>
<template>
<UApp :locale="locales[locale]">
<RouterView />
</UApp>
</template>
```
:::
::
:: ::
### Dynamic direction ### Dynamic direction
@@ -245,11 +154,6 @@ Each locale has a `dir` property which will be used by the `App` component to se
In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://unhead.unjs.io/usage/composables/use-head) composable: In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://unhead.unjs.io/usage/composables/use-head) composable:
::module-only
#ui
:::div
```vue [App.vue] ```vue [App.vue]
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
@@ -277,41 +181,6 @@ useHead({
</template> </template>
``` ```
:::
#ui-pro
:::div
```vue [App.vue]
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useHead } from '@unhead/vue'
import * as locales from '@nuxt/ui-pro/locale'
const { locale } = useI18n()
const lang = computed(() => locales[locale.value].code)
const dir = computed(() => locales[locale.value].dir)
useHead({
htmlAttrs: {
lang,
dir
}
})
</script>
<template>
<UApp :locale="locales[locale]">
<RouterView />
</UApp>
</template>
```
:::
::
## Supported languages ## Supported languages
:supported-languages :supported-languages

View File

@@ -55,7 +55,6 @@ export default defineNuxtConfig({
}] }]
}, },
rootAttrs: { rootAttrs: {
// @ts-expect-error - vaul-drawer-wrapper is not typed
'vaul-drawer-wrapper': '', 'vaul-drawer-wrapper': '',
'class': 'bg-(--ui-bg)' 'class': 'bg-(--ui-bg)'
} }

View File

@@ -4,25 +4,25 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@iconify-json/logos": "^1.2.4", "@iconify-json/logos": "^1.2.4",
"@iconify-json/lucide": "^1.2.29", "@iconify-json/lucide": "^1.2.28",
"@iconify-json/simple-icons": "^1.2.28", "@iconify-json/simple-icons": "^1.2.27",
"@iconify-json/vscode-icons": "^1.2.16", "@iconify-json/vscode-icons": "^1.2.16",
"@nuxt/content": "^3.3.0", "@nuxt/content": "^3.3.0",
"@nuxt/image": "^1.9.0", "@nuxt/image": "^1.9.0",
"@nuxt/ui": "latest", "@nuxt/ui": "latest",
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@a2768ed", "@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@02b7ea0",
"@nuxthub/core": "^0.8.18", "@nuxthub/core": "^0.8.18",
"@nuxtjs/plausible": "^1.2.0", "@nuxtjs/plausible": "^1.2.0",
"@octokit/rest": "^21.1.1", "@octokit/rest": "^21.1.1",
"@rollup/plugin-yaml": "^4.1.2", "@rollup/plugin-yaml": "^4.1.2",
"@vueuse/nuxt": "^13.0.0", "@vueuse/nuxt": "^12.8.2",
"joi": "^17.13.3", "joi": "^17.13.3",
"motion": "^12.5.0", "motion": "^12.4.10",
"motion-v": "0.11.3", "motion-v": "0.11.1",
"nuxt": "^3.16.0", "nuxt": "^3.15.4",
"nuxt-component-meta": "^0.10.0", "nuxt-component-meta": "^0.10.0",
"nuxt-llms": "^0.1.0", "nuxt-llms": "^0.1.0",
"nuxt-og-image": "^5.0.2", "nuxt-og-image": "^4.2.0",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"shiki-transformer-color-highlight": "^1.0.0", "shiki-transformer-color-highlight": "^1.0.0",
"superstruct": "^2.0.2", "superstruct": "^2.0.2",

View File

@@ -1,8 +1,8 @@
{ {
"name": "@nuxt/ui", "name": "@nuxt/ui",
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.", "description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
"version": "3.0.0", "version": "3.0.0-beta.2",
"packageManager": "pnpm@10.6.2", "packageManager": "pnpm@10.6.1",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/nuxt/ui.git" "url": "git+https://github.com/nuxt/ui.git"
@@ -67,7 +67,7 @@
"dev:build": "nuxi build playground", "dev:build": "nuxi build playground",
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && nuxi prepare docs && vite build playground-vue", "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && nuxi prepare docs && vite build playground-vue",
"docs": "DEV=true nuxi dev docs", "docs": "DEV=true nuxi dev docs",
"docs:build": "NODE_OPTIONS='--max-old-space-size=8192' nuxi build docs", "docs:build": "nuxi build docs",
"docs:prepare": "nuxt-component-meta docs", "docs:prepare": "nuxt-component-meta docs",
"lint": "eslint .", "lint": "eslint .",
"lint:fix": "eslint . --fix", "lint:fix": "eslint . --fix",
@@ -75,23 +75,23 @@
"test": "vitest", "test": "vitest",
"test:vue": "vitest -c vitest.vue.config.ts", "test:vue": "vitest -c vitest.vue.config.ts",
"test:vue:build": "vite build playground-vue", "test:vue:build": "vite build playground-vue",
"release": "release-it" "release": "release-it --preRelease=beta --npm.tag=next"
}, },
"dependencies": { "dependencies": {
"@iconify/vue": "^4.3.0", "@iconify/vue": "^4.3.0",
"@internationalized/date": "^3.7.0", "@internationalized/date": "^3.7.0",
"@internationalized/number": "^3.6.0", "@internationalized/number": "^3.6.0",
"@nuxt/fonts": "^0.11.0", "@nuxt/fonts": "^0.10.3",
"@nuxt/icon": "^1.11.0", "@nuxt/icon": "^1.10.3",
"@nuxt/kit": "^3.16.0", "@nuxt/kit": "^3.15.4",
"@nuxt/schema": "^3.16.0", "@nuxt/schema": "^3.15.4",
"@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/color-mode": "^3.5.2",
"@tailwindcss/postcss": "^4.0.13", "@tailwindcss/postcss": "^4.0.12",
"@tailwindcss/vite": "^4.0.13", "@tailwindcss/vite": "^4.0.12",
"@tanstack/vue-table": "^8.21.2", "@tanstack/vue-table": "^8.21.2",
"@unhead/vue": "^2.0.0-rc.10", "@unhead/vue": "^1.11.20",
"@vueuse/core": "^13.0.0", "@vueuse/core": "^12.8.2",
"@vueuse/integrations": "^13.0.0", "@vueuse/integrations": "^12.8.2",
"colortranslator": "^4.1.0", "colortranslator": "^4.1.0",
"consola": "^3.4.0", "consola": "^3.4.0",
"defu": "^6.1.4", "defu": "^6.1.4",
@@ -110,28 +110,26 @@
"pathe": "^2.0.3", "pathe": "^2.0.3",
"reka-ui": "^2.0.2", "reka-ui": "^2.0.2",
"scule": "^1.3.0", "scule": "^1.3.0",
"tailwind-variants": "^1.0.0", "tailwind-variants": "^0.3.1",
"tailwindcss": "^4.0.13", "tailwindcss": "^4.0.12",
"tinyglobby": "^0.2.12", "tinyglobby": "^0.2.12",
"unplugin": "^2.2.0", "unplugin": "^2.2.0",
"unplugin-auto-import": "^19.1.1", "unplugin-auto-import": "^19.1.1",
"unplugin-vue-components": "^28.4.1", "unplugin-vue-components": "^28.4.1",
"vaul-vue": "^0.3.0", "vaul-vue": "^0.3.0"
"vue": "^3.5.13",
"vue-router": "^4.5.0"
}, },
"devDependencies": { "devDependencies": {
"@nuxt/eslint-config": "^1.2.0", "@nuxt/eslint-config": "^1.1.0",
"@nuxt/module-builder": "^0.8.4", "@nuxt/module-builder": "^0.8.4",
"@nuxt/test-utils": "^3.17.2", "@nuxt/test-utils": "^3.17.1",
"@release-it/conventional-changelog": "^10.0.0", "@release-it/conventional-changelog": "^10.0.0",
"@standard-schema/spec": "^1.0.0", "@standard-schema/spec": "^1.0.0",
"@vue/test-utils": "^2.4.6", "@vue/test-utils": "^2.4.6",
"embla-carousel": "^8.5.2", "embla-carousel": "^8.5.2",
"eslint": "^9.22.0", "eslint": "^9.21.0",
"happy-dom": "^17.4.4", "happy-dom": "^17.1.2",
"joi": "^17.13.3", "joi": "^17.13.3",
"nuxt": "^3.16.0", "nuxt": "^3.15.4",
"release-it": "^18.1.2", "release-it": "^18.1.2",
"superstruct": "^2.0.2", "superstruct": "^2.0.2",
"valibot": "^0.42.1", "valibot": "^0.42.1",
@@ -148,9 +146,12 @@
"@nuxt/ui": "workspace:*", "@nuxt/ui": "workspace:*",
"chokidar": "3.6.0", "chokidar": "3.6.0",
"debug": "4.3.7", "debug": "4.3.7",
"rollup": "4.34.9", "happy-dom": "17.1.2",
"rollup": "4.32.1",
"typescript": "5.6.3", "typescript": "5.6.3",
"unimport": "3.14.5",
"unplugin": "^2.2.0", "unplugin": "^2.2.0",
"vue": "3.5.13",
"vue-tsc": "2.2.0" "vue-tsc": "2.2.0"
}, },
"pnpm": { "pnpm": {

View File

@@ -2,9 +2,8 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nuxt UI - Vue Playground</title> <title>Nuxt UI ❤️ Vue</title>
</head> </head>
<body> <body>
<div id="app" class="isolate"></div> <div id="app" class="isolate"></div>

View File

@@ -1,8 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<style>
.st0 { fill: #42B883; }
.st1 { fill: #35495E; }
</style>
<path class="st0" d="M78.8,10L64,35.4L49.2,10H0l64,110l64-110C128,10,78.8,10,78.8,10z" />
<path class="st1" d="M78.8,10L64,35.4L49.2,10H25.6L64,76l38.4-66H78.8z" />
</svg>

Before

Width:  |  Height:  |  Size: 316 B

View File

@@ -8,10 +8,10 @@
"generate": "nuxi generate" "generate": "nuxi generate"
}, },
"dependencies": { "dependencies": {
"@iconify-json/lucide": "^1.2.29", "@iconify-json/lucide": "^1.2.28",
"@iconify-json/simple-icons": "^1.2.28", "@iconify-json/simple-icons": "^1.2.27",
"@nuxt/ui": "latest", "@nuxt/ui": "latest",
"@nuxthub/core": "^0.8.18", "@nuxthub/core": "^0.8.18",
"nuxt": "^3.16.0" "nuxt": "^3.15.4"
} }
} }

3418
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,13 +6,13 @@
"enabled": true "enabled": true
}, },
"ignoreDeps": [ "ignoreDeps": [
"happy-dom",
"valibot30", "valibot30",
"valibot31", "valibot31",
"typescript", "typescript",
"vaul-vue",
"vue-tsc" "vue-tsc"
], ],
"baseBranches": ["v2", "v3"], "baseBranches": ["dev", "v3"],
"packageRules": [{ "packageRules": [{
"matchBaseBranches": ["v3"], "matchBaseBranches": ["v3"],
"labels": ["v3"] "labels": ["v3"]

View File

@@ -53,7 +53,7 @@ export default defineNuxtModule<ModuleOptions>({
name: 'ui', name: 'ui',
configKey: 'ui', configKey: 'ui',
compatibility: { compatibility: {
nuxt: '>=3.16.0' nuxt: '>=3.13.1'
}, },
docs: 'https://ui3.nuxt.dev/getting-started/installation/nuxt' docs: 'https://ui3.nuxt.dev/getting-started/installation/nuxt'
}, },

View File

@@ -1,11 +1,12 @@
<script lang="ts"> <script lang="ts">
import type { ConfigProviderProps, TooltipProviderProps } from 'reka-ui' import type { ConfigProviderProps, TooltipProviderProps } from 'reka-ui'
import type { ToasterProps, Locale, Messages } from '../types' import { localeContextInjectionKey } from '../composables/useLocale'
import type { ToasterProps, Locale } from '../types'
export interface AppProps<T extends Messages = Messages> extends Omit<ConfigProviderProps, 'useId' | 'dir' | 'locale'> { export interface AppProps extends Omit<ConfigProviderProps, 'useId' | 'dir' | 'locale'> {
tooltip?: TooltipProviderProps tooltip?: TooltipProviderProps
toaster?: ToasterProps | null toaster?: ToasterProps | null
locale?: Locale<T> locale?: Locale
} }
export interface AppSlots { export interface AppSlots {
@@ -17,15 +18,14 @@ export default {
} }
</script> </script>
<script setup lang="ts" generic="T extends Messages = Messages"> <script setup lang="ts">
import { toRef, useId, provide } from 'vue' import { toRef, useId, provide } from 'vue'
import { ConfigProvider, TooltipProvider, useForwardProps } from 'reka-ui' import { ConfigProvider, TooltipProvider, useForwardProps } from 'reka-ui'
import { reactivePick } from '@vueuse/core' import { reactivePick } from '@vueuse/core'
import { localeContextInjectionKey } from '../composables/useLocale'
import UToaster from './Toaster.vue' import UToaster from './Toaster.vue'
import UOverlayProvider from './OverlayProvider.vue' import UOverlayProvider from './OverlayProvider.vue'
const props = defineProps<AppProps<T>>() const props = defineProps<AppProps>()
defineSlots<AppSlots>() defineSlots<AppSlots>()
const configProviderProps = useForwardProps(reactivePick(props, 'scrollBody')) const configProviderProps = useForwardProps(reactivePick(props, 'scrollBody'))

View File

@@ -60,7 +60,6 @@ import { pickLinkProps } from '../utils/link'
import UIcon from './Icon.vue' import UIcon from './Icon.vue'
import UAvatar from './Avatar.vue' import UAvatar from './Avatar.vue'
import ULink from './Link.vue' import ULink from './Link.vue'
import ULinkBase from './LinkBase.vue'
const props = withDefaults(defineProps<ButtonProps>(), { const props = withDefaults(defineProps<ButtonProps>(), {
active: undefined, active: undefined,

View File

@@ -29,7 +29,7 @@ export interface FormEmits<T extends object> {
} }
export interface FormSlots { export interface FormSlots {
default(props?: { errors: FormError[] }): any default(props?: {}): any
} }
</script> </script>
@@ -69,7 +69,7 @@ onMounted(async () => {
nestedForms.value.set(event.formId, { validate: event.validate }) nestedForms.value.set(event.formId, { validate: event.validate })
} else if (event.type === 'detach') { } else if (event.type === 'detach') {
nestedForms.value.delete(event.formId) nestedForms.value.delete(event.formId)
} else if (props.validateOn?.includes(event.type) && !loading.value) { } else if (props.validateOn?.includes(event.type)) {
if (event.type !== 'input') { if (event.type !== 'input') {
await _validate({ name: event.name, silent: true, nested: false }) await _validate({ name: event.name, silent: true, nested: false })
} else if (event.eager || blurredFields.has(event.name)) { } else if (event.eager || blurredFields.has(event.name)) {
@@ -121,7 +121,7 @@ const blurredFields = new Set<keyof T>()
function resolveErrorIds(errs: FormError[]): FormErrorWithId[] { function resolveErrorIds(errs: FormError[]): FormErrorWithId[] {
return errs.map(err => ({ return errs.map(err => ({
...err, ...err,
id: err?.name ? inputs.value[err.name]?.id : undefined id: inputs.value[err.name]?.id
})) }))
} }
@@ -159,12 +159,12 @@ async function _validate(opts: { name?: keyof T | (keyof T)[], silent?: boolean,
if (names) { if (names) {
const otherErrors = errors.value.filter(error => !names.some((name) => { const otherErrors = errors.value.filter(error => !names.some((name) => {
const pattern = inputs.value?.[name]?.pattern const pattern = inputs.value?.[name]?.pattern
return name === error.name || (pattern && error.name?.match(pattern)) return name === error.name || (pattern && error.name.match(pattern))
})) }))
const pathErrors = (await getErrors()).filter(error => names.some((name) => { const pathErrors = (await getErrors()).filter(error => names.some((name) => {
const pattern = inputs.value?.[name]?.pattern const pattern = inputs.value?.[name]?.pattern
return name === error.name || (pattern && error.name?.match(pattern)) return name === error.name || (pattern && error.name.match(pattern))
})) }))
errors.value = otherErrors.concat(pathErrors) errors.value = otherErrors.concat(pathErrors)
@@ -269,6 +269,6 @@ defineExpose<Form<T>>({
:class="form({ class: props.class })" :class="form({ class: props.class })"
@submit.prevent="onSubmitWrapper" @submit.prevent="onSubmitWrapper"
> >
<slot :errors="errors" /> <slot />
</component> </component>
</template> </template>

View File

@@ -63,7 +63,7 @@ const ui = computed(() => formField({
const formErrors = inject<Ref<FormError[]> | null>('form-errors', null) const formErrors = inject<Ref<FormError[]> | null>('form-errors', null)
const error = computed(() => props.error || formErrors?.value?.find(error => error.name && (error.name === props.name || (props.errorPattern && error.name.match(props.errorPattern))))?.message) const error = computed(() => props.error || formErrors?.value?.find(error => error.name === props.name || (props.errorPattern && error.name.match(props.errorPattern)))?.message)
const id = ref(useId()) const id = ref(useId())
// Copies id's initial value to bind aria-attributes such as aria-describedby. // Copies id's initial value to bind aria-attributes such as aria-describedby.

View File

@@ -82,7 +82,7 @@ const props = withDefaults(defineProps<InputProps>(), {
const emits = defineEmits<InputEmits>() const emits = defineEmits<InputEmits>()
const slots = defineSlots<InputSlots>() const slots = defineSlots<InputSlots>()
const [modelValue, modelModifiers] = defineModel<string | number | null>() const [modelValue, modelModifiers] = defineModel<string | number>()
const { emitFormBlur, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled, emitFormFocus, ariaAttrs } = useFormField<InputProps>(props, { deferInputValidation: true }) const { emitFormBlur, emitFormInput, emitFormChange, size: formGroupSize, color, id, name, highlight, disabled, emitFormFocus, ariaAttrs } = useFormField<InputProps>(props, { deferInputValidation: true })
const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props) const { orientation, size: buttonGroupSize } = useButtonGroup<InputProps>(props)
@@ -111,19 +111,15 @@ function autoFocus() {
} }
// Custom function to handle the v-model properties // Custom function to handle the v-model properties
function updateInput(value: string | null) { function updateInput(value: string) {
if (modelModifiers.trim) { if (modelModifiers.trim) {
value = value?.trim() ?? null value = value.trim()
} }
if (modelModifiers.number || props.type === 'number') { if (modelModifiers.number || props.type === 'number') {
value = looseToNumber(value) value = looseToNumber(value)
} }
if (modelModifiers.nullify) {
value ||= null
}
modelValue.value = value modelValue.value = value
emitFormInput() emitFormInput()
} }

View File

@@ -1,6 +1,4 @@
<script lang="ts"> <script lang="ts">
import type { LinkProps } from '../types'
export interface LinkBaseProps { export interface LinkBaseProps {
as?: string as?: string
type?: string type?: string
@@ -8,8 +6,8 @@ export interface LinkBaseProps {
onClick?: ((e: MouseEvent) => void | Promise<void>) | Array<((e: MouseEvent) => void | Promise<void>)> onClick?: ((e: MouseEvent) => void | Promise<void>) | Array<((e: MouseEvent) => void | Promise<void>)>
href?: string href?: string
navigate?: (e: MouseEvent) => void navigate?: (e: MouseEvent) => void
target?: LinkProps['target'] rel?: string
rel?: LinkProps['rel'] target?: string
isExternal?: boolean isExternal?: boolean
} }
</script> </script>

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { PaginationRootProps, PaginationRootEmits } from 'reka-ui' import type { PaginationRootProps, PaginationRootEmits } from 'reka-ui'
import type { AppConfig } from '@nuxt/schema' import type { AppConfig } from '@nuxt/schema'
import type { RouteLocationRaw } from '#vue-router'
import _appConfig from '#build/app.config' import _appConfig from '#build/app.config'
import theme from '#build/ui/pagination' import theme from '#build/ui/pagination'
import { tv } from '../utils/tv' import { tv } from '../utils/tv'
@@ -77,7 +78,7 @@ export interface PaginationProps extends Partial<Pick<PaginationRootProps, 'defa
* A function to render page controls as links. * A function to render page controls as links.
* @param page The page number to navigate to. * @param page The page number to navigate to.
*/ */
to?: (page: number) => ButtonProps['to'] to?: (page: number) => RouteLocationRaw
class?: any class?: any
ui?: Partial<typeof pagination.slots> ui?: Partial<typeof pagination.slots>
} }

View File

@@ -74,7 +74,7 @@ const props = withDefaults(defineProps<TextareaProps>(), {
defineSlots<TextareaSlots>() defineSlots<TextareaSlots>()
const emits = defineEmits<TextareaEmits>() const emits = defineEmits<TextareaEmits>()
const [modelValue, modelModifiers] = defineModel<string | number | null>() const [modelValue, modelModifiers] = defineModel<string | number>()
const { emitFormFocus, emitFormBlur, emitFormInput, emitFormChange, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField<TextareaProps>(props, { deferInputValidation: true }) const { emitFormFocus, emitFormBlur, emitFormInput, emitFormChange, size, color, id, name, highlight, disabled, ariaAttrs } = useFormField<TextareaProps>(props, { deferInputValidation: true })
@@ -94,19 +94,15 @@ function autoFocus() {
} }
// Custom function to handle the v-model properties // Custom function to handle the v-model properties
function updateInput(value: string | null) { function updateInput(value: string) {
if (modelModifiers.trim) { if (modelModifiers.trim) {
value = value?.trim() ?? null value = value.trim()
} }
if (modelModifiers.number) { if (modelModifiers.number) {
value = looseToNumber(value) value = looseToNumber(value)
} }
if (modelModifiers.nullify) {
value ||= null
}
modelValue.value = value modelValue.value = value
emitFormInput() emitFormInput()
} }

View File

@@ -1,13 +1,13 @@
import { defu } from 'defu' import { defu } from 'defu'
import type { Locale, Direction } from '../types/locale' import type { Locale, Direction, Messages } from '../types/locale'
interface DefineLocaleOptions<M> { interface DefineLocaleOptions {
name: string name: string
code: string code: string
dir?: Direction dir?: Direction
messages: M messages: Messages
} }
export function defineLocale<M>(options: DefineLocaleOptions<M>): Locale<M> { export function defineLocale(options: DefineLocaleOptions): Locale {
return defu<DefineLocaleOptions<M>, [{ dir: Direction }]>(options, { dir: 'ltr' }) return defu<DefineLocaleOptions, [{ dir: Direction }]>(options, { dir: 'ltr' })
} }

View File

@@ -1,16 +1,16 @@
import { computed, inject, toRef } from 'vue' import { computed, inject, ref } from 'vue'
import type { InjectionKey, Ref } from 'vue' import type { InjectionKey, Ref } from 'vue'
import { createSharedComposable } from '@vueuse/core' import type { Locale } from '../types/locale'
import type { Locale, Messages } from '../types/locale'
import { buildLocaleContext } from '../utils/locale' import { buildLocaleContext } from '../utils/locale'
import en from '../locale/en' import en from '../locale/en'
import { createSharedComposable } from '@vueuse/core'
export const localeContextInjectionKey: InjectionKey<Ref<Locale<unknown> | undefined>> = Symbol('nuxt-ui.locale-context') export const localeContextInjectionKey: InjectionKey<Ref<Locale | undefined>> = Symbol('nuxt-ui.locale-context')
const _useLocale = (localeOverrides?: Ref<Locale<Messages> | undefined>) => { const _useLocale = (localeOverrides?: Ref<Locale | undefined>) => {
const locale = localeOverrides || toRef(inject<Locale<Messages>>(localeContextInjectionKey)) const locale = localeOverrides || inject(localeContextInjectionKey, ref())!
return buildLocaleContext<Messages>(computed(() => locale.value || en)) return buildLocaleContext(computed(() => locale.value || en))
} }
export const useLocale = createSharedComposable(_useLocale) export const useLocale = createSharedComposable(_useLocale)

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'العربية', name: 'العربية',
code: 'ar', code: 'ar',
dir: 'rtl', dir: 'rtl',

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Azərbaycanca', name: 'Azərbaycanca',
code: 'az', code: 'az',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'বাংলা', name: 'বাংলা',
code: 'bn', code: 'bn',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Čeština', name: 'Čeština',
code: 'cs', code: 'cs',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Danish', name: 'Danish',
code: 'da', code: 'da',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Deutsch', name: 'Deutsch',
code: 'de', code: 'de',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Ελληνικά', name: 'Ελληνικά',
code: 'el', code: 'el',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'English', name: 'English',
code: 'en', code: 'en',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Español', name: 'Español',
code: 'es', code: 'es',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Eesti', name: 'Eesti',
code: 'et', code: 'et',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'فارسی', name: 'فارسی',
code: 'fa-IR', code: 'fa-IR',
dir: 'rtl', dir: 'rtl',

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Suomeksi', name: 'Suomeksi',
code: 'fi', code: 'fi',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Français', name: 'Français',
code: 'fr', code: 'fr',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Hebrew', name: 'Hebrew',
code: 'he', code: 'he',
dir: 'rtl', dir: 'rtl',

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Hindi', name: 'Hindi',
code: 'hi', code: 'hi',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Magyar', name: 'Magyar',
code: 'hu', code: 'hu',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Indonesia', name: 'Indonesia',
code: 'id', code: 'id',
messages: { messages: {

View File

@@ -5,15 +5,13 @@ export { default as cs } from './cs'
export { default as da } from './da' export { default as da } from './da'
export { default as de } from './de' export { default as de } from './de'
export { default as el } from './el' export { default as el } from './el'
export { default as et } from './et'
export { default as en } from './en' export { default as en } from './en'
export { default as es } from './es' export { default as es } from './es'
export { default as et } from './et'
export { default as fa_ir } from './fa_ir' export { default as fa_ir } from './fa_ir'
export { default as fi } from './fi' export { default as fi } from './fi'
export { default as fr } from './fr' export { default as fr } from './fr'
export { default as he } from './he'
export { default as hi } from './hi' export { default as hi } from './hi'
export { default as hu } from './hu'
export { default as id } from './id' export { default as id } from './id'
export { default as it } from './it' export { default as it } from './it'
export { default as ja } from './ja' export { default as ja } from './ja'
@@ -33,3 +31,4 @@ export { default as uk } from './uk'
export { default as vi } from './vi' export { default as vi } from './vi'
export { default as zh_cn } from './zh_cn' export { default as zh_cn } from './zh_cn'
export { default as zh_tw } from './zh_tw' export { default as zh_tw } from './zh_tw'
export { default as he } from './he'

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Italiano', name: 'Italiano',
code: 'it', code: 'it',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: '日本語', name: '日本語',
code: 'ja', code: 'ja',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'ភាសាខ្មែរ', name: 'ភាសាខ្មែរ',
code: 'km', code: 'km',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: '한국어', name: '한국어',
code: 'ko', code: 'ko',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Norsk Bokmål', name: 'Norsk Bokmål',
code: 'nb-NO', code: 'nb-NO',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Nederlands', name: 'Nederlands',
code: 'nl', code: 'nl',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Polski', name: 'Polski',
code: 'pl', code: 'pl',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Português', name: 'Português',
code: 'pt', code: 'pt',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Português (Brasil)', name: 'Português (Brasil)',
code: 'pt-BR', code: 'pt-BR',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Русский', name: 'Русский',
code: 'ru', code: 'ru',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Slovenčina', name: 'Slovenčina',
code: 'sk', code: 'sk',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Svenska', name: 'Svenska',
code: 'sv', code: 'sv',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'ไทย', name: 'ไทย',
code: 'th', code: 'th',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Türkçe', name: 'Türkçe',
code: 'tr', code: 'tr',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Українська', name: 'Українська',
code: 'uk', code: 'uk',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: 'Tiếng Việt', name: 'Tiếng Việt',
code: 'vi', code: 'vi',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: '简体中文', name: '简体中文',
code: 'zh-CN', code: 'zh-CN',
messages: { messages: {

View File

@@ -1,7 +1,6 @@
import type { Messages } from '../types'
import { defineLocale } from '../composables/defineLocale' import { defineLocale } from '../composables/defineLocale'
export default defineLocale<Messages>({ export default defineLocale({
name: '繁體中文', name: '繁體中文',
code: 'zh-TW', code: 'zh-TW',
messages: { messages: {

View File

@@ -55,7 +55,5 @@ export default defineNuxtPlugin(() => {
}] }]
} }
if (!nuxtApp.isVue) { useHead(headData)
useHead(headData)
}
}) })

View File

@@ -36,7 +36,7 @@ export type FormSchema<T extends object> =
export type FormInputEvents = 'input' | 'blur' | 'change' | 'focus' export type FormInputEvents = 'input' | 'blur' | 'change' | 'focus'
export interface FormError<P extends string = string> { export interface FormError<P extends string = string> {
name?: P name: P
message: string message: string
} }

View File

@@ -50,9 +50,9 @@ export type Messages = {
export type Direction = 'ltr' | 'rtl' export type Direction = 'ltr' | 'rtl'
export type Locale<M> = { export type Locale = {
name: string name: string
code: string code: string
dir: Direction dir: Direction
messages: M messages: Messages
} }

View File

@@ -6,19 +6,19 @@ import { get } from './index'
export type TranslatorOption = Record<string, string | number> export type TranslatorOption = Record<string, string | number>
export type Translator = (path: string, option?: TranslatorOption) => string export type Translator = (path: string, option?: TranslatorOption) => string
export type LocaleContext<M> = { export type LocaleContext = {
locale: Ref<Locale<M>> locale: Ref<Locale>
lang: Ref<string> lang: Ref<string>
dir: Ref<Direction> dir: Ref<Direction>
code: Ref<string> code: Ref<string>
t: Translator t: Translator
} }
export function buildTranslator<M>(locale: MaybeRef<Locale<M>>): Translator { export function buildTranslator(locale: MaybeRef<Locale>): Translator {
return (path, option) => translate(path, option, unref(locale)) return (path, option) => translate(path, option, unref(locale))
} }
export function translate<M>(path: string, option: undefined | TranslatorOption, locale: Locale<M>): string { export function translate(path: string, option: undefined | TranslatorOption, locale: Locale): string {
const prop: string = get(locale, `messages.${path}`, path) const prop: string = get(locale, `messages.${path}`, path)
return prop.replace( return prop.replace(
@@ -27,11 +27,11 @@ export function translate<M>(path: string, option: undefined | TranslatorOption,
) )
} }
export function buildLocaleContext<M>(locale: MaybeRef<Locale<M>>): LocaleContext<M> { export function buildLocaleContext(locale: MaybeRef<Locale>): LocaleContext {
const lang = computed(() => unref(locale).name) const lang = computed(() => unref(locale).name)
const code = computed(() => unref(locale).code) const code = computed(() => unref(locale).code)
const dir = computed(() => unref(locale).dir) const dir = computed(() => unref(locale).dir)
const localeRef = isRef(locale) ? locale : ref(locale) as Ref<Locale<M>> const localeRef = isRef(locale) ? locale : ref(locale)
return { return {
lang, lang,

View File

@@ -1,9 +1,8 @@
import { createHead } from '@unhead/vue/client' import { createHead, setHeadInjectionHandler } from '@unhead/vue'
import type { Plugin } from 'vue' import type { Plugin } from 'vue'
export default { export default {
install(app) { install() {
const head = createHead() setHeadInjectionHandler(() => createHead())
app.use(head)
} }
} satisfies Plugin } satisfies Plugin

View File

@@ -6,10 +6,89 @@ import type { NuxtApp } from '#app'
import { useColorMode as useColorModeVueUse } from '@vueuse/core' import { useColorMode as useColorModeVueUse } from '@vueuse/core'
export { useHead } from '@unhead/vue' export { useHead } from '@unhead/vue'
export { useRoute, useRouter } from 'vue-router'
// Create stub implementations for vue-router
export const useRouteStub = () => ({
path: '',
name: null,
params: {},
query: {},
hash: '',
fullPath: '',
matched: [],
meta: {},
redirectedFrom: undefined
})
export const useRouterStub = () => ({
push: () => Promise.resolve(),
replace: () => Promise.resolve(),
go: () => Promise.resolve(),
back: () => Promise.resolve(),
forward: () => Promise.resolve(),
beforeEach: () => () => {},
afterEach: () => () => {},
getRoutes: () => [],
hasRoute: () => false,
currentRoute: ref({})
})
// Create a module-level cache for the imported modules
const moduleCache: Record<string, any> = {}
// Function to dynamically import a module and cache the result
function lazyImport(moduleName: string) {
return () => {
if (!moduleCache[moduleName]) {
moduleCache[moduleName] = import(/* @vite-ignore */ moduleName).catch(() => ({}))
}
return moduleCache[moduleName]
}
}
// Lazy import vue-router
const importVueRouter = lazyImport('vue-router')
// Create wrapper functions that will dynamically import or use stubs
export function useRoute() {
// Try to get the real implementation
const vueRouterModule = moduleCache['vue-router']
if (vueRouterModule && vueRouterModule.useRoute) {
return vueRouterModule.useRoute()
}
// If not available yet, try to import it
importVueRouter().then((module: any) => {
if (module && module.useRoute) {
// Module loaded successfully, but it's too late for this call
// Future calls will use the cached module
}
})
// Fall back to stub for this call
return useRouteStub()
}
export function useRouter() {
// Try to get the real implementation
const vueRouterModule = moduleCache['vue-router']
if (vueRouterModule && vueRouterModule.useRouter) {
return vueRouterModule.useRouter()
}
// If not available yet, try to import it
importVueRouter().then((module: any) => {
if (module && module.useRouter) {
// Module loaded successfully, but it's too late for this call
// Future calls will use the cached module
}
})
// Fall back to stub for this call
return useRouterStub()
}
export { defineShortcuts } from '../composables/defineShortcuts' export { defineShortcuts } from '../composables/defineShortcuts'
export { defineLocale } from '../composables/defineLocale'
export { useLocale } from '../composables/useLocale' export { useLocale } from '../composables/useLocale'
export const useColorMode = () => { export const useColorMode = () => {
@@ -61,7 +140,6 @@ export const useState = <T>(key: string, init: () => T): Ref<T> => {
export function useNuxtApp() { export function useNuxtApp() {
return { return {
isHydrating: true, isHydrating: true,
isVue: true,
payload: { serverRendered: false } payload: { serverRendered: false }
} }
} }

View File

@@ -122,10 +122,6 @@ type AppConfigUI = {
declare module '@nuxt/schema' { declare module '@nuxt/schema' {
interface AppConfigInput { interface AppConfigInput {
/**
* Nuxt UI theme configuration
* @see https://ui3.nuxt.dev/getting-started/theme#customize-theme
*/
ui?: AppConfigUI ui?: AppConfigUI
} }
} }

View File

@@ -52,8 +52,7 @@ describe('Input', () => {
it.each([ it.each([
['with .trim modifier', { props: { modelModifiers: { trim: true } } }, { input: 'input ', expected: 'input' }], ['with .trim modifier', { props: { modelModifiers: { trim: true } } }, { input: 'input ', expected: 'input' }],
['with .number modifier', { props: { modelModifiers: { number: true } } }, { input: '42', expected: 42 }], ['with .number modifier', { props: { modelModifiers: { number: true } } }, { input: '42', expected: 42 }],
['with .lazy modifier', { props: { modelModifiers: { lazy: true } } }, { input: 'input', expected: 'input' }], ['with .lazy modifier', { props: { modelModifiers: { lazy: true } } }, { input: 'input', expected: 'input' }]
['with .nullify modifier', { props: { modelModifiers: { nullify: true } } }, { input: '', expected: null }]
])('%s works', async (_nameOrHtml: string, options: { props?: any, slots?: any }, spec: { input: any, expected: any }) => { ])('%s works', async (_nameOrHtml: string, options: { props?: any, slots?: any }, spec: { input: any, expected: any }) => {
const wrapper = mount(Input, { const wrapper = mount(Input, {
...options ...options

View File

@@ -35,8 +35,7 @@ describe('Textarea', () => {
it.each([ it.each([
['with .trim modifier', { props: { modelModifiers: { trim: true } } }, { input: 'input ', expected: 'input' }], ['with .trim modifier', { props: { modelModifiers: { trim: true } } }, { input: 'input ', expected: 'input' }],
['with .number modifier', { props: { modelModifiers: { number: true } } }, { input: '42', expected: 42 }], ['with .number modifier', { props: { modelModifiers: { number: true } } }, { input: '42', expected: 42 }],
['with .lazy modifier', { props: { modelModifiers: { lazy: true } } }, { input: 'input', expected: 'input' }], ['with .lazy modifier', { props: { modelModifiers: { lazy: true } } }, { input: 'input', expected: 'input' }]
['with .nullify modifier', { props: { modelModifiers: { nullify: true } } }, { input: '', expected: null }]
])('%s works', async (_nameOrHtml: string, options: { props?: any, slots?: any }, spec: { input: any, expected: any }) => { ])('%s works', async (_nameOrHtml: string, options: { props?: any, slots?: any }, spec: { input: any, expected: any }) => {
const wrapper = mount(Textarea, { const wrapper = mount(Textarea, {
...options ...options

View File

@@ -252,13 +252,13 @@ exports[`CommandPalette > renders with defaultValue correctly 1`] = `
exports[`CommandPalette > renders with disabled correctly 1`] = ` exports[`CommandPalette > renders with disabled correctly 1`] = `
"<div dir="ltr" data-disabled="" class="flex flex-col min-h-0 min-w-0 divide-y divide-(--ui-border)"> "<div dir="ltr" data-disabled="" class="flex flex-col min-h-0 min-w-0 divide-y divide-(--ui-border)">
<div class="relative inline-flex items-center [&amp;>input]:h-12"><input type="text" placeholder="Type a command or search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-3 py-2 text-sm gap-2 text-(--ui-text-highlighted) bg-transparent ps-10" disabled="" autocomplete="off" data-disabled="" aria-disabled="true" value=""><span class="absolute inset-y-0 start-0 flex items-center ps-3"><span class="iconify i-lucide:search shrink-0 text-(--ui-text-dimmed) size-5" aria-hidden="true"></span></span> <div class="relative inline-flex items-center [&amp;>input]:h-12"><input type="text" placeholder="Type a command or search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-3 py-2 text-sm gap-2 text-(--ui-text-highlighted) bg-transparent ps-10" disabled="" autocomplete="off" data-disabled="" aria-disabled="true" value="" aria-activedescendant="reka-listbox-item-v-0-0-1"><span class="absolute inset-y-0 start-0 flex items-center ps-3"><span class="iconify i-lucide:search shrink-0 text-(--ui-text-dimmed) size-5" aria-hidden="true"></span></span>
<!--v-if--> <!--v-if-->
</div> </div>
<div role="listbox" aria-orientation="vertical" aria-multiselectable="false" data-orientation="vertical" class="relative overflow-hidden flex flex-col"> <div role="listbox" aria-orientation="vertical" aria-multiselectable="false" data-orientation="vertical" class="relative overflow-hidden flex flex-col">
<div class="relative divide-y divide-(--ui-border) scroll-py-1 overflow-y-auto flex-1 focus:outline-none"> <div class="relative divide-y divide-(--ui-border) scroll-py-1 overflow-y-auto flex-1 focus:outline-none">
<div role="group" aria-labelledby="reka-listbox-group-v-0-0-0" class="p-1 isolate"> <div role="group" aria-labelledby="reka-listbox-group-v-0-0-0" class="p-1 isolate">
<!--v-if--><button type="button" id="reka-listbox-item-v-0-0-1" role="option" tabindex="-1" aria-selected="false" data-disabled="" data-state="unchecked" data-reka-collection-item="" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text-highlighted) before:bg-(--ui-bg-elevated)"><span class="iconify i-lucide:file-plus shrink-0 size-5 text-(--ui-text)" aria-hidden="true"></span><span class="truncate space-x-1 rtl:space-x-reverse text-(--ui-text-dimmed)"><!--v-if--><span class="text-(--ui-text-highlighted) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Add new file</span><span class="text-(--ui-text-dimmed) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Create a new file in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">⊞</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">N</kbd></span> <!--v-if--><button type="button" id="reka-listbox-item-v-0-0-1" role="option" tabindex="-1" aria-selected="false" data-disabled="" data-state="unchecked" data-reka-collection-item="" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text-highlighted) before:bg-(--ui-bg-elevated)" data-highlighted=""><span class="iconify i-lucide:file-plus shrink-0 size-5 text-(--ui-text)" aria-hidden="true"></span><span class="truncate space-x-1 rtl:space-x-reverse text-(--ui-text-dimmed)"><!--v-if--><span class="text-(--ui-text-highlighted) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Add new file</span><span class="text-(--ui-text-dimmed) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Create a new file in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">⊞</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">N</kbd></span>
<!----></span> <!----></span>
</button><button type="button" id="reka-listbox-item-v-0-0-2" role="option" tabindex="-1" aria-selected="false" data-disabled="" data-state="unchecked" data-reka-collection-item="" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors"><span class="iconify i-lucide:folder-plus shrink-0 size-5 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors" aria-hidden="true"></span><span class="truncate space-x-1 rtl:space-x-reverse text-(--ui-text-dimmed)"><!--v-if--><span class="text-(--ui-text-highlighted) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Add new folder</span><span class="text-(--ui-text-dimmed) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Create a new folder in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">⊞</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">F</kbd></span> </button><button type="button" id="reka-listbox-item-v-0-0-2" role="option" tabindex="-1" aria-selected="false" data-disabled="" data-state="unchecked" data-reka-collection-item="" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors"><span class="iconify i-lucide:folder-plus shrink-0 size-5 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors" aria-hidden="true"></span><span class="truncate space-x-1 rtl:space-x-reverse text-(--ui-text-dimmed)"><!--v-if--><span class="text-(--ui-text-highlighted) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Add new folder</span><span class="text-(--ui-text-dimmed) [&amp;>mark]:text-(--ui-bg) [&amp;>mark]:bg-(--ui-primary)">Create a new folder in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">⊞</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-(--ui-radius) font-medium font-sans bg-(--ui-bg) text-(--ui-text-highlighted) ring ring-inset ring-(--ui-border-accented) h-5 min-w-[20px] text-[11px]">F</kbd></span>
<!----></span> <!----></span>

View File

@@ -2,6 +2,6 @@
exports[`Container > renders with as correctly 1`] = `"<article class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8"></article>"`; exports[`Container > renders with as correctly 1`] = `"<article class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8"></article>"`;
exports[`Container > renders with class correctly 1`] = `"<div class="mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl"></div>"`; exports[`Container > renders with class correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl"></div>"`;
exports[`Container > renders with default slot correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8">Default slot</div>"`; exports[`Container > renders with default slot correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8">Default slot</div>"`;

View File

@@ -2,6 +2,6 @@
exports[`Container > renders with as correctly 1`] = `"<article class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8"></article>"`; exports[`Container > renders with as correctly 1`] = `"<article class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8"></article>"`;
exports[`Container > renders with class correctly 1`] = `"<div class="mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl"></div>"`; exports[`Container > renders with class correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 max-w-5xl"></div>"`;
exports[`Container > renders with default slot correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8">Default slot</div>"`; exports[`Container > renders with default slot correctly 1`] = `"<div class="max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8">Default slot</div>"`;

View File

@@ -223,7 +223,7 @@ exports[`InputMenu > renders with defaultValue correctly 1`] = `
`; `;
exports[`InputMenu > renders with disabled correctly 1`] = ` exports[`InputMenu > renders with disabled correctly 1`] = `
"<div dir="ltr" data-disabled="" class="relative inline-flex items-center" style="pointer-events: auto;"><input disabled="" data-disabled="" aria-disabled="true" type="text" aria-expanded="true" aria-controls="" aria-autocomplete="list" role="combobox" autocomplete="false" class="rounded-[calc(var(--ui-radius)*1.5)] transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text-highlighted) bg-(--ui-bg) ring ring-inset ring-(--ui-border-accented) w-full border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--ui-primary) pe-9" value=""> "<div dir="ltr" data-disabled="" class="relative inline-flex items-center" style="pointer-events: auto;"><input disabled="" data-disabled="" aria-disabled="true" type="text" aria-expanded="true" aria-controls="" aria-autocomplete="list" role="combobox" autocomplete="false" class="rounded-[calc(var(--ui-radius)*1.5)] transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text-highlighted) bg-(--ui-bg) ring ring-inset ring-(--ui-border-accented) w-full border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--ui-primary) pe-9" value="" aria-activedescendant="reka-combobox-item-v-0-0-3">
<!--v-if--><button disabled="" type="button" tabindex="-1" aria-label="Show popup" aria-haspopup="listbox" aria-expanded="true" aria-controls="" data-state="open" data-disabled="" aria-disabled="true" class="group absolute inset-y-0 end-0 flex items-center disabled:cursor-not-allowed disabled:opacity-75 pe-2.5"><span class="iconify i-lucide:chevron-down shrink-0 text-(--ui-text-dimmed) size-5" aria-hidden="true"></span></button> <!--v-if--><button disabled="" type="button" tabindex="-1" aria-label="Show popup" aria-haspopup="listbox" aria-expanded="true" aria-controls="" data-state="open" data-disabled="" aria-disabled="true" class="group absolute inset-y-0 end-0 flex items-center disabled:cursor-not-allowed disabled:opacity-75 pe-2.5"><span class="iconify i-lucide:chevron-down shrink-0 text-(--ui-text-dimmed) size-5" aria-hidden="true"></span></button>
<!--teleport start--> <!--teleport start-->
<div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;"> <div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;">
@@ -232,7 +232,7 @@ exports[`InputMenu > renders with disabled correctly 1`] = `
<div class="divide-y divide-(--ui-border) scroll-py-1" data-reka-combobox-viewport="" role="presentation" style="position: relative; overflow: auto; flex-grow: 1; flex-shrink: 1; flex-basis: 0%;"> <div class="divide-y divide-(--ui-border) scroll-py-1" data-reka-combobox-viewport="" role="presentation" style="position: relative; overflow: auto; flex-grow: 1; flex-shrink: 1; flex-basis: 0%;">
<!--v-if--> <!--v-if-->
<div role="group" aria-labelledby="" id="reka-combobox-group-v-0-0-1" class="p-1 isolate"> <div role="group" aria-labelledby="" id="reka-combobox-group-v-0-0-1" class="p-1 isolate">
<div id="reka-combobox-item-v-0-0-3" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-help shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Backlog</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-3" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item="" data-highlighted=""><span class="iconify i-lucide:circle-help shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Backlog</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-5" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-plus shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Todo</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-5" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-plus shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Todo</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-7" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-arrow-up shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">In Progress</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-7" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-arrow-up shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">In Progress</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-9" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-check shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Done</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-9" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-check shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Done</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>

View File

@@ -270,7 +270,7 @@ exports[`SelectMenu > renders with disabled correctly 1`] = `
<div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;"> <div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;">
<div position="popper" id="reka-combobox-content-v-0-0-0" data-state="open" style="display: flex; flex-direction: column; box-sizing: border-box; --reka-combobox-content-transform-origin: var(--reka-popper-transform-origin); --reka-combobox-content-available-width: var(--reka-popper-available-width); --reka-combobox-content-available-height: var(--reka-popper-available-height); --reka-combobox-trigger-width: var(--reka-popper-anchor-width); --reka-combobox-trigger-height: var(--reka-popper-anchor-height); animation: none; outline-color: none; outline-style: none; outline-width: initial;" data-dismissable-layer="" role="listbox" aria-orientation="vertical" aria-multiselectable="false" data-orientation="vertical" class="max-h-60 w-(--reka-popper-anchor-width) bg-(--ui-bg) shadow-lg rounded-[calc(var(--ui-radius)*1.5)] ring ring-(--ui-border) overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] pointer-events-auto" data-side="bottom" data-align="center"> <div position="popper" id="reka-combobox-content-v-0-0-0" data-state="open" style="display: flex; flex-direction: column; box-sizing: border-box; --reka-combobox-content-transform-origin: var(--reka-popper-transform-origin); --reka-combobox-content-available-width: var(--reka-popper-available-width); --reka-combobox-content-available-height: var(--reka-popper-available-height); --reka-combobox-trigger-width: var(--reka-popper-anchor-width); --reka-combobox-trigger-height: var(--reka-popper-anchor-height); animation: none; outline-color: none; outline-style: none; outline-width: initial;" data-dismissable-layer="" role="listbox" aria-orientation="vertical" aria-multiselectable="false" data-orientation="vertical" class="max-h-60 w-(--reka-popper-anchor-width) bg-(--ui-bg) shadow-lg rounded-[calc(var(--ui-radius)*1.5)] ring ring-(--ui-border) overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] pointer-events-auto" data-side="bottom" data-align="center">
<div tabindex="-1" class="flex flex-col min-h-0"> <div tabindex="-1" class="flex flex-col min-h-0">
<div class="relative inline-flex items-center border-b border-(--ui-border)"><input type="text" placeholder="Search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text-highlighted) bg-transparent" disabled="" autocomplete="off" data-disabled="" aria-disabled="true" aria-expanded="true" aria-controls="reka-combobox-content-v-0-0-0" aria-autocomplete="list" role="combobox" value=""> <div class="relative inline-flex items-center border-b border-(--ui-border)"><input type="text" placeholder="Search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-(--ui-text-dimmed) focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text-highlighted) bg-transparent" disabled="" autocomplete="off" data-disabled="" aria-disabled="true" aria-expanded="true" aria-controls="reka-combobox-content-v-0-0-0" aria-autocomplete="list" role="combobox" value="" aria-activedescendant="reka-combobox-item-v-0-0-3">
<!--v-if--> <!--v-if-->
<!--v-if--> <!--v-if-->
</div> </div>
@@ -278,7 +278,7 @@ exports[`SelectMenu > renders with disabled correctly 1`] = `
<div class="divide-y divide-(--ui-border) scroll-py-1" data-reka-combobox-viewport="" role="presentation" style="position: relative; overflow: auto; flex-grow: 1; flex-shrink: 1; flex-basis: 0%;"> <div class="divide-y divide-(--ui-border) scroll-py-1" data-reka-combobox-viewport="" role="presentation" style="position: relative; overflow: auto; flex-grow: 1; flex-shrink: 1; flex-basis: 0%;">
<!--v-if--> <!--v-if-->
<div role="group" aria-labelledby="" id="reka-combobox-group-v-0-0-1" class="p-1 isolate"> <div role="group" aria-labelledby="" id="reka-combobox-group-v-0-0-1" class="p-1 isolate">
<div id="reka-combobox-item-v-0-0-3" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-help shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Backlog</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-3" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item="" data-highlighted=""><span class="iconify i-lucide:circle-help shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Backlog</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-5" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-plus shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Todo</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-5" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-plus shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Todo</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-7" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-arrow-up shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">In Progress</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-7" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-arrow-up shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">In Progress</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>
<div id="reka-combobox-item-v-0-0-9" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-check shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Done</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div> <div id="reka-combobox-item-v-0-0-9" role="option" tabindex="-1" aria-selected="false" disabled="" data-disabled="" data-state="unchecked" class="group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-(--ui-text) data-highlighted:text-(--ui-text-highlighted) data-highlighted:before:bg-(--ui-bg-elevated)/50 transition-colors before:transition-colors p-1.5 text-sm gap-1.5" data-reka-collection-item=""><span class="iconify i-lucide:circle-check shrink-0 text-(--ui-text-dimmed) group-data-highlighted:text-(--ui-text) transition-colors size-5" aria-hidden="true"></span><span class="truncate">Done</span><span class="ms-auto inline-flex gap-1.5 items-center"><!----></span></div>

View File

@@ -33,7 +33,7 @@ exports[`Slider > renders with defaultValue correctly 1`] = `
exports[`Slider > renders with disabled correctly 1`] = ` exports[`Slider > renders with disabled correctly 1`] = `
"<span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex items-center select-none touch-none w-full opacity-75 cursor-not-allowed" aria-disabled="true" data-disabled=""><span data-disabled="" data-orientation="horizontal" class="relative bg-(--ui-bg-accented) overflow-hidden rounded-full grow h-[8px]"><span data-disabled="" data-orientation="horizontal" style="left: 0%; right: 100%;" class="absolute rounded-full bg-(--ui-primary) h-full"></span></span> "<span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex items-center select-none touch-none w-full opacity-75 cursor-not-allowed" aria-disabled="true" data-disabled=""><span data-disabled="" data-orientation="horizontal" class="relative bg-(--ui-bg-accented) overflow-hidden rounded-full grow h-[8px]"><span data-disabled="" data-orientation="horizontal" style="left: 0%; right: 100%;" class="absolute rounded-full bg-(--ui-primary) h-full"></span></span>
<div class="rounded-full bg-(--ui-bg) ring-2 focus-visible:outline-2 focus-visible:outline-offset-2 ring-(--ui-primary) focus-visible:outline-(--ui-primary)/50 size-4" role="slider" data-disabled="" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px);" data-reka-collection-item=""></div> <div class="rounded-full bg-(--ui-bg) ring-2 focus-visible:outline-2 focus-visible:outline-offset-2 ring-(--ui-primary) focus-visible:outline-(--ui-primary)/50 size-4" role="slider" data-disabled="" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px);" data-reka-collection-item="" aria-valuenow="0"></div>
<!----></span>" <!----></span>"
`; `;

View File

@@ -33,7 +33,7 @@ exports[`Slider > renders with defaultValue correctly 1`] = `
exports[`Slider > renders with disabled correctly 1`] = ` exports[`Slider > renders with disabled correctly 1`] = `
"<span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex items-center select-none touch-none w-full opacity-75 cursor-not-allowed" aria-disabled="true" data-disabled=""><span data-disabled="" data-orientation="horizontal" class="relative bg-(--ui-bg-accented) overflow-hidden rounded-full grow h-[8px]"><span data-disabled="" data-orientation="horizontal" style="left: 0%; right: 100%;" class="absolute rounded-full bg-(--ui-primary) h-full"></span></span> "<span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex items-center select-none touch-none w-full opacity-75 cursor-not-allowed" aria-disabled="true" data-disabled=""><span data-disabled="" data-orientation="horizontal" class="relative bg-(--ui-bg-accented) overflow-hidden rounded-full grow h-[8px]"><span data-disabled="" data-orientation="horizontal" style="left: 0%; right: 100%;" class="absolute rounded-full bg-(--ui-primary) h-full"></span></span>
<div class="rounded-full bg-(--ui-bg) ring-2 focus-visible:outline-2 focus-visible:outline-offset-2 ring-(--ui-primary) focus-visible:outline-(--ui-primary)/50 size-4" role="slider" data-disabled="" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px);" data-reka-collection-item=""></div> <div class="rounded-full bg-(--ui-bg) ring-2 focus-visible:outline-2 focus-visible:outline-offset-2 ring-(--ui-primary) focus-visible:outline-(--ui-primary)/50 size-4" role="slider" data-disabled="" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px);" data-reka-collection-item="" aria-valuenow="0"></div>
<!----></span>" <!----></span>"
`; `;

View File

@@ -1,12 +1,13 @@
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { defineVitestConfig } from '@nuxt/test-utils/config' import { defineVitestConfig } from '@nuxt/test-utils/config'
import { defaultExclude } from 'vitest/config'
export default defineVitestConfig({ export default defineVitestConfig({
test: { test: {
testTimeout: 1000, testTimeout: 1000,
globals: true, globals: true,
silent: true, silent: true,
include: ['./test/components/**.spec.ts'], exclude: [...defaultExclude, './test/vue/**.spec.ts'],
environment: 'nuxt', environment: 'nuxt',
environmentOptions: { environmentOptions: {
nuxt: { nuxt: {

View File

@@ -9,7 +9,6 @@ const vueComponents = await glob('./src/runtime/vue/components/*.vue', { absolut
export default defineConfig({ export default defineConfig({
test: { test: {
testTimeout: 1000,
environment: 'happy-dom', environment: 'happy-dom',
silent: true, silent: true,
include: ['./test/components/**.spec.ts'], include: ['./test/components/**.spec.ts'],