mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 15:31:46 +01:00
Compare commits
13 Commits
chore/dyna
...
v3.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f6fa6ae4a | ||
|
|
c7bb6d4c4b | ||
|
|
c23f85fe33 | ||
|
|
591d59fe89 | ||
|
|
caa3bf9c7e | ||
|
|
2731011bb7 | ||
|
|
aebf0b3dca | ||
|
|
6651987dc6 | ||
|
|
61aabd72e4 | ||
|
|
8dfdd63ce3 | ||
|
|
e6369a6746 | ||
|
|
a4f3f6d531 | ||
|
|
c5bdec0f64 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,5 +1,27 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [3.1.1](https://github.com/nuxt/ui/compare/v3.1.0...v3.1.1) (2025-05-02)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **useOverlay:** add `closeAll` method ([#3984](https://github.com/nuxt/ui/issues/3984)) ([ac4c194](https://github.com/nuxt/ui/commit/ac4c1946ec399aec59b4bce9d538e3ff67868abf))
|
||||||
|
* **useOverlay:** add `isOpen` method to check overlay state ([#4041](https://github.com/nuxt/ui/issues/4041)) ([a4f3f6d](https://github.com/nuxt/ui/commit/a4f3f6d531f9c0281f99085a6688d296f8f13f2f))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Calendar:** add `place-items-center` to grid row ([#4034](https://github.com/nuxt/ui/issues/4034)) ([8dfdd63](https://github.com/nuxt/ui/commit/8dfdd63ce3b3a0e904f7c013c774cf9aaf46b240))
|
||||||
|
* **defineShortcuts:** bring back `meta` to `ctrl` convert on non macos platforms ([f3b8b17](https://github.com/nuxt/ui/commit/f3b8b17dc5f43936ef7ffb11c1ed7f9a5f94d0bb)), closes [#3869](https://github.com/nuxt/ui/issues/3869) [#3318](https://github.com/nuxt/ui/issues/3318)
|
||||||
|
* **module:** support `nuxt-nightly` ([#3996](https://github.com/nuxt/ui/issues/3996)) ([bc0a296](https://github.com/nuxt/ui/commit/bc0a296f9d68ca72cd991b11cd3489b63c7b13db))
|
||||||
|
* **NavigationMenu:** remove `sm:w-auto` from content slot ([aebf0b3](https://github.com/nuxt/ui/commit/aebf0b3dca50c51c093cb6abf16c4fd995fc1b39)), closes [#3987](https://github.com/nuxt/ui/issues/3987)
|
||||||
|
* **RadioGroup:** improve items `value` field type ([#3995](https://github.com/nuxt/ui/issues/3995)) ([195773e](https://github.com/nuxt/ui/commit/195773ec7dac12ccc3a0a67867751e8ca634cc04))
|
||||||
|
* **templates:** put back args to watch in dev ([#4033](https://github.com/nuxt/ui/issues/4033)) ([c5bdec0](https://github.com/nuxt/ui/commit/c5bdec0f64963ef602975270a09a1ee795cdacf9))
|
||||||
|
* **theme:** add missing `border-bg` / `divide-bg` utilities ([82b5f32](https://github.com/nuxt/ui/commit/82b5f322ebd8a08e63588122bd4ef567dcb8ba8c))
|
||||||
|
* **theme:** add missing `ring-offset-*` utilities ([#3992](https://github.com/nuxt/ui/issues/3992)) ([e5df026](https://github.com/nuxt/ui/commit/e5df0269935be59df759fe0e1378acb2b0d9014a))
|
||||||
|
* **theme:** define default shades for named tailwindcss colors ([8acf3c5](https://github.com/nuxt/ui/commit/8acf3c51db6c2f9443d04be6ba7d9f062c5cf8ab)), closes [#3977](https://github.com/nuxt/ui/issues/3977)
|
||||||
|
* **theme:** improve app config types for `ui` object ([591d59f](https://github.com/nuxt/ui/commit/591d59fe89f1d9bf016c121bf9160f73fe0a290d)), closes [#3579](https://github.com/nuxt/ui/issues/3579)
|
||||||
|
* **theme:** use `[@theme](https://github.com/theme) inline` to properly reference css variables ([6131871](https://github.com/nuxt/ui/commit/6131871a0d124c5942d60dc5dff20981e8542e51)), closes [#4018](https://github.com/nuxt/ui/issues/4018)
|
||||||
|
* **useOverlay:** improve types and docs ([#4012](https://github.com/nuxt/ui/issues/4012)) ([39e29fc](https://github.com/nuxt/ui/commit/39e29fccf1840c723a13237d65002501b2829b70))
|
||||||
|
|
||||||
## [3.1.0](https://github.com/nuxt/ui/compare/v3.0.2...v3.1.0) (2025-04-24)
|
## [3.1.0](https://github.com/nuxt/ui/compare/v3.0.2...v3.1.0) (2025-04-24)
|
||||||
|
|
||||||
### ⚠ BREAKING CHANGES
|
### ⚠ BREAKING CHANGES
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default defineBuildConfig({
|
|||||||
delimiters: ['', ''],
|
delimiters: ['', ''],
|
||||||
values: {
|
values: {
|
||||||
// Used in development to import directly from theme
|
// Used in development to import directly from theme
|
||||||
'const isUiDev = true': 'const isUiDev = false'
|
'process.argv.includes(\'--uiDev\')': 'false'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ function onClickPrev() {
|
|||||||
function onClickNext() {
|
function onClickNext() {
|
||||||
activeIndex.value++
|
activeIndex.value++
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSelect(index: number) {
|
function onSelect(index: number) {
|
||||||
activeIndex.value = index
|
activeIndex.value = index
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(index: number) {
|
||||||
|
activeIndex.value = index
|
||||||
|
|
||||||
carousel.value?.emblaApi?.scrollTo(index)
|
carousel.value?.emblaApi?.scrollTo(index)
|
||||||
}
|
}
|
||||||
@@ -35,6 +38,7 @@ function onSelect(index: number) {
|
|||||||
:prev="{ onClick: onClickPrev }"
|
:prev="{ onClick: onClickPrev }"
|
||||||
:next="{ onClick: onClickNext }"
|
:next="{ onClick: onClickNext }"
|
||||||
class="w-full max-w-xs mx-auto"
|
class="w-full max-w-xs mx-auto"
|
||||||
|
@select="onSelect"
|
||||||
>
|
>
|
||||||
<img :src="item" width="320" height="320" class="rounded-lg">
|
<img :src="item" width="320" height="320" class="rounded-lg">
|
||||||
</UCarousel>
|
</UCarousel>
|
||||||
@@ -45,7 +49,7 @@ function onSelect(index: number) {
|
|||||||
:key="index"
|
:key="index"
|
||||||
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
|
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
|
||||||
:class="{ 'opacity-100': activeIndex === index }"
|
:class="{ 'opacity-100': activeIndex === index }"
|
||||||
@click="onSelect(index)"
|
@click="select(index)"
|
||||||
>
|
>
|
||||||
<img :src="item" width="44" height="44" class="rounded-lg">
|
<img :src="item" width="44" height="44" class="rounded-lg">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ const modal = overlay.create(LazyModalExample, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function open() {
|
async function open() {
|
||||||
const shouldIncrement = await modal.open()
|
const instance = modal.open()
|
||||||
|
|
||||||
|
const shouldIncrement = await instance.result
|
||||||
|
|
||||||
if (shouldIncrement) {
|
if (shouldIncrement) {
|
||||||
count.value++
|
count.value++
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ const items = [
|
|||||||
class="w-full justify-center"
|
class="w-full justify-center"
|
||||||
:ui="{
|
:ui="{
|
||||||
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
|
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
|
||||||
|
content: 'sm:w-auto',
|
||||||
childList: 'sm:w-96',
|
childList: 'sm:w-96',
|
||||||
childLinkDescription: 'text-balance line-clamp-2'
|
childLinkDescription: 'text-balance line-clamp-2'
|
||||||
}"
|
}"
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ const slideover = overlay.create(LazySlideoverExample, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function open() {
|
async function open() {
|
||||||
const shouldIncrement = await slideover.open()
|
const instance = slideover.open()
|
||||||
|
|
||||||
|
const shouldIncrement = await instance.result
|
||||||
|
|
||||||
if (shouldIncrement) {
|
if (shouldIncrement) {
|
||||||
count.value++
|
count.value++
|
||||||
|
|||||||
@@ -62,10 +62,17 @@ Update an overlay using its `id`
|
|||||||
- `id`: The identifier of the overlay
|
- `id`: The identifier of the overlay
|
||||||
- `props`: An object of props to update on the rendered component.
|
- `props`: An object of props to update on the rendered component.
|
||||||
|
|
||||||
### `unmount(id: symbol): void`
|
### `unMount(id: symbol): void`
|
||||||
|
|
||||||
Removes the overlay from the DOM using its `id`
|
Removes the overlay from the DOM using its `id`
|
||||||
|
|
||||||
|
- Parameters:
|
||||||
|
- `id`: The identifier of the overlay
|
||||||
|
|
||||||
|
### `isOpen(id: symbol): boolean`
|
||||||
|
|
||||||
|
Checks if an overlay its open using its `id`
|
||||||
|
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- `id`: The identifier of the overlay
|
- `id`: The identifier of the overlay
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ name: 'toast-example'
|
|||||||
:toaster-position-example
|
:toaster-position-example
|
||||||
::
|
::
|
||||||
|
|
||||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L3"}
|
||||||
In this example, we use the `AppConfig` to configure the `position` prop of the `Toaster` component globally.
|
In this example, we use the `AppConfig` to configure the `position` prop of the `Toaster` component globally.
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ name: 'toast-example'
|
|||||||
:toaster-duration-example
|
:toaster-duration-example
|
||||||
::
|
::
|
||||||
|
|
||||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L5"}
|
||||||
In this example, we use the `AppConfig` to configure the `duration` prop of the `Toaster` component globally.
|
In this example, we use the `AppConfig` to configure the `duration` prop of the `Toaster` component globally.
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ name: 'toast-example'
|
|||||||
:toaster-expand-example
|
:toaster-expand-example
|
||||||
::
|
::
|
||||||
|
|
||||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L4"}
|
||||||
In this example, we use the `AppConfig` to configure the `expand` prop of the `Toaster` component globally.
|
In this example, we use the `AppConfig` to configure the `expand` prop of the `Toaster` component globally.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export default defineNuxtConfig({
|
|||||||
],
|
],
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
|
'../src/module',
|
||||||
'@nuxt/ui-pro',
|
'@nuxt/ui-pro',
|
||||||
'@nuxt/content',
|
'@nuxt/content',
|
||||||
'@nuxt/image',
|
'@nuxt/image',
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"capture-website": "^4.2.0",
|
"capture-website": "^4.2.0",
|
||||||
"joi": "^17.13.3",
|
"joi": "^17.13.3",
|
||||||
"motion-v": "^1.0.0",
|
"motion-v": "^1.0.0",
|
||||||
"nuxt": "^3.16.2",
|
"nuxt": "^3.17.1",
|
||||||
"nuxt-component-meta": "^0.11.0",
|
"nuxt-component-meta": "^0.11.0",
|
||||||
"nuxt-llms": "^0.1.2",
|
"nuxt-llms": "^0.1.2",
|
||||||
"nuxt-og-image": "^5.1.3",
|
"nuxt-og-image": "^5.1.3",
|
||||||
|
|||||||
17
package.json
17
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"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.1.0",
|
"version": "3.1.1",
|
||||||
"packageManager": "pnpm@10.10.0",
|
"packageManager": "pnpm@10.10.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -96,12 +96,12 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt-module-build build",
|
"build": "nuxt-module-build build",
|
||||||
"prepack": "pnpm build",
|
"prepack": "pnpm build",
|
||||||
"dev": "nuxi dev playground",
|
"dev": "nuxi dev playground --uiDev",
|
||||||
"dev:build": "nuxi build playground",
|
"dev:build": "nuxi build playground",
|
||||||
"dev:vue": "vite playground-vue",
|
"dev:vue": "vite playground-vue -- --uiDev",
|
||||||
"dev:vue:build": "vite build playground-vue",
|
"dev:vue:build": "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",
|
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground && nuxi prepare docs && vite build playground-vue",
|
||||||
"docs": "nuxi dev docs",
|
"docs": "nuxi dev docs --uiDev",
|
||||||
"docs:build": "nuxi build docs",
|
"docs:build": "nuxi build docs",
|
||||||
"docs:prepare": "nuxt-component-meta docs",
|
"docs:prepare": "nuxt-component-meta docs",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
@@ -117,8 +117,8 @@
|
|||||||
"@internationalized/number": "^3.6.1",
|
"@internationalized/number": "^3.6.1",
|
||||||
"@nuxt/fonts": "^0.11.2",
|
"@nuxt/fonts": "^0.11.2",
|
||||||
"@nuxt/icon": "^1.12.0",
|
"@nuxt/icon": "^1.12.0",
|
||||||
"@nuxt/kit": "^3.16.2",
|
"@nuxt/kit": "^3.17.1",
|
||||||
"@nuxt/schema": "^3.16.2",
|
"@nuxt/schema": "^3.17.1",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@standard-schema/spec": "^1.0.0",
|
"@standard-schema/spec": "^1.0.0",
|
||||||
"@tailwindcss/postcss": "^4.1.4",
|
"@tailwindcss/postcss": "^4.1.4",
|
||||||
@@ -152,7 +152,8 @@
|
|||||||
"unplugin": "^2.3.2",
|
"unplugin": "^2.3.2",
|
||||||
"unplugin-auto-import": "^19.1.2",
|
"unplugin-auto-import": "^19.1.2",
|
||||||
"unplugin-vue-components": "^28.5.0",
|
"unplugin-vue-components": "^28.5.0",
|
||||||
"vaul-vue": "^0.4.1"
|
"vaul-vue": "^0.4.1",
|
||||||
|
"vue-component-type-helpers": "^2.2.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^1.3.0",
|
"@nuxt/eslint-config": "^1.3.0",
|
||||||
@@ -163,7 +164,7 @@
|
|||||||
"embla-carousel": "^8.6.0",
|
"embla-carousel": "^8.6.0",
|
||||||
"eslint": "^9.25.1",
|
"eslint": "^9.25.1",
|
||||||
"happy-dom": "^17.4.4",
|
"happy-dom": "^17.4.4",
|
||||||
"nuxt": "^3.16.2",
|
"nuxt": "^3.17.1",
|
||||||
"release-it": "^19.0.1",
|
"release-it": "^19.0.1",
|
||||||
"vitest": "^3.1.2",
|
"vitest": "^3.1.2",
|
||||||
"vitest-environment-nuxt": "^1.0.1",
|
"vitest-environment-nuxt": "^1.0.1",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"@iconify-json/simple-icons": "^1.2.33",
|
"@iconify-json/simple-icons": "^1.2.33",
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"@nuxthub/core": "^0.8.25",
|
"@nuxthub/core": "^0.8.25",
|
||||||
"nuxt": "^3.16.2",
|
"nuxt": "^3.17.1",
|
||||||
"zod": "^3.24.3"
|
"zod": "^3.24.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
3258
pnpm-lock.yaml
generated
3258
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -122,6 +122,12 @@ function _useOverlay() {
|
|||||||
return overlay
|
return overlay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isOpen = (id: symbol): boolean => {
|
||||||
|
const overlay = getOverlay(id)
|
||||||
|
|
||||||
|
return overlay.isOpen
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
overlays,
|
overlays,
|
||||||
open,
|
open,
|
||||||
@@ -129,7 +135,8 @@ function _useOverlay() {
|
|||||||
closeAll,
|
closeAll,
|
||||||
create,
|
create,
|
||||||
patch,
|
patch,
|
||||||
unMount
|
unMount,
|
||||||
|
isOpen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
63
src/runtime/types/tv.ts
Normal file
63
src/runtime/types/tv.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import type { ClassValue, TVVariants, TVCompoundVariants, TVDefaultVariants } from 'tailwind-variants'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the AppConfig object based on the tailwind-variants configuration.
|
||||||
|
*/
|
||||||
|
export type TVConfig<T extends Record<string, any>> = {
|
||||||
|
[P in keyof T]?: {
|
||||||
|
[K in keyof T[P]as K extends 'base' | 'slots' | 'variants' | 'compoundVariants' | 'defaultVariants' ? K : never]?: K extends 'base' ? ClassValue
|
||||||
|
: K extends 'slots' ? {
|
||||||
|
[S in keyof T[P]['slots']]?: ClassValue
|
||||||
|
}
|
||||||
|
: K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, T[P]['variants']>
|
||||||
|
: K extends 'compoundVariants' ? TVCompoundVariants<T[P]['variants'], T[P]['slots'], ClassValue, object, undefined>
|
||||||
|
: K extends 'defaultVariants' ? TVDefaultVariants<T[P]['variants'], T[P]['slots'], object, undefined>
|
||||||
|
: never
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility type to flatten intersection types for better IDE hover information.
|
||||||
|
* @template T The type to flatten.
|
||||||
|
*/
|
||||||
|
type Id<T> = {} & { [P in keyof T]: T[P] }
|
||||||
|
|
||||||
|
type ComponentVariants<T extends { variants?: Record<string, Record<string, any>> }> = {
|
||||||
|
[K in keyof T['variants']]: keyof T['variants'][K]
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentSlots<T extends { slots?: Record<string, any> }> = Id<{
|
||||||
|
[K in keyof T['slots']]?: ClassValue
|
||||||
|
}>
|
||||||
|
|
||||||
|
type GetComponentAppConfig<A, U extends string, K extends string> =
|
||||||
|
A extends Record<U, Record<K, any>> ? A[U][K] : {}
|
||||||
|
|
||||||
|
type ComponentAppConfig<
|
||||||
|
T,
|
||||||
|
A extends Record<string, any>,
|
||||||
|
K extends string,
|
||||||
|
U extends string = 'ui' | 'uiPro' | 'uiPro.prose'
|
||||||
|
> = A & (
|
||||||
|
U extends 'uiPro.prose'
|
||||||
|
? { uiPro?: { prose?: { [k in K]?: Partial<T> } } }
|
||||||
|
: { [key in Exclude<U, 'uiPro.prose'>]?: { [k in K]?: Partial<T> } }
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the configuration shape expected for a component.
|
||||||
|
* @template T The component's theme imported from `#build/ui/*`.
|
||||||
|
* @template A The base AppConfig type from `@nuxt/schema`.
|
||||||
|
* @template K The key identifying the component (e.g., 'badge').
|
||||||
|
* @template U The top-level key in AppConfig ('ui' or 'uiPro').
|
||||||
|
*/
|
||||||
|
export type ComponentConfig<
|
||||||
|
T extends Record<string, any>,
|
||||||
|
A extends Record<string, any>,
|
||||||
|
K extends string,
|
||||||
|
U extends 'ui' | 'uiPro' | 'uiPro.prose' = 'ui'
|
||||||
|
> = {
|
||||||
|
AppConfig: ComponentAppConfig<T, A, K, U>
|
||||||
|
variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>
|
||||||
|
slots: ComponentSlots<T>
|
||||||
|
}
|
||||||
@@ -1,20 +1,5 @@
|
|||||||
import type { AcceptableValue as _AcceptableValue } from 'reka-ui'
|
|
||||||
import type { ClassValue } from 'tailwind-variants'
|
|
||||||
import type { VNode } from 'vue'
|
import type { VNode } from 'vue'
|
||||||
|
import type { AcceptableValue as _AcceptableValue } from 'reka-ui'
|
||||||
export interface TightMap<O = any> {
|
|
||||||
[key: string]: TightMap | O
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DeepPartial<T, O = any> = {
|
|
||||||
[P in keyof T]?: T[P] extends Array<string>
|
|
||||||
? string
|
|
||||||
: T[P] extends object
|
|
||||||
? DeepPartial<T[P], O>
|
|
||||||
: T[P];
|
|
||||||
} & {
|
|
||||||
[key: string]: O | TightMap<O>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DynamicSlotsKeys<Name extends string | undefined, Suffix extends string | undefined = undefined> = (
|
export type DynamicSlotsKeys<Name extends string | undefined, Suffix extends string | undefined = undefined> = (
|
||||||
Name extends string
|
Name extends string
|
||||||
@@ -56,13 +41,13 @@ export type MergeTypes<T extends object> = {
|
|||||||
export type GetItemKeys<I> = keyof Extract<NestedItem<I>, object>
|
export type GetItemKeys<I> = keyof Extract<NestedItem<I>, object>
|
||||||
|
|
||||||
export type GetItemValue<I, VK extends GetItemKeys<I> | undefined, T extends NestedItem<I> = NestedItem<I>> =
|
export type GetItemValue<I, VK extends GetItemKeys<I> | undefined, T extends NestedItem<I> = NestedItem<I>> =
|
||||||
T extends object
|
T extends object
|
||||||
? VK extends undefined
|
? VK extends undefined
|
||||||
? T
|
? T
|
||||||
: VK extends keyof T
|
: VK extends keyof T
|
||||||
? T[VK]
|
? T[VK]
|
||||||
: never
|
: never
|
||||||
: T
|
: T
|
||||||
|
|
||||||
export type GetModelValue<
|
export type GetModelValue<
|
||||||
T,
|
T,
|
||||||
@@ -92,48 +77,4 @@ export type EmitsToProps<T> = {
|
|||||||
: never
|
: never
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export * from './tv'
|
||||||
* Utility type to flatten intersection types for better IDE hover information.
|
|
||||||
* @template T The type to flatten.
|
|
||||||
*/
|
|
||||||
type Id<T> = {} & { [P in keyof T]: T[P] }
|
|
||||||
|
|
||||||
type ComponentVariants<T extends { variants?: Record<string, Record<string, any>> }> = {
|
|
||||||
[K in keyof T['variants']]: keyof T['variants'][K]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ComponentSlots<T extends { slots?: Record<string, any> }> = Id<{
|
|
||||||
[K in keyof T['slots']]?: ClassValue
|
|
||||||
}>
|
|
||||||
|
|
||||||
type GetComponentAppConfig<A, U extends string, K extends string> =
|
|
||||||
A extends Record<U, Record<K, any>> ? A[U][K] : {}
|
|
||||||
|
|
||||||
type ComponentAppConfig<
|
|
||||||
T,
|
|
||||||
A extends Record<string, any>,
|
|
||||||
K extends string,
|
|
||||||
U extends string = 'ui' | 'uiPro' | 'uiPro.prose'
|
|
||||||
> = A & (
|
|
||||||
U extends 'uiPro.prose'
|
|
||||||
? { uiPro?: { prose?: { [k in K]?: Partial<T> } } }
|
|
||||||
: { [key in Exclude<U, 'uiPro.prose'>]?: { [k in K]?: Partial<T> } }
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the configuration shape expected for a component.
|
|
||||||
* @template T The component's theme imported from `#build/ui/*`.
|
|
||||||
* @template A The base AppConfig type from `@nuxt/schema`.
|
|
||||||
* @template K The key identifying the component (e.g., 'badge').
|
|
||||||
* @template U The top-level key in AppConfig ('ui' or 'uiPro').
|
|
||||||
*/
|
|
||||||
export type ComponentConfig<
|
|
||||||
T extends Record<string, any>,
|
|
||||||
A extends Record<string, any>,
|
|
||||||
K extends string,
|
|
||||||
U extends 'ui' | 'uiPro' | 'uiPro.prose' = 'ui'
|
|
||||||
> = {
|
|
||||||
AppConfig: ComponentAppConfig<T, A, K, U>
|
|
||||||
variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>
|
|
||||||
slots: ComponentSlots<T>
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For local development, import directly from theme
|
// For local development, import directly from theme
|
||||||
const isUiDev = true
|
if (process.argv.includes('--uiDev')) {
|
||||||
if (isUiDev) {
|
|
||||||
const templatePath = fileURLToPath(new URL(`./theme/${kebabCase(component)}`, import.meta.url))
|
const templatePath = fileURLToPath(new URL(`./theme/${kebabCase(component)}`, import.meta.url))
|
||||||
return [
|
return [
|
||||||
`import template from ${JSON.stringify(templatePath)}`,
|
`import template from ${JSON.stringify(templatePath)}`,
|
||||||
@@ -150,7 +149,7 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
|
|||||||
templates.push({
|
templates.push({
|
||||||
filename: 'types/ui.d.ts',
|
filename: 'types/ui.d.ts',
|
||||||
getContents: () => `import * as ui from '#build/ui'
|
getContents: () => `import * as ui from '#build/ui'
|
||||||
import type { DeepPartial } from '@nuxt/ui'
|
import type { TVConfig } from '@nuxt/ui'
|
||||||
import type { defaultConfig } from 'tailwind-variants'
|
import type { defaultConfig } from 'tailwind-variants'
|
||||||
import colors from 'tailwindcss/colors'
|
import colors from 'tailwindcss/colors'
|
||||||
|
|
||||||
@@ -166,7 +165,7 @@ type AppConfigUI = {
|
|||||||
}
|
}
|
||||||
icons?: Partial<typeof icons>
|
icons?: Partial<typeof icons>
|
||||||
tv?: typeof defaultConfig
|
tv?: typeof defaultConfig
|
||||||
} & DeepPartial<typeof ui>
|
} & TVConfig<typeof ui>
|
||||||
|
|
||||||
declare module '@nuxt/schema' {
|
declare module '@nuxt/schema' {
|
||||||
interface AppConfigInput {
|
interface AppConfigInput {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default (options: Required<ModuleOptions>) => ({
|
|||||||
body: 'flex flex-col space-y-4 pt-4 sm:flex-row sm:space-x-4 sm:space-y-0',
|
body: 'flex flex-col space-y-4 pt-4 sm:flex-row sm:space-x-4 sm:space-y-0',
|
||||||
heading: 'text-center font-medium truncate mx-auto',
|
heading: 'text-center font-medium truncate mx-auto',
|
||||||
grid: 'w-full border-collapse select-none space-y-1 focus:outline-none',
|
grid: 'w-full border-collapse select-none space-y-1 focus:outline-none',
|
||||||
gridRow: 'grid grid-cols-7',
|
gridRow: 'grid grid-cols-7 place-items-center',
|
||||||
gridWeekDaysRow: 'mb-1 grid w-full grid-cols-7',
|
gridWeekDaysRow: 'mb-1 grid w-full grid-cols-7',
|
||||||
gridBody: 'grid',
|
gridBody: 'grid',
|
||||||
headCell: 'rounded-md',
|
headCell: 'rounded-md',
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default (options: Required<ModuleOptions>) => ({
|
|||||||
separator: 'px-2 h-px bg-border',
|
separator: 'px-2 h-px bg-border',
|
||||||
viewportWrapper: 'absolute top-full left-0 flex w-full',
|
viewportWrapper: 'absolute top-full left-0 flex w-full',
|
||||||
viewport: 'relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]',
|
viewport: 'relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]',
|
||||||
content: 'absolute top-0 left-0 w-full sm:w-auto',
|
content: 'absolute top-0 left-0 w-full',
|
||||||
indicator: 'absolute data-[state=visible]:animate-[fade-in_100ms_ease-out] data-[state=hidden]:animate-[fade-out_100ms_ease-in] data-[state=hidden]:opacity-0 bottom-0 z-[2] w-(--reka-navigation-menu-indicator-size) translate-x-(--reka-navigation-menu-indicator-position) flex h-2.5 items-end justify-center overflow-hidden transition-[translate,width] duration-200',
|
indicator: 'absolute data-[state=visible]:animate-[fade-in_100ms_ease-out] data-[state=hidden]:animate-[fade-out_100ms_ease-in] data-[state=hidden]:opacity-0 bottom-0 z-[2] w-(--reka-navigation-menu-indicator-size) translate-x-(--reka-navigation-menu-indicator-position) flex h-2.5 items-end justify-center overflow-hidden transition-[translate,width] duration-200',
|
||||||
arrow: 'relative top-[50%] size-2.5 rotate-45 border border-default bg-default z-[1] rounded-xs'
|
arrow: 'relative top-[50%] size-2.5 rotate-45 border border-default bg-default z-[1] rounded-xs'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ import PluginsPlugin from './plugins/plugins'
|
|||||||
import AppConfigPlugin from './plugins/app-config'
|
import AppConfigPlugin from './plugins/app-config'
|
||||||
import ComponentImportPlugin from './plugins/components'
|
import ComponentImportPlugin from './plugins/components'
|
||||||
import NuxtEnvironmentPlugin from './plugins/nuxt-environment'
|
import NuxtEnvironmentPlugin from './plugins/nuxt-environment'
|
||||||
|
|
||||||
import type { DeepPartial } from './runtime/types/utils'
|
|
||||||
import AutoImportPlugin from './plugins/auto-import'
|
import AutoImportPlugin from './plugins/auto-import'
|
||||||
|
|
||||||
|
import type { TVConfig } from './runtime/types/tv'
|
||||||
|
|
||||||
type NeutralColor = 'slate' | 'gray' | 'zinc' | 'neutral' | 'stone'
|
type NeutralColor = 'slate' | 'gray' | 'zinc' | 'neutral' | 'stone'
|
||||||
type Color = Exclude<keyof typeof colors, 'inherit' | 'current' | 'transparent' | 'black' | 'white' | NeutralColor> | (string & {})
|
type Color = Exclude<keyof typeof colors, 'inherit' | 'current' | 'transparent' | 'black' | 'white' | NeutralColor> | (string & {})
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ type AppConfigUI = {
|
|||||||
// TODO: add type hinting for colors from `options.theme.colors`
|
// TODO: add type hinting for colors from `options.theme.colors`
|
||||||
colors?: Record<string, Color> & { neutral?: NeutralColor }
|
colors?: Record<string, Color> & { neutral?: NeutralColor }
|
||||||
icons?: Partial<typeof icons>
|
icons?: Partial<typeof icons>
|
||||||
} & DeepPartial<typeof ui>
|
} & TVConfig<typeof ui>
|
||||||
|
|
||||||
export interface NuxtUIOptions extends Omit<ModuleOptions, 'fonts' | 'colorMode'> {
|
export interface NuxtUIOptions extends Omit<ModuleOptions, 'fonts' | 'colorMode'> {
|
||||||
/** Whether to generate declaration files for auto-imported components. */
|
/** Whether to generate declaration files for auto-imported components. */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1226,7 +1226,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
|||||||
<div class="absolute top-full left-0 flex w-full justify-center">
|
<div class="absolute top-full left-0 flex w-full justify-center">
|
||||||
<!--v-if-->
|
<!--v-if-->
|
||||||
<div class="relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]" data-state="closed" data-orientation="horizontal" style="pointer-events: none;" hidden="">
|
<div class="relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]" data-state="closed" data-orientation="horizontal" style="pointer-events: none;" hidden="">
|
||||||
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-content-1" aria-labelledby="reka-navigation-menu-v-0-trigger-1" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full sm:w-auto data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-content-1" aria-labelledby="reka-navigation-menu-v-0-trigger-1" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
||||||
<ul class="grid p-2 grid-cols-2 gap-2">
|
<ul class="grid p-2 grid-cols-2 gap-2">
|
||||||
<li class=""><button type="button" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" width="1em" height="1em" viewBox="0 0 16 16"></svg>
|
<li class=""><button type="button" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" width="1em" height="1em" viewBox="0 0 16 16"></svg>
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
@@ -1262,7 +1262,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
|||||||
</button></li>
|
</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-content-2" aria-labelledby="reka-navigation-menu-v-0-trigger-2" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full sm:w-auto data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-content-2" aria-labelledby="reka-navigation-menu-v-0-trigger-2" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
||||||
<ul class="grid p-2 grid-cols-2 gap-2">
|
<ul class="grid p-2 grid-cols-2 gap-2">
|
||||||
<li class=""><a href="/components/link" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" width="1em" height="1em" viewBox="0 0 16 16"></svg>
|
<li class=""><a href="/components/link" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" width="1em" height="1em" viewBox="0 0 16 16"></svg>
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
|
|||||||
@@ -1226,7 +1226,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
|||||||
<div class="absolute top-full left-0 flex w-full justify-center">
|
<div class="absolute top-full left-0 flex w-full justify-center">
|
||||||
<!--v-if-->
|
<!--v-if-->
|
||||||
<div class="relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]" data-state="closed" data-orientation="horizontal" style="pointer-events: none;" hidden="">
|
<div class="relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]" data-state="closed" data-orientation="horizontal" style="pointer-events: none;" hidden="">
|
||||||
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-0-0-content-1" aria-labelledby="reka-navigation-menu-v-0-0-0-trigger-1" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full sm:w-auto data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-0-0-content-1" aria-labelledby="reka-navigation-menu-v-0-0-0-trigger-1" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
||||||
<ul class="grid p-2 grid-cols-2 gap-2">
|
<ul class="grid p-2 grid-cols-2 gap-2">
|
||||||
<li class=""><button type="button" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><span class="iconify i-lucide:house size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" aria-hidden="true"></span>
|
<li class=""><button type="button" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><span class="iconify i-lucide:house size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" aria-hidden="true"></span>
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
@@ -1262,7 +1262,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
|||||||
</button></li>
|
</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-0-0-content-2" aria-labelledby="reka-navigation-menu-v-0-0-0-trigger-2" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full sm:w-auto data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
<div data-dismissable-layer="" style="pointer-events: none;" id="reka-navigation-menu-v-0-0-0-content-2" aria-labelledby="reka-navigation-menu-v-0-0-0-trigger-2" data-state="closed" data-orientation="horizontal" class="absolute top-0 left-0 w-full data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]" hidden="">
|
||||||
<ul class="grid p-2 grid-cols-2 gap-2">
|
<ul class="grid p-2 grid-cols-2 gap-2">
|
||||||
<li class=""><a href="/components/link" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><span class="iconify i-lucide:file size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" aria-hidden="true"></span>
|
<li class=""><a href="/components/link" class="group size-full px-3 py-2 rounded-md flex items-start gap-2 text-start focus-visible:outline-primary hover:bg-elevated/50 text-default hover:text-highlighted transition-colors" data-reka-collection-item=""><span class="iconify i-lucide:file size-5 shrink-0 text-dimmed group-hover:text-default transition-colors" aria-hidden="true"></span>
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
|
|||||||
Reference in New Issue
Block a user