mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 12:39:35 +01:00
Compare commits
1 Commits
fix/inerti
...
chore/dyna
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46058f8004 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,27 +1,5 @@
|
||||
# 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)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
@@ -11,7 +11,7 @@ export default defineBuildConfig({
|
||||
delimiters: ['', ''],
|
||||
values: {
|
||||
// Used in development to import directly from theme
|
||||
'process.argv.includes(\'--uiDev\')': 'false'
|
||||
'const isUiDev = true': 'const isUiDev = false'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,11 +17,8 @@ function onClickPrev() {
|
||||
function onClickNext() {
|
||||
activeIndex.value++
|
||||
}
|
||||
function onSelect(index: number) {
|
||||
activeIndex.value = index
|
||||
}
|
||||
|
||||
function select(index: number) {
|
||||
function onSelect(index: number) {
|
||||
activeIndex.value = index
|
||||
|
||||
carousel.value?.emblaApi?.scrollTo(index)
|
||||
@@ -38,7 +35,6 @@ function select(index: number) {
|
||||
:prev="{ onClick: onClickPrev }"
|
||||
:next="{ onClick: onClickNext }"
|
||||
class="w-full max-w-xs mx-auto"
|
||||
@select="onSelect"
|
||||
>
|
||||
<img :src="item" width="320" height="320" class="rounded-lg">
|
||||
</UCarousel>
|
||||
@@ -49,7 +45,7 @@ function select(index: number) {
|
||||
:key="index"
|
||||
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
|
||||
:class="{ 'opacity-100': activeIndex === index }"
|
||||
@click="select(index)"
|
||||
@click="onSelect(index)"
|
||||
>
|
||||
<img :src="item" width="44" height="44" class="rounded-lg">
|
||||
</div>
|
||||
|
||||
@@ -13,9 +13,7 @@ const modal = overlay.create(LazyModalExample, {
|
||||
})
|
||||
|
||||
async function open() {
|
||||
const instance = modal.open()
|
||||
|
||||
const shouldIncrement = await instance.result
|
||||
const shouldIncrement = await modal.open()
|
||||
|
||||
if (shouldIncrement) {
|
||||
count.value++
|
||||
|
||||
@@ -65,7 +65,6 @@ const items = [
|
||||
class="w-full justify-center"
|
||||
:ui="{
|
||||
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
|
||||
content: 'sm:w-auto',
|
||||
childList: 'sm:w-96',
|
||||
childLinkDescription: 'text-balance line-clamp-2'
|
||||
}"
|
||||
|
||||
@@ -13,9 +13,7 @@ const slideover = overlay.create(LazySlideoverExample, {
|
||||
})
|
||||
|
||||
async function open() {
|
||||
const instance = slideover.open()
|
||||
|
||||
const shouldIncrement = await instance.result
|
||||
const shouldIncrement = await slideover.open()
|
||||
|
||||
if (shouldIncrement) {
|
||||
count.value++
|
||||
|
||||
@@ -62,17 +62,10 @@ Update an overlay using its `id`
|
||||
- `id`: The identifier of the overlay
|
||||
- `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`
|
||||
|
||||
- Parameters:
|
||||
- `id`: The identifier of the overlay
|
||||
|
||||
### `isOpen(id: symbol): boolean`
|
||||
|
||||
Checks if an overlay its open using its `id`
|
||||
|
||||
- Parameters:
|
||||
- `id`: The identifier of the overlay
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ name: 'toast-example'
|
||||
:toaster-position-example
|
||||
::
|
||||
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L3"}
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
||||
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
|
||||
::
|
||||
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L5"}
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
||||
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
|
||||
::
|
||||
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.config.ts#L4"}
|
||||
::note{to="https://github.com/nuxt/ui/blob/v3/docs/app/app.vue#L77"}
|
||||
In this example, we use the `AppConfig` to configure the `expand` prop of the `Toaster` component globally.
|
||||
::
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ export default defineNuxtConfig({
|
||||
],
|
||||
|
||||
modules: [
|
||||
'../src/module',
|
||||
'@nuxt/ui-pro',
|
||||
'@nuxt/content',
|
||||
'@nuxt/image',
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"@nuxt/content": "^3.5.1",
|
||||
"@nuxt/image": "^1.10.0",
|
||||
"@nuxt/ui": "latest",
|
||||
"@nuxt/ui-pro": "^3.1.1",
|
||||
"@nuxt/ui-pro": "^3.1.0",
|
||||
"@nuxthub/core": "^0.8.25",
|
||||
"@nuxtjs/plausible": "^1.2.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
@@ -22,7 +22,7 @@
|
||||
"capture-website": "^4.2.0",
|
||||
"joi": "^17.13.3",
|
||||
"motion-v": "^1.0.0",
|
||||
"nuxt": "^3.17.1",
|
||||
"nuxt": "^3.16.2",
|
||||
"nuxt-component-meta": "^0.11.0",
|
||||
"nuxt-llms": "^0.1.2",
|
||||
"nuxt-og-image": "^5.1.3",
|
||||
|
||||
17
package.json
17
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nuxt/ui",
|
||||
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.0",
|
||||
"packageManager": "pnpm@10.10.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -96,12 +96,12 @@
|
||||
"scripts": {
|
||||
"build": "nuxt-module-build build",
|
||||
"prepack": "pnpm build",
|
||||
"dev": "nuxi dev playground --uiDev",
|
||||
"dev": "nuxi dev playground",
|
||||
"dev:build": "nuxi build playground",
|
||||
"dev:vue": "vite playground-vue -- --uiDev",
|
||||
"dev:vue": "vite 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",
|
||||
"docs": "nuxi dev docs --uiDev",
|
||||
"docs": "nuxi dev docs",
|
||||
"docs:build": "nuxi build docs",
|
||||
"docs:prepare": "nuxt-component-meta docs",
|
||||
"lint": "eslint .",
|
||||
@@ -117,8 +117,8 @@
|
||||
"@internationalized/number": "^3.6.1",
|
||||
"@nuxt/fonts": "^0.11.2",
|
||||
"@nuxt/icon": "^1.12.0",
|
||||
"@nuxt/kit": "^3.17.1",
|
||||
"@nuxt/schema": "^3.17.1",
|
||||
"@nuxt/kit": "^3.16.2",
|
||||
"@nuxt/schema": "^3.16.2",
|
||||
"@nuxtjs/color-mode": "^3.5.2",
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@tailwindcss/postcss": "^4.1.4",
|
||||
@@ -152,8 +152,7 @@
|
||||
"unplugin": "^2.3.2",
|
||||
"unplugin-auto-import": "^19.1.2",
|
||||
"unplugin-vue-components": "^28.5.0",
|
||||
"vaul-vue": "^0.4.1",
|
||||
"vue-component-type-helpers": "^2.2.10"
|
||||
"vaul-vue": "^0.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint-config": "^1.3.0",
|
||||
@@ -164,7 +163,7 @@
|
||||
"embla-carousel": "^8.6.0",
|
||||
"eslint": "^9.25.1",
|
||||
"happy-dom": "^17.4.4",
|
||||
"nuxt": "^3.17.1",
|
||||
"nuxt": "^3.16.2",
|
||||
"release-it": "^19.0.1",
|
||||
"vitest": "^3.1.2",
|
||||
"vitest-environment-nuxt": "^1.0.1",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@iconify-json/simple-icons": "^1.2.33",
|
||||
"@nuxt/ui": "latest",
|
||||
"@nuxthub/core": "^0.8.25",
|
||||
"nuxt": "^3.17.1",
|
||||
"nuxt": "^3.16.2",
|
||||
"zod": "^3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
3262
pnpm-lock.yaml
generated
3262
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -122,12 +122,6 @@ function _useOverlay() {
|
||||
return overlay
|
||||
}
|
||||
|
||||
const isOpen = (id: symbol): boolean => {
|
||||
const overlay = getOverlay(id)
|
||||
|
||||
return overlay.isOpen
|
||||
}
|
||||
|
||||
return {
|
||||
overlays,
|
||||
open,
|
||||
@@ -135,8 +129,7 @@ function _useOverlay() {
|
||||
closeAll,
|
||||
create,
|
||||
patch,
|
||||
unMount,
|
||||
isOpen
|
||||
unMount
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,14 +110,14 @@ const linkClass = computed(() => {
|
||||
})
|
||||
|
||||
const page = usePage()
|
||||
const url = computed(() => props.to ?? props.href ?? '')
|
||||
const url = computed(() => props.to ?? props.href ?? '#')
|
||||
|
||||
const isActive = computed(() => props.active || (!!url.value && (props.exact ? url.value === props.href : page?.url.startsWith(url.value))))
|
||||
const isActive = computed(() => props.active || (props.exact ? url.value === props.href : page?.url.startsWith(url.value)))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="!isExternal && !!url">
|
||||
<InertiaLink v-bind="routerLinkProps" :href="url">
|
||||
<template v-if="!isExternal">
|
||||
<InertiaLink v-bind="routerLinkProps" :href="url" custom>
|
||||
<template v-if="custom">
|
||||
<slot
|
||||
v-bind="{
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
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,5 +1,20 @@
|
||||
import type { VNode } from 'vue'
|
||||
import type { AcceptableValue as _AcceptableValue } from 'reka-ui'
|
||||
import type { ClassValue } from 'tailwind-variants'
|
||||
import type { VNode } from 'vue'
|
||||
|
||||
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> = (
|
||||
Name extends string
|
||||
@@ -41,13 +56,13 @@ export type MergeTypes<T extends 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>> =
|
||||
T extends object
|
||||
? VK extends undefined
|
||||
? T
|
||||
: VK extends keyof T
|
||||
? T[VK]
|
||||
: never
|
||||
: T
|
||||
T extends object
|
||||
? VK extends undefined
|
||||
? T
|
||||
: VK extends keyof T
|
||||
? T[VK]
|
||||
: never
|
||||
: T
|
||||
|
||||
export type GetModelValue<
|
||||
T,
|
||||
@@ -77,4 +92,48 @@ export type EmitsToProps<T> = {
|
||||
: 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>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { kebabCase } from 'scule'
|
||||
import { addTemplate, addTypeTemplate } from '@nuxt/kit'
|
||||
import { addTemplate, addTypeTemplate, updateTemplates } from '@nuxt/kit'
|
||||
import type { Nuxt, NuxtTemplate, NuxtTypeTemplate } from '@nuxt/schema'
|
||||
import type { Resolver } from '@nuxt/kit'
|
||||
import type { ModuleOptions } from './module'
|
||||
@@ -50,19 +49,6 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
|
||||
})
|
||||
}
|
||||
|
||||
// For local development, import directly from theme
|
||||
if (process.argv.includes('--uiDev')) {
|
||||
const templatePath = fileURLToPath(new URL(`./theme/${kebabCase(component)}`, import.meta.url))
|
||||
return [
|
||||
`import template from ${JSON.stringify(templatePath)}`,
|
||||
...generateVariantDeclarations(variants),
|
||||
`const result = typeof template === 'function' ? (template as Function)(${JSON.stringify(options, null, 2)}) : template`,
|
||||
`const theme = ${json}`,
|
||||
`export default result as typeof theme`
|
||||
].join('\n\n')
|
||||
}
|
||||
|
||||
// For production build
|
||||
return [
|
||||
...generateVariantDeclarations(variants),
|
||||
`export default ${json}`
|
||||
@@ -149,7 +135,7 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
|
||||
templates.push({
|
||||
filename: 'types/ui.d.ts',
|
||||
getContents: () => `import * as ui from '#build/ui'
|
||||
import type { TVConfig } from '@nuxt/ui'
|
||||
import type { DeepPartial } from '@nuxt/ui'
|
||||
import type { defaultConfig } from 'tailwind-variants'
|
||||
import colors from 'tailwindcss/colors'
|
||||
|
||||
@@ -165,7 +151,7 @@ type AppConfigUI = {
|
||||
}
|
||||
icons?: Partial<typeof icons>
|
||||
tv?: typeof defaultConfig
|
||||
} & TVConfig<typeof ui>
|
||||
} & DeepPartial<typeof ui>
|
||||
|
||||
declare module '@nuxt/schema' {
|
||||
interface AppConfigInput {
|
||||
@@ -196,6 +182,7 @@ export {}
|
||||
|
||||
export function addTemplates(options: ModuleOptions, nuxt: Nuxt, resolve: Resolver['resolve']) {
|
||||
const templates = getTemplates(options, nuxt.options.appConfig.ui)
|
||||
|
||||
for (const template of templates) {
|
||||
if (template.filename!.endsWith('.d.ts')) {
|
||||
addTypeTemplate(template as NuxtTypeTemplate)
|
||||
@@ -204,6 +191,28 @@ export function addTemplates(options: ModuleOptions, nuxt: Nuxt, resolve: Resolv
|
||||
}
|
||||
}
|
||||
|
||||
// For local module development, watch changes in themes
|
||||
const isUiDev = true
|
||||
if (isUiDev) {
|
||||
nuxt.options.watch.push(resolve('./theme'))
|
||||
|
||||
nuxt.hook('builder:watch', async (event, path) => {
|
||||
await updateTemplates({
|
||||
filter: (template) => {
|
||||
if (template.filename.startsWith('ui/') && template.filename !== 'ui/index.ts') {
|
||||
const templatePath = template.filename.replace(/^ui/, 'src/theme')
|
||||
|
||||
if (path.endsWith(templatePath)) {
|
||||
console.log(`[nuxt-ui] template ${templatePath} changed`)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
nuxt.hook('prepare:types', ({ references }) => {
|
||||
references.push({ path: resolve('./runtime/types/app.config.d.ts') })
|
||||
})
|
||||
|
||||
@@ -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',
|
||||
heading: 'text-center font-medium truncate mx-auto',
|
||||
grid: 'w-full border-collapse select-none space-y-1 focus:outline-none',
|
||||
gridRow: 'grid grid-cols-7 place-items-center',
|
||||
gridRow: 'grid grid-cols-7',
|
||||
gridWeekDaysRow: 'mb-1 grid w-full grid-cols-7',
|
||||
gridBody: 'grid',
|
||||
headCell: 'rounded-md',
|
||||
|
||||
@@ -27,7 +27,7 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
separator: 'px-2 h-px bg-border',
|
||||
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]',
|
||||
content: 'absolute top-0 left-0 w-full',
|
||||
content: 'absolute top-0 left-0 w-full sm:w-auto',
|
||||
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'
|
||||
},
|
||||
|
||||
@@ -20,9 +20,9 @@ import PluginsPlugin from './plugins/plugins'
|
||||
import AppConfigPlugin from './plugins/app-config'
|
||||
import ComponentImportPlugin from './plugins/components'
|
||||
import NuxtEnvironmentPlugin from './plugins/nuxt-environment'
|
||||
import AutoImportPlugin from './plugins/auto-import'
|
||||
|
||||
import type { TVConfig } from './runtime/types/tv'
|
||||
import type { DeepPartial } from './runtime/types/utils'
|
||||
import AutoImportPlugin from './plugins/auto-import'
|
||||
|
||||
type NeutralColor = 'slate' | 'gray' | 'zinc' | 'neutral' | 'stone'
|
||||
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`
|
||||
colors?: Record<string, Color> & { neutral?: NeutralColor }
|
||||
icons?: Partial<typeof icons>
|
||||
} & TVConfig<typeof ui>
|
||||
} & DeepPartial<typeof ui>
|
||||
|
||||
export interface NuxtUIOptions extends Omit<ModuleOptions, 'fonts' | 'colorMode'> {
|
||||
/** 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">
|
||||
<!--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 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="">
|
||||
<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="">
|
||||
<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>
|
||||
<div class="flex flex-col items-start">
|
||||
@@ -1262,7 +1262,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
||||
</button></li>
|
||||
</ul>
|
||||
</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 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 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="">
|
||||
<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>
|
||||
<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">
|
||||
<!--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 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="">
|
||||
<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="">
|
||||
<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>
|
||||
<div class="flex flex-col items-start">
|
||||
@@ -1262,7 +1262,7 @@ exports[`NavigationMenu > renders with unmountOnHide correctly 1`] = `
|
||||
</button></li>
|
||||
</ul>
|
||||
</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 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 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="">
|
||||
<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>
|
||||
<div class="flex flex-col items-start">
|
||||
|
||||
Reference in New Issue
Block a user