Compare commits

..

101 Commits

Author SHA1 Message Date
Benjamin Canac
e487f2e877 chore(release): v3.0.0-alpha.5 2024-10-02 15:58:14 +02:00
Benjamin Canac
7addc2f70d docs(getting-started): improve faq 2024-10-02 15:57:02 +02:00
Benjamin Canac
0986f5e4b7 docs(Header): display color mode button 2024-10-02 15:57:02 +02:00
Benjamin Canac
077a9210db docs(getting-started): display color-mode page 2024-10-02 15:57:02 +02:00
Benjamin Canac
9dcf903926 feat(module): enable @nuxtjs/color-mode 2024-10-02 15:57:01 +02:00
Benjamin Canac
0f86b87385 feat(module): override dark variant with class strategy 2024-10-02 15:57:01 +02:00
Sébastien Chopin
c9a2631bc3 docs: update link to downloads count badge 2024-10-02 15:53:47 +02:00
Benjamin Canac
1518d0024f chore(README): invalid documentation url 2024-10-02 14:21:54 +02:00
Benjamin Canac
421a193d20 docs(nuxt.config): invalid site.url 2024-10-02 14:21:45 +02:00
Sébastien Chopin
dd54abf243 docs: update GitHub link to v3 branch 2024-10-02 12:45:47 +02:00
Benjamin Canac
c837ca5cc0 docs(getting-started): describe Tailwind CSS @source and @plugin 2024-10-02 12:25:01 +02:00
Benjamin Canac
66a04add91 fix(Button): props specified more than once 2024-10-01 15:31:18 +02:00
Benjamin Canac
a5153d6c8d docs(deps): update @nuxt/ui-pro 2024-10-01 15:24:37 +02:00
Benjamin Canac
cc6db6f14b chore(release): v3.0.0-alpha.4 2024-10-01 15:05:23 +02:00
Benjamin Canac
1f9abdae61 fix(Toast): improve focus styles 2024-10-01 14:50:27 +02:00
Benjamin Canac
f54f607413 fix(build.config): disable mkdist addRelativeDeclarationExtensions option 2024-10-01 14:41:19 +02:00
Benjamin Canac
08db1c68b3 docs(command-palette): update 2024-10-01 11:43:47 +02:00
Benjamin Canac
725833c4a9 cli: fix paths 2024-10-01 11:43:34 +02:00
Benjamin Canac
6a6c43378b chore(CHANGELOG): update from dev 2024-09-30 14:36:51 +02:00
Benjamin Canac
10ab4ce06d docs(composables): clean 2024-09-30 14:33:07 +02:00
Benjamin Canac
afd9b8f2b9 docs(command-palette): use index in example to prevent ts error for now 2024-09-30 14:30:42 +02:00
Benjamin Canac
6aac821e80 docs(roadmap): invalid appConfig access 2024-09-30 14:30:21 +02:00
Benjamin Canac
f4e135d07a test(Drawer): types 2024-09-30 12:48:16 +02:00
Benjamin Canac
ef4a3a09c9 docs(app): put back community links 2024-09-30 12:06:37 +02:00
Benjamin Canac
c738bd9d53 docs(composables): update 2024-09-30 12:01:35 +02:00
Benjamin Canac
aeccf30a92 docs(getting-started): update 2024-09-30 11:44:39 +02:00
Benjamin Canac
673fef1595 docs(nuxt.config): set icon.provider to iconify 2024-09-30 11:12:08 +02:00
renovate[bot]
0ed13f33b5 chore(deps): update all non-major dependencies (v3) (#2265)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 10:22:11 +02:00
Maxime Pauvert
30c33c7113 fix(README): npm badge link (#2271) 2024-09-30 09:34:26 +02:00
renovate[bot]
fd0ecc6d96 chore(deps): lock file maintenance (v3) (#2279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 09:33:49 +02:00
Benjamin Canac
6863254d89 docs(toast): update 2024-09-27 15:37:26 +02:00
Benjamin Canac
d2e075bb4a docs(ComponentExample): improve options handling 2024-09-27 15:37:15 +02:00
Benjamin Canac
6f0b7309c9 docs(drawer): update description 2024-09-27 13:08:15 +02:00
Benjamin Canac
30d9a2653b chore(Link): allow title field 2024-09-27 12:49:32 +02:00
Benjamin Canac
fac52fa933 fix(Drawer): improve max-width on mobile 2024-09-27 12:21:29 +02:00
Benjamin Canac
5f77aac368 feat(Drawer): handle direction + handle props 2024-09-27 11:44:52 +02:00
Benjamin Canac
5b62a8c8ca docs(pagination): update 2024-09-26 17:00:54 +02:00
Benjamin Canac
04a2f2b7a0 chore(Pagination): update defaults 2024-09-26 17:00:43 +02:00
Benjamin Canac
ad3dc26e41 docs(ComponentCode): fix display of false value in select 2024-09-26 16:35:54 +02:00
Benjamin Canac
fd6c1b02ea docs(ComponentCode): handle model prop for cases like v-model:page 2024-09-26 16:21:07 +02:00
Benjamin Canac
19362a9302 chore(deps): update 2024-09-26 16:18:59 +02:00
renovate[bot]
4e2b957882 chore(deps): update dependency @nuxt/fonts to ^0.9.2 (v3) (#2250)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-26 15:30:03 +02:00
Benjamin Canac
83ee05dd0e chore(renovate): update 2024-09-26 15:12:25 +02:00
Benjamin Canac
5591854ed4 docs(getting-started): update description 2024-09-26 12:04:24 +02:00
Benjamin Canac
db754740ef docs(input-menu): update 2024-09-26 12:04:12 +02:00
Benjamin Canac
2c7c41bd04 fix(InputMenu): missing group on trailing 2024-09-26 12:00:06 +02:00
Benjamin Canac
9edb23080d docs(define-shortcuts): update 2024-09-25 19:22:44 +02:00
Benjamin Canac
fb8e6a6a66 docs(select-menu): update 2024-09-25 19:07:21 +02:00
Benjamin Canac
183207c2b8 chore(SelectMenu): merge search / searchPlaceholder into searchInput prop 2024-09-25 19:07:11 +02:00
Benjamin Canac
237e7a4e0e docs(nuxt.config): move routeRules cache in $production 2024-09-25 16:56:22 +02:00
Benjamin Canac
cac41137ae docs(getting-started): update 2024-09-25 16:42:40 +02:00
Benjamin Canac
eb0756674a docs(nuxt.config): put back /api/* in cloudflare exclude 2024-09-25 12:34:01 +02:00
Benjamin Canac
9cb863bc21 docs(nuxt.config): remove /api/* in cloudflare exclude 2024-09-25 12:25:27 +02:00
Benjamin Canac
9125a2d467 docs(nuxt.config): try icon serverBundle to remote 2024-09-25 12:19:28 +02:00
Benjamin Canac
0297361319 docs(nuxt.config): update icon options 2024-09-25 12:06:29 +02:00
Sébastien Chopin
749bf90dd1 docs: add auto sub folder 2024-09-25 11:36:05 +02:00
Benjamin Canac
d283887407 docs(nuxt.config): remove experimental.buildCache 2024-09-25 11:07:01 +02:00
Benjamin Canac
d7e46e3637 docs(nuxt.config): remove og-image from cloudflare option 2024-09-25 10:54:41 +02:00
Pooya Parsa
713021f12d docs: enable crawlLinks with exclude patterns (#2246) 2024-09-25 10:44:24 +02:00
Benjamin Canac
1aff74e985 docs(app): update title template 2024-09-25 10:44:05 +02:00
Benjamin Canac
5b3cda741c docs(Header): responsive 2024-09-24 23:10:24 +02:00
Benjamin Canac
a61e7656c2 fix(CommandPalette): missing min-w-0 on root 2024-09-24 23:06:02 +02:00
Benjamin Canac
85b21381e8 docs(app): update loading indicator color 2024-09-24 22:58:34 +02:00
Benjamin Canac
44b98bc7c9 docs(app): use navigation?.title in metas 2024-09-24 22:58:23 +02:00
Benjamin Canac
6c285977bd fix(Accordion): missing min-w-0 on trigger 2024-09-24 22:14:04 +02:00
Benjamin Canac
4c39fa8b0f docs(nuxt.config): add cache 2024-09-24 18:47:13 +02:00
Benjamin Canac
e584941df9 docs: add @nuxthub/core module 2024-09-24 18:28:01 +02:00
Benjamin Canac
991e725b1a docs(nuxt.config): try without crawLinks 2024-09-24 18:16:03 +02:00
Benjamin Canac
b638521ffa docs(public): remove illustrations 2024-09-24 18:08:02 +02:00
Benjamin Canac
2ec978ed0d docs(getting-started): use Public sans to prevent bundle of Inter 2024-09-24 18:02:23 +02:00
Benjamin Canac
b7f9422091 docs: make generate work 2024-09-24 17:53:21 +02:00
Benjamin Canac
d921b764de docs(ComponentCode/ComponentExample): wrong border on light mode 2024-09-24 14:58:40 +02:00
Benjamin Canac
b83ecc9a6f Revert "chore(deps): refresh lock"
This reverts commit cfe4e0bd65.
2024-09-24 14:47:31 +02:00
Benjamin Canac
40f1161b04 docs(app): update font 2024-09-24 14:43:45 +02:00
Benjamin Canac
d419f0a9cb playground(app): update font 2024-09-24 14:43:35 +02:00
Benjamin Canac
7bd06ecfd9 docs(prettier): format in worker like on ssr 2024-09-24 14:43:19 +02:00
Benjamin Canac
cac33c87b2 chore(InputMenu/SelectMenu): handle item select 2024-09-24 14:42:40 +02:00
Benjamin Canac
5e55e15ddf chore(InputMenu/Progress/SelectMenu): clean interfaces for syntax highlight 2024-09-24 14:42:40 +02:00
Benjamin Canac
09d453b5cf docs(ComponentCode/ComponentExample): use justify-center everywhere 2024-09-23 17:16:34 +02:00
Benjamin Canac
4f5a8ee4f6 docs(installation): fix theme.colors option example 2024-09-23 17:14:14 +02:00
Benjamin Canac
cfe4e0bd65 chore(deps): refresh lock 2024-09-23 11:59:32 +02:00
renovate[bot]
1932aa2671 chore(deps): update all non-major dependencies (v3) (#2230)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 11:45:16 +02:00
Anthony Fu
cc8fa471e9 chore: replace dev time flag for build (#2231)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2024-09-23 11:00:51 +02:00
Benjamin Canac
19bfc36976 test(Input): add missing file type 2024-09-23 10:52:02 +02:00
Benjamin Canac
7d754c0015 chore(components): add newline before script to correct syntax highlight 2024-09-20 23:20:39 +02:00
Benjamin Canac
8709717a32 docs(command-palette): update 2024-09-20 18:45:52 +02:00
Benjamin Canac
32ac575d56 chore(README): update 2024-09-20 17:54:30 +02:00
Benjamin Canac
c39996c0fe docs(app): increase container size 2024-09-20 15:39:47 +02:00
renovate[bot]
235f1cc330 chore(deps): update all non-major dependencies (v3) (#2219)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
2024-09-20 14:16:59 +02:00
Benjamin Canac
f45b39937b docs(command-palette): update 2024-09-18 17:32:01 +02:00
Benjamin Canac
a70ba04fc3 chore(Alert): rename close event to update:open for consistency 2024-09-18 17:31:42 +02:00
Benjamin Canac
500b4727e8 docs(ComponentExample): update 2024-09-18 15:00:23 +02:00
Benjamin Canac
d36576b1fe chore(module): gray now defaults to slate 2024-09-18 12:21:50 +02:00
Benjamin Canac
6498f8a0c1 test: move colors into theme.colors 2024-09-18 12:20:12 +02:00
Benjamin Canac
96c9246d83 fix(templates): app config colors type 2024-09-18 12:19:46 +02:00
Benjamin Canac
e45398f6ce docs(playground): update theme 2024-09-18 12:14:33 +02:00
Benjamin Canac
a32d2c034a docs(app): update theme 2024-09-18 12:14:23 +02:00
Benjamin Canac
f52310d4a1 docs(deps): use @nuxt/ui-pro 2024-09-18 11:33:56 +02:00
Benjamin Canac
a6ae1dcb1d chore(release): v3.0.0-alpha.3 2024-09-18 11:31:39 +02:00
Benjamin Canac
2e954467c4 feat(module): move colors options into theme.colors 2024-09-18 11:28:31 +02:00
Benjamin Canac
d3317d828e docs: use shiki-transformer-color-highlight (#2215) 2024-09-18 10:54:59 +02:00
197 changed files with 8401 additions and 4652 deletions

View File

@@ -1,5 +1,49 @@
# Changelog
## [3.0.0-alpha.5](https://github.com/nuxt/ui/compare/v3.0.0-alpha.4...v3.0.0-alpha.5) (2024-10-02)
### Features
* **module:** enable `@nuxtjs/color-mode` ([9dcf903](https://github.com/nuxt/ui/commit/9dcf903926046b6e92b4784043e374d2174e4201))
* **module:** override `dark` variant with class strategy ([0f86b87](https://github.com/nuxt/ui/commit/0f86b87385375e5bd859e84d21f8b4f06b0a99e0))
### Bug Fixes
* **Button:** props specified more than once ([66a04ad](https://github.com/nuxt/ui/commit/66a04add91389910e1336bf0be1cfeada3540f76))
## [3.0.0-alpha.4](https://github.com/nuxt/ui/compare/v3.0.0-alpha.3...v3.0.0-alpha.4) (2024-10-01)
### Features
* **Drawer:** handle `direction` + `handle` props ([5f77aac](https://github.com/nuxt/ui/commit/5f77aac368448c7c45a0f9238d2dc3a5b0de825e))
### Bug Fixes
* **Accordion:** missing `min-w-0` on trigger ([6c28597](https://github.com/nuxt/ui/commit/6c285977bd175d4866ca601bca47132ebb2d3440))
* **build.config:** disable mkdist `addRelativeDeclarationExtensions` option ([f54f607](https://github.com/nuxt/ui/commit/f54f6074131db0f68eab1edcde3a4b2a7ecaba92))
* **CommandPalette:** missing `min-w-0` on root ([a61e765](https://github.com/nuxt/ui/commit/a61e7656c25b26409cab77178e67d1cb9ec22dbd))
* **Drawer:** improve max-width on mobile ([fac52fa](https://github.com/nuxt/ui/commit/fac52fa933aeb02f0855d20be37c4214efba0ab7))
* **InputMenu:** missing `group` on trailing ([2c7c41b](https://github.com/nuxt/ui/commit/2c7c41bd046a961d398bbe8ee4a5945cd1fbaeab))
* **README:** npm badge link ([#2271](https://github.com/nuxt/ui/issues/2271)) ([30c33c7](https://github.com/nuxt/ui/commit/30c33c71134ccbea4258949a851eaf8b26213b60))
* **templates:** app config colors type ([96c9246](https://github.com/nuxt/ui/commit/96c9246d83b54637ceb2e2dd77542e435690c387))
* **Toast:** improve focus styles ([1f9abda](https://github.com/nuxt/ui/commit/1f9abdae614acbfa0be868a599071a601406f0f5))
### Reverts
* Revert "chore(deps): refresh lock" ([b83ecc9](https://github.com/nuxt/ui/commit/b83ecc9a6f309d37d3f096667143a4ed7700db6d))
## [3.0.0-alpha.3](https://github.com/nuxt/ui/compare/v3.0.0-alpha.2...v3.0.0-alpha.3) (2024-09-18)
### Features
* **module:** move `colors` options into `theme.colors` ([2e95446](https://github.com/nuxt/ui/commit/2e954467c4679d70b68d3155ae34eca300508e38))
## [3.0.0-alpha.2](https://github.com/nuxt/ui/compare/v3.0.0-alpha.1...v3.0.0-alpha.2) (2024-09-18)
@@ -283,6 +327,195 @@
* **types:** useless import ([5f7872f](https://github.com/nuxt/ui/commit/5f7872f06e81e03443e2d1c27a654cfe32c55fb3))
* **useComponentIcons:** reactivity when using `defu` ([45454fa](https://github.com/nuxt/ui/commit/45454fae45b8571a9691284bd6a13a838e8ea1c9))
## [2.18.6](https://github.com/nuxt/ui/compare/v2.18.5...v2.18.6) (2024-09-23)
### Bug Fixes
* **components:** accept partial config in `ui` prop ([#2235](https://github.com/nuxt/ui/issues/2235)) ([eecf4f7](https://github.com/nuxt/ui/commit/eecf4f7ed8a32a874f00afd7bff2964a1366e0b5))
* **Modal/Slideover:** bind transition class to `TransitionChild` for Vue 3.5 ([#2227](https://github.com/nuxt/ui/issues/2227)) ([803c20a](https://github.com/nuxt/ui/commit/803c20ad92e8a31fefd6d300856735b0e9adbdf9))
* **SelectMenu:** wrong placeholder color with multiple ([#2218](https://github.com/nuxt/ui/issues/2218)) ([28ad5cf](https://github.com/nuxt/ui/commit/28ad5cf98251c6a8acec8d0bf4f0fd07ff6b7066))
* **Table:** colspan with expand ([#2217](https://github.com/nuxt/ui/issues/2217)) ([56118c4](https://github.com/nuxt/ui/commit/56118c4a794f3d763dad7b65e044814cf7ef11cf))
* **Tabs:** handle icon `margin` in RTL mode ([#2233](https://github.com/nuxt/ui/issues/2233)) ([ea05414](https://github.com/nuxt/ui/commit/ea05414930fe3f5e6805c8aa25bbe8f746bcc86e))
* **useFormField:** optional property access ([#2226](https://github.com/nuxt/ui/issues/2226)) ([0a054a5](https://github.com/nuxt/ui/commit/0a054a52b64b4f774041c40223e18e7e056cfd80))
## [2.18.5](https://github.com/nuxt/ui/compare/v2.18.4...v2.18.5) (2024-09-18)
### Features
* **Form:** add errors slot prop ([#2188](https://github.com/nuxt/ui/issues/2188)) ([67c6a74](https://github.com/nuxt/ui/commit/67c6a74ed15db1ee8a40e9c74ecfef0d3c3e374a))
### Bug Fixes
* **Button:** button link not showing disabled classes ([#2185](https://github.com/nuxt/ui/issues/2185)) ([e8ea84a](https://github.com/nuxt/ui/commit/e8ea84a5736759d953664f8f397a2339c212b294))
* **Carousel:** remove trailing space in next button icon ([#2088](https://github.com/nuxt/ui/issues/2088)) ([1282a5f](https://github.com/nuxt/ui/commit/1282a5f6c001aa05597d458800bafcf6b6419634))
* **FormGroup:** remove id when used with `RadioGroup` ([#2152](https://github.com/nuxt/ui/issues/2152)) ([7aec42c](https://github.com/nuxt/ui/commit/7aec42ca15aaa0ccc63c520b484cba203fd3232b))
* **Input:** avoid binding value when type is `file` ([#2047](https://github.com/nuxt/ui/issues/2047)) ([82313e8](https://github.com/nuxt/ui/commit/82313e862cbf21ae631156af4cd057f1383db634))
* **module:** allow CSS variables in tailwind colors ([#2014](https://github.com/nuxt/ui/issues/2014)) ([7f50c70](https://github.com/nuxt/ui/commit/7f50c7031fecb5ab26a6d0f58b576b2fd0860487))
* **module:** augment `@nuxt/schema` rather than `nuxt/schema` ([#2171](https://github.com/nuxt/ui/issues/2171)) ([ead904f](https://github.com/nuxt/ui/commit/ead904fd2f2bbb29fd60ccde063bf02daa2cbdbb))
* **module:** consider user tailwind `configPath` for module as string ([#2074](https://github.com/nuxt/ui/issues/2074)) ([e4ba4f7](https://github.com/nuxt/ui/commit/e4ba4f7c729f99dde51891636605793864812d30))
* **Pagination:** use links on prev and next button ([#2179](https://github.com/nuxt/ui/issues/2179)) ([c850f85](https://github.com/nuxt/ui/commit/c850f85aaa40c7abbe8cc4dc1bd4705bf7677390))
* **README:** update license link ([#2154](https://github.com/nuxt/ui/issues/2154)) ([8d79eea](https://github.com/nuxt/ui/commit/8d79eea19b3276b1f1e069d33b98b311e9b91cfd))
* **Slideover:** bind `rounded` class to panel ([#2187](https://github.com/nuxt/ui/issues/2187)) ([bf32baa](https://github.com/nuxt/ui/commit/bf32baaab01dc4150622f67b3b4a8d02d21b922c))
* **Slideover:** bind `shadow` class to panel ([#2201](https://github.com/nuxt/ui/issues/2201)) ([d22526c](https://github.com/nuxt/ui/commit/d22526c0c10735a92e63b7d086e7b8534a08d768))
* **Table:** checkbox can emit the `[@select](https://github.com/select)` event ([#2072](https://github.com/nuxt/ui/issues/2072)) ([b1f691f](https://github.com/nuxt/ui/commit/b1f691f28ca8c94f6b658dcb61eeff06951bd1d0))
* **Table:** select all rows reactivity issue ([#2200](https://github.com/nuxt/ui/issues/2200)) ([68124de](https://github.com/nuxt/ui/commit/68124de5106e55cb2987a6ba4ec1120d79b51788))
* **Tabs:** recalculate marker if items change ([#2101](https://github.com/nuxt/ui/issues/2101)) ([82c4926](https://github.com/nuxt/ui/commit/82c4926c090ce7fac48022a93b1b05b877bb48dd))
* **Textarea:** resolve row count calculation errors caused by scrollbar ([#2040](https://github.com/nuxt/ui/issues/2040)) ([8210936](https://github.com/nuxt/ui/commit/8210936f22fcf6b7eb5b9711e2c29be38956b8d6))
## [2.18.4](https://github.com/nuxt/ui/compare/v2.18.3...v2.18.4) (2024-08-05)
### Bug Fixes
* **Form:** submit event data ([#2012](https://github.com/nuxt/ui/issues/2012)) ([4d61936](https://github.com/nuxt/ui/commit/4d61936e7e90b664846a8f265825612c509511d7))
* **module:** handle nested colors from ui config ([#2008](https://github.com/nuxt/ui/issues/2008)) ([1cc7e2a](https://github.com/nuxt/ui/commit/1cc7e2a306e0f3f666b9a588f6ed02e7eabc0272))
* **module:** reduce css bundle size by fixing safelist regex ([#2005](https://github.com/nuxt/ui/issues/2005)) ([8ac9ca4](https://github.com/nuxt/ui/commit/8ac9ca49789a9a7281f7a40926e7e9a8068cc395))
* **module:** suffix types imports with `/index` ([7e37668](https://github.com/nuxt/ui/commit/7e37668940d06c5aa20b60d9bfd600d50a171014)), closes [#2018](https://github.com/nuxt/ui/issues/2018)
* **Tabs:** use `nextTick` before marker calc ([#2020](https://github.com/nuxt/ui/issues/2020)) ([9c04969](https://github.com/nuxt/ui/commit/9c049690227af8aba61a1f7c002b00c5dfeb63ff))
* **useFormGroup:** app config default input size ([#2011](https://github.com/nuxt/ui/issues/2011)) ([3485092](https://github.com/nuxt/ui/commit/3485092edb55f9ef2ca038a8c137431866d6c28a))
## [2.18.3](https://github.com/nuxt/ui/compare/v2.18.2...v2.18.3) (2024-07-30)
### Bug Fixes
* **Link:** define `rel` as any ([69f605f](https://github.com/nuxt/ui/commit/69f605fa724454e4be9e4cee9666a5d57f43a129))
* **types:** only use `.ts` for index ([93ddf1d](https://github.com/nuxt/ui/commit/93ddf1d60b0ea5f99f564f3d3969c397ad91cc72))
## [2.18.2](https://github.com/nuxt/ui/compare/v2.18.1...v2.18.2) (2024-07-25)
### Bug Fixes
* **Tabs:** add missing `UIcon` import ([4fd1be2](https://github.com/nuxt/ui/commit/4fd1be28922bf39584005c14982e5cd9a7d0c624))
## [2.18.1](https://github.com/nuxt/ui/compare/v2.18.0...v2.18.1) (2024-07-25)
### Bug Fixes
* **components:** use relative imports ([ea721a3](https://github.com/nuxt/ui/commit/ea721a3705cfbcef3075f8c9c1f4acf359974597))
## [2.18.0](https://github.com/nuxt/ui/compare/v2.17.0...v2.18.0) (2024-07-25)
### ⚠ BREAKING CHANGES
* **Icon:** migrate from `@egoist/tailwindcss-icons` to new `@nuxt/icon` (#1789)
### Features
* **Checkbox/Radio/RadioGroup:** add `help` slot ([c3122f7](https://github.com/nuxt/ui/commit/c3122f776daa6d68f201f22c37e0084aac37ed06)), closes [#1957](https://github.com/nuxt/ui/issues/1957)
* **CommandPalette:** handle `static` groups ([#1458](https://github.com/nuxt/ui/issues/1458)) ([b264ad2](https://github.com/nuxt/ui/commit/b264ad2ebdc8d4ee4aab5c994df968025207021f))
* **Icon:** migrate from `@egoist/tailwindcss-icons` to new `@nuxt/icon` ([#1789](https://github.com/nuxt/ui/issues/1789)) ([c904604](https://github.com/nuxt/ui/commit/c904604c23987c2535e0e91e9c4fec50477f6b34))
* **module:** improve app config types autocomplete ([#1870](https://github.com/nuxt/ui/issues/1870)) ([3f8ea5d](https://github.com/nuxt/ui/commit/3f8ea5dbded7b6836495103739688905ff26fe22))
* **RadioGroup:** add `selected` to label slot props ([#1587](https://github.com/nuxt/ui/issues/1587)) ([d18477d](https://github.com/nuxt/ui/commit/d18477def58171d51bdb7d00e31e2807b2e7015b))
* **SelectMenu:** add selected to `label` / `leading` / `trailing` slots props ([#1349](https://github.com/nuxt/ui/issues/1349)) ([6b216ca](https://github.com/nuxt/ui/commit/6b216cab1ba3bb69cb317254dfd562ab020c5e92))
* **SelectMenu:** handle function in `showCreateOptionWhen` prop ([#1853](https://github.com/nuxt/ui/issues/1853)) ([7e974b5](https://github.com/nuxt/ui/commit/7e974b55d72b8ac0ab42ef722a2d1904c3e4e091))
* **Skeleton:** add `as` prop ([#1955](https://github.com/nuxt/ui/issues/1955)) ([bce94db](https://github.com/nuxt/ui/commit/bce94db9fdb2c29a4f2e5981e5dce49a44a4ac8a))
* **Table:** expand row ([#1036](https://github.com/nuxt/ui/issues/1036)) ([7155318](https://github.com/nuxt/ui/commit/71553180294c53024c28de9bbebf4ea69f616da7))
* **Table:** handle `rowClass` property in `columns` ([#1632](https://github.com/nuxt/ui/issues/1632)) ([748e491](https://github.com/nuxt/ui/commit/748e49175da37b85bd18d62a8455875990866d5b))
* **Tabs:** handle `icon` in items ([#1798](https://github.com/nuxt/ui/issues/1798)) ([e8eb394](https://github.com/nuxt/ui/commit/e8eb3941ad4c1c306ccbe9e11d979d5f6c808330))
### Bug Fixes
* **Accordion:** truncate buttons ([5db18c0](https://github.com/nuxt/ui/commit/5db18c00565f9d2bb9f2768c2de2ab291a55bcae)), closes [#1909](https://github.com/nuxt/ui/issues/1909)
* **Alert/Notification:** missing margin on description ([2c55fb6](https://github.com/nuxt/ui/commit/2c55fb63365ee7cc1e993ebd5aa5f83ddadcd26a)), closes [#1959](https://github.com/nuxt/ui/issues/1959)
* **Breadcrumb:** use `rotate` on rtl icon ([53003fc](https://github.com/nuxt/ui/commit/53003fcd07d67d13ada0759ff6c5cd3635fba0e3))
* **ButtonGroup/FormGroup:** pass default sizes to children ([#1875](https://github.com/nuxt/ui/issues/1875)) ([6b6b03d](https://github.com/nuxt/ui/commit/6b6b03d59f5ab3096b731c59d18a1085d25b5e8e))
* **Carousel:** remove `mix-blend-overlay` on indicators ([#1714](https://github.com/nuxt/ui/issues/1714)) ([f74f1df](https://github.com/nuxt/ui/commit/f74f1df6ca5f93e11e542245b611c1aa7c4b8308))
* **FormGroup:** don't check for `error` slot so `help` slot can render ([#1888](https://github.com/nuxt/ui/issues/1888)) ([99c52e5](https://github.com/nuxt/ui/commit/99c52e50082d5e99440894c7a077a17510f0de50))
* **InputMenu/SelectMenu:** invalid `label` with `value-attribute` and async search ([4d5f250](https://github.com/nuxt/ui/commit/4d5f2509022e4fb74fc268d5479f7cc8f0415040)), closes [#1780](https://github.com/nuxt/ui/issues/1780)
* **InputMenu/SelectMenu:** prevent double filter with async search ([e2881d3](https://github.com/nuxt/ui/commit/e2881d3801c54c49d66d41d4f0ba312a7b3ebce7)), closes [#1966](https://github.com/nuxt/ui/issues/1966)
* **Link:** allow `ariaLabel` to be picked ([720c44d](https://github.com/nuxt/ui/commit/720c44dd5ee90bb3b30aef32f01ff6eae1397aa4)), closes [#1934](https://github.com/nuxt/ui/issues/1934)
* **Progress:** pass down attrs to `<progress>` to improve accessibility ([#1881](https://github.com/nuxt/ui/issues/1881)) ([abd13f1](https://github.com/nuxt/ui/commit/abd13f1f8fd4c8b10069174534c5fdec6c83576e))
* **RadioGroup:** allow boolean in `modelValue` prop ([#1913](https://github.com/nuxt/ui/issues/1913)) ([8eca5a0](https://github.com/nuxt/ui/commit/8eca5a0d627e22f42350a060f09c4e44b6de422f))
## [2.17.0](https://github.com/nuxt/ui/compare/v2.16.0...v2.17.0) (2024-06-13)
### Features
* **Alert:** add `actions` slot ([#1785](https://github.com/nuxt/ui/issues/1785)) ([c8dd71c](https://github.com/nuxt/ui/commit/c8dd71c4f5a5239811b07b50f1dc802101af07d5))
* **Form:** update and migrate `valibot` to v0.31.0 ([#1848](https://github.com/nuxt/ui/issues/1848)) ([1d5bd89](https://github.com/nuxt/ui/commit/1d5bd89d5881163fc6dc917e138b9d8304dff6c4))
* **Notification:** allow ring customization with `{color}` ([#1830](https://github.com/nuxt/ui/issues/1830)) ([3ebff4d](https://github.com/nuxt/ui/commit/3ebff4d133372e339e2c4c439576e9e192b29cc3))
* **Slideover:** handle `top` and `bottom` side ([#1834](https://github.com/nuxt/ui/issues/1834)) ([50ad14f](https://github.com/nuxt/ui/commit/50ad14f9dffe4f76bef888cd10d30b417c75bca5))
* **Tabs:** add `content` prop to avoid the render of the HTML markup ([#1831](https://github.com/nuxt/ui/issues/1831)) ([6e2678d](https://github.com/nuxt/ui/commit/6e2678d1d8a498322eb3eff909ccbba55e40a2b7))
### Bug Fixes
* **Alert/Notification:** use `div` for description ([e8898d1](https://github.com/nuxt/ui/commit/e8898d15a667ba66e78828315e3cc4e92845cd3f)), closes [#1551](https://github.com/nuxt/ui/issues/1551)
* **Alert:** base style not applied on icon ([#1859](https://github.com/nuxt/ui/issues/1859)) ([f65aefb](https://github.com/nuxt/ui/commit/f65aefb7067c1c64c1355b5d699129e716ef1281))
* **Breadcrumb:** allow `aria-current` to be overrideable ([ebfb835](https://github.com/nuxt/ui/commit/ebfb8350339725c0a6f88c73f16bff01d61538c2)), closes [#1856](https://github.com/nuxt/ui/issues/1856)
* **Carousel:** prevent mouse click when dragging ([#1781](https://github.com/nuxt/ui/issues/1781)) ([4f0d00f](https://github.com/nuxt/ui/commit/4f0d00f7a6eebf05adceaf1e7c2869ad91949cf3))
* **CommandPalette:** hide `empty-state` when `null` ([249bbd4](https://github.com/nuxt/ui/commit/249bbd49dc8420603e8d561543d237abeb400908)), closes [#1787](https://github.com/nuxt/ui/issues/1787)
* **Form:** maintain other errors when using `setErrors` with a path ([#1818](https://github.com/nuxt/ui/issues/1818)) ([06990be](https://github.com/nuxt/ui/commit/06990beabf67f668322b4d3fb2ec93cc4f3bdcd4))
* **Input:** hide wrapper when type is `hidden` ([#1797](https://github.com/nuxt/ui/issues/1797)) ([e7c2f78](https://github.com/nuxt/ui/commit/e7c2f7856c05ed96f48c83d64d8e1d3f41ab58fe))
* **Link:** typo in `exactHash` type ([581b470](https://github.com/nuxt/ui/commit/581b470cc79c2315bb2d56e02a7c134a7861c616)), closes [#1767](https://github.com/nuxt/ui/issues/1767)
* **SelectMenu:** wrong placeholder color when `modelValue` is an empty string ([9b9ccdb](https://github.com/nuxt/ui/commit/9b9ccdb59e98fed096dd18809af646b10de46b9f)), closes [#1862](https://github.com/nuxt/ui/issues/1862)
* **Select:** remove defaults for `value` and `text` ([6c124bb](https://github.com/nuxt/ui/commit/6c124bb1ac2fef116161da56a3a8e5f92144ce3a)), closes [#1702](https://github.com/nuxt/ui/issues/1702)
## [2.16.0](https://github.com/nuxt/ui/compare/v2.15.2...v2.16.0) (2024-05-07)
### ⚠ BREAKING CHANGES
* **Input:** redesign `file` type without absolute positioning (#1712)
### Features
* **InputMenu/SelectMenu:** allow lazy search ([#1705](https://github.com/nuxt/ui/issues/1705)) ([7e6ba78](https://github.com/nuxt/ui/commit/7e6ba786816516ab5007a2ff15fc974cfdd796ab))
* **module:** HMR support with `@nuxtjs/tailwindcss` ([#1665](https://github.com/nuxt/ui/issues/1665)) ([821e15b](https://github.com/nuxt/ui/commit/821e15b696b03d0f5e20e001d39f86a8b3cec426))
* **Table:** allow providing a `<caption>` ([#1680](https://github.com/nuxt/ui/issues/1680)) ([3fca668](https://github.com/nuxt/ui/commit/3fca66857d3616bf24a1b0579c90179a7883869d))
* **useToast:** allow clearing all notifications ([#1695](https://github.com/nuxt/ui/issues/1695)) ([82d619b](https://github.com/nuxt/ui/commit/82d619b2a75b9d08f3f5b314d37c30d77d8341e9))
### Bug Fixes
* **Breadcrumb:** pass `click` event to `ULink` ([5481dab](https://github.com/nuxt/ui/commit/5481dab53dbe0b28188b4a16811f3e8816d93edf))
* **Input:** redesign `file` type without absolute positioning ([#1712](https://github.com/nuxt/ui/issues/1712)) ([ed5c74d](https://github.com/nuxt/ui/commit/ed5c74dc17df784485eabc39c83e62ada9210a49))
* **Notification:** update timer when timeout prop changes ([#1673](https://github.com/nuxt/ui/issues/1673)) ([cba9ad7](https://github.com/nuxt/ui/commit/cba9ad78db58cb9228bb9c96f0469d43bde2bf3e))
* **Slideover:** export and clean types ([#1692](https://github.com/nuxt/ui/issues/1692)) ([bd3fa86](https://github.com/nuxt/ui/commit/bd3fa8658f84fb7bd96d322968462c5eaa987b86))
* **Table:** provide `aria-sort` for sortable table headings ([#1675](https://github.com/nuxt/ui/issues/1675)) ([6f60fa9](https://github.com/nuxt/ui/commit/6f60fa9a980020f6a5afc2916e699a7f9a47e8ce))
## [2.15.2](https://github.com/nuxt/ui/compare/v2.15.1...v2.15.2) (2024-04-12)
### Features
* **Accordion:** add `unmount` prop to allow lazy mounting for heavy components ([#1590](https://github.com/nuxt/ui/issues/1590)) ([91e5002](https://github.com/nuxt/ui/commit/91e50020507ac66992dfb52b3e0ad1a1ae5614b5))
* **Table:** add `checkbox` ui config ([#1409](https://github.com/nuxt/ui/issues/1409)) ([8b54660](https://github.com/nuxt/ui/commit/8b546600dbfbff187d9c5be1b35ea1772e94f83f))
### Bug Fixes
* **Breadcrumb:** missing `min-w-0` on wrapper to truncate ([9f01145](https://github.com/nuxt/ui/commit/9f01145bc674378371ff34d7110f3235b57d2459)), closes [#1650](https://github.com/nuxt/ui/issues/1650)
* **Carousel:** next and prev buttons disabled ([#1619](https://github.com/nuxt/ui/issues/1619)) ([e909884](https://github.com/nuxt/ui/commit/e909884d0327bfd7b4d5551382123f8998beff6a))
* **Popover/Dropdown:** prevent unintended closure on touchstart in mobile devices ([#1609](https://github.com/nuxt/ui/issues/1609)) ([2392b4a](https://github.com/nuxt/ui/commit/2392b4aa405430fc22766f130448a7cc5ced9a3a))
* **Slideover:** remove dynamic component when closing ([#1615](https://github.com/nuxt/ui/issues/1615)) ([58faa10](https://github.com/nuxt/ui/commit/58faa1053b9be3f627c3fcff1bcaa14850bb9e7f))
* **Slideover:** wait for transition to complete to reset state ([#1624](https://github.com/nuxt/ui/issues/1624)) ([07a4d13](https://github.com/nuxt/ui/commit/07a4d13c0fcb05c87fb42e02a3a2d6c5c52ccf09))
## [2.15.1](https://github.com/nuxt/ui/compare/v2.15.0...v2.15.1) (2024-04-02)
### Features
* **Avatar:** add `as` prop to use `NuxtImg` underneath ([49b73aa](https://github.com/nuxt/ui/commit/49b73aa024be14a9aa150a2804f4dcb18542fa49)), closes [#1577](https://github.com/nuxt/ui/issues/1577)
### Bug Fixes
* **Checkbox:** `[@change](https://github.com/change)` event value ([#1580](https://github.com/nuxt/ui/issues/1580)) ([c98d6e3](https://github.com/nuxt/ui/commit/c98d6e31c0e3f46b97957d5cf3de7f9da1f70c58))
* **Divider:** add `w-full` only on horizontal wrapper ([#1565](https://github.com/nuxt/ui/issues/1565)) ([bd8b737](https://github.com/nuxt/ui/commit/bd8b737642280e6a83b67f9a27dd7a823a77e963))
* **Dropdown:** missing `mouseenter` event on container ([7288953](https://github.com/nuxt/ui/commit/72889535e7e9763e7ebf59498f22c39bf09d6477))
* **Input/SelectMenu:** handle `file` type and `change` events ([#1570](https://github.com/nuxt/ui/issues/1570)) ([878f707](https://github.com/nuxt/ui/commit/878f7078a28c5e70a662682d1293db466d518c7d))
* **Popover:** missing `mouseenter` event on container ([8517897](https://github.com/nuxt/ui/commit/8517897c34adaa9e3624f867b43106deb59fcbe8)), closes [#1564](https://github.com/nuxt/ui/issues/1564)
## [2.15.0](https://github.com/nuxt/ui/compare/v2.14.2...v2.15.0) (2024-03-26)

View File

@@ -1,97 +1,76 @@
[![nuxt-ui.png](https://repository-images.githubusercontent.com/428329515/43fec891-9030-4601-8233-5d45ba5c6013)](https://ui.nuxt.com)
# Nuxt UI
# Nuxt UI v3
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![License][license-src]][license-href]
[![Nuxt][nuxt-src]][nuxt-href]
Nuxt UI is a module that provides a set of Vue components and composables built with [Tailwind CSS](https://tailwindcss.com/) and [Headless UI](https://headlessui.dev/) to help you build beautiful and accessible user interfaces.
Its goal is to provide everything related to UI when building a Nuxt app. This includes components, icons, colors, dark mode but also keyboard shortcuts.
## Features
- Built with [Headless UI](https://headlessui.dev/) and [Tailwind CSS](https://tailwindcss.com/)
- HMR support through Nuxt App Config
- Dark mode support
- Support for LTR and RTL languages
- Keyboard shortcuts
- Bundled icons
- Fully typed
- [Figma Kit](https://www.figma.com/community/file/1288455405058138934)
Read more on [ui.nuxt.com](https://ui.nuxt.com)
We're thrilled to introduce Nuxt UI v3, a significant upgrade to our UI library that delivers extensive improvements and robust new capabilities. This major update harnesses the combined strengths of [Radix Vue](https://www.radix-vue.com/), [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4-alpha), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces.
## Installation
```bash
# npm
npm install @nuxt/ui
# yarn
yarn add @nuxt/ui
# pnpm
pnpm add @nuxt/ui
# bun
bun add @nuxt/ui
1. Install the Nuxt UI v3 alpha package:
```bash [pnpm]
pnpm add @nuxt/ui@next
```
Then, register the module in your `nuxt.config.ts`:
```bash [yarn]
yarn add @nuxt/ui@next
```
```js
```bash [npm]
npm install @nuxt/ui@next
```
```bash [bun]
bun add @nuxt/ui@next
```
> [!WARNING]
> Make sure you have `typescript` installed in your dev dependencies.
2. Register the Nuxt UI module in your `nuxt.config.ts`:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: [
'@nuxt/ui'
]
modules: ['@nuxt/ui']
})
```
If you want latest updates, please use `@nuxt/ui-edge` in your `package.json`:
3. Import Tailwind and Nuxt UI in your `app.vue` or in your [CSS](https://nuxt.com/docs/getting-started/styling#the-css-property):
```json
{
"devDependencies": {
"@nuxt/ui": "npm:@nuxt/ui-edge@latest"
}
}
```css [main.css]
@import "tailwindcss";
@import "@nuxt/ui";
```
## Documentation
Visit https://ui.nuxt.com to explore the documentation.
Visit https://ui3.nuxt.dev to explore the documentation.
## Credits
- [nuxt/nuxt](https://github.com/nuxt/nuxt)
- [nuxt/icon](https://github.com/nuxt/icon)
- [nuxt/fonts](https://github.com/nuxt/fonts)
- [nuxt-modules/color-mode](https://github.com/nuxt-modules/color-mode)
- [nuxt-modules/tailwindcss](https://github.com/nuxt-modules/tailwindcss)
- [radix-vue/radix-vue](https://github.com/radix-vue/radix-vue)
- [tailwindlabs/tailwindcss](https://github.com/tailwindlabs/tailwindcss)
- [tailwindlabs/headlessui](https://github.com/tailwindlabs/headlessui)
- [vueuse/vueuse](https://github.com/vueuse/vueuse)
- [egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons)
## Contributing
Thank you for considering contributing to Nuxt UI. Here are a few ways you can get involved:
- Reporting Bugs: If you come across any bugs or issues, please check out the reporting bugs guide to learn how to submit a bug report.
- Suggestions: Have any thoughts to enhance Nuxt UI? We'd love to hear them! Check out the [contribution guide](https://ui.nuxt.com/getting-started/contributing) to share your suggestions.
## Local Development
Follow the docs to [Set up your local development environment](https://ui.nuxt.com/getting-started/contributing#_2-local-development-setup) and contribute.
## License
Licensed under the [MIT license](https://github.com/nuxt/ui/blob/dev/LICENSE.md).
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/next.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-version-href]: https://npmjs.com/package/@nuxt/ui
[npm-downloads-src]: https://img.shields.io/npm/dm/@nuxt/ui.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-downloads-href]: https://npmjs.com/package/@nuxt/ui
[npm-downloads-href]: https://npm.chart.dev/@nuxt/ui
[license-src]: https://img.shields.io/github/license/nuxt/ui.svg?style=flat&colorA=18181B&colorB=28CF8D
[license-href]: https://github.com/nuxt/ui/blob/main/LICENSE.md

12
build.config.ts Normal file
View File

@@ -0,0 +1,12 @@
import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
replace: {
'process.env.DEV': 'false'
},
hooks: {
'mkdist:entry:options'(ctx, entry, options) {
options.addRelativeDeclarationExtensions = false
}
}
})

View File

@@ -75,7 +75,7 @@ export default defineCommand({
await sortFile(themePath)
if (!args.prose) {
const typesPath = resolve(path, 'src/runtime/types/index.d.ts')
const typesPath = resolve(path, 'src/runtime/types/index.ts')
await appendFile(typesPath, `export * from '../components/${args.content ? 'content/' : ''}${splitByCase(name).map(p => upperFirst(p)).join('')}.vue'`)
await sortFile(typesPath)
}

View File

@@ -5,7 +5,7 @@ const playground = ({ name, pro }) => {
const kebabName = kebabCase(name)
return {
filename: `playground/pages/components/${kebabName}.vue`,
filename: `playground/app/pages/components/${kebabName}.vue`,
contents: pro
? undefined
: `

View File

@@ -1,8 +1,13 @@
export default defineAppConfig({
toaster: {
position: 'bottom-right' as const,
expand: true,
duration: 5000
},
ui: {
colors: {
primary: 'sky',
gray: 'cool'
primary: 'green',
gray: 'slate'
}
}
})

View File

@@ -4,12 +4,13 @@ import { withoutTrailingSlash } from 'ufo'
// import type { ContentSearchFile } from '@nuxt/ui-pro'
const route = useRoute()
const appConfig = useAppConfig()
// const colorMode = useColorMode()
const runtimeConfig = useRuntimeConfig()
const { integrity, api } = runtimeConfig.public.content
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation(), { default: () => [] })
const { data: files } = await useLazyFetch<any[]>(`${api.baseURL}/search${integrity ? '.' + integrity : ''}`, { default: () => [] })
const { data: files } = await useLazyFetch<any[]>(`${api.baseURL}/search${integrity ? '-' + integrity : ''}`, { default: () => [] })
const searchTerm = ref('')
@@ -71,24 +72,29 @@ useServerSeoMeta({
})
provide('navigation', navigation)
provide('files', files)
</script>
<template>
<UApp>
<NuxtLoadingIndicator />
<UApp :toaster="appConfig.toaster">
<NuxtLoadingIndicator color="#FFF" />
<Banner v-if="!route.path.startsWith('/examples')" />
<template v-if="!route.path.startsWith('/examples')">
<Banner />
<Header v-if="!route.path.startsWith('/examples')" :links="links" />
<Header :links="links" />
</template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<Footer v-if="!route.path.startsWith('/examples')" />
<template v-if="!route.path.startsWith('/examples')">
<Footer />
<LazyUContentSearch v-model:search-term="searchTerm" :files="files" :navigation="navigation" :fuse="{ resultLimit: 42 }" />
<ClientOnly>
<LazyUContentSearch v-model:search-term="searchTerm" :files="files" :navigation="navigation" :fuse="{ resultLimit: 42 }" />
</ClientOnly>
</template>
</UApp>
</template>
@@ -99,6 +105,22 @@ provide('files', files)
@source "../content/**/*.md";
@theme {
--font-family-sans: 'Inter', sans-serif;
--font-family-sans: 'Public Sans', sans-serif;
--color-green-50: #EFFDF5;
--color-green-100: #D9FBE8;
--color-green-200: #B3F5D1;
--color-green-300: #75EDAE;
--color-green-400: #00DC82;
--color-green-500: #00C16A;
--color-green-600: #00A155;
--color-green-700: #007F45;
--color-green-800: #016538;
--color-green-900: #0A5331;
--color-green-950: #052E16;
}
:root {
--container-width: 90rem;
}
</style>

View File

@@ -2,7 +2,7 @@
import type { NavItem } from '@nuxt/content'
import type { NavigationMenuItem } from '@nuxt/ui'
const props = defineProps<{
defineProps<{
links: NavigationMenuItem[]
}>()
@@ -10,16 +10,16 @@ const config = useRuntimeConfig().public
const navigation = inject<Ref<NavItem[]>>('navigation')
const items = computed(() => props.links.map(({ icon, ...link }) => link))
// const items = computed(() => props.links.map(({ icon, ...link }) => link))
</script>
<template>
<UHeader>
<UHeader :ui="{ left: 'min-w-0' }">
<template #left>
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-gray-900 dark:text-white" aria-label="Nuxt UI">
<Logo class="w-auto h-6" />
<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">
<Logo class="w-auto h-6 shrink-0" />
<UBadge :label="`v${config.version}`" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold" />
<UBadge :label="`v${config.version}`" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold truncate" />
</NuxtLink>
</template>
@@ -32,12 +32,12 @@ const items = computed(() => props.links.map(({ icon, ...link }) => link))
<UContentSearchButton />
</UTooltip>
<!-- <UColorModeButton /> -->
<ColorModeButton />
<UButton
color="gray"
variant="ghost"
to="https://github.com/nuxt/ui"
to="https://github.com/nuxt/ui/tree/v3"
target="_blank"
icon="i-simple-icons-github"
aria-label="GitHub"
@@ -45,9 +45,9 @@ const items = computed(() => props.links.map(({ icon, ...link }) => link))
</template>
<template #content>
<UNavigationMenu orientation="vertical" :items="items" class="-ml-2.5" />
<!-- <UNavigationMenu orientation="vertical" :items="items" class="-ml-2.5" />
<USeparator type="dashed" class="my-4" />
<USeparator type="dashed" class="my-4" /> -->
<UContentNavigation :navigation="navigation" />
</template>

View File

@@ -0,0 +1,38 @@
<template>
<ClientOnly v-if="!colorMode?.forced">
<UButton
:icon="isDark ? appConfig.ui.icons.dark : appConfig.ui.icons.light"
color="gray"
variant="ghost"
v-bind="{
...$attrs
}"
:aria-label="`Switch to ${isDark ? 'light' : 'dark'} mode`"
@click="isDark = !isDark"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
</template>
<script setup lang="ts">
defineOptions({
inheritAttrs: false
})
const colorMode = useColorMode()
const appConfig = useAppConfig()
// Computed
const isDark = computed({
get() {
return colorMode.value === 'dark'
},
set() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>

View File

@@ -2,6 +2,7 @@
<script setup lang="ts">
import json5 from 'json5'
import { upperFirst, camelCase, kebabCase } from 'scule'
import { hash } from 'ohash'
import * as theme from '#build/ui'
import { get, set } from '#ui/utils'
@@ -15,6 +16,8 @@ const props = defineProps<{
hide?: string[]
/** List of props to externalize in script setup */
external?: string[]
/** List of props to use with `v-model` */
model?: string[]
/** List of items for each prop */
items?: { [key: string]: string[] }
props?: { [key: string]: any }
@@ -38,9 +41,13 @@ const camelName = camelCase(props.slug ?? route.params.slug?.[route.params.slug.
const name = `U${upperFirst(camelName)}`
const componentProps = reactive({ ...(props.props || {}) })
const componentEvents = reactive({
...Object.fromEntries((props.model || []).map(key => [`onUpdate:${key}`, (e: any) => setComponentProp(key, e)])),
...(componentProps.modelValue ? { [`onUpdate:modelValue`]: (e: any) => setComponentProp('modelValue', e) } : {})
})
function getComponentProp(name: string) {
return get(componentProps, name) || undefined
return get(componentProps, name) ?? undefined
}
function setComponentProp(name: string, value: any) {
@@ -121,6 +128,11 @@ const code = computed(() => {
continue
}
if (props.model?.includes(key)) {
code += ` v-model:${key}="${key}"`
continue
}
if (value === undefined || value === null || value === '' || props.hide?.includes(key)) {
continue
}
@@ -179,7 +191,7 @@ const code = computed(() => {
return code
})
const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringify({ props: componentProps, slots: props.slots })}`, async () => {
const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props: componentProps, slots: props.slots })}`, async () => {
if (!props.prettier) {
return parseMarkdown(code.value)
}
@@ -202,7 +214,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringif
<template>
<div class="my-5">
<div>
<div v-if="options.length" class="flex items-center gap-2.5 border border-gray-300 dark:border-gray-700 border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
<div v-if="options.length" class="flex items-center gap-2.5 border border-gray-200 dark:border-gray-700 border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
<template v-for="option in options" :key="option.name">
<UFormField
:label="option.label"
@@ -222,7 +234,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringif
color="gray"
variant="soft"
class="rounded rounded-l-none min-w-12"
:search="false"
:search-input="false"
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
:ui="{ itemLeadingChip: 'size-2' }"
@update:model-value="setComponentProp(option.name, $event)"
@@ -251,8 +263,8 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringif
</template>
</div>
<div class="flex border border-b-0 border-gray-300 dark:border-gray-700 relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class]">
<component :is="name" v-bind="componentProps" @update:model-value="!!componentProps.modelValue && setComponentProp('modelValue', $event)">
<div class="flex justify-center border border-b-0 border-gray-200 dark:border-gray-700 relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class]">
<component :is="name" v-bind="{ ...componentProps, ...componentEvents }">
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
<ContentSlot :name="slot" unwrap="p">
{{ slots?.[slot] }}

View File

@@ -22,7 +22,7 @@ const meta = await fetchComponentMeta(name as any)
</ProseTr>
</ProseThead>
<ProseTbody>
<ProseTr v-for="event in meta.meta.events" :key="event.name">
<ProseTr v-for="event in (meta?.meta?.events || [])" :key="event.name">
<ProseTd>
<ProseCodeInline>
{{ event.name }}

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { camelCase } from 'scule'
import { get, set } from '#ui/utils'
const props = withDefaults(defineProps<{
name: string
@@ -32,17 +33,22 @@ const props = withDefaults(defineProps<{
* A list of variable props to link to the component.
*/
options?: Array<{
alias?: string
name: string
label: string
items: any[]
items?: any[]
default: any
multiple: boolean
multiple?: boolean
}>
}>(), {
preview: true,
source: true
})
const slots = defineSlots<{
options(props?: {}): any
}>()
const { $prettier } = useNuxtApp()
const camelName = camelCase(props.name)
@@ -92,7 +98,14 @@ const { data: ast } = await useAsyncData(`component-example-${camelName}`, async
const optionsValues = ref(props.options?.reduce((acc, option) => {
if (option.name) {
acc[option.name] = option.default
acc[option.alias || option.name] = option.default
}
if (option.name.toLowerCase().endsWith('color') && option.items?.length) {
option.items = option.items.map((item: any) => ({
label: item,
value: item,
chip: { color: item }
}))
}
return acc
}, {} as Record<string, any>) || {})
@@ -101,8 +114,10 @@ const optionsValues = ref(props.options?.reduce((acc, option) => {
<template>
<div class="my-5">
<div v-if="preview">
<div class="border border-gray-300 dark:border-gray-700 relative z-[1]" :class="[props.class, { 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source }]">
<div v-if="props.options?.length" class="flex gap-4 p-4 border-b border-gray-300 dark:border-gray-700">
<div class="border border-gray-200 dark:border-gray-700 relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source }]">
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-gray-200 dark:border-gray-700">
<slot name="options" />
<UFormField
v-for="option in props.options"
:key="option.name"
@@ -117,15 +132,41 @@ const optionsValues = ref(props.options?.reduce((acc, option) => {
}"
>
<USelectMenu
v-model="optionsValues[option.name]"
v-if="option.items?.length"
:model-value="get(optionsValues, option.name)"
:items="option.items"
class="rounded rounded-l-none w-40"
multiple
:search-input="false"
:value-key="option.name.toLowerCase().endsWith('color') ? 'value' : undefined"
color="gray"
variant="soft"
class="rounded rounded-l-none min-w-12"
:multiple="option.multiple"
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
:ui="{ itemLeadingChip: 'size-2' }"
@update:model-value="set(optionsValues, option.name, $event)"
>
<template v-if="option.name.toLowerCase().endsWith('color')" #leading="{ modelValue, ui }">
<UChip
inset
standalone
:color="(modelValue as any)"
:size="ui.itemLeadingChipSize()"
class="size-2"
/>
</template>
</USelectMenu>
<UInput
v-else
:model-value="get(optionsValues, option.name)"
color="gray"
variant="soft"
:ui="{ base: 'rounded rounded-l-none min-w-12' }"
@update:model-value="set(optionsValues, option.name, $event)"
/>
</UFormField>
</div>
<div class="p-4">
<div class="flex justify-center p-4" :class="props.class">
<component :is="camelName" v-bind="{ ...componentProps, ...optionsValues }" />
</div>
</div>

View File

@@ -22,7 +22,7 @@ const meta = await fetchComponentMeta(name as any)
</ProseTr>
</ProseThead>
<ProseTbody>
<ProseTr v-for="slot in meta.meta.slots" :key="slot.name">
<ProseTr v-for="slot in (meta?.meta?.slots || [])" :key="slot.name">
<ProseTd>
<ProseCodeInline>
{{ slot.name }}

View File

@@ -9,8 +9,8 @@ const name = camelCase(route.params.slug?.[route.params.slug.length - 1] ?? '')
const strippedCompoundVariants = ref(false)
function stripCompoundVariants(component: any) {
if (component.compoundVariants) {
function stripCompoundVariants(component?: any) {
if (component?.compoundVariants) {
component.compoundVariants = component.compoundVariants.filter((compoundVariant: any) => {
if (compoundVariant.color) {
if (!['primary', 'gray'].includes(compoundVariant.color)) {

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { murmurHash } from 'ohash'
const props = defineProps<{
type: string
}>()
@@ -21,7 +23,7 @@ const type = computed(() => {
return type
})
const { data: ast } = await useAsyncData(`hightlight-inline-code-${type.value}`, () => parseMarkdown(`\`${type.value}\`{lang="ts-type"}`))
const { data: ast } = await useAsyncData(`hightlight-inline-code-${murmurHash(type.value)}`, () => parseMarkdown(`\`${type.value}\`{lang="ts-type"}`))
</script>
<template>

View File

@@ -0,0 +1,48 @@
<script setup lang="ts">
const groups = [{
id: 'settings',
items: [{
label: 'Profile',
icon: 'i-heroicons-user',
kbds: ['meta', 'P']
}, {
label: 'Billing',
icon: 'i-heroicons-credit-card',
kbds: ['meta', 'B'],
slot: 'billing'
}, {
label: 'Notifications',
icon: 'i-heroicons-bell'
}, {
label: 'Security',
icon: 'i-heroicons-lock-closed'
}]
}, {
id: 'users',
label: 'Users',
slot: 'users',
items: [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
}]
</script>
<template>
<UCommandPalette :groups="groups" class="flex-1 h-80">
<template #users-leading="{ index }">
<UAvatar :src="`https://i.pravatar.cc/120?img=${index}`" size="2xs" />
</template>
<template #billing-label="{ item }">
{{ item.label }}
<UBadge variant="subtle" size="sm">
50% off
</UBadge>
</template>
</UCommandPalette>
</template>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
const searchTerm = ref('')
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
},
lazy: true
})
const groups = computed(() => [{
id: 'users',
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
items: users.value || []
}])
</script>
<template>
<UCommandPalette
v-model:search-term="searchTerm"
:loading="status === 'pending'"
:groups="groups"
class="flex-1 h-80"
/>
</template>

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
},
lazy: true
})
const groups = computed(() => [{
id: 'users',
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
items: users.value || [],
filter: false
}])
</script>
<template>
<UCommandPalette
v-model:search-term="searchTerm"
:loading="status === 'pending'"
:groups="groups"
class="flex-1 h-80"
/>
</template>

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
},
lazy: true
})
</script>
<template>
<UCommandPalette
:groups="[{ id: 'users', items: users || [] }]"
:fuse="{ fuseOptions: { includeMatches: true } }"
class="flex-1 h-80"
/>
</template>

View File

@@ -0,0 +1,24 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
const selected = ref(users[0])
function onSelect(item: any) {
console.log(item)
}
</script>
<template>
<UCommandPalette
v-model="selected"
:groups="[{ id: 'users', items: users }]"
class="flex-1"
@update:model-value="onSelect"
/>
</template>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
const selected = ref([users[0], users[1]])
function onSelect(items: any) {
console.log(items)
}
</script>
<template>
<UCommandPalette
v-model="selected"
multiple
:groups="[{ id: 'users', items: users }]"
class="flex-1"
@update:model-value="onSelect"
/>
</template>

View File

@@ -0,0 +1,30 @@
<script setup lang="ts">
const open = ref(false)
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
</script>
<template>
<UModal v-model:open="open">
<UButton
label="Search users..."
color="gray"
variant="subtle"
icon="i-heroicons-magnifying-glass"
/>
<template #content>
<UCommandPalette
close
:groups="[{ id: 'users', items: users }]"
@update:open="open = $event"
/>
</template>
</UModal>
</template>

View File

@@ -0,0 +1,40 @@
<script setup lang="ts">
const items = [{
id: '/',
label: 'Introduction',
level: 1
}, {
id: '/getting-started#whats-new-in-v3',
label: 'What\'s new in v3?',
level: 2
}, {
id: '/getting-started#radix-vue-3',
label: 'Radix Vue',
level: 3
}, {
id: '/getting-started#tailwind-css-v4',
label: 'Tailwind CSS v4',
level: 3
}, {
id: '/getting-started#tailwind-variants',
label: 'Tailwind Variants',
level: 3
}, {
id: '/getting-started/installation',
label: 'Installation',
level: 1
}]
function postFilter(searchTerm: string, items: any[]) {
// Filter only first level items if no searchTerm
if (!searchTerm) {
return items?.filter(item => item.level === 1)
}
return items
}
</script>
<template>
<UCommandPalette :groups="[{ id: 'files', items, postFilter }]" class="flex-1" />
</template>

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
const users = [
{ id: 1, label: 'Durward Reynolds' },
{ id: 2, label: 'Kenton Towne' },
{ id: 3, label: 'Therese Wunsch' },
{ id: 4, label: 'Benedict Kessler' },
{ id: 5, label: 'Katelyn Rohan' }
]
const searchTerm = ref('Th')
</script>
<template>
<UCommandPalette
v-model:search-term="searchTerm"
:groups="[{ id: 'users', items: users }]"
class="flex-1"
/>
</template>

View File

@@ -3,7 +3,7 @@ const searchTerm = ref('')
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
params: { q: searchTerm },
transform: (data: any[]) => {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
},
lazy: true
@@ -19,7 +19,12 @@ const groups = computed(() => [{
<template>
<UDrawer>
<UButton label="Search users..." color="gray" variant="subtle" icon="i-heroicons-magnifying-glass" />
<UButton
label="Search users..."
color="gray"
variant="subtle"
icon="i-heroicons-magnifying-glass"
/>
<template #content>
<UCommandPalette

View File

@@ -3,7 +3,7 @@ const open = ref(false)
</script>
<template>
<UDrawer v-model:open="open" title="Drawer with footer" description="This is useful when you want a form in a Drawer.">
<UDrawer v-model:open="open" title="Drawer with footer" description="This is useful when you want a form in a Drawer." :ui="{ container: 'max-w-xl mx-auto' }">
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
<template #body>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<UInputMenu
:items="users || []"
:loading="status === 'pending'"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</UInputMenu>
</template>

View File

@@ -0,0 +1,37 @@
<script setup lang="ts">
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<UInputMenu
v-model:search-term="searchTerm"
:items="users || []"
:loading="status === 'pending'"
:filter="false"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</UInputMenu>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({
label: user.name,
email: user.email,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<UInputMenu
:items="users || []"
:loading="status === 'pending'"
:filter="['name', 'email']"
icon="i-heroicons-user"
placeholder="Select user"
class="w-80"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
<template #item-label="{ item }">
{{ item.label }}
<span class="text-gray-500 dark:text-gray-400">
{{ item.email }}
</span>
</template>
</UInputMenu>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
</script>
<template>
<UInputMenu
v-model="selected"
:items="items"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
}"
/>
</template>

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
const items = ref([
{
label: 'benjamincanac',
value: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png',
alt: 'benjamincanac'
}
},
{
label: 'romhml',
value: 'romhml',
avatar: {
src: 'https://github.com/romhml.png',
alt: 'romhml'
}
},
{
label: 'noook',
value: 'noook',
avatar: {
src: 'https://github.com/noook.png',
alt: 'noook'
}
}
])
const selected = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :items="items" class="w-40">
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</UInputMenu>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
const items = ref([
{
label: 'bug',
value: 'bug',
chip: {
color: 'red' as const
}
},
{
label: 'enhancement',
value: 'enhancement',
chip: {
color: 'blue' as const
}
},
{
label: 'feature',
value: 'feature',
chip: {
color: 'violet' as const
}
}
])
const selected = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :items="items" class="w-40">
<template #leading="{ modelValue, ui }">
<UChip
v-if="modelValue"
v-bind="modelValue.chip"
inset
standalone
:size="ui.itemLeadingChipSize()"
:class="ui.itemLeadingChip()"
/>
</template>
</UInputMenu>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
const items = ref([
{
label: 'Backlog',
value: 'backlog',
icon: 'i-heroicons-question-mark-circle'
},
{
label: 'Todo',
value: 'todo',
icon: 'i-heroicons-plus-circle'
},
{
label: 'In Progress',
value: 'in_progress',
icon: 'i-heroicons-arrow-up-circle'
},
{
label: 'Done',
value: 'done',
icon: 'i-heroicons-check-circle'
}
])
const selected = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :icon="selected?.icon" :items="items" class="w-40" />
</template>

View File

@@ -0,0 +1,13 @@
<script setup lang="ts">
const open = ref(false)
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
defineShortcuts({
o: () => open.value = !open.value
})
</script>
<template>
<UInputMenu v-model="selected" v-model:open="open" :items="items" />
</template>

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
const searchTerm = ref('D')
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
</script>
<template>
<UInputMenu v-model="selected" v-model:search-term="searchTerm" :items="items" />
</template>

View File

@@ -3,7 +3,7 @@ const searchTerm = ref('')
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
params: { q: searchTerm },
transform: (data: any[]) => {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
},
lazy: true
@@ -19,7 +19,12 @@ const groups = computed(() => [{
<template>
<UModal>
<UButton label="Search users..." color="gray" variant="subtle" icon="i-heroicons-magnifying-glass" />
<UButton
label="Search users..."
color="gray"
variant="subtle"
icon="i-heroicons-magnifying-glass"
/>
<template #content>
<UCommandPalette

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
const page = ref(5)
function to(page: number) {
return {
query: {
page
},
hash: '#with-links'
}
}
</script>
<template>
<UPagination v-model:page="page" :total="100" :to="to" :sibling-count="1" show-edges />
</template>

View File

@@ -0,0 +1,40 @@
<script setup lang="ts">
const labels = [{
label: 'bug',
chip: {
color: 'red' as const
}
}, {
label: 'feature',
chip: {
color: 'green' as const
}
}, {
label: 'enhancement',
chip: {
color: 'blue' as const
}
}]
const label = ref([])
</script>
<template>
<UPopover :content="{ side: 'right', align: 'start' }">
<UButton
icon="i-heroicons-tag"
label="Select labels"
color="gray"
variant="subtle"
/>
<template #content>
<UCommandPalette
v-model="label"
multiple
placeholder="Search labels..."
:groups="[{ id: 'labels', items: labels }]"
:ui="{ input: '[&>input]:h-8' }"
/>
</template>
</UPopover>
</template>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<USelectMenu
:items="users || []"
:loading="status === 'pending'"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,37 @@
<script setup lang="ts">
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<USelectMenu
v-model:search-term="searchTerm"
:items="users || []"
:loading="status === 'pending'"
:filter="false"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({
label: user.name,
email: user.email,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
},
lazy: true
})
</script>
<template>
<USelectMenu
:items="users || []"
:loading="status === 'pending'"
:filter="['name', 'email']"
icon="i-heroicons-user"
placeholder="Select user"
class="w-80"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
<template #item-label="{ item }">
{{ item.label }}
<span class="text-gray-500 dark:text-gray-400">
{{ item.email }}
</span>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
</script>
<template>
<USelectMenu
v-model="selected"
:items="items"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
}"
/>
</template>

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
const items = ref([
{
label: 'benjamincanac',
value: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png',
alt: 'benjamincanac'
}
},
{
label: 'romhml',
value: 'romhml',
avatar: {
src: 'https://github.com/romhml.png',
alt: 'romhml'
}
},
{
label: 'noook',
value: 'noook',
avatar: {
src: 'https://github.com/noook.png',
alt: 'noook'
}
}
])
const selected = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :items="items" class="w-40">
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
const items = ref([
{
label: 'bug',
value: 'bug',
chip: {
color: 'red' as const
}
},
{
label: 'enhancement',
value: 'enhancement',
chip: {
color: 'blue' as const
}
},
{
label: 'feature',
value: 'feature',
chip: {
color: 'violet' as const
}
}
])
const selected = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :items="items" class="w-40">
<template #leading="{ modelValue, ui }">
<UChip
v-if="modelValue"
v-bind="modelValue.chip"
inset
standalone
:size="ui.itemLeadingChipSize()"
:class="ui.itemLeadingChip()"
/>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
const items = ref([
{
label: 'Backlog',
value: 'backlog',
icon: 'i-heroicons-question-mark-circle'
},
{
label: 'Todo',
value: 'todo',
icon: 'i-heroicons-plus-circle'
},
{
label: 'In Progress',
value: 'in_progress',
icon: 'i-heroicons-arrow-up-circle'
},
{
label: 'Done',
value: 'done',
icon: 'i-heroicons-check-circle'
}
])
const selected = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :icon="selected?.icon" :items="items" class="w-40" />
</template>

View File

@@ -0,0 +1,13 @@
<script setup lang="ts">
const open = ref(false)
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
defineShortcuts({
o: () => open.value = !open.value
})
</script>
<template>
<USelectMenu v-model="selected" v-model:open="open" :items="items" />
</template>

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
const searchTerm = ref('D')
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
</script>
<template>
<USelectMenu v-model="selected" v-model:search-term="searchTerm" :items="items" />
</template>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
transform: (data: { name: string, id: number }[]) => {
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
const toast = useToast()
const props = defineProps<{
description: string
}>()
function showToast() {
toast.add({
title: 'Uh oh! Something went wrong.',
description: props.description,
actions: [{
icon: 'i-heroicons-arrow-path-20-solid',
label: 'Retry',
color: 'gray',
variant: 'outline',
onClick: (e) => {
e?.stopPropagation()
}
}]
})
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,21 @@
<script setup lang="ts">
import type { AvatarProps } from '@nuxt/ui'
const props = defineProps<{
avatar: AvatarProps
}>()
const toast = useToast()
function showToast() {
toast.add({
title: 'User invited',
description: 'benjamincanac was invited to the team.',
avatar: props.avatar
})
}
</script>
<template>
<UButton label="Invite user" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,20 @@
<script setup lang="ts">
const toast = useToast()
function showToast() {
toast.add({
title: 'Uh oh! Something went wrong.',
description: 'There was a problem with your request.',
icon: 'i-heroicons-wifi',
close: {
color: 'primary',
variant: 'outline',
class: 'rounded-full'
}
})
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
const props = defineProps<{
closeIcon: string
}>()
const toast = useToast()
function showToast() {
toast.add({
title: 'Uh oh! Something went wrong.',
description: 'There was a problem with your request.',
closeIcon: props.closeIcon
})
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import type { ToastProps } from '@nuxt/ui'
const props = defineProps<{
color: ToastProps['color']
}>()
const toast = useToast()
function showToast() {
toast.add({
title: 'Uh oh! Something went wrong.',
description: 'There was a problem with your request.',
icon: 'i-heroicons-wifi',
color: props.color
})
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,16 @@
<script setup lang="ts">
const props = defineProps<{
title: string
description: string
}>()
const toast = useToast()
function showToast() {
toast.add(props)
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
const toast = useToast()
function addToCalendar() {
const eventDate = new Date(Date.now() + Math.random() * 31536000000)
const formattedDate = eventDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
toast.add({
title: 'Event added to calendar',
description: `This event is scheduled for ${formattedDate}.`,
icon: 'i-heroicons-calendar-days'
})
}
</script>
<template>
<UButton label="Add to calendar" color="gray" variant="outline" icon="i-heroicons-plus" @click="addToCalendar" />
</template>

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
const props = defineProps<{
icon: string
}>()
const toast = useToast()
function showToast() {
toast.add({
title: 'Uh oh! Something went wrong.',
description: 'There was a problem with your request.',
icon: props.icon
})
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,15 @@
<script setup lang="ts">
const props = defineProps<{
title: string
}>()
const toast = useToast()
function showToast() {
toast.add(props)
}
</script>
<template>
<UButton label="Show toast" color="gray" variant="outline" @click="showToast" />
</template>

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
const appConfig = useAppConfig()
</script>
<template>
<div>
<UFormField
label="toaster.duration"
size="sm"
class="inline-flex ring ring-gray-300 dark:ring-gray-700 rounded"
:ui="{
wrapper: 'bg-gray-50 dark:bg-gray-800/50 rounded-l flex border-r border-gray-300 dark:border-gray-700',
label: 'text-gray-500 dark:text-gray-400 px-2 py-1.5',
container: 'mt-0'
}"
>
<UInput
v-model="appConfig.toaster.duration"
color="gray"
variant="soft"
class="rounded rounded-l-none min-w-12"
:search-input="false"
/>
</UFormField>
</div>
</template>

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
const appConfig = useAppConfig()
</script>
<template>
<div>
<UFormField
label="toaster.expand"
size="sm"
class="inline-flex ring ring-gray-300 dark:ring-gray-700 rounded"
:ui="{
wrapper: 'bg-gray-50 dark:bg-gray-800/50 rounded-l flex border-r border-gray-300 dark:border-gray-700',
label: 'text-gray-500 dark:text-gray-400 px-2 py-1.5',
container: 'mt-0'
}"
>
<USelectMenu
v-model="appConfig.toaster.expand"
:items="[true, false]"
color="gray"
variant="soft"
class="rounded rounded-l-none min-w-12"
:search-input="false"
/>
</UFormField>
</div>
</template>

View File

@@ -0,0 +1,30 @@
<script setup lang="ts">
import theme from '#build/ui/toaster'
const positions = Object.keys(theme.variants.position)
const appConfig = useAppConfig()
</script>
<template>
<div>
<UFormField
label="toaster.position"
size="sm"
class="inline-flex ring ring-gray-300 dark:ring-gray-700 rounded"
:ui="{
wrapper: 'bg-gray-50 dark:bg-gray-800/50 rounded-l flex border-r border-gray-300 dark:border-gray-700',
label: 'text-gray-500 dark:text-gray-400 px-2 py-1.5',
container: 'mt-0'
}"
>
<USelectMenu
v-model="appConfig.toaster.position"
:items="positions"
color="gray"
variant="soft"
class="rounded rounded-l-none min-w-12"
:search-input="false"
/>
</UFormField>
</div>
</template>

10
docs/app/mdc.config.ts Normal file
View File

@@ -0,0 +1,10 @@
import { defineConfig } from '@nuxtjs/mdc/config'
import { transformerColorHighlight } from 'shiki-transformer-color-highlight'
export default defineConfig({
shiki: {
transformers: [
transformerColorHighlight()
]
}
})

View File

@@ -28,9 +28,9 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
const headline = computed(() => findPageHeadline(page.value))
useSeoMeta({
titleTemplate: '%s - Nuxt UI',
title: page.value.title,
ogTitle: `${page.value.title} - Nuxt UI`,
titleTemplate: '%s - Nuxt UI v3',
title: page.value.navigation?.title || page.value.title,
ogTitle: `${page.value.navigation?.title || page.value.title} - Nuxt UI v3`,
description: page.value.description,
ogDescription: page.value.description
})
@@ -39,25 +39,21 @@ defineOgImageComponent('Docs', {
headline: headline.value
})
// const communityLinks = computed(() => [{
// icon: 'i-heroicons-pencil-square',
// label: 'Edit this page',
// to: `https://github.com/nuxt/ui/edit/dev/docs/content/${page?.value?._file}`,
// target: '_blank'
// }, {
// icon: 'i-heroicons-star',
// label: 'Star on GitHub',
// to: 'https://github.com/nuxt/ui',
// target: '_blank'
// }, {
// icon: 'i-heroicons-lifebuoy',
// label: 'Contributing',
// to: '/getting-started/contributing'
// }, {
// label: 'Roadmap',
// icon: 'i-heroicons-map',
// to: '/roadmap'
// }])
const communityLinks = computed(() => [{
icon: 'i-heroicons-pencil-square',
label: 'Edit this page',
to: `https://github.com/nuxt/ui/edit/v3/docs/content/${page?.value?._file}`,
target: '_blank'
}, {
icon: 'i-heroicons-star',
label: 'Star on GitHub',
to: 'https://github.com/nuxt/ui',
target: '_blank'
}, {
label: 'Roadmap',
icon: 'i-heroicons-map',
to: '/roadmap'
}])
// const resourcesLinks = [{
// icon: 'i-simple-icons-figma',
@@ -79,7 +75,7 @@ defineOgImageComponent('Docs', {
<template>
<UPage v-if="page">
<UPageHeader :title="page.title" :links="page.links" :headline="headline" :ui="{}">
<UPageHeader :title="page.title" :links="page.links" :headline="headline">
<template #description>
<MDC v-if="page.description" :value="page.description" unwrap="p" />
</template>
@@ -90,25 +86,25 @@ defineOgImageComponent('Docs', {
<USeparator />
<UContentSurround :surround="surround as any" />
<UContentSurround :surround="(surround as any)" />
</UPageBody>
<template v-if="page?.body?.toc?.links?.length" #right>
<UContentToc :links="page.body.toc.links">
<!-- <template #bottom>
<template #bottom>
<USeparator v-if="page.body?.toc?.links?.length" type="dashed" />
<UPageLinks title="Community" :links="communityLinks" />
<USeparator type="dashed" />
<!-- <USeparator type="dashed" />
<UPageLinks title="Resources" :links="resourcesLinks" />
<USeparator type="dashed" />
<AdsPro />
<AdsCarbon />
</template> -->
<AdsCarbon /> -->
</template>
</UContentToc>
</template>
</UPage>

View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
const title = 'Roadmap'
const description = 'Discover our Volta board for @nuxt/ui development status.'
useSeoMeta({
titleTemplate: '%s - Nuxt UI',
title,
ogTitle: 'Nuxt UI Roadmap',
description
})
defineOgImageComponent('Docs')
const appConfig = useAppConfig()
const colorMode = useColorMode()
const token = 'eyJ2aWV3IjoiYm9hcmQiLCJib2FyZFN0YXR1c2VzIjpbInRyaWFnZSIsImJhY2tsb2ciLCJ0b2RvIiwiaW5fcHJvZ3Jlc3MiLCJpbl9yZXZpZXciLCJkb25lIiwicmVsZWFzZWQiXSwiYm9hcmRMaW5rZWRQcnMiOmZhbHNlLCJsaXN0R3JvdXAiOiJzdGF0ZSIsImxpc3RPcmRlciI6ImNyZWF0ZWRfYXQiLCJ0aW1lbGluZVpvb20iOiJtb250aCIsInRpbWVsaW5lT3JkZXIiOiJzdGF0ZSIsInRpbWVsaW5lRGlzcGxheSI6ImFsbF9taWxlc3RvbmVzIiwiZmlsdGVycyI6e30sIm93bmVyIjoibnV4dCIsIm5hbWUiOiJ1aSJ9'
const src = computed(() => `https://volta.net/embed/${token}?theme=${colorMode.value}&gray=${appConfig.ui.colors.gray}&primary=${appConfig.ui.colors.primary}`)
</script>
<template>
<div class="h-[calc(100vh-var(--header-height)-var(--header-height)-1px)]">
<ClientOnly>
<iframe :src="src" width="100%" height="100%" />
</ClientOnly>
</div>
</template>

View File

@@ -1,7 +1,10 @@
/* eslint-disable no-undef */
import('https://unpkg.com/prettier@3.3.3/standalone.js')
import('https://unpkg.com/prettier@3.3.3/plugins/babel.js')
import('https://unpkg.com/prettier@3.3.3/plugins/estree.js')
import('https://unpkg.com/prettier@3.3.3/plugins/html.js')
import('https://unpkg.com/prettier@3.3.3/plugins/markdown.js')
import('https://unpkg.com/prettier@3.3.3/plugins/typescript.js')
self.onmessage = async function (event) {
self.postMessage({
@@ -19,6 +22,7 @@ function handleMessage(message) {
async function handleFormatMessage(message) {
const { options, source } = message
const formatted = await prettier.format(source, {
parser: 'markdown',
plugins: prettierPlugins,

View File

@@ -1,7 +1,7 @@
---
navigation.title: Introduction
title: Nuxt UI v3
description: A comprehensive, Nuxt-integrated UI library offering powerful components, unparalleled flexibility, and an optimized developer experience.
description: 'A comprehensive, Nuxt-integrated UI library providing a rich set of fully-styled, accessible and highly customizable components for building modern web applications.'
---
We're thrilled to introduce this major update to our UI library, bringing significant improvements and powerful new features. Nuxt UI v3 represents a leap forward in creating robust, accessible, and highly customizable user interfaces for Nuxt applications.
@@ -42,6 +42,26 @@ We've adopted [Tailwind Variants](https://www.tailwind-variants.org/) to manage
This integration unifies the styling of components, ensuring consistency and code maintainability.
### TypeScript Integration
Nuxt UI v3 offers significantly improved TypeScript integration, providing a superior developer experience:
- **Enhanced Auto-completion**:
- Full auto-completion for component props based on your theme
- Intelligent suggestions for `app.config.ts` theme configuration
- **Generic-based Components**:
- Built using [Vue 3 Generics](https://vuejs.org/api/sfc-script-setup.html#generics)
- Improved type inference for slots and events
- **Type-safe Theming**:
- Leveraging Tailwind Variants for type-safe styling options
- Customizable types for extended theme configurations
::note{to="/components/accordion#with-custom-slot"}
Check out an example of the Accordion component with auto-completion for props and slots.
::
## Migration
We want to be transparent: migrating from Nuxt UI v2 to v3 will require significant effort. While we've maintained core concepts and components, Nuxt UI v3 has been rebuilt from the ground up, resulting in a new library with enhanced capabilities.
@@ -66,6 +86,14 @@ Key points to consider:
We're planning to add Vue support in the near future. For now, Nuxt UI v3 is only available for Nuxt. Track progress on Vue compatibility [in this issue](https://github.com/nuxt/ui/issues/2129).
::
::accordion-item{label="How does Nuxt UI v3 handle accessibility?"}
Nuxt UI v3 enhances accessibility through Radix Vue integration. This provides automatic ARIA attributes, keyboard navigation support, intelligent focus management, and screen reader announcements. While offering a strong foundation, proper implementation and testing in your specific use case remains crucial for full accessibility compliance. For more detailed information, refer to [Radix Vue's accessibility documentation](https://www.radix-vue.com/overview/accessibility.html).
::
::accordion-item{label="What is the testing approach for Nuxt UI v3?"}
Nuxt UI v3 ensures reliability with 800+ Vitest tests, covering core functionality and accessibility. This robust testing suite supports the library's stability and serves as a reference for developers.
::
::accordion-item{label="Is this version stable and suitable for production use?"}
As Nuxt UI v3 is currently in alpha, we recommend thorough testing before using it in production environments. We're actively working on stabilization and welcome feedback from early adopters to improve the library. Feel free to report any issues you encounter on our [GitHub repository](https://github.com/nuxt/ui/issues).
::

View File

@@ -76,25 +76,6 @@ export default defineNuxtConfig({
})
```
### `colors`
Use the `colors` option to choose which Tailwind CSS colors are used to generate classes for components.
- Default: `['red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose']`{lang="ts-type"}
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
colors: ['blue', 'green', 'red']
}
})
```
::note{to="/getting-started/colors#build-colors"}
This can help reduce the number of CSS classes generated in your bundle.
::
### `fonts`
Use the `fonts` option to enable or disable the `@nuxt/fonts` module.
@@ -110,6 +91,27 @@ export default defineNuxtConfig({
})
```
### `theme.colors`
Use the `theme.colors` option to choose which Tailwind CSS colors are used to generate classes for components.
- Default: `['red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose']`{lang="ts-type" class="inline"}
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
theme: {
colors: ['blue', 'green', 'red']
}
}
})
```
::note{to="/getting-started/colors#build-colors"}
This can help reduce the number of CSS classes generated in your bundle.
::
### `theme.transitions`
Use the `theme.transitions` option to disable all transitions on components.

View File

@@ -1,10 +1,13 @@
---
description: 'Learn how to customize the appearance of Nuxt UI components using Tailwind CSS.'
title: Theme
description: 'Learn to customize Nuxt UI components using Tailwind CSS v4 and the Tailwind Variants API.'
---
## Tailwind CSS
Since Nuxt UI v3 uses Tailwind CSS v4 alpha which doesn't have a documentation yet, let's have a look on how to use it.
Nuxt UI v3 uses Tailwind CSS v4 alpha which doesn't have a documentation yet, let's have a look on how to use it.
### `@theme`
Tailwind CSS v4 takes a CSS-first configuration approach, you now customize your theme with CSS variables inside a `@theme` directive:
@@ -13,7 +16,7 @@ Tailwind CSS v4 takes a CSS-first configuration approach, you now customize your
@import "@nuxt/ui";
@theme {
--font-family-display: "Inter", "sans-serif";
--font-family-sans: 'Public Sans', sans-serif;
--breakpoint-3xl: 1920px;
@@ -27,7 +30,7 @@ Tailwind CSS v4 takes a CSS-first configuration approach, you now customize your
--color-green-700: #007F45;
--color-green-800: #016538;
--color-green-900: #0A5331;
--color-green-950: #052e16;
--color-green-950: #052E16;
}
```
@@ -39,6 +42,38 @@ You can learn more about this on [https://tailwindcss.com/blog/tailwindcss-v4-al
This is exactly what the [`@import "@nuxt/ui";`](https://github.com/nuxt/ui/blob/v3/src/runtime/index.css) is all about, it extends the default Tailwind CSS theme and declares the `primary`, `error` and `gray` colors to be configurable through the [App Config](https://nuxt.com/docs/guide/directory-structure/app-config#app-config-file) but we'll talk more about that in the [Colors](/getting-started/colors) section.
### `@source`
You can use the `@source` directive to add explicit content glob patterns if you want to look for Tailwind classes in other files that are not automatically detected.
This can be useful when writing Tailwind classes in markdown files with `@nuxt/content`:
```css [main.css]
@import "tailwindcss";
@import "@nuxt/ui";
@source "../content/**/*.md";
```
::note{to="https://github.com/tailwindlabs/tailwindcss/pull/14078"}
You can learn more about the `@source` directive in this pull request.
::
### `@plugin`
You can use the `@plugin` directive to import Tailwind CSS plugins.
```css [main.css]
@import "tailwindcss";
@import "@nuxt/ui";
@plugin "@tailwindcss/typography";
```
::note{to="https://github.com/tailwindlabs/tailwindcss/pull/14264"}
You can learn more about the `@plugin` directive in this pull request.
::
## Tailwind Variants API
Nuxt UI components are styled using the [Tailwind Variants](https://www.tailwind-variants.org/) API, which provides a powerful way to create variants and manage component styles. Let's explore the key features of this API:

View File

@@ -1,5 +1,6 @@
---
description: 'Learn how to customize colors and optimize your color palette for Nuxt UI components.'
title: Colors
description: 'Learn to customize Nuxt UI component colors, enhancing your application visual theme.'
---
## Build colors
@@ -15,7 +16,7 @@ slots:
---
::
You can change these colors with the [`colors`](/getting-started/installation#colors) option in your `nuxt.config.ts` to select only the colors you're actually using.
You can change these colors with the [`theme.colors`](/getting-started/installation#themecolors) option in your `nuxt.config.ts` to select only the colors you're actually using.
For example, if you added a custom `cerise` color and only use the default `blue` and `green` colors in your application, you can configure the `colors` option like this:
@@ -25,7 +26,9 @@ For example, if you added a custom `cerise` color and only use the default `blue
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
colors: ['cerise', 'blue', 'green']
theme: {
colors: ['cerise', 'blue', 'green']
}
}
})
```
@@ -68,9 +71,13 @@ This configuration will ensure that only classes for those three colors are gene
Nuxt UI introduces three key color aliases used to style components:
1. `primary`{color="primary"}: Main brand color. Default: `green`{color="green"}.
2. `error`{color="error"}: For error states. Default: `red`{color="red"}.
3. `gray`: Neutral color for backgrounds, text, etc. Default: `cool`.
- `primary`: Main brand color, used as the default color for components.
- Default: `green`{color="green"}
- `error`: For form error validation states.
- Default: `red`{color="red"}
- `gray`: Neutral color for backgrounds, text, etc.
- Default: `slate`
- `slate | cool | zinc | neutral | stone`
::warning{to="https://tailwindcss.com/docs/customizing-colors#default-color-palette" target="_blank"}
The Tailwind CSS `gray` color is renamed to `cool` in Nuxt UI to avoid conflicts with the `gray` alias.
@@ -83,7 +90,7 @@ export default defineAppConfig({
ui: {
colors: {
primary: 'blue',
error: 'red',
error: 'orange',
gray: 'zinc'
}
}
@@ -101,7 +108,7 @@ These alias colors don't need to be explicitly listed in the `colors` option of
::
::note
You can try this out by clicking on the :prose-icon{name="i-heroicons-swatch-20-solid" class="text-primary-500 dark:text-primary-400"} button in the header of this documentation.
You can try this out by using the :prose-icon{name="i-heroicons-swatch-20-solid" class="text-primary-500 dark:text-primary-400"} menu in the header of this documentation.
::
### Custom aliases

View File

@@ -1,5 +1,6 @@
---
description: 'Nuxt UI integrates seamlessly with `@nuxt/icon`, providing access to over 200,000+ icons from [Iconify](https://iconify.design/).'
title: Icons
description: 'Nuxt UI integrates with `@nuxt/icon` to access over 200,000+ icons from [Iconify](https://iconify.design/).'
links:
- label: 'nuxt/icon'
to: https://github.com/nuxt/icon

View File

@@ -1,5 +1,6 @@
---
description: 'Nuxt UI integrates seamlessly with `@nuxt/fonts`, providing plug-and-play font optimization for your Nuxt applications.'
title: Fonts
description: 'Nuxt UI integrates with `@nuxt/fonts` to provide plug-and-play font optimization.'
links:
- label: 'nuxt/fonts'
to: https://github.com/nuxt/fonts
@@ -19,7 +20,7 @@ Nuxt UI automatically registers the `@nuxt/fonts` module for you, so there's no
@import "@nuxt/ui";
@theme {
--font-family-sans: Inter, sans-serif;
--font-family-sans: 'Public Sans', sans-serif;
}
</style>
```
@@ -29,7 +30,7 @@ Nuxt UI automatically registers the `@nuxt/fonts` module for you, so there's no
@import "@nuxt/ui";
@theme {
--font-family-sans: Inter, sans-serif;
--font-family-sans: 'Public Sans', sans-serif;
}
```

View File

@@ -1,16 +1,16 @@
---
description: 'Nuxt UI integrates seamlessly with `@nuxtjs/color-mode`, offering effortless switching between light and dark themes.'
title: Color Mode
description: 'Nuxt UI integrates with `@nuxtjs/color-mode` to allow for easy switching between light and dark themes.'
links:
- label: 'nuxtjs/color-mode'
to: https://github.com/nuxt-modules/color-mode
target: _blank
icon: i-simple-icons-github
navigation: false
---
## Usage
Nuxt UI automatically registers the `@nuxtjs/color-mode` module for you and takes advantage of [Tailwind CSS dark mode](https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually) class strategy, so there's no additional setup required.
Nuxt UI automatically registers the `@nuxtjs/color-mode` module for you, so there's no additional setup required.
You can disable dark mode by setting the `preference` to `light` instead of `system` in your `nuxt.config.ts`.

View File

@@ -1,5 +0,0 @@
---
title: TypeScript
description: ''
navigation: false
---

View File

@@ -20,7 +20,7 @@ defineShortcuts({
```
- Shortcuts are automatically adjusted for non-macOS platforms, converting `meta` to `ctrl`.
- The composable uses Vue's `useEventListener` to handle keydown events.
- The composable uses VueUse's [`useEventListener`](https://vueuse.org/core/useEventListener/) to handle keydown events.
- For a complete list of available shortcut keys, refer to the [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) API documentation. Note that the key should be written in lowercase.
::tip{to="/components/kbd"}
@@ -35,6 +35,7 @@ Define keyboard shortcuts for your application.
- `config`: An object where keys are shortcut definitions and values are either handler functions or shortcut configuration objects.
- `options`: Optional configuration for the shortcuts behavior.
- `chainDelay`: The delay between key presses to consider the shortcut as chained. Default is `250`.
#### Shortcut Definition
@@ -73,24 +74,6 @@ interface ShortcutConfig {
- `true`: Shortcut triggers even when any input is focused
- `string`: Shortcut only triggers when the specified input (by name) is focused
#### ShortcutsOptions
The `options` parameter allows you to configure the behavior of the shortcuts. It has the following properties:
```ts
interface ShortcutsOptions {
repeat?: boolean
trigger?: 'keydown' | 'keyup'
capture?: boolean
passive?: boolean
}
```
- `repeat`: If `true`, the shortcut will trigger repeatedly while the key is held down. Default is `false`.
- `trigger`: Specifies whether the shortcut should trigger on 'keydown' or 'keyup' events. Default is 'keydown'.
- `capture`: If `true`, the event listener will be set to capture phase. Default is `false`.
- `passive`: If `true`, indicates that the function specified by listener will never call preventDefault(). Default is `false`.
## Examples
### Basic usage

View File

@@ -1,9 +1,7 @@
---
title: useFormField
title: useFormField
description: 'A composable to integrate custom inputs with the Form component'
navigation:
badge:
label: Todo
navigation: false
---
## Usage

View File

@@ -1,9 +1,6 @@
---
title: useModal
description: 'A composable to programmatically control a Modal component.'
navigation:
badge:
label: Todo
---
## Usage
@@ -15,3 +12,103 @@ Use the auto-imported `useModal` composable to programmatically control a [Modal
const modal = useModal()
</script>
```
- The `useModal` composable is created using `createSharedComposable`, ensuring that the same modal state is shared across your entire application.
::tip{to="/components/modal"}
Learn how to customize the appearance and behavior of modals in the **Modal** component documentation.
::
## API
### `open(component: Component, props?: ModalProps & ComponentProps<T>)`
Opens a modal with the specified component and props.
- Parameters:
- `component`: The Vue component to render inside the modal.
- `props`: An optional object of props to pass to both the Modal and the rendered component.
```vue
<script setup lang="ts">
const modal = useModal()
function openModal() {
modal.open(MyModalContent, { title: 'Welcome' })
}
</script>
```
### `close()`
Closes the currently open modal.
```vue
<script setup lang="ts">
const modal = useModal()
async function closeModal() {
await modal.close()
}
</script>
```
### `reset()`
Resets the modal state to its default values.
```vue
<script setup lang="ts">
const modal = useModal()
function resetModal() {
modal.reset()
}
</script>
```
### `patch(props: Partial<ModalProps & ComponentProps<T>>)`
Updates the props of the currently open modal.
```vue
<script setup lang="ts">
const modal = useModal()
function updateModalTitle() {
modal.patch({ title: 'Updated Title' })
}
</script>
```
## Example
Here's a complete example of how to use the `useModal` composable:
```vue
<template>
<div>
<button @click="openModal">Open Modal</button>
<button @click="closeModal">Close Modal</button>
<button @click="updateModalTitle">Update Title</button>
</div>
</template>
<script setup lang="ts">
const modal = useModal()
const openModal = () => {
modal.open(MyModalContent, { title: 'Welcome' })
}
const closeModal = async () => {
await modal.close()
}
const updateModalTitle = () => {
modal.patch({ title: 'Updated Welcome' })
}
</script>
```
In this example, we're using the `useModal` composable to control a modal. We can open it with a specific component and props, close it, and update its props.

View File

@@ -1,9 +1,6 @@
---
title: useSlideover
description: 'A composable to programmatically control a Slideover component.'
navigation:
badge:
label: Todo
---
## Usage
@@ -15,3 +12,103 @@ Use the auto-imported `useSlideover` composable to programmatically control a [S
const slideover = useSlideover()
</script>
```
- The `useSlideover` composable is created using `createSharedComposable`, ensuring that the same slideover state is shared across your entire application.
::tip{to="/components/slideover"}
Learn how to customize the appearance and behavior of slideovers in the **Slideover** component documentation.
::
## API
### `open(component: Component, props?: SlideoverProps & ComponentProps<T>)`
Opens a slideover with the specified component and props.
- Parameters:
- `component`: The Vue component to render inside the slideover.
- `props`: An optional object of props to pass to both the Slideover and the rendered component.
````vue
<script setup lang="ts">
const slideover = useSlideover()
function openSlideover() {
slideover.open(MySlideoverContent, { title: 'Welcome' })
}
</script>
````
### `close(): Promise<void>`
Closes the currently open slideover.
````vue
<script setup lang="ts">
const slideover = useSlideover()
async function closeSlideover() {
await slideover.close()
}
</script>
````
### `reset()`
Resets the slideover state to its default values.
````vue
<script setup lang="ts">
const slideover = useSlideover()
function resetSlideover() {
slideover.reset()
}
</script>
````
### `patch(props: Partial<SlideoverProps & ComponentProps<T>>)`
Updates the props of the currently open slideover.
````vue
<script setup lang="ts">
const slideover = useSlideover()
function updateSlideoverTitle() {
slideover.patch({ title: 'Updated Title' })
}
</script>
````
## Example
Here's a complete example of how to use the `useSlideover` composable:
````vue
<template>
<div>
<button @click="openSlideover">Open Slideover</button>
<button @click="closeSlideover">Close Slideover</button>
<button @click="updateSlideoverTitle">Update Title</button>
</div>
</template>
<script setup lang="ts">
const slideover = useSlideover()
const openSlideover = () => {
slideover.open(MySlideoverContent, { title: 'Welcome' })
}
const closeSlideover = async () => {
await slideover.close()
}
const updateSlideoverTitle = () => {
slideover.patch({ title: 'Updated Welcome' })
}
</script>
````
In this example, we're using the `useSlideover` composable to control a slideover. We can open it with a specific component and props, close it, and update its props.

View File

@@ -13,7 +13,7 @@ const toast = useToast()
</script>
```
- The `useToast` composable uses Vue's `useState` to manage the toast state, ensuring reactivity across your application.
- The `useToast` composable uses Nuxt's `useState` to manage the toast state, ensuring reactivity across your application.
- A maximum of 5 toasts are displayed at a time. When adding a new toast that would exceed this limit, the oldest toast is automatically removed.
- When removing a toast, there's a 200ms delay before it's actually removed from the state, allowing for exit animations.

View File

@@ -135,7 +135,7 @@ props:
---
::
### Icon
### Trailing Icon
Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon) of each item. Defaults to `i-heroicons-chevron-down-20-solid`.
@@ -153,12 +153,12 @@ hide:
- class
props:
class: 'px-4'
trailingIcon: 'i-heroicons-plus'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
items:
- label: 'Icons'
icon: 'i-heroicons-face-smile'
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
trailingIcon: 'i-heroicons-arrow-down'
trailingIcon: 'i-heroicons-plus-20-solid'
- label: 'Colors'
icon: 'i-heroicons-swatch'
content: 'Choose a primary and a gray color from your Tailwind CSS theme.'
@@ -168,7 +168,7 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronDown` key.
::

View File

@@ -110,11 +110,9 @@ props:
Use the `close` prop to display a [Button](/components/button) to dismiss the Alert.
::tip
A `close` event will be emitted when the close button is clicked.
An `update:open` event will be emitted when the close button is clicked.
::
Use the `close-icon` prop to customize the button [Icon](/components/icon). Defaults to `i-heroicons-x-mark-20-solid`.
::component-code
---
prettier: true
@@ -126,15 +124,10 @@ props:
title: 'Heads up!'
description: 'You can change the primary color in your app config.'
close: true
closeIcon: ''
---
::
::tip
You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key.
::
You can pass all the props of the [Button](/components/button) component to customize it.
You can also pass all the props of the [Button](/components/button) component to customize it.
::component-code
---
@@ -154,6 +147,29 @@ props:
---
::
### Close Icon
Use the `close-icon` prop to customize the close button [Icon](/components/icon). Defaults to `i-heroicons-x-mark-20-solid`.
::component-code
---
prettier: true
ignore:
- title
- description
- close
props:
title: 'Heads up!'
description: 'You can change the primary color in your app config.'
close: true
closeIcon: 'i-heroicons-arrow-right'
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key.
::
### Actions
Use the `actions` prop to add some [Button](/components/button) actions to the Alert.

View File

@@ -80,13 +80,13 @@ The `alt` prop is passed to the `img` element as the `alt` attribute.
### With tooltip
You can use the [Tooltip](/components/tooltip) component to display a tooltip when hovering the Avatar.
You can use a [Tooltip](/components/tooltip) component to display a tooltip when hovering the Avatar.
:component-example{name="avatar-tooltip-example"}
### With chip
You can use the [Chip](/components/chip) component to display a chip around the Avatar.
You can use a [Chip](/components/chip) component to display a chip around the Avatar.
:component-example{name="avatar-chip-example"}

View File

@@ -43,7 +43,7 @@ props:
A `span` is rendered instead of a link when the `to` property is not defined.
::
### Separator
### Separator Icon
Use the `separator-icon` prop to customize the [Icon](/components/icon) between each item. Defaults to `i-heroicons-chevron-right-20-solid`.
@@ -67,7 +67,7 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronRight` key.
::

View File

@@ -129,13 +129,10 @@ props:
Use the `loading` prop to show a loading icon and disable the Button.
Use the `loading-icon` prop to customize this icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
props:
loading: true
loadingIcon: ''
trailing: false
slots:
default: Button
@@ -143,10 +140,6 @@ slots:
Button
::
::tip
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
Use the `loading-auto` prop to show the loading icon automatically while the `@click` promise is pending.
:component-example{name="button-loading-auto-example"}
@@ -155,6 +148,25 @@ This also works with the [Form](/components/form) component.
:component-example{name="button-loading-auto-form-example"}
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
props:
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
slots:
default: Button
---
Button
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
### Disabled
Use the `disabled` prop to disable the Button.

View File

@@ -15,7 +15,7 @@ navigation:
## Examples
## API
<!-- ## API
### Props
@@ -31,4 +31,4 @@ navigation:
## Theme
:component-theme
:component-theme -->

View File

@@ -39,17 +39,26 @@ props:
Use the `indeterminate` prop to set the Checkbox to an [indeterminate state](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#indeterminate_state_checkboxes).
Use the `indeterminate-icon` prop to customize this icon. Defaults to `i-heroicons-minus-20-solid`.
::component-code
---
props:
indeterminate: true
---
::
### Indeterminate Icon
Use the `indeterminate-icon` prop to customize the indeterminate icon. Defaults to `i-heroicons-minus-20-solid`.
::component-code
---
props:
indeterminate: true
indeterminateIcon: ''
indeterminateIcon: 'i-heroicons-plus-20-solid'
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.minus` key.
::
@@ -106,7 +115,7 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::

View File

@@ -20,7 +20,6 @@ Then, use the `#content` slot to add the content displayed when the Collapsible
prettier: true
ignore:
- class
class: 'justify-center'
props:
class: 'w-48'
slots:
@@ -48,7 +47,6 @@ Use the `disabled` prop to disable the Collapsible.
prettier: true
ignore:
- class
class: 'justify-center'
props:
class: 'w-48'
disabled: true
@@ -77,7 +75,6 @@ You can control the open state by using the `default-open` prop or the `v-model:
::component-example
---
name: 'collapsible-open-example'
class: 'justify-center'
---
::
@@ -96,7 +93,6 @@ Here is an example with a rotating icon in the Button that indicates the open st
::component-example
---
name: 'collapsible-icon-example'
class: 'justify-center'
---
::

View File

@@ -8,29 +8,22 @@ links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/CommandPalette.vue
navigation:
badge:
label: Todo
---
## Usage
Use the `v-model` directive to control the value of the CommandPalette or the `default-value` prop to set the initial value when you do not need to control its state.
::note
You can also use it without any of these and either use the `select` field on each item and/or the `@update:model-value` event to handle the selection.
::
The CommandPalette component leverages [Fuse.js](https://fusejs.io/) to provide robust and efficient fuzzy search functionality.
### Groups
Use the `groups` prop as an array of objects with the following properties:
When searching for a command, the groups are filtered and the matching commands are presented in order of relevance. Use the `groups` prop as an array of objects with the following properties:
- `id: string`{lang="ts-type"}
- `label?: string`{lang="ts-type"}
- `slot?: string`{lang="ts-type"}
- `items?: CommandPaletteItem[]`{lang="ts-type"}
- `filter?: boolean`{lang="ts-type"}
- `postFilter?: (searchTerm: string, items: T[]) => T[]`{lang="ts-type"}
- [`filter?: boolean`{lang="ts-type"}](#without-internal-search)
- [`postFilter?: (searchTerm: string, items: T[]) => T[]`{lang="ts-type"}](#with-post-filtered-items)
- `highlightedIcon?: string`{lang="ts-type"}
Each group takes some `items` as an array of objects with the following properties:
@@ -43,7 +36,7 @@ Each group takes some `items` as an array of objects with the following properti
- `chip?: ChipProps`{lang="ts-type"}
- `kbds?: string[] | KbdProps[]`{lang="ts-type"}
- `disabled?: boolean`{lang="ts-type"}
- `slot?: string`{lang="ts-type"}
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
- `select?(e?: Event): void`{lang="ts-type"}
::component-code
@@ -57,25 +50,173 @@ external:
class: '!p-0'
props:
groups:
- id: 'users'
label: 'Users'
- id: 'suggestions'
label: 'Suggestions'
items:
- label: 'John Doe'
suffix: 'john.doe@example.com'
icon: 'i-heroicons-user'
- label: 'Jane Doe'
suffix: 'jane.doe@example.com'
icon: 'i-heroicons-user'
- label: 'John Smith'
suffix: 'john.smith@example.com'
icon: 'i-heroicons-user'
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
- id: 'actions'
items:
- label: 'Add new file'
suffix: 'Create a new file in the current directory or workspace.'
icon: 'i-heroicons-document-plus'
kbds:
- meta
- N
- label: 'Add new folder'
suffix: 'Create a new folder in the current directory or workspace.'
icon: 'i-heroicons-folder-plus'
kbds:
- meta
- F
- label: 'Add hashtag'
suffix: 'Add a hashtag to the current item.'
icon: 'i-heroicons-hashtag'
kbds:
- meta
- H
- label: 'Add label'
suffix: 'Add a label to the current item.'
icon: 'i-heroicons-tag'
kbds:
- meta
- L
class: 'flex-1 max-h-80'
---
::
::caution
You must provide an `id` for each group otherwise the group will be ignored.
::
### Placeholder
Use the `placeholder` prop to change the placeholder text.
::component-code
---
collapse: true
ignore:
- class
- groups
external:
- groups
class: '!p-0'
props:
placeholder: 'Search an app...'
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
### Multiple
### Icon
Use the `multiple` prop to allow multiple selections.
Use the `icon` prop to customize the input [Icon](/components/icon). Defaults to `i-heroicons-magnifying-glass-20-solid`.
::component-code
---
collapse: true
ignore:
- class
- groups
external:
- groups
class: '!p-0'
props:
icon: 'i-heroicons-cube'
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.search` key.
::
### Loading
Use the `loading` prop to show a loading icon on the CommandPalette.
::component-code
---
collapse: true
ignore:
- class
- groups
external:
- groups
class: '!p-0'
props:
loading: true
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
collapse: true
ignore:
- class
- groups
external:
- groups
class: '!p-0'
props:
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
### Disabled
Use the `disabled` prop to disable the CommandPalette.
::component-code
---
@@ -87,73 +228,311 @@ external:
- groups
class: '!p-0'
props:
disabled: true
groups:
- id: 'actions'
label: 'Actions'
- id: 'apps'
items:
- label: 'Add new file'
suffix: 'Create a new file in the current directory or workspace.'
icon: 'i-heroicons-document-plus'
kbds:
- 'meta'
- 'N'
- label: 'Add new folder'
suffix: 'Create a new folder in the current directory or workspace.'
icon: 'i-heroicons-folder-plus'
kbds:
- 'meta'
- 'F'
- label: 'Add hashtag'
suffix: 'Add a hashtag to the current item.'
icon: 'i-heroicons-hashtag'
kbds:
- 'meta'
- 'H'
- label: 'Add label'
suffix: 'Add a label to the current item.'
icon: 'i-heroicons-tag'
kbds:
- 'meta'
- 'L'
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
### Placeholder
### Icon
### Loading
### Disabled
### Close
Use the `close` prop to display a [Button](/components/button) to dismiss the CommandPalette.
::tip
An `update:open` event will be emitted when the close button is clicked.
::
::component-code
---
collapse: true
ignore:
- class
- groups
- close
external:
- groups
class: '!p-0'
props:
close: true
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
You can also pass all the props of the [Button](/components/button) component to customize it.
::component-code
---
collapse: true
prettier: true
ignore:
- close.color
- close.variant
- groups
- class
external:
- groups
class: '!p-0'
props:
close:
color: primary
variant: outline
class: 'rounded-full'
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
### Close Icon
Use the `close-icon` prop to customize the close button [Icon](/components/icon). Defaults to `i-heroicons-x-mark-20-solid`.
::component-code
---
collapse: true
ignore:
- class
- groups
- close
external:
- groups
class: '!p-0'
props:
close: true
closeIcon: 'i-heroicons-arrow-right'
groups:
- id: 'apps'
items:
- label: 'Calendar'
icon: 'i-heroicons-calendar'
- label: 'Music'
icon: 'i-heroicons-musical-note'
- label: 'Maps'
icon: 'i-heroicons-map'
class: 'flex-1'
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key.
::
## Examples
### Control selected item(s)
You can control the selected item by using the `default-value` prop or the `v-model` directive.
::component-example
---
collapse: true
name: 'command-palette-model-value-example'
class: '!p-0'
---
::
::note
You can also use the `select` field on each item and/or the `@update:model-value` event.
::
Use the `multiple` prop to allow multiple selections.
::component-example
---
collapse: true
name: 'command-palette-model-value-multiple-example'
class: '!p-0'
---
::
::caution
Ensure to pass an array to the `default-value` prop or the `v-model` directive.
::
### Control search term
### Control selected value
Use the `v-model:search-term` directive to control the search term.
::component-example
---
collapse: true
name: 'command-palette-search-term-example'
class: '!p-0'
---
::
### With fetched items
### With filtered items
You can fetch items from an API and use them in the CommandPalette.
### Within a modal
::component-example
---
collapse: true
name: 'command-palette-fetch-example'
class: '!p-0'
---
::
### Within a drawer
### Without internal search
You can set the `filter` field to `false` on a group to disable the internal search and use your own search logic.
::component-example
---
collapse: true
name: 'command-palette-filter-example'
class: '!p-0'
---
::
::note
This example uses [refDebounced](https://vueuse.org/shared/refDebounced/#refdebounced) to debounce the API calls.
::
### With post-filtered items
You can use the `postFilter` field on a group to filter items after the search happened.
::component-example
---
collapse: true
name: 'command-palette-post-filter-example'
class: '!p-0'
---
::
::note
Start typing to see items with higher level appear.
::
### With custom fuse search
You can use the `fuse` prop to override the options of [useFuse](https://vueuse.org/integrations/useFuse) which defaults to:
```ts
{
fuseOptions: {
ignoreLocation: true,
threshold: 0.1,
keys: ['label', 'suffix']
},
resultLimit: 12,
matchAllWhenSearchEmpty: true
}
```
::tip
The `fuseOptions` are the options of [Fuse.js](https://www.fusejs.io/api/options.html), the `resultLimit` is the maximum number of results to return and the `matchAllWhenSearchEmpty` is a boolean to match all items when the search term is empty.
::
You can for example set `{ fuseOptions: { includeMatches: true } }`{lang="ts-type"} to highlight the search term in the items.
::component-example
---
collapse: true
name: 'command-palette-fuse-example'
class: '!p-0'
---
::
### Within a popover
You can use the CommandPalette component inside a [Popover](/components/popover)'s content.
::component-example
---
collapse: true
name: 'popover-command-palette-example'
---
::
### Within a modal
You can use the CommandPalette component inside a [Modal](/components/modal)'s content.
::component-example
---
collapse: true
name: 'modal-command-palette-example'
---
::
### Within a drawer
You can use the CommandPalette component inside a [Drawer](/components/drawer)'s content.
::component-example
---
collapse: true
name: 'drawer-command-palette-example'
---
::
### Listen open state
### With custom search
When using the `close` prop, you can listen to the `update:open` event when the button is clicked.
### With highlighted search
::component-example
---
collapse: true
name: 'command-palette-open-example'
---
::
::note
This can be useful when using the CommandPalette inside a [Modal](/components/modal) for example.
::
### With custom slot
### With empty slot
Use the `slot` property to customize a specific item or group.
You will have access to the following slots:
- `#{{ item.slot }}`{lang="ts-type"}
- `#{{ item.slot }}-leading`{lang="ts-type"}
- `#{{ item.slot }}-label`{lang="ts-type"}
- `#{{ item.slot }}-trailing`{lang="ts-type"}
- `#{{ group.slot }}`{lang="ts-type"}
- `#{{ group.slot }}-leading`{lang="ts-type"}
- `#{{ group.slot }}-label`{lang="ts-type"}
- `#{{ group.slot }}-trailing`{lang="ts-type"}
::component-example
---
name: 'command-palette-custom-slot-example'
class: '!p-0'
---
::
::tip{to="#slots"}
You can also use the `#item`, `#item-leading`, `#item-label` and `#item-trailing` slots to customize all items.
::
## API

View File

@@ -39,7 +39,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
items:
- - label: Appearance
@@ -119,7 +118,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
size: xl
items:
@@ -153,7 +151,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
disabled: true
items:
@@ -191,7 +188,6 @@ You will have access to the following slots:
::component-example
---
name: 'context-menu-custom-slot-example'
class: 'justify-center'
---
::

View File

@@ -1,5 +1,5 @@
---
description: A drawer that slides in from the bottom of the screen.
description: A drawer that smoothly slides in & out of the screen.
links:
- label: Drawer
icon: i-custom-radix-vue
@@ -18,7 +18,6 @@ Then, use the `#content` slot to add the content displayed when the Drawer is op
::component-code
---
prettier: true
class: 'justify-center'
slots:
default: |
@@ -44,7 +43,6 @@ Use the `title` prop to set the title of the Drawer's header.
::component-code
---
prettier: true
class: 'justify-center'
props:
title: 'Drawer with title'
slots:
@@ -70,7 +68,6 @@ Use the `description` prop to set the description of the Drawer's header.
::component-code
---
prettier: true
class: 'justify-center'
ignore:
- title
props:
@@ -92,6 +89,85 @@ slots:
:placeholder{class="h-48"}
::
### Direction
Use the `direction` prop to control the direction of the Drawer. Defaults to `bottom`.
::component-code
---
prettier: true
items:
direction:
- top
- bottom
props:
direction: 'top'
slots:
default: |
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
content: |
<Placeholder class="h-96 m-4" />
---
:u-button{label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid"}
#content
:placeholder{class="h-96 m-4"}
::
::component-code
---
prettier: true
items:
direction:
- right
- left
props:
direction: 'right'
slots:
default: |
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
content: |
<Placeholder class="w-96 m-4" />
---
:u-button{label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid"}
#content
:placeholder{class="w-96 m-4"}
::
### Handle
Use the `handle` prop to control whether the Drawer has a handle or not. Defaults to `true`.
::component-code
---
prettier: true
props:
handle: false
slots:
default: |
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
content: |
<Placeholder class="h-48 m-4" />
---
:u-button{label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid"}
#content
:placeholder{class="h-48 m-4"}
::
### Overlay
Use the `overlay` prop to control whether the Drawer has an overlay or not. Defaults to `true`.
@@ -99,7 +175,6 @@ Use the `overlay` prop to control whether the Drawer has an overlay or not. Defa
::component-code
---
prettier: true
class: 'justify-center'
props:
overlay: false
slots:
@@ -125,7 +200,6 @@ Use the `should-scale-background` prop to scale the background when the Drawer i
::component-code
---
prettier: true
class: 'justify-center'
props:
shouldScaleBackground: true
slots:
@@ -179,8 +253,8 @@ You can control the open state by using the `default-open` prop or the `v-model:
::component-example
---
prettier: true
name: 'drawer-open-example'
class: 'justify-center'
---
::
@@ -198,20 +272,20 @@ Use the `#footer` slot to add content after the Drawer's body.
::component-example
---
prettier: true
collapse: true
name: 'drawer-footer-slot-example'
class: 'justify-center'
---
::
### With command palette
You can use the [CommandPalette](/components/command-palette) component inside the Drawer's content.
You can use a [CommandPalette](/components/command-palette) component inside the Drawer's content.
::component-example
---
collapse: true
name: 'drawer-command-palette-example'
class: 'justify-center'
---
::

View File

@@ -39,7 +39,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
items:
- - label: Benjamin
@@ -128,7 +127,6 @@ items:
- left
- top
- bottom
class: 'justify-center'
props:
items:
- label: Profile
@@ -164,7 +162,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
arrow: true
items:
@@ -197,7 +194,6 @@ ignore:
- content.align
external:
- items
class: 'justify-center'
props:
size: xl
items:
@@ -239,7 +235,6 @@ ignore:
- class
external:
- items
class: 'justify-center'
props:
disabled: true
items:
@@ -268,7 +263,6 @@ You can control the open state by using the `default-open` prop or the `v-model:
::component-example
---
name: 'dropdown-menu-open-example'
class: 'justify-center'
---
::
@@ -290,7 +284,6 @@ You will have access to the following slots:
::component-example
---
name: 'dropdown-menu-custom-slot-example'
class: 'justify-center'
---
::

View File

@@ -8,15 +8,640 @@ links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/InputMenu.vue
navigation:
badge:
label: Todo
---
## Usage
Use the `v-model` directive to control the value of the InputMenu or the `default-value` prop to set the initial value when you do not need to control its state.
::tip
Use this over an [Input](/components/input) to take advantage of Radix Vue's [Combobox](https://www.radix-vue.com/components/combobox.html) component that offers autocomplete capabilities.
::
::note
This component is similar to the [SelectMenu](/components/select-menu) but it's using an Input instead of a Select.
::
### Items
Use the `items` prop as an array of strings, numbers or booleans:
::component-code
---
prettier: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
You can also pass an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- [`type?: "label" | "separator" | "item"`{lang="ts-type"}](#with-typed-items)
- [`icon?: string`{lang="ts-type"}](#with-icons-in-items)
- [`avatar?: AvatarProps`{lang="ts-type"}](#with-avatar-in-items)
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
- `disabled?: boolean`{lang="ts-type"}
- `select?(e: Event): void`{lang="ts-type"}
::component-code
---
ignore:
- modelValue.label
- items
external:
- items
- modelValue
props:
modelValue:
label: 'Todo'
items:
- label: 'Backlog'
- label: 'Todo'
- label: 'In Progress'
- label: 'Done'
---
::
You can also pass an array of arrays to the `items` prop to display separated groups of items.
::component-code
---
prettier: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Apple'
items:
- - Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- - Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
---
::
### Value Key
You can choose to bind a single property of the object rather than the whole object by using the `value-key` prop. Defaults to `undefined`.
::component-code
---
collapse: true
ignore:
- modelValue
- valueKey
- items
external:
- items
- modelValue
props:
modelValue: 'todo'
valueKey: 'id'
items:
- label: 'Backlog'
id: 'backlog'
- label: 'Todo'
id: 'todo'
- label: 'In Progress'
id: 'in_progress'
- label: 'Done'
id: 'done'
---
::
### Multiple
Use the `multiple` prop to allow multiple selections, the selected items will be displayed as badges.
::component-code
---
prettier: true
ignore:
- modelValue
- items
- multiple
external:
- items
- modelValue
props:
modelValue:
- Backlog
- Todo
multiple: true
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::caution
Ensure to pass an array to the `default-value` prop or the `v-model` directive.
::
### Delete Icon
With `multiple`, use the `delete-icon` prop to customize the delete [Icon](/components/icon) in the badges. Defaults to `i-heroicons-x-mark-20-solid`.
::component-code
---
prettier: true
ignore:
- modelValue
- items
- multiple
external:
- items
- modelValue
props:
modelValue:
- Backlog
- Todo
multiple: true
deleteIcon: 'i-heroicons-trash'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key.
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
::component-code
---
prettier: true
ignore:
- items
external:
- items
props:
placeholder: 'Select status'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Content
Use the `content` prop to control how the InputMenu content is rendered, like its `align` or `side` for example.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
items:
content.align:
- start
- center
- end
content.side:
- right
- left
- top
- bottom
props:
modelValue: Backlog
content:
align: center
side: bottom
sideOffset: 8
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Color
Use the `color` prop to change the ring color when the InputMenu is focused.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: gray
highlight: true
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::note
The `highlight` prop is used here to show the focus state. It's used internally when a validation error occurs.
::
### Variant
Use the `variant` prop to change the variant of the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: gray
variant: subtle
highlight: false
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Size
Use the `size` prop to change the size of the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
size: xl
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Icon
Use the `icon` prop to show an [Icon](/components/icon) inside the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
icon: 'i-heroicons-magnifying-glass'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Trailing Icon
Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon). Defaults to `i-heroicons-chevron-down-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronDown` key.
::
### Selected Icon
Use the `selected-icon` prop to customize the icon when an item is selected. Defaults to `i-heroicons-check-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
selectedIcon: 'i-heroicons-fire'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
### Loading
Use the `loading` prop to show a loading icon on the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
trailing: false
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
### Disabled
Use the `disabled` prop to disable the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- placeholder
external:
- items
props:
disabled: true
placeholder: 'Select status'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
## Examples
### With typed items
You can use the `type` property with `separator` to display a separator between items or `label` to display a label.
::component-code
---
collapse: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Apple'
items:
- type: 'label'
label: 'Fruits'
- Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- type: 'separator'
- type: 'label'
label: 'Vegetables'
- Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
---
::
### With icons in items
You can use the `icon` property to display an [Icon](/components/icon) inside the items.
::component-example
---
collapse: true
name: 'input-menu-items-icon-example'
---
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
::
### With avatar in items
You can use the `avatar` property to display an [Avatar](/components/avatar) inside the items.
::component-example
---
collapse: true
name: 'input-menu-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::
### With chip in items
You can use the `chip` property to display a [Chip](/components/chip) inside the items.
::component-example
---
collapse: true
name: 'input-menu-items-chip-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected chip.
::
### Control open state
You can control the open state by using the `default-open` prop or the `v-model:open` directive.
::component-example
---
name: 'input-menu-open-example'
---
::
::note
In this example, press :kbd{value="O"} to toggle the InputMenu.
::
### Control search term
Use the `v-model:search-term` directive to control the search term.
::component-example
---
name: 'input-menu-search-term-example'
---
::
### With rotating icon
Here is an example with a rotating icon that indicates the open state of the InputMenu.
::component-example
---
name: 'input-menu-icon-example'
---
::
### With fetched items
You can fetch items from an API and use them in the InputMenu.
::component-example
---
collapse: true
name: 'input-menu-fetch-example'
---
::
### Without internal search
Set the `filter` prop to `false` to disable the internal search and use your own search logic.
::component-example
---
collapse: true
name: 'input-menu-filter-example'
---
::
::note
This example uses [refDebounced](https://vueuse.org/shared/refDebounced/#refdebounced) to debounce the API calls.
::
### With custom search
Use the `filter` prop with an array of fields to filter on.
::component-example
---
collapse: true
name: 'input-menu-filter-fields-example'
---
::
## API
### Props

View File

@@ -140,7 +140,20 @@ props:
Use the `loading` prop to show a loading icon on the Input.
Use the `loading-icon` prop to customize this icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
ignore:
- placeholder
props:
loading: true
trailing: false
placeholder: 'Search...'
---
::
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
@@ -148,13 +161,12 @@ ignore:
- placeholder
props:
loading: true
loadingIcon: ''
trailing: false
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
placeholder: 'Search...'
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::

View File

@@ -18,7 +18,6 @@ Then, use the `#content` slot to add the content displayed when the Modal is ope
::component-code
---
prettier: true
class: 'justify-center'
slots:
default: |
@@ -44,7 +43,6 @@ Use the `title` prop to set the title of the Modal's header.
::component-code
---
prettier: true
class: 'justify-center'
props:
title: 'Modal with title'
slots:
@@ -70,7 +68,6 @@ Use the `description` prop to set the description of the Modal's header.
::component-code
---
prettier: true
class: 'justify-center'
ignore:
- title
props:
@@ -94,18 +91,13 @@ slots:
### Close
Use the `close` prop to customize or hide the close button displayed in the Modal's header. You can pass all the props of the [Button](/components/button) component to customize it.
Use the `close` prop to customize or hide the close button (with `false` value) displayed in the Modal's header.
::tip
The close button is not displayed if the `#content` slot is used as it's a part of the header.
::
Use the `close-icon` prop to customize the button [Icon](/components/icon). Defaults to `i-heroicons-x-mark-20-solid`.
You can pass all the props of the [Button](/components/button) component to customize it.
::component-code
---
prettier: true
class: 'justify-center'
ignore:
- title
- close.color
@@ -116,7 +108,6 @@ props:
color: primary
variant: outline
class: 'rounded-full'
closeIcon: ''
slots:
default: |
@@ -134,6 +125,38 @@ slots:
::
::tip
The close button is not displayed if the `#content` slot is used as it's a part of the header.
::
### Close Icon
Use the `close-icon` prop to customize the close button [Icon](/components/icon). Defaults to `i-heroicons-x-mark-20-solid`.
::component-code
---
prettier: true
ignore:
- title
props:
title: 'Modal with close button'
closeIcon: 'i-heroicons-arrow-right'
slots:
default: |
<UButton label="Open" color="gray" variant="subtle" />
body: |
<Placeholder class="h-48" />
---
:u-button{label="Open" color="gray" variant="subtle"}
#body
:placeholder{class="h-48"}
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.close` key.
::
@@ -146,7 +169,6 @@ Use the `overlay` prop to control whether the Modal has an overlay or not. Defau
prettier: true
ignore:
- title
class: 'justify-center'
props:
overlay: false
title: 'Modal without overlay'
@@ -175,7 +197,6 @@ Use the `transition` prop to control whether the Modal is animated or not. Defau
prettier: true
ignore:
- title
class: 'justify-center'
props:
transition: false
title: 'Modal without transition'
@@ -205,7 +226,6 @@ prettier: true
ignore:
- title
- fullscreen
class: 'justify-center'
props:
fullscreen: true
title: 'Modal fullscreen'
@@ -235,7 +255,6 @@ prettier: true
ignore:
- title
- preventClose
class: 'justify-center'
props:
preventClose: true
title: 'Modal prevent close'
@@ -264,7 +283,6 @@ You can control the open state by using the `default-open` prop or the `v-model:
::component-example
---
name: 'modal-open-example'
class: 'justify-center'
---
::
@@ -298,7 +316,6 @@ Then, use it in your app:
::component-example
---
name: 'modal-programmatic-example'
class: 'justify-center'
---
::
@@ -313,7 +330,6 @@ You can nest modals within each other.
::component-example
---
name: 'modal-nested-example'
class: 'justify-center'
---
::
@@ -324,19 +340,17 @@ Use the `#footer` slot to add content after the Modal's body.
::component-example
---
name: 'modal-footer-slot-example'
class: 'justify-center'
---
::
### With command palette
You can use the [CommandPalette](/components/command-palette) component inside the Modal's content.
You can use a [CommandPalette](/components/command-palette) component inside the Modal's content.
::component-example
---
collapse: true
name: 'modal-command-palette-example'
class: 'justify-center'
---
::

View File

@@ -279,7 +279,7 @@ props:
The `highlight` prop changes the `pill` variant active item style. Try it out to see the difference.
::
### Icon
### Trailing Icon
Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon) of each item. Defaults to `i-heroicons-chevron-down-20-solid`. This icon is only displayed when an item has children.
@@ -296,7 +296,7 @@ ignore:
external:
- items
props:
trailingIcon: 'i-heroicons-plus'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
items:
- label: Guide
icon: i-heroicons-book-open
@@ -370,7 +370,7 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronDown` key.
::
@@ -497,7 +497,6 @@ You will have access to the following slots:
::component-example
---
name: 'navigation-menu-custom-slot-example'
class: 'justify-center'
---
::

View File

@@ -7,15 +7,356 @@ links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/Pagination.vue
navigation:
badge:
label: Todo
---
## Usage
Use the `default-page` prop or the `v-model:page` directive to control the current page.
::note
The Pagination component uses some [Button](/components/button) to display the pages, use [`color`](#color), [`variant`](#variant) and [`size`](#size) props to style them.
::
### Total
Use the `total` prop to set the total number of items in the list.
::component-code
---
external:
- page
model:
- page
props:
page: 5
total: 100
---
::
### Items Per Page
Use the `items-per-page` prop to set the number of items per page. Defaults to `10`.
::component-code
---
ignore:
- page
external:
- page
model:
- page
props:
page: 5
itemsPerPage: 20
total: 100
---
::
### Sibling Count
Use the `sibling-count` prop to set the number of siblings to show. Defaults to `2`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
props:
page: 5
siblingCount: 1
total: 100
---
::
### Show Edges
Use the `show-edges` prop to always show the ellipsis, first and last pages. Defaults to `false`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
props:
page: 5
showEdges: true
siblingCount: 1
total: 100
---
::
### Show Controls
Use the `show-controls` prop to show the first, prev, next and last buttons. Defaults to `true`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
props:
page: 5
showControls: false
showEdges: true
total: 100
---
::
### Color
Use the `color` prop to set the color of the inactive controls. Defaults to `gray`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
items:
color:
- primary
- green
- red
- orange
- amber
- yellow
- lime
- emerald
- teal
- cyan
- sky
- blue
- indigo
- violet
- purple
- fuchsia
- pink
- rose
- gray
props:
page: 5
color: primary
total: 100
---
::
### Variant
Use the `variant` prop to set the variant of the inactive controls. Defaults to `outline`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
items:
color:
- primary
- green
- red
- orange
- amber
- yellow
- lime
- emerald
- teal
- cyan
- sky
- blue
- indigo
- violet
- purple
- fuchsia
- pink
- rose
- gray
variant:
- solid
- outline
- soft
- subtle
- ghost
- link
props:
page: 5
color: gray
variant: subtle
total: 100
---
::
### Active Color
Use the `active-color` prop to set the color of the active control. Defaults to `primary`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
items:
activeColor:
- primary
- green
- red
- orange
- amber
- yellow
- lime
- emerald
- teal
- cyan
- sky
- blue
- indigo
- violet
- purple
- fuchsia
- pink
- rose
- gray
props:
page: 5
activeColor: gray
total: 100
---
::
### Active Variant
Use the `active-variant` prop to set the variant of the active control. Defaults to `solid`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
items:
activeColor:
- primary
- green
- red
- orange
- amber
- yellow
- lime
- emerald
- teal
- cyan
- sky
- blue
- indigo
- violet
- purple
- fuchsia
- pink
- rose
- gray
activeVariant:
- solid
- outline
- soft
- subtle
- ghost
- link
props:
page: 5
activeColor: primary
activeVariant: subtle
total: 100
---
::
### Size
Use the `size` prop to set the size of the controls. Defaults to `md`.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
items:
size:
- xs
- sm
- md
- lg
- xl
props:
page: 5
size: xl
total: 100
---
::
### Disabled
Use the `disabled` prop to disable the pagination controls.
::component-code
---
ignore:
- page
- total
external:
- page
model:
- page
props:
page: 5
total: 100
disabled: true
---
::
## Examples
### With links
Use the `to` prop to transform buttons into links. Pass a function that receives the page number and returns a route destination.
::component-example
---
name: 'pagination-links-example'
---
::
::note
In this example we're adding the `#with-links` hash to avoid going to the top of the page.
::
## API
### Props

View File

@@ -18,7 +18,6 @@ Then, use the `#content` slot to add the content displayed when the Popover is o
::component-code
---
prettier: true
class: 'justify-center'
slots:
default: |
@@ -42,7 +41,6 @@ Use the `mode` prop to change the mode of the Popover. Defaults to `click`.
::component-code
---
prettier: true
class: 'justify-center'
items:
mode:
- click
@@ -76,7 +74,6 @@ When using the `hover` mode, you can use the `open-delay` and `close-delay` prop
::component-code
---
prettier: true
class: 'justify-center'
ignore:
- mode
props:
@@ -106,7 +103,6 @@ Use the `content` prop to control how the Popover content is rendered, like its
::component-code
---
prettier: true
class: 'justify-center'
items:
content.align:
- start
@@ -145,7 +141,6 @@ Use the `arrow` prop to display an arrow on the Popover.
::component-code
---
prettier: true
class: 'justify-center'
ignore:
- arrow
props:
@@ -175,7 +170,6 @@ You can control the open state by using the `default-open` prop or the `v-model:
::component-example
---
name: 'popover-open-example'
class: 'justify-center'
---
::
@@ -183,6 +177,17 @@ class: 'justify-center'
In this example, press :kbd{value="O"} to toggle the Popover.
::
### With command palette
You can use a [CommandPalette](/components/command-palette) component inside the Popover's content.
::component-example
---
collapse: true
name: 'popover-command-palette-example'
---
::
## API
### Props

View File

@@ -102,7 +102,6 @@ Use the `orientation` prop to change the orientation of the Progress. Defaults t
---
ignore:
- class
class: 'justify-center'
props:
orientation: vertical
class: 'h-48'

View File

@@ -25,8 +25,8 @@ ignore:
- modelValue
- items
external:
- modelValue
- items
- modelValue
props:
modelValue: 'System'
items:
@@ -49,8 +49,8 @@ ignore:
- modelValue
- items
external:
- modelValue
- items
- modelValue
props:
modelValue: 'system'
items:
@@ -70,9 +70,9 @@ props:
When using objects, you need to reference the `value` property of the object in the `v-model` directive or the `default-value` prop.
::
#### Value Key
### Value Key
You can change the property that is used to set the value by using the `value-key` prop.
You can change the property that is used to set the value by using the `value-key` prop. Defaults to `value`.
::component-code
---
@@ -81,8 +81,8 @@ ignore:
- items
- valueKey
external:
- modelValue
- items
- modelValue
props:
modelValue: 'light'
valueKey: 'id'

View File

@@ -8,15 +8,648 @@ links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/SelectMenu.vue
navigation:
badge:
label: Todo
---
## Usage
Use the `v-model` directive to control the value of the SelectMenu or the `default-value` prop to set the initial value when you do not need to control its state.
::tip
Use this over a [Select](/components/select) to take advantage of Radix Vue's [Combobox](https://www.radix-vue.com/components/combobox.html) component that offers search capabilities and multiple selection.
::
::note
This component is similar to the [InputMenu](/components/input-menu) but it's using a Select instead of an Input with the search inside the menu.
::
### Items
Use the `items` prop as an array of strings, numbers or booleans:
::component-code
---
prettier: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
You can also pass an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- [`type?: "label" | "separator" | "item"`{lang="ts-type"}](#with-typed-items)
- [`icon?: string`{lang="ts-type"}](#with-icons-in-items)
- [`avatar?: AvatarProps`{lang="ts-type"}](#with-avatar-in-items)
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
- `disabled?: boolean`{lang="ts-type"}
- `select?(e: Event): void`{lang="ts-type"}
::component-code
---
ignore:
- modelValue.label
- items
external:
- items
- modelValue
props:
modelValue:
label: 'Todo'
items:
- label: 'Backlog'
- label: 'Todo'
- label: 'In Progress'
- label: 'Done'
---
::
::note
Unlike the [Select](/components/select) component, the SelectMenu expects the whole object to be passed to the `v-model` directive or the `default-value` prop by default.
::
You can also pass an array of arrays to the `items` prop to display separated groups of items.
::component-code
---
prettier: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Apple'
items:
- - Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- - Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
---
::
### Value Key
You can choose to bind a single property of the object rather than the whole object by using the `value-key` prop. Defaults to `undefined`.
::component-code
---
collapse: true
ignore:
- modelValue
- valueKey
- items
external:
- items
- modelValue
props:
modelValue: 'todo'
valueKey: 'id'
items:
- label: 'Backlog'
id: 'backlog'
- label: 'Todo'
id: 'todo'
- label: 'In Progress'
id: 'in_progress'
- label: 'Done'
id: 'done'
---
::
### Multiple
Use the `multiple` prop to allow multiple selections, the selected items will be separated by a comma in the trigger.
::component-code
---
prettier: true
ignore:
- modelValue
- items
- multiple
external:
- items
- modelValue
props:
modelValue:
- Backlog
- Todo
multiple: true
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::caution
Ensure to pass an array to the `default-value` prop or the `v-model` directive.
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
::component-code
---
prettier: true
ignore:
- items
external:
- items
props:
placeholder: 'Select status'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Search Input
Use the `search-input` prop to customize the search input. Defaults to `{ placeholder: 'Search...' }`{lang="ts-type"}.
::component-code
---
prettier: true
ignore:
- modelValue.label
- modelValue.icon
- items
external:
- items
- modelValue
props:
modelValue:
label: 'Backlog'
icon: 'i-heroicons-question-mark-circle'
searchInput:
placeholder: 'Filter...'
items:
- label: Backlog
icon: 'i-heroicons-question-mark-circle'
- label: Todo
icon: 'i-heroicons-plus-circle'
- label: In Progress
icon: 'i-heroicons-arrow-up-circle'
- label: Done
icon: 'i-heroicons-check-circle'
---
::
::tip
You can set the `search-input` prop to `false` to hide the search input.
::
### Content
Use the `content` prop to control how the SelectMenu content is rendered, like its `align` or `side` for example.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
items:
content.align:
- start
- center
- end
content.side:
- right
- left
- top
- bottom
props:
modelValue: Backlog
content:
align: center
side: bottom
sideOffset: 8
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Color
Use the `color` prop to change the ring color when the SelectMenu is focused.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: gray
highlight: true
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::note
The `highlight` prop is used here to show the focus state. It's used internally when a validation error occurs.
::
### Variant
Use the `variant` prop to change the variant of the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: gray
variant: subtle
highlight: false
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Size
Use the `size` prop to change the size of the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
size: xl
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Icon
Use the `icon` prop to show an [Icon](/components/icon) inside the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
icon: 'i-heroicons-magnifying-glass'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Trailing Icon
Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon). Defaults to `i-heroicons-chevron-down-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronDown` key.
::
### Selected Icon
Use the `selected-icon` prop to customize the icon when an item is selected. Defaults to `i-heroicons-check-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
selectedIcon: 'i-heroicons-fire'
size: md
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
### Loading
Use the `loading` prop to show a loading icon on the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
trailing: false
items:
- Backlog
- Todo
- In Progress
- Done
---
::
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
### Disabled
Use the `disabled` prop to disable the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- placeholder
external:
- items
props:
disabled: true
placeholder: 'Select status'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
## Examples
### With typed items
You can use the `type` property with `separator` to display a separator between items or `label` to display a label.
::component-code
---
collapse: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Apple'
items:
- type: 'label'
label: 'Fruits'
- Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- type: 'separator'
- type: 'label'
label: 'Vegetables'
- Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
---
::
### With icons in items
You can use the `icon` property to display an [Icon](/components/icon) inside the items.
::component-example
---
collapse: true
name: 'select-menu-items-icon-example'
---
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
::
### With avatar in items
You can use the `avatar` property to display an [Avatar](/components/avatar) inside the items.
::component-example
---
collapse: true
name: 'select-menu-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::
### With chip in items
You can use the `chip` property to display a [Chip](/components/chip) inside the items.
::component-example
---
collapse: true
name: 'select-menu-items-chip-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected chip.
::
### Control open state
You can control the open state by using the `default-open` prop or the `v-model:open` directive.
::component-example
---
name: 'select-menu-open-example'
---
::
::note
In this example, press :kbd{value="O"} to toggle the SelectMenu.
::
### Control search term
Use the `v-model:search-term` directive to control the search term.
::component-example
---
name: 'select-menu-search-term-example'
---
::
### With rotating icon
Here is an example with a rotating icon that indicates the open state of the SelectMenu.
::component-example
---
name: 'select-menu-icon-example'
---
::
### With fetched items
You can fetch items from an API and use them in the SelectMenu.
::component-example
---
collapse: true
name: 'select-menu-fetch-example'
---
::
### Without internal search
Set the `filter` prop to `false` to disable the internal search and use your own search logic.
::component-example
---
collapse: true
name: 'select-menu-filter-example'
---
::
::note
This example uses [refDebounced](https://vueuse.org/shared/refDebounced/#refdebounced) to debounce the API calls.
::
### With custom search
Use the `filter` prop with an array of fields to filter on.
::component-example
---
collapse: true
name: 'select-menu-filter-fields-example'
---
::
## API
### Props

View File

@@ -19,12 +19,13 @@ Use the `items` prop as an array of strings, numbers or booleans:
::component-code
---
prettier: true
ignore:
- modelValue
- items
external:
- modelValue
- items
- modelValue
props:
modelValue: 'Backlog'
items:
@@ -39,21 +40,20 @@ You can also pass an array of objects with the following properties:
- `label?: string`{lang="ts-type"}
- [`value?: string`{lang="ts-type"}](#value-key)
- [`type?: "label" | "separator" | "item"`{lang="ts-type"}](#items-type)
- [`icon?: string`{lang="ts-type"}](#items-icon)
- [`avatar?: AvatarProps`{lang="ts-type"}](#items-avatar)
- [`chip?: ChipProps`{lang="ts-type"}](#items-chip)
- [`type?: "label" | "separator" | "item"`{lang="ts-type"}](#with-typed-items)
- [`icon?: string`{lang="ts-type"}](#with-icons-in-items)
- [`avatar?: AvatarProps`{lang="ts-type"}](#with-avatar-in-items)
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
- `disabled?: boolean`{lang="ts-type"}
::component-code
---
collapse: true
ignore:
- modelValue
- items
external:
- modelValue
- items
- modelValue
props:
modelValue: 'backlog'
items:
@@ -72,49 +72,19 @@ props:
When using objects, you need to reference the `value` property of the object in the `v-model` directive or the `default-value` prop.
::
#### Value Key
You can change the property that is used to set the value by using the `value-key` prop.
::component-code
---
collapse: true
ignore:
- modelValue
- valueKey
- items
external:
- modelValue
- items
props:
valueKey: 'id'
modelValue: 'backlog'
items:
- label: 'Backlog'
id: 'backlog'
- label: 'Todo'
id: 'todo'
- label: 'In Progress'
id: 'in_progress'
- label: 'Done'
id: 'done'
---
::
#### Group items
You can pass an array of arrays to the `items` prop to display separated groups of items.
You can also pass an array of arrays to the `items` prop to display separated groups of items.
::component-code
---
prettier: true
ignore:
- defaultValue
- modelValue
- items
external:
- items
- modelValue
props:
defaultValue: 'Apple'
modelValue: 'Apple'
items:
- - Apple
- Banana
@@ -129,89 +99,34 @@ props:
---
::
#### Items Type
### Value Key
You can use the `type` property with `separator` to display a separator between items or `label` to display a label.
You can change the property that is used to set the value by using the `value-key` prop. Defaults to `value`.
::component-code
---
prettier: true
collapse: true
ignore:
- defaultValue
- modelValue
- valueKey
- items
external:
- items
- modelValue
props:
defaultValue: 'Apple'
modelValue: 'backlog'
valueKey: 'id'
items:
- type: 'label'
label: 'Fruits'
- Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- type: 'separator'
- type: 'label'
label: 'Vegetables'
- Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
- label: 'Backlog'
id: 'backlog'
- label: 'Todo'
id: 'todo'
- label: 'In Progress'
id: 'in_progress'
- label: 'Done'
id: 'done'
---
::
#### Items Icon
You can use the `icon` property to display an [Icon](/components/icon) inside the items.
::component-example
---
collapse: true
name: 'select-items-icon-example'
---
::
::note
In this example, the icon is computed from the `value` property of the selected item.
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
::
#### Items Avatar
You can use the `avatar` property to display an [Avatar](/components/avatar) inside the items.
::component-example
---
collapse: true
name: 'select-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::
#### Items Chip
You can use the `chip` property to display a [Chip](/components/chip) inside the items.
::component-example
---
collapse: true
name: 'select-items-chip-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected chip.
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
@@ -219,10 +134,10 @@ Use the `placeholder` prop to set a placeholder text.
::component-code
---
prettier: true
external:
- items
ignore:
- items
external:
- items
props:
placeholder: 'Select status'
items:
@@ -233,6 +148,54 @@ props:
---
::
### Content
Use the `content` prop to control how the Select content is rendered, like its its `align`, `side` or `position` for example. Defaults to `popper` to match other components.
::caution
The `content.align`, `content.side`, etc. properties only apply when `content.position` is set to `popper`.
::
::component-code
---
prettier: true
ignore:
- items
- defaultValue
external:
- items
items:
content.position:
- 'item-aligned'
- 'popper'
content.align:
- start
- center
- end
content.side:
- right
- left
- top
- bottom
props:
content:
position: 'item-aligned'
align: center
side: bottom
sideOffset: 8
items:
- Backlog
- Todo
- In Progress
- Done
defaultValue: 'Todo'
---
::
::note{to="https://www.radix-vue.com/components/select.html#change-the-positioning-mode"}
Read more about the `content.position` prop in the [Radix Vue documentation](https://www.radix-vue.com/components/select.html#change-the-positioning-mode).
::
### Color
Use the `color` prop to change the ring color when the Select is focused.
@@ -240,11 +203,11 @@ Use the `color` prop to change the ring color when the Select is focused.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
color: gray
highlight: true
@@ -268,11 +231,11 @@ Use the `variant` prop to change the variant of the Select.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
color: gray
variant: subtle
@@ -293,11 +256,11 @@ Use the `size` prop to change the size of the Select.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
size: xl
defaultValue: 'Backlog'
@@ -316,11 +279,11 @@ Use the `icon` prop to show an [Icon](/components/icon) inside the Select.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
icon: 'i-heroicons-magnifying-glass'
size: md
@@ -333,18 +296,20 @@ props:
---
::
Use the `trailing-icon` prop to customize the trailing icon. Defaults to `i-heroicons-chevron-down-20-solid`.
### Trailing Icon
Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon). Defaults to `i-heroicons-chevron-down-20-solid`.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
trailingIcon: 'i-heroicons-arrow-small-right'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
size: md
defaultValue: 'Backlog'
items:
@@ -355,20 +320,22 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.chevronDown` key.
::
### Selected Icon
Use the `selected-icon` prop to customize the icon when an item is selected. Defaults to `i-heroicons-check-20-solid`.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
selectedIcon: 'i-heroicons-fire'
size: md
@@ -381,7 +348,7 @@ props:
---
::
::tip
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
@@ -389,19 +356,16 @@ You can customize this icon globally in your `app.config.ts` under `ui.icons.che
Use the `loading` prop to show a loading icon on the Select.
Use the `loading-icon` prop to customize this icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- defaultValue
external:
- items
props:
loading: true
loadingIcon: ''
trailing: false
defaultValue: 'Backlog'
items:
@@ -412,7 +376,31 @@ props:
---
::
::tip
### Loading Icon
Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-code
---
prettier: true
ignore:
- items
- defaultValue
external:
- items
props:
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
---
::
::tip{to="/getting-started/icons#theme"}
You can customize this icon globally in your `app.config.ts` under `ui.icons.loading` key.
::
@@ -423,11 +411,11 @@ Use the `disabled` prop to disable the Select.
::component-code
---
prettier: true
external:
- items
ignore:
- items
- placeholder
external:
- items
props:
disabled: true
placeholder: 'Select status'
@@ -441,6 +429,89 @@ props:
## Examples
### With typed items
You can use the `type` property with `separator` to display a separator between items or `label` to display a label.
::component-code
---
collapse: true
ignore:
- modelValue
- items
external:
- items
- modelValue
props:
modelValue: 'Apple'
items:
- type: 'label'
label: 'Fruits'
- Apple
- Banana
- Blueberry
- Grapes
- Pineapple
- type: 'separator'
- type: 'label'
label: 'Vegetables'
- Aubergine
- Broccoli
- Carrot
- Courgette
- Leek
---
::
### With icons in items
You can use the `icon` property to display an [Icon](/components/icon) inside the items.
::component-example
---
collapse: true
name: 'select-items-icon-example'
---
::
::note
In this example, the icon is computed from the `value` property of the selected item.
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
::
### With avatar in items
You can use the `avatar` property to display an [Avatar](/components/avatar) inside the items.
::component-example
---
collapse: true
name: 'select-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::
### With chip in items
You can use the `chip` property to display a [Chip](/components/chip) inside the items.
::component-example
---
collapse: true
name: 'select-items-chip-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected chip.
::
### Control open state
You can control the open state by using the `default-open` prop or the `v-model:open` directive.
@@ -472,6 +543,7 @@ You can fetch items from an API and use them in the Select.
::component-example
---
name: 'select-fetch-example'
collapse: true
---
::

View File

@@ -27,7 +27,7 @@ Use the `orientation` prop to change the orientation of the Separator. Defaults
---
ignore:
- class
class: 'p-8 justify-center'
class: 'p-8'
props:
orientation: vertical
class: 'h-48'
@@ -40,7 +40,7 @@ Use the `label` prop to display a label in the middle of the Separator.
::component-code
---
class: 'p-8 justify-center'
class: 'p-8'
props:
label: 'Hello World'
---
@@ -52,7 +52,7 @@ Use the `icon` prop to display an icon in the middle of the Separator.
::component-code
---
class: 'p-8 justify-center'
class: 'p-8'
props:
icon: 'i-simple-icons-nuxtdotjs'
---
@@ -65,7 +65,7 @@ Use the `avatar` prop to display an avatar in the middle of the Separator.
::component-code
---
prettier: true
class: 'p-8 justify-center'
class: 'p-8'
props:
avatar:
src: 'https://github.com/benjamincanac.png'
@@ -78,7 +78,7 @@ Use the `color` prop to change the color of the Separator. Defaults to `gray`.
::component-code
---
class: 'p-8 justify-center'
class: 'p-8'
props:
color: 'primary'
type: solid

Some files were not shown because too many files have changed in this diff Show More