Compare commits

...

43 Commits

Author SHA1 Message Date
Benjamin Canac
b654c93e93 chore(release): v2.20.0 2024-12-09 12:30:42 +01:00
renovate[bot]
b7e04db645 chore(deps): lock file maintenance (dev) (#2862)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 10:18:14 +01:00
renovate[bot]
e6034a2765 chore(deps): update pnpm to v9.15.0 (dev) (#2847)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 10:17:34 +01:00
renovate[bot]
a8c38224c6 chore(deps): update devdependency @nuxt/test-utils to ^3.15.1 (dev) (#2838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-07 00:55:49 +01:00
renovate[bot]
a9ef6406ea chore(deps): update all non-major dependencies (dev) (#2819)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 12:59:41 +01:00
renovate[bot]
96e846ddee chore(deps): update dependency tailwindcss to ^3.4.16 (dev) (#2830)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 13:41:45 +01:00
Benjamin Canac
16dbc1b536 docs(app): remove banner 2024-12-03 10:54:25 +01:00
Benjamin Canac
c6b2ae45e5 docs(Header): hide color mode button on mobile 2024-12-03 10:54:19 +01:00
renovate[bot]
547c657ee7 chore(deps): lock file maintenance (dev) (#2817)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 11:18:30 +01:00
renovate[bot]
b16b434041 chore(deps): update all non-major dependencies (dev) (#2756)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2024-12-02 10:56:20 +01:00
Benjamin Canac
fb12323304 docs(Header): move dropdown out of link 2024-11-30 11:48:03 +01:00
Benjamin Canac
0a404615ff docs(Header): replace badge by dropdown 2024-11-30 11:33:09 +01:00
renovate[bot]
cbf0f22efd chore(deps): update vueuse monorepo to v12 (dev) (major) (#2783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-27 12:11:47 +01:00
Sandro Circi
4cde571e38 fix(Link): exactQuery prop type (#2781) 2024-11-27 09:47:39 +01:00
Benjamin Canac
023497d144 chore(README): update 2024-11-26 15:18:27 +01:00
Benjamin Canac
56d4ca3b74 docs(Header): update GitHub link 2024-11-26 15:09:10 +01:00
Harsh Patel
11b8c3d9db feat(Notification): add pauseTimeoutOnHover prop (#2661) 2024-11-25 22:09:40 +01:00
Hans Knöchel
419a24f703 feat(Accordion): add close event (#2750) 2024-11-25 14:58:30 +01:00
renovate[bot]
854bb81295 chore(deps): lock file maintenance (dev) (#2751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2024-11-25 12:54:17 +01:00
Benjamin Canac
bf8e3954a4 docs(Banner): update for black friday 2024-11-25 12:26:31 +01:00
renovate[bot]
637ec4d27b chore(deps): update all non-major dependencies (dev) (#2704)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-25 11:27:00 +01:00
kyyy
f3632ddee5 fix(Form)!: resolve async validation in yup & issue directly mutate state (#2701) 2024-11-23 19:29:54 +01:00
Jevin
dbd2aed20b docs(table): columns select is obscured (#2714) 2024-11-21 11:19:37 +01:00
Giorgio Boa
51c8b8e3e5 fix(components): replace as const with correct type in config (#2652)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2024-11-20 10:54:37 +01:00
renovate[bot]
588a908358 chore(deps): update all non-major dependencies (dev) (#2693)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 10:21:06 +01:00
renovate[bot]
d692a81b1e chore(deps): update nuxt framework to ^3.14.1592 (dev) (#2699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 09:52:12 +01:00
Daniel Roe
ec98d415b4 docs: remove local module from list (#2690) 2024-11-19 18:24:40 +01:00
renovate[bot]
c80d2e6c12 chore(deps): lock file maintenance (dev) (#2671)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 11:40:14 +01:00
renovate[bot]
ce61a2b6db chore(deps): update all non-major dependencies (dev) (#2641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 10:50:58 +01:00
Benjamin Canac
eee5bb9939 chore(deps): set chokidar resolution 2024-11-18 09:35:35 +01:00
Benjamin Canac
d3804157ec docs(input): correct loading behavior
Resolves nuxt/ui#2669
2024-11-18 09:35:23 +01:00
Sandro Circi
03e24f4583 feat(Link): allow partial query match for activeClass (#2663) 2024-11-17 12:15:22 +01:00
jcahal
d0e626c551 docs(table): correct spelling of contextmenu right-clickable (#2653) 2024-11-15 17:32:37 +01:00
renovate[bot]
670d8bfbac chore(deps): update dependency tailwindcss to ^3.4.15 (dev) (#2648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-15 09:47:28 +01:00
renovate[bot]
64b703df8d chore(deps): update dependency @nuxt/icon to ^1.7.5 (dev) (#2638)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-14 16:45:31 +01:00
Julien Blatecky
976b03f241 fix(types): improve DeepPartial type for App Config (#2621) 2024-11-14 10:33:26 +01:00
renovate[bot]
35e3b8c720 chore(deps): update all non-major dependencies (dev) (#2628)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-14 10:16:36 +01:00
Benjamin Canac
07ef771b17 fix(Carousel): wrong ui type with strategy 2024-11-13 21:02:00 +01:00
Maxime Pauvert
5c75b5c490 docs(Banner): wrong aria label (#2632) 2024-11-13 17:53:50 +01:00
kyyy
53df9d9a8c feat(InputMenu/SelectMenu): add support for dot notation in by prop (#2607) 2024-11-13 12:25:31 +01:00
Malik-Jouda
0d1a76e3c6 feat(Badge): handle icon prop (#2594)
Co-authored-by: malik jouda <m.jouda@approved.tech>
2024-11-12 16:16:20 +01:00
renovate[bot]
b2ed4662af chore(deps): update devdependency @release-it/conventional-changelog to ^9.0.3 (dev) (#2604)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-12 16:07:30 +01:00
Benjamin Canac
423c48879d chore(github): update issue templates 2024-11-12 13:11:09 +01:00
45 changed files with 2425 additions and 2380 deletions

View File

@@ -29,11 +29,20 @@ body:
- Build Modules: `-`
validations:
required: true
- type: dropdown
id: package
attributes:
label: Is this bug related to Nuxt or Vue?
options:
- Nuxt
- Vue
validations:
required: true
- type: input
id: version
attributes:
label: Version
placeholder: v3.0.0-alpha.5
placeholder: v3.0.0-alpha.x
validations:
required: true
- type: textarea

View File

@@ -12,7 +12,7 @@ body:
label: For what version of Nuxt UI are you suggesting this?
options:
- v2.x
- v3-alpha
- v3.0.0-alpha.x
validations:
required: true
- type: textarea

View File

@@ -12,7 +12,7 @@ body:
label: For what version of Nuxt UI are you asking this question?
options:
- v2.x
- v3-alpha
- v3.0.0-alpha.x
validations:
required: true
- type: textarea

View File

@@ -1,5 +1,38 @@
# Changelog
## [2.20.0](https://github.com/nuxt/ui/compare/v2.19.2...v2.20.0) (2024-12-09)
### ⚠ BREAKING CHANGES
* **Form:** resolve async validation in yup & issue directly mutate state (#2701)
### Features
* **Accordion:** add `close` event ([#2750](https://github.com/nuxt/ui/issues/2750)) ([419a24f](https://github.com/nuxt/ui/commit/419a24f7034cefda2c6669f3c26742552e500f63))
* **Badge:** handle `icon` prop ([#2594](https://github.com/nuxt/ui/issues/2594)) ([0d1a76e](https://github.com/nuxt/ui/commit/0d1a76e3c69e08534abb295b96548e67cfbea00c))
* **InputMenu/SelectMenu:** add support for `dot notation` in `by` prop ([#2607](https://github.com/nuxt/ui/issues/2607)) ([53df9d9](https://github.com/nuxt/ui/commit/53df9d9a8cd6850803bdafc7ef6efe4e7404d334))
* **Link:** allow partial query match for `activeClass` ([#2663](https://github.com/nuxt/ui/issues/2663)) ([03e24f4](https://github.com/nuxt/ui/commit/03e24f45836bdddd94b30cbaecc2288a78b56b0b))
* **Notification:** add `pauseTimeoutOnHover` prop ([#2661](https://github.com/nuxt/ui/issues/2661)) ([11b8c3d](https://github.com/nuxt/ui/commit/11b8c3d9db1ec62b1c3557703c7ab5c99cb42df5))
* **Table:** add contextmenu handling to table rows ([#2283](https://github.com/nuxt/ui/issues/2283)) ([c9e6256](https://github.com/nuxt/ui/commit/c9e6256e7f2c06da8bfda13700f56f6994e76eab))
* **Table:** add custom `[@select](https://github.com/select):all` event ([#2581](https://github.com/nuxt/ui/issues/2581)) ([ac323c4](https://github.com/nuxt/ui/commit/ac323c4cccd930f2cd8c1f54b325bd509acd40bf))
* **Table:** allow dynamically render `checkbox` ([#2549](https://github.com/nuxt/ui/issues/2549)) ([d6daf46](https://github.com/nuxt/ui/commit/d6daf466ace42b828151c45b18cd47179e85d66d))
### Bug Fixes
* **AvatarGroup/ButtonGroup/MeterGroup:** allow deeply partial `ui` config ([#2542](https://github.com/nuxt/ui/issues/2542)) ([bf58086](https://github.com/nuxt/ui/commit/bf580863af11d6a1a4c6c6774b44ec37b082e933))
* **Carousel:** wrong `ui` type with `strategy` ([07ef771](https://github.com/nuxt/ui/commit/07ef771b17c72e275508a273371454a5e8a62257))
* **components:** replace `as const` with correct type in config ([#2652](https://github.com/nuxt/ui/issues/2652)) ([51c8b8e](https://github.com/nuxt/ui/commit/51c8b8e3e59d7eceff72625650a199fcf7c6feca))
* **date-picker:** undefined `dayIndex` ([#2545](https://github.com/nuxt/ui/issues/2545)) ([ce955d2](https://github.com/nuxt/ui/commit/ce955d24f1dfd222e87ce88428c0612c3f13cd50))
* **Form:** resolve async validation in yup & issue directly mutate state ([#2701](https://github.com/nuxt/ui/issues/2701)) ([f3632dd](https://github.com/nuxt/ui/commit/f3632ddee511f0fccb24d4fc37403421e84ffdae))
* **Form:** use parsed value from `joi` instead of original state ([#2587](https://github.com/nuxt/ui/issues/2587)) ([acecff4](https://github.com/nuxt/ui/commit/acecff40ec0156e45b4934c5d10c4dfa7c135f8e))
* **InputMenu/SelectMenu:** use `by` prop to compare objects & support dot notation in `value-attribute` ([#2566](https://github.com/nuxt/ui/issues/2566)) ([7154254](https://github.com/nuxt/ui/commit/7154254ac22830f651ec200f7f3af2f5577f2de0))
* **Link:** `exactQuery` prop type ([#2781](https://github.com/nuxt/ui/issues/2781)) ([4cde571](https://github.com/nuxt/ui/commit/4cde571e387775a9b12759f6f8c99117c84cbcff))
* **Notification:** element renders even when no `notification` is present ([#2561](https://github.com/nuxt/ui/issues/2561)) ([d4e408c](https://github.com/nuxt/ui/commit/d4e408cfd8e2ef26021519f2f30f57e9120e1939))
* **Table:** data outdated when rows change ([#2600](https://github.com/nuxt/ui/issues/2600)) ([b23f2de](https://github.com/nuxt/ui/commit/b23f2decfc9607555a315d0d087d0a042f03a938))
* **Table:** missing type on props `loadingState` ([#2551](https://github.com/nuxt/ui/issues/2551)) ([6e66990](https://github.com/nuxt/ui/commit/6e66990372ef6bd7c109a64c753d9b50e96a450b))
* **Table:** prevent `onClick` while blocking element ([#2592](https://github.com/nuxt/ui/issues/2592)) ([9703786](https://github.com/nuxt/ui/commit/97037864b39749db228fa5f51981f19e4a9c29dd))
* **types:** improve `DeepPartial` type for App Config ([#2621](https://github.com/nuxt/ui/issues/2621)) ([976b03f](https://github.com/nuxt/ui/commit/976b03f241ef9626a6338685e43c844a8b3953fd))
## [2.19.2](https://github.com/nuxt/ui/compare/v2.19.1...v2.19.2) (2024-11-05)
### Bug Fixes

View File

@@ -1,4 +1,4 @@
[![nuxt-ui.png](https://repository-images.githubusercontent.com/428329515/43fec891-9030-4601-8233-5d45ba5c6013)](https://ui.nuxt.com)
[![nuxt-ui.png](https://volta.s3.fr-par.scw.cloud/nuxt_ui_social_card_531d133fa2.png)](https://ui.nuxt.com)
# Nuxt UI

View File

@@ -3,7 +3,7 @@
<div>
<NuxtLoadingIndicator />
<Banner v-if="!$route.path.startsWith('/examples')" />
<!-- <Banner v-if="!$route.path.startsWith('/examples')" /> -->
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
const id = 'nuxt-ui-banner-2'
const to = 'https://ui3.nuxt.dev'
const id = 'nuxt-ui-banner-3'
const to = '/pro/pricing'
const hideBanner = () => {
localStorage.setItem(id, 'true')
@@ -28,9 +28,8 @@ if (import.meta.server) {
<NuxtLink
v-if="to"
:to="to"
target="_blank"
class="focus:outline-none"
aria-label="Nuxt UI Pro pricing"
aria-label="20% off on all Nuxt UI Pro products for Black Friday week"
tabindex="-1"
>
<span class="absolute inset-0 " aria-hidden="true" />
@@ -40,19 +39,19 @@ if (import.meta.server) {
<div class="lg:flex-1 hidden lg:flex items-center" />
<p class="text-sm font-medium text-white dark:text-gray-900 truncate">
<UIcon name="i-heroicons-rocket-launch" class="w-5 h-5 align-top flex-shrink-0 pointer-events-none mr-2" />
<span class="font-semibold">Nuxt UI v3-alpha</span> has been released!
<UIcon name="i-ri-discount-percent-fill" class="size-5 align-top flex-shrink-0 pointer-events-none mr-2" />
<span class="font-bold">Black Friday Week</span>: <UBadge label="20% off" color="white" class="ring-0 font-semibold" /> on all Nuxt UI Pro products from <span class="font-semibold">Nov 25</span> to <span class="font-semibold">Dec 2</span>!
</p>
<UButton
to="https://ui3.nuxt.dev"
<!-- <UButton
:to="to"
target="_blank"
label="Try it out"
label="Buy now"
color="black"
variant="solid"
size="2xs"
trailing-icon="i-heroicons-arrow-right-20-solid"
/>
/> -->
<div class="flex items-center justify-end lg:flex-1">
<button

View File

@@ -10,12 +10,34 @@
}"
>
<template #left>
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-gray-900 dark:text-white min-w-0" aria-label="Nuxt UI">
<NuxtLink to="/" class="flex items-end gap-2 text-xl text-gray-900 dark:text-white min-w-0 shrink-0" aria-label="Nuxt UI">
<LogoPro v-if="$route.path.startsWith('/pro')" class="w-auto h-6 shrink-0" />
<Logo v-else class="w-auto h-6 shrink-0" />
<UBadge :label="$route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`" variant="subtle" size="xs" class="-mb-[2px] rounded font-semibold truncate hidden sm:inline-flex" />
</NuxtLink>
<UDropdown
:items="[[{ label: $route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`, class: 'text-primary-500 dark:text-primary-400' }, { label: 'v3.0.0-alpha.x', to: 'https://ui3.nuxt.dev' }]]"
:popper="{ strategy: 'absolute', offsetDistance: 11, placement: 'bottom-start' }"
:ui="{
background: 'dark:bg-gray-900',
ring: 'dark:ring-gray-800',
width: 'w-auto',
item: {
padding: 'p-1',
size: 'text-xs',
active: 'dark:bg-gray-800/50'
}
}"
>
<UButton
:label="$route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`"
trailing-icon="i-lucide-chevron-down"
variant="outline"
size="2xs"
truncate
class="-mb-[6px] font-semibold rounded-full truncate ring-primary-500/25 dark:ring-primary-400/25 bg-primary-500/10 dark:bg-primary-400/10 hover:bg-primary-500/15 dark:hover:bg-primary-400/15 transition-colors"
/>
</UDropdown>
</template>
<template #right>
@@ -25,10 +47,10 @@
<UContentSearchButton :label="null" />
</UTooltip>
<UColorModeButton />
<UColorModeButton class="hidden lg:inline-flex" />
<UButton
to="https://github.com/nuxt/ui"
to="https://github.com/nuxt/ui/tree/dev"
target="_blank"
icon="i-simple-icons-github"
aria-label="GitHub"

View File

@@ -45,7 +45,7 @@ const ui = {
inactive: 'text-gray-400 dark:text-gray-500'
},
avatar: {
size: '2xs' as const
size: '2xs'
}
}
}

View File

@@ -141,6 +141,74 @@ Badge
You can customize the whole [preset](#preset) by using the `ui` prop.
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position.
::component-card
---
props:
icon: 'i-heroicons-rocket-launch'
size: 'sm'
color: 'primary'
variant: 'solid'
label: Badge
trailing: false
options:
- name: variant
restriction: only
values:
- solid
excludedProps:
- icon
- label
---
::
## Slots
### `leading`
Use the `#leading` slot to set the content of the leading icon.
::component-card
---
slots:
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
baseProps:
color: 'gray'
props:
label: Badge
color: 'gray'
excludedProps:
- color
---
#leading
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs"}
::
### `trailing`
Use the `#trailing` slot to set the content of the trailing icon.
::component-card
---
slots:
trailing: <UIcon name="i-heroicons-rocket-launch" class="w-4 h-4" />
props:
label: Badge
color: 'gray'
excludedProps:
- color
---
#trailing
:u-icon{name="i-heroicons-rocket-launch" class="w-4 h-4"}
::
## Props
:component-props

View File

@@ -142,7 +142,7 @@ props:
### Loading
Use the `loading` prop to show a loading icon and disable the Input.
Use the `loading` prop to show a loading icon in the Input.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.input.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.

View File

@@ -14,6 +14,7 @@ The Link component is a wrapper around [`<NuxtLink>`](https://nuxt.com/docs/api/
- `inactive-class` prop to set a class when the link is inactive, `active-class` is used when active.
- `exact` prop to style with `active-class` when the link is active and the route is exactly the same as the current route.
- `exact-query` and `exact-hash` props to style with `active-class` when the link is active and the query or hash is exactly the same as the current query or hash.
- use `exact-query="partial"` to style with `active-class` when the link is active and the query partially match the current query.
The incentive behind this is to provide the same API as NuxtLink back in Nuxt 2 / Vue 2. You can read more about it in the Vue Router [migration from Vue 2](https://router.vuejs.org/guide/migration/#removal-of-the-exact-prop-in-router-link) guide.

View File

@@ -137,9 +137,9 @@ excludedProps:
### Timeout
Use the `timeout` prop to configure how long the Notification will remain. The default value is `5000`, set it to `0` to disable the timeout.
Use the `timeout` prop to configure how long the Notification will remain. The default value is `5000`, set it to `0` to disable the timeout. The `pauseTimeoutOnHover` prop (`true` by default) controls whether hovering the notification should pause the timeout.
You will see a progress bar at the bottom of the Notification which will indicate the remaining time. When hovering the Notification, the progress bar will be paused.
You will see a progress bar at the bottom of the Notification which will indicate the remaining time. When hovering the Notification, the progress bar will be paused if `pauseTimeoutOnHover` is enabled; otherwise, it won't stop.
::component-card
---
@@ -149,6 +149,7 @@ baseProps:
description: 'This is a notification.'
props:
timeout: 60000
pauseTimeoutOnHover: true
---
::

View File

@@ -62,7 +62,7 @@ extraClass: 'overflow-hidden'
padding: false
component: 'table-example-columns-selectable'
componentProps:
class: 'flex-1 flex-col overflow-hidden'
class: 'flex-1 flex-col overflow-hidden min-h-[230px]'
---
::
@@ -346,7 +346,7 @@ componentProps:
### Contextmenu
Use the `contextmenu` listener on your Table to make the rows righ-clickable. The function will receive the original event as the first argument and the row as the second argument.
Use the `contextmenu` listener on your Table to make the rows right-clickable. The function will receive the original event as the first argument and the row as the second argument.
You can use this to open a [ContextMenu](/components/context-menu) for that row.

View File

@@ -27,8 +27,7 @@ export default defineNuxtConfig({
'@nuxtjs/plausible',
'@vueuse/nuxt',
'nuxt-component-meta',
'nuxt-cloudflare-analytics',
'modules/content-examples-code'
'nuxt-cloudflare-analytics'
],
site: {

View File

@@ -4,27 +4,27 @@
"type": "module",
"dependencies": {
"@iconify-json/heroicons": "^1.2.1",
"@iconify-json/simple-icons": "^1.2.11",
"@iconify-json/vscode-icons": "^1.2.2",
"@iconify-json/simple-icons": "^1.2.14",
"@iconify-json/vscode-icons": "^1.2.3",
"@nuxt/content": "^2.13.4",
"@nuxt/fonts": "^0.10.2",
"@nuxt/fonts": "^0.10.3",
"@nuxt/image": "^1.8.1",
"@nuxt/ui": "latest",
"@nuxt/ui-pro": "^1.5.0",
"@nuxtjs/plausible": "^1.0.3",
"@nuxtjs/plausible": "^1.2.0",
"@octokit/rest": "^21.0.2",
"@vueuse/nuxt": "^11.2.0",
"@vueuse/nuxt": "^12.0.0",
"date-fns": "^4.1.0",
"joi": "^17.13.3",
"nuxt": "^3.14.159",
"nuxt": "^3.14.1592",
"nuxt-cloudflare-analytics": "^1.0.8",
"nuxt-component-meta": "^0.9.0",
"nuxt-og-image": "^3.0.8",
"prettier": "^3.3.3",
"nuxt-og-image": "^3.1.1",
"prettier": "^3.4.2",
"ufo": "^1.5.4",
"v-calendar": "^3.1.2",
"valibot": "^0.42.1",
"yup": "^1.4.0",
"yup": "^1.5.0",
"zod": "^3.23.8"
}
}

View File

@@ -1,8 +1,8 @@
{
"name": "@nuxt/ui",
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
"version": "2.19.2",
"packageManager": "pnpm@9.12.3",
"version": "2.20.0",
"packageManager": "pnpm@9.15.0",
"repository": "nuxt/ui",
"homepage": "https://ui.nuxt.com",
"type": "module",
@@ -35,8 +35,8 @@
"@headlessui/tailwindcss": "^0.2.1",
"@headlessui/vue": "^1.7.23",
"@iconify-json/heroicons": "^1.2.1",
"@nuxt/icon": "^1.7.2",
"@nuxt/kit": "^3.14.159",
"@nuxt/icon": "^1.9.1",
"@nuxt/kit": "^3.14.1592",
"@nuxtjs/color-mode": "^3.5.2",
"@nuxtjs/tailwindcss": "^6.12.2",
"@popperjs/core": "^2.11.8",
@@ -44,44 +44,45 @@
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@vueuse/core": "^11.2.0",
"@vueuse/integrations": "^11.2.0",
"@vueuse/math": "^11.2.0",
"@vueuse/core": "^12.0.0",
"@vueuse/integrations": "^12.0.0",
"@vueuse/math": "^12.0.0",
"defu": "^6.1.4",
"fuse.js": "^7.0.0",
"ohash": "^1.1.4",
"pathe": "^1.1.2",
"scule": "^1.3.0",
"tailwind-merge": "^2.5.4",
"tailwindcss": "^3.4.14"
"tailwind-merge": "^2.5.5",
"tailwindcss": "^3.4.16"
},
"devDependencies": {
"@nuxt/eslint-config": "^0.6.1",
"@nuxt/eslint-config": "^0.7.2",
"@nuxt/module-builder": "^0.8.4",
"@nuxt/test-utils": "^3.14.4",
"@release-it/conventional-changelog": "^9.0.2",
"@nuxt/test-utils": "^3.15.1",
"@release-it/conventional-changelog": "^9.0.3",
"@vue/test-utils": "^2.4.6",
"eslint": "^9.14.0",
"eslint": "^9.16.0",
"happy-dom": "^14.12.3",
"joi": "^17.13.3",
"nuxt": "^3.14.159",
"nuxt": "^3.14.1592",
"release-it": "^17.10.0",
"superstruct": "^2.0.2",
"typescript": "^5.6.3",
"unbuild": "^2.0.0",
"valibot": "^0.42.1",
"valibot30": "npm:valibot@0.30.0",
"valibot31": "npm:valibot@0.31.0",
"vitest": "^2.1.4",
"vitest": "^2.1.8",
"vitest-environment-nuxt": "^1.0.1",
"vue-tsc": "^2.1.10",
"yup": "^1.4.0",
"yup": "^1.5.0",
"zod": "^3.23.8"
},
"resolutions": {
"@nuxt/ui": "workspace:*",
"@nuxt/content": "2.13.2",
"@nuxtjs/mdc": "0.9.0",
"nuxt": "3.13.2",
"@nuxt/kit": "3.13.2"
"chokidar": "3.6.0",
"typescript": "5.6.3"
}
}

View File

@@ -9,6 +9,6 @@
},
"dependencies": {
"@nuxt/ui": "latest",
"nuxt": "^3.14.159"
"nuxt": "^3.14.1592"
}
}

4248
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -126,7 +126,7 @@ export default defineComponent({
default: () => ({})
}
},
emits: ['open'],
emits: ['open', 'close'],
setup(props, { emit }) {
const { ui, attrs } = useUI('accordion', toRef(props, 'ui'), config, toRef(props, 'class'))
@@ -142,6 +142,8 @@ export default defineComponent({
if (!isOpenBefore && isOpenAfter) {
emit('open', index)
} else if (isOpenBefore && !isOpenAfter) {
emit('close', index)
}
}
}, { immediate: true })

View File

@@ -1,6 +1,18 @@
<template>
<span :class="badgeClass" v-bind="attrs">
<slot>{{ label }}</slot>
<slot name="leading">
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
</slot>
<slot>
<span v-if="label">
{{ label }}
</span>
</slot>
<slot name="trailing">
<UIcon v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass" aria-hidden="true" />
</slot>
</span>
</template>
@@ -8,6 +20,7 @@
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
@@ -19,6 +32,9 @@ import { badge } from '#ui/ui.config'
const config = mergeConfig<typeof badge>(appConfig.ui.strategy, appConfig.ui.badge, badge)
export default defineComponent({
components: {
UIcon
},
inheritAttrs: false,
props: {
size: {
@@ -49,6 +65,26 @@ export default defineComponent({
type: [String, Number],
default: null
},
icon: {
type: String,
default: null
},
leadingIcon: {
type: String,
default: null
},
trailingIcon: {
type: String,
default: null
},
trailing: {
type: Boolean,
default: false
},
leading: {
type: Boolean,
default: false
},
class: {
type: [String, Object, Array] as PropType<any>,
default: () => ''
@@ -63,6 +99,14 @@ export default defineComponent({
const { size, rounded } = useInjectButtonGroup({ ui, props })
const isLeading = computed(() => {
return (props.icon && props.leading) || (props.icon && !props.trailing) || !props.trailing || props.leadingIcon
})
const isTrailing = computed(() => {
return (props.icon && props.trailing) || props.trailing || props.trailingIcon
})
const badgeClass = computed(() => {
const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant]
@@ -71,13 +115,42 @@ export default defineComponent({
ui.value.font,
rounded.value,
ui.value.size[size.value],
ui.value.gap[size.value],
variant?.replaceAll('{color}', props.color)
), props.class)
})
const leadingIconName = computed(() => {
return props.leadingIcon || props.icon
})
const trailingIconName = computed(() => {
return props.trailingIcon || props.icon
})
const leadingIconClass = computed(() => {
return twJoin(
ui.value.icon.base,
ui.value.icon.size[size.value]
)
})
const trailingIconClass = computed(() => {
return twJoin(
ui.value.icon.base,
ui.value.icon.size[size.value]
)
})
return {
attrs,
badgeClass
isLeading,
isTrailing,
badgeClass,
leadingIconName,
trailingIconName,
leadingIconClass,
trailingIconClass
}
}
})

View File

@@ -106,7 +106,7 @@ export default defineComponent({
default: () => ''
},
ui: {
type: Object as PropType<DeepPartial<typeof config & { strategy?: Strategy }>>,
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
default: undefined
}
},

View File

@@ -32,8 +32,8 @@
</template>
<script lang="ts">
import { isEqual } from 'ohash'
import { defineComponent } from 'vue'
import { isEqual, diff } from 'ohash'
import { type PropType, defineComponent } from 'vue'
import { nuxtLinkProps } from '../../utils'
export default defineComponent({
@@ -61,7 +61,7 @@ export default defineComponent({
default: false
},
exactQuery: {
type: Boolean,
type: [Boolean, String] as PropType<boolean | 'partial'>,
default: false
},
exactHash: {
@@ -74,9 +74,21 @@ export default defineComponent({
}
},
setup(props) {
function isPartiallyEqual(item1, item2) {
const diffedKeys = diff(item1, item2).reduce((filtered, q) => {
if (q.type === 'added') {
filtered.push(q.key)
}
return filtered
}, [])
return isEqual(item1, item2, { excludeKeys: key => diffedKeys.includes(key) })
}
function resolveLinkClass(route, $route, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
if (props.exactQuery && !isEqual(route.query, $route.query)) {
return props.inactiveClass
if (props.exactQuery === 'partial') {
if (!isPartiallyEqual(route.query, $route.query)) return props.inactiveClass
} else if (props.exactQuery === true) {
if (!isEqual(route.query, $route.query)) return props.inactiveClass
}
if (props.exactHash && route.hash !== $route.hash) {
return props.inactiveClass

View File

@@ -60,6 +60,8 @@ export default defineComponent({
const formId = useId()
const bus = useEventBus<FormEvent>(`form-${formId}`)
const parsedValue = ref(null)
onMounted(() => {
bus.on(async (event) => {
if (event.type !== 'submit' && props.validateOn?.includes(event.type)) {
@@ -87,7 +89,7 @@ export default defineComponent({
if (errors) {
errs = errs.concat(errors)
} else {
Object.assign(props.state, result)
parsedValue.value = result
}
}
@@ -130,7 +132,7 @@ export default defineComponent({
if (props.validateOn?.includes('submit')) {
await validate()
}
event.data = props.state
event.data = props.schema ? parsedValue.value : props.state
emit('submit', event)
} catch (error) {
if (!(error instanceof FormException)) {
@@ -321,7 +323,7 @@ async function validateYupSchema(
schema: YupObjectSchema<any>
): Promise<ValidateReturnSchema<typeof state>> {
try {
const result = schema.validateSync(state, { abortEarly: false })
const result = await schema.validate(state, { abortEarly: false })
return {
errors: null,
result

View File

@@ -293,6 +293,24 @@ export default defineComponent({
const size = computed(() => sizeButtonGroup.value ?? sizeFormGroup.value)
const by = computed(() => {
if (!props.by) return undefined
if (typeof props.by === 'function') {
return props.by
}
const key = props.by
const hasDot = key.indexOf('.')
if (hasDot > 0) {
return (a: any, z: any) => {
return accessor(a, key) === accessor(z, key)
}
}
return key
})
const internalQuery = ref('')
const query = computed({
get() {
@@ -305,9 +323,7 @@ export default defineComponent({
})
const label = computed(() => {
if (!props.modelValue) {
return
}
if (!props.modelValue) return null
function getValue(value: any) {
if (props.valueAttribute) {
@@ -318,7 +334,7 @@ export default defineComponent({
}
function compareValues(value1: any, value2: any) {
if (props.by && typeof value1 === 'object' && typeof value2 === 'object') {
if (by.value && typeof by.value !== 'function' && typeof value1 === 'object' && typeof value2 === 'object') {
return isEqual(value1[props.by], value2[props.by])
}
return isEqual(value1, value2)
@@ -507,7 +523,9 @@ export default defineComponent({
query,
accessor,
onUpdate,
onQueryChange
onQueryChange,
// eslint-disable-next-line vue/no-dupe-keys
by
}
}
})

View File

@@ -348,6 +348,24 @@ export default defineComponent({
const [trigger, container] = usePopper(popper.value)
const by = computed(() => {
if (!props.by) return undefined
if (typeof props.by === 'function') {
return props.by
}
const key = props.by
const hasDot = key.indexOf('.')
if (hasDot > 0) {
return (a: any, z: any) => {
return accessor(a, key) === accessor(z, key)
}
}
return key
})
const { size: sizeButtonGroup, rounded } = useInjectButtonGroup({ ui, props })
const { emitFormBlur, emitFormChange, inputId, color, size: sizeFormGroup, name } = useFormGroup(props, config)
@@ -366,8 +384,8 @@ export default defineComponent({
const selected = computed(() => {
function compareValues(value1: any, value2: any) {
if (props.by && typeof value1 === 'object' && typeof value2 === 'object') {
return isEqual(value1[props.by], value2[props.by])
if (by.value && typeof by.value !== 'function' && typeof value1 === 'object' && typeof value2 === 'object') {
return isEqual(value1[by.value], value2[by.value])
}
return isEqual(value1, value2)
}
@@ -399,16 +417,12 @@ export default defineComponent({
})
const label = computed(() => {
if (!selected.value) return null
if (props.valueAttribute) {
return accessor(selected.value as Record<string, any>, props.optionAttribute)
}
if (!props.modelValue) return null
if (Array.isArray(props.modelValue) && props.modelValue.length) {
return `${props.modelValue.length} selected`
} else if (['string', 'number'].includes(typeof props.modelValue)) {
return props.modelValue
return props.valueAttribute ? accessor(selected.value, props.optionAttribute) : props.modelValue
}
return accessor(props.modelValue as Record<string, any>, props.optionAttribute)
@@ -612,7 +626,9 @@ export default defineComponent({
// eslint-disable-next-line vue/no-dupe-keys
query,
onUpdate,
onQueryChange
onQueryChange,
// eslint-disable-next-line vue/no-dupe-keys
by
}
}
})

View File

@@ -117,6 +117,10 @@ export default defineComponent({
ui: {
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
default: () => ({})
},
pauseTimeoutOnHover: {
type: Boolean,
default: true
}
},
emits: ['close'],
@@ -157,13 +161,13 @@ export default defineComponent({
})
function onMouseover() {
if (timer) {
if (props.pauseTimeoutOnHover && timer) {
timer.pause()
}
}
function onMouseleave() {
if (timer) {
if (props.pauseTimeoutOnHover && timer) {
timer.resume()
}
}

3
src/runtime/types/checkbox.d.ts vendored Normal file
View File

@@ -0,0 +1,3 @@
import type colors from '#ui-colors'
export type CheckboxColor = typeof colors[number]

View File

@@ -1,3 +1,3 @@
import type { divider } from '#ui/ui.config'
import type { divider } from '../ui.config'
export type DividerSize = keyof typeof divider.border.size.horizontal | keyof typeof divider.border.size.vertical

View File

@@ -4,6 +4,7 @@ export * from './avatar'
export * from './badge'
export * from './breadcrumb'
export * from './button'
export * from './checkbox'
export * from './chip'
export * from './clipboard'
export * from './command-palette'

View File

@@ -6,7 +6,7 @@ export interface Link extends NuxtLinkProps {
disabled?: boolean
active?: boolean
exact?: boolean
exactQuery?: boolean
exactQuery?: boolean | 'partial'
exactHash?: boolean
inactiveClass?: string
}

View File

@@ -7,7 +7,7 @@ export interface TightMap<O = any> {
export type DeepPartial<T, O = any> = {
[P in keyof T]?: T[P] extends object
? DeepPartial<T[P], O>
: T[P];
: T[P] extends string ? string : T[P];
} & {
[key: string]: O | TightMap<O>
}

View File

@@ -1,3 +1,5 @@
import type { ButtonColor, ButtonSize, ButtonVariant, CheckboxColor, ProgressAnimation, ProgressColor } from '../../types'
export default {
wrapper: 'relative overflow-x-auto',
base: 'min-w-full table-fixed',
@@ -51,23 +53,23 @@ export default {
icon: 'i-heroicons-arrows-up-down-20-solid',
trailing: true,
square: true,
color: 'gray' as const,
variant: 'ghost' as const,
color: 'gray' as ButtonColor,
variant: 'ghost' as ButtonVariant,
class: '-m-1.5'
},
expandButton: {
icon: 'i-heroicons-chevron-down',
color: 'gray' as const,
variant: 'ghost' as const,
size: 'xs' as const,
color: 'gray' as ButtonColor,
variant: 'ghost' as ButtonVariant,
size: 'xs' as ButtonSize,
class: '-my-1.5 align-middle'
},
checkbox: {
color: 'primary' as const
color: 'primary' as CheckboxColor
},
progress: {
color: 'primary' as const,
animation: 'carousel' as const
color: 'primary' as ProgressColor,
animation: 'carousel' as ProgressAnimation
},
loadingState: {
icon: 'i-heroicons-arrow-path-20-solid',

View File

@@ -16,7 +16,7 @@ export default {
openIcon: 'i-heroicons-chevron-down-20-solid',
closeIcon: '',
class: 'mb-1.5 w-full',
variant: 'soft' as const,
variant: 'soft',
truncate: true
}
}

View File

@@ -1,3 +1,5 @@
import type { AvatarSize, ButtonColor, ButtonSize, ButtonVariant } from '../../types'
export default {
wrapper: 'w-full relative overflow-hidden',
inner: 'w-0 flex-1',
@@ -13,7 +15,7 @@ export default {
},
avatar: {
base: 'flex-shrink-0 self-center',
size: 'md' as const
size: 'md' as AvatarSize
},
color: {
white: {
@@ -32,9 +34,9 @@ export default {
icon: null,
closeButton: null,
actionButton: {
size: 'xs' as const,
color: 'primary' as const,
variant: 'link' as const
size: 'xs' as ButtonSize,
color: 'primary' as ButtonColor,
variant: 'link' as ButtonVariant
}
}
}

View File

@@ -8,6 +8,12 @@ export default {
md: 'text-sm px-2 py-1',
lg: 'text-sm px-2.5 py-1.5'
},
gap: {
xs: 'gap-0.5',
sm: 'gap-1',
md: 'gap-1',
lg: 'gap-1.5'
},
color: {
white: {
solid: 'ring-1 ring-inset ring-gray-300 dark:ring-gray-700 text-gray-900 dark:text-white bg-white dark:bg-gray-900'
@@ -25,6 +31,15 @@ export default {
soft: 'bg-{color}-50 dark:bg-{color}-400 dark:bg-opacity-10 text-{color}-500 dark:text-{color}-400',
subtle: 'bg-{color}-50 dark:bg-{color}-400 dark:bg-opacity-10 text-{color}-500 dark:text-{color}-400 ring-1 ring-inset ring-{color}-500 dark:ring-{color}-400 ring-opacity-25 dark:ring-opacity-25'
},
icon: {
base: 'flex-shrink-0',
size: {
xs: 'h-4 w-4',
sm: 'h-4 w-4',
md: 'h-5 w-5',
lg: 'h-5 w-5'
}
},
default: {
size: 'sm',
variant: 'solid',

View File

@@ -1,3 +1,5 @@
import type { ButtonColor } from '../../types'
export default {
wrapper: 'relative',
container: 'relative w-full flex overflow-x-auto snap-x snap-mandatory scroll-smooth',
@@ -13,12 +15,12 @@ export default {
},
default: {
prevButton: {
color: 'black' as const,
color: 'black' as ButtonColor,
class: 'rtl:[&_span:first-child]:rotate-180 absolute start-4 top-1/2 transform -translate-y-1/2 rounded-full',
icon: 'i-heroicons-chevron-left-20-solid'
},
nextButton: {
color: 'black' as const,
color: 'black' as ButtonColor,
class: 'rtl:[&_span:last-child]:rotate-180 absolute end-4 top-1/2 transform -translate-y-1/2 rounded-full',
icon: 'i-heroicons-chevron-right-20-solid'
}

View File

@@ -1,3 +1,4 @@
import type { AvatarSize } from '../../types'
import { arrow } from '../popper'
export default {
@@ -28,7 +29,7 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
label: 'truncate',
shortcuts: 'hidden md:inline-flex flex-shrink-0 gap-0.5 ms-auto'

View File

@@ -1,3 +1,4 @@
import type { AvatarSize } from '../../types'
import { arrow } from '../popper'
export default {
@@ -36,7 +37,7 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
chip: {
base: 'flex-shrink-0 w-2 h-2 mx-1 rounded-full'

View File

@@ -1,3 +1,5 @@
import type { AvatarSize } from '../../types'
export default {
wrapper: {
base: 'flex items-center align-center text-center',
@@ -42,11 +44,11 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
label: 'text-sm',
default: {
size: '2xs' as const,
type: 'solid' as const
size: '2xs',
type: 'solid'
}
}

View File

@@ -1,3 +1,5 @@
import type { AvatarSize } from '../../types'
export default {
wrapper: 'flex flex-col flex-1 min-h-0 divide-y divide-gray-100 dark:divide-gray-800',
container: 'relative flex-1 overflow-y-auto divide-y divide-gray-100 dark:divide-gray-800 scroll-py-2',
@@ -46,7 +48,7 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
chip: {
base: 'flex-shrink-0 w-2 h-2 mx-1 rounded-full'

View File

@@ -1,3 +1,5 @@
import type { AvatarSize, BadgeColor, BadgeSize, BadgeVariant } from '../../types'
export default {
wrapper: 'relative w-full flex items-center justify-between',
container: 'flex items-center min-w-0',
@@ -15,12 +17,12 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
badge: {
base: 'flex-shrink-0 ms-auto relative rounded',
color: 'gray' as const,
variant: 'solid' as const,
size: 'xs' as const
color: 'gray' as BadgeColor,
variant: 'solid' as BadgeVariant,
size: 'xs' as BadgeSize
}
}

View File

@@ -1,3 +1,5 @@
import type { ButtonColor } from '../../types'
export default {
wrapper: 'flex items-center -space-x-px',
base: '',
@@ -5,28 +7,28 @@ export default {
default: {
size: 'sm',
activeButton: {
color: 'primary' as const
color: 'primary' as ButtonColor
},
inactiveButton: {
color: 'white' as const
color: 'white' as ButtonColor
},
firstButton: {
color: 'white' as const,
color: 'white' as ButtonColor,
class: 'rtl:[&_span:first-child]:rotate-180',
icon: 'i-heroicons-chevron-double-left-20-solid'
},
lastButton: {
color: 'white' as const,
color: 'white' as ButtonColor,
class: 'rtl:[&_span:last-child]:rotate-180',
icon: 'i-heroicons-chevron-double-right-20-solid'
},
prevButton: {
color: 'white' as const,
color: 'white' as ButtonColor,
class: 'rtl:[&_span:first-child]:rotate-180',
icon: 'i-heroicons-chevron-left-20-solid'
},
nextButton: {
color: 'white' as const,
color: 'white' as ButtonColor,
class: 'rtl:[&_span:last-child]:rotate-180',
icon: 'i-heroicons-chevron-right-20-solid'
}

View File

@@ -1,3 +1,5 @@
import type { AvatarSize, BadgeColor, BadgeSize, BadgeVariant } from '../../types'
export default {
wrapper: 'relative',
base: 'group relative flex items-center gap-1.5 focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-1 focus-visible:before:ring-primary-500 dark:focus-visible:before:ring-primary-400 before:absolute before:inset-px before:rounded-md disabled:cursor-not-allowed disabled:opacity-75',
@@ -17,13 +19,13 @@ export default {
},
avatar: {
base: 'flex-shrink-0',
size: '2xs' as const
size: '2xs' as AvatarSize
},
badge: {
base: 'flex-shrink-0 ms-auto relative rounded',
color: 'gray' as const,
variant: 'solid' as const,
size: 'xs' as const
color: 'gray' as BadgeColor,
variant: 'solid' as BadgeVariant,
size: 'xs' as BadgeSize
},
divider: {
wrapper: {

View File

@@ -1,3 +1,5 @@
import type { AvatarSize, ButtonColor, ButtonSize, ButtonVariant } from '../../types'
export default {
wrapper: 'w-full pointer-events-auto',
container: 'relative overflow-hidden',
@@ -17,7 +19,7 @@ export default {
},
avatar: {
base: 'flex-shrink-0 self-center',
size: 'md' as const
size: 'md' as AvatarSize
},
progress: {
base: 'absolute bottom-0 end-0 start-0 h-1',
@@ -38,13 +40,13 @@ export default {
timeout: 5000,
closeButton: {
icon: 'i-heroicons-x-mark-20-solid',
color: 'gray' as const,
variant: 'link' as const,
color: 'gray' as ButtonColor,
variant: 'link' as ButtonVariant,
padded: false
},
actionButton: {
size: 'xs' as const,
color: 'white' as const
size: 'xs' as ButtonSize,
color: 'white' as ButtonColor
}
}
}