mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 20:48:12 +01:00
Compare commits
487 Commits
v3.0.0-bet
...
docs/ai-se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16a4b0bbb1 | ||
|
|
dd34d49cd9 | ||
|
|
d29e1481f2 | ||
|
|
79aa161c6d | ||
|
|
94ea75f441 | ||
|
|
0c368c8ab8 | ||
|
|
c5796c4f82 | ||
|
|
204953b780 | ||
|
|
2e4c3082a1 | ||
|
|
f2fd778c0a | ||
|
|
d79da9d7b6 | ||
|
|
a4429eee09 | ||
|
|
0905b2b3d5 | ||
|
|
c7fba2e0eb | ||
|
|
4167f04205 | ||
|
|
276268d311 | ||
|
|
717e35f098 | ||
|
|
459a0410ab | ||
|
|
b9adc83e78 | ||
|
|
d7a4d029b7 | ||
|
|
3c8d6cd01d | ||
|
|
67da90a2f6 | ||
|
|
894e8a61b6 | ||
|
|
1b6ab271ea | ||
|
|
0dc4678c68 | ||
|
|
e86dc79e51 | ||
|
|
35997377a6 | ||
|
|
12303a87be | ||
|
|
f84ccddcd6 | ||
|
|
869c0708bd | ||
|
|
c63d2f380a | ||
|
|
92632e969e | ||
|
|
f6d7994a55 | ||
|
|
f738f68f76 | ||
|
|
17d6803329 | ||
|
|
732a67aa88 | ||
|
|
bdf129fc38 | ||
|
|
d140acc608 | ||
|
|
cc20a26f07 | ||
|
|
983c6382d1 | ||
|
|
37eabc89bd | ||
|
|
a57844e416 | ||
|
|
2be60cddfe | ||
|
|
09b4699aea | ||
|
|
46c2987ebf | ||
|
|
f244d15b96 | ||
|
|
1820e3cc6f | ||
|
|
450948646a | ||
|
|
aaa60c0798 | ||
|
|
5467d71cc2 | ||
|
|
941a54e5e3 | ||
|
|
655f98ffed | ||
|
|
999a0f8467 | ||
|
|
2739939c46 | ||
|
|
2a241c87c3 | ||
|
|
e6e510b848 | ||
|
|
a655da1394 | ||
|
|
3a71256d59 | ||
|
|
404359a6ca | ||
|
|
1e4e9c4708 | ||
|
|
6f07f6bd6e | ||
|
|
4c1093bde4 | ||
|
|
7d51a9e479 | ||
|
|
04bdbcfc6e | ||
|
|
58aa296425 | ||
|
|
d3df3bb929 | ||
|
|
4863775e17 | ||
|
|
7551a85ad2 | ||
|
|
c2bcb8e264 | ||
|
|
88124b85c5 | ||
|
|
9f539c9545 | ||
|
|
41d4ffe5b5 | ||
|
|
d8a0bbe710 | ||
|
|
06e5689da8 | ||
|
|
67d19f582a | ||
|
|
650bc40253 | ||
|
|
2f0f317a12 | ||
|
|
d2a26939ad | ||
|
|
b7a8146898 | ||
|
|
e81464a43e | ||
|
|
4b3d2a7b00 | ||
|
|
6f6fa6ae4a | ||
|
|
c7bb6d4c4b | ||
|
|
c23f85fe33 | ||
|
|
591d59fe89 | ||
|
|
caa3bf9c7e | ||
|
|
2731011bb7 | ||
|
|
aebf0b3dca | ||
|
|
6651987dc6 | ||
|
|
61aabd72e4 | ||
|
|
8dfdd63ce3 | ||
|
|
e6369a6746 | ||
|
|
a4f3f6d531 | ||
|
|
c5bdec0f64 | ||
|
|
87a7828931 | ||
|
|
501468960b | ||
|
|
13cd6be679 | ||
|
|
e421ea57ec | ||
|
|
799d7ae422 | ||
|
|
be9b1f659a | ||
|
|
39e29fccf1 | ||
|
|
195773ec7d | ||
|
|
d7710795df | ||
|
|
53f8b34bef | ||
|
|
df83ab355e | ||
|
|
e5df026993 | ||
|
|
6131871a0d | ||
|
|
9543bce787 | ||
|
|
5e345a8a73 | ||
|
|
8acf3c51db | ||
|
|
f3b8b17dc5 | ||
|
|
bc0a296f9d | ||
|
|
ac4c1946ec | ||
|
|
82b5f322eb | ||
|
|
fb6cf708a6 | ||
|
|
8ab1f75e47 | ||
|
|
e9b19349ba | ||
|
|
b2b206e3f4 | ||
|
|
b779064129 | ||
|
|
94155258e2 | ||
|
|
c63a6dd133 | ||
|
|
79833035de | ||
|
|
79e7c7b729 | ||
|
|
bc06185282 | ||
|
|
6e27304d8c | ||
|
|
b4f8ac7ff7 | ||
|
|
a2fa1accaa | ||
|
|
f486423381 | ||
|
|
975331a7b1 | ||
|
|
75e4792f7f | ||
|
|
4a969a8b9e | ||
|
|
664a8c7524 | ||
|
|
fbcc3139a3 | ||
|
|
1a46394668 | ||
|
|
9ca213bd33 | ||
|
|
3484832822 | ||
|
|
80dfa88ea4 | ||
|
|
d710141a1b | ||
|
|
d3e2a3f33a | ||
|
|
9c3d53a02d | ||
|
|
22edfd708a | ||
|
|
e25aa78050 | ||
|
|
122e8ac8f4 | ||
|
|
5fc6312ab1 | ||
|
|
83f0a24704 | ||
|
|
13c299533f | ||
|
|
db11db6ff1 | ||
|
|
50863635d6 | ||
|
|
29fa46276d | ||
|
|
7a35baebc7 | ||
|
|
b6f6cee1a9 | ||
|
|
d49e0dadee | ||
|
|
2b315fd855 | ||
|
|
f42949820b | ||
|
|
d2ba99797c | ||
|
|
fd23038b1a | ||
|
|
fe3ec0c183 | ||
|
|
1a0d7a3103 | ||
|
|
c31bffad1b | ||
|
|
dd8f7a77a5 | ||
|
|
eb46e31ffb | ||
|
|
8ea99f0c4f | ||
|
|
f6b376110c | ||
|
|
01d8dc72ad | ||
|
|
445aac2d57 | ||
|
|
391828a2c2 | ||
|
|
02b6b38a56 | ||
|
|
47cdc2e1d8 | ||
|
|
a7d3097f8d | ||
|
|
7ac7aa9ba7 | ||
|
|
f9737c8f40 | ||
|
|
4e39cc59f8 | ||
|
|
28accc4aa0 | ||
|
|
5d10f242bd | ||
|
|
2d5c881639 | ||
|
|
ad63753b5e | ||
|
|
e5a1e26f9d | ||
|
|
113e2e7166 | ||
|
|
9d4880be35 | ||
|
|
8dd9d08209 | ||
|
|
f309a46b8d | ||
|
|
d5bcb0da59 | ||
|
|
0a3cc5a25d | ||
|
|
52735fdd40 | ||
|
|
59fd4d52e1 | ||
|
|
8e78eb15c8 | ||
|
|
b7fc69baa7 | ||
|
|
43153c4e91 | ||
|
|
d059efca25 | ||
|
|
eea14155aa | ||
|
|
4ba8503c60 | ||
|
|
fdee2522bb | ||
|
|
39c861a64b | ||
|
|
333b7e4c9b | ||
|
|
f42a79b5ef | ||
|
|
50012d4866 | ||
|
|
b558b8c5aa | ||
|
|
3447a062b6 | ||
|
|
063a23e738 | ||
|
|
da0150a9ec | ||
|
|
981de8b295 | ||
|
|
fb4c210b41 | ||
|
|
8c68af5e3b | ||
|
|
81b46ab880 | ||
|
|
619b6f2a0e | ||
|
|
25913188a7 | ||
|
|
f3098df84a | ||
|
|
3deed4c271 | ||
|
|
e6b1c238b9 | ||
|
|
626b023ddb | ||
|
|
4c667f75f4 | ||
|
|
e04dd53046 | ||
|
|
d25265c8b7 | ||
|
|
7d8353ffdc | ||
|
|
ba534f18b9 | ||
|
|
864083156a | ||
|
|
8435a0fe16 | ||
|
|
d339dcbfb8 | ||
|
|
cd7ab413f6 | ||
|
|
cea881abdc | ||
|
|
d227a105d8 | ||
|
|
f6ff157bc4 | ||
|
|
21fbd07639 | ||
|
|
de234e8aeb | ||
|
|
95a7707963 | ||
|
|
24b54f6d9a | ||
|
|
b3e37688d9 | ||
|
|
eeba3b4049 | ||
|
|
a0c9731f63 | ||
|
|
af1bf1bbde | ||
|
|
54a7d04217 | ||
|
|
dfa2113db4 | ||
|
|
abe0859691 | ||
|
|
cf91f3c4cf | ||
|
|
175fc73e63 | ||
|
|
1d459803dc | ||
|
|
60e2ee9a6c | ||
|
|
7f1c6caa6e | ||
|
|
7ac17ae7e8 | ||
|
|
52a97e2df7 | ||
|
|
041989549a | ||
|
|
31c37ce1a1 | ||
|
|
74cb2c3769 | ||
|
|
5025e15d14 | ||
|
|
36c24ffe5c | ||
|
|
b3a6b861cd | ||
|
|
c21eb32c70 | ||
|
|
44e6ba039d | ||
|
|
ef75610244 | ||
|
|
ffafd81e1e | ||
|
|
06414d344b | ||
|
|
cb193f1d25 | ||
|
|
4d8179ba08 | ||
|
|
ce767c8429 | ||
|
|
1ae5cc09cb | ||
|
|
9d2fed1250 | ||
|
|
924515ad07 | ||
|
|
4d138ad671 | ||
|
|
615fcfd73b | ||
|
|
f5e62849c9 | ||
|
|
f25fed58e9 | ||
|
|
ca15bc0c75 | ||
|
|
29f004db95 | ||
|
|
97274f15b8 | ||
|
|
8471fb9fa4 | ||
|
|
9ec159e207 | ||
|
|
0456670dac | ||
|
|
f05dbd26d1 | ||
|
|
9be36d328c | ||
|
|
4f28e1fe96 | ||
|
|
bd99c2d850 | ||
|
|
23bfeb9370 | ||
|
|
88f349d0d7 | ||
|
|
e7e6745599 | ||
|
|
d2c832292a | ||
|
|
bc61d29cce | ||
|
|
777fe4a309 | ||
|
|
3074632523 | ||
|
|
94b6e520f5 | ||
|
|
754dd36473 | ||
|
|
67a52b6f4e | ||
|
|
2e7d4989b5 | ||
|
|
c07a79571f | ||
|
|
4cebdb5152 | ||
|
|
06dfb963be | ||
|
|
4ebb94cd7e | ||
|
|
afff54fecd | ||
|
|
7ec08017e0 | ||
|
|
3dd88bacec | ||
|
|
d6d7971d44 | ||
|
|
20c33920d0 | ||
|
|
a63047b79a | ||
|
|
f3e32ba5a2 | ||
|
|
bd3f54aa80 | ||
|
|
9509c37af8 | ||
|
|
df00149598 | ||
|
|
f72c886d3a | ||
|
|
c531d0248b | ||
|
|
d73768b704 | ||
|
|
b9983549a4 | ||
|
|
370054b20c | ||
|
|
4a2b77d86c | ||
|
|
ade16b76cf | ||
|
|
1babad4f74 | ||
|
|
8fb8dc29cf | ||
|
|
e0ec60d1b1 | ||
|
|
3db3058395 | ||
|
|
0095d8916b | ||
|
|
58ae62413d | ||
|
|
1965495768 | ||
|
|
5465fcb61d | ||
|
|
ef8ebaf687 | ||
|
|
1094881878 | ||
|
|
d6fd18fc4f | ||
|
|
e2e079f0d8 | ||
|
|
cec9dadc7a | ||
|
|
c76f590097 | ||
|
|
4dee7c3bd3 | ||
|
|
47bbe35d2a | ||
|
|
60bcd4fdf0 | ||
|
|
c231fe5f26 | ||
|
|
1769d5ed6e | ||
|
|
68787b26fd | ||
|
|
f7604e565f | ||
|
|
82e26655a4 | ||
|
|
2453714136 | ||
|
|
973f36539d | ||
|
|
05ab54d03a | ||
|
|
db83df5f5e | ||
|
|
a5168666b7 | ||
|
|
f30d45c79a | ||
|
|
31be5f656e | ||
|
|
0ef5f3b77b | ||
|
|
a0fec4e467 | ||
|
|
f401766e26 | ||
|
|
70f469b868 | ||
|
|
f92df1f661 | ||
|
|
16edbdf1f0 | ||
|
|
fe0bd83d11 | ||
|
|
8a26de230b | ||
|
|
65a6861b54 | ||
|
|
ecff9abc72 | ||
|
|
06bc7d3028 | ||
|
|
b2034ccc91 | ||
|
|
53cf1b4c14 | ||
|
|
0229b0fd46 | ||
|
|
302e04bd77 | ||
|
|
126ba2326f | ||
|
|
dfc27514ec | ||
|
|
26321c4857 | ||
|
|
5dec0e16e2 | ||
|
|
f4c417d9ef | ||
|
|
9046b9d679 | ||
|
|
99df056cad | ||
|
|
08bebcae48 | ||
|
|
764c41a0c6 | ||
|
|
2abcc24018 | ||
|
|
67f90f5f26 | ||
|
|
024fccf8bb | ||
|
|
edb0f0afc6 | ||
|
|
fd160339a6 | ||
|
|
2a023b9060 | ||
|
|
ab52830dc8 | ||
|
|
9a4bb34d7d | ||
|
|
02184b016a | ||
|
|
57efc78a3b | ||
|
|
dec2730aae | ||
|
|
c8ca604bdf | ||
|
|
ef86108f14 | ||
|
|
a1caac47c5 | ||
|
|
fad715d8df | ||
|
|
b0d0d926ab | ||
|
|
a8e6b74e38 | ||
|
|
177fb79cb4 | ||
|
|
175c7027a3 | ||
|
|
cc504b8a4b | ||
|
|
0897e9ef05 | ||
|
|
6588ae8669 | ||
|
|
0b41cebee4 | ||
|
|
e80cc1592f | ||
|
|
5d52af6292 | ||
|
|
5e62493321 | ||
|
|
37f8619c1a | ||
|
|
5376a835f7 | ||
|
|
f2ba755ba5 | ||
|
|
c8d712747f | ||
|
|
816cf50b37 | ||
|
|
3c60f70cab | ||
|
|
05758fa915 | ||
|
|
ce4b229264 | ||
|
|
09b4e9e282 | ||
|
|
50d68a636c | ||
|
|
7646c95c73 | ||
|
|
4c30baffe0 | ||
|
|
0b411936c4 | ||
|
|
047582c246 | ||
|
|
b00f1206f6 | ||
|
|
9ba5cfe70c | ||
|
|
ee9aca33fd | ||
|
|
8d29e50340 | ||
|
|
0ad18d0a7a | ||
|
|
4c96909020 | ||
|
|
06dee66722 | ||
|
|
8494f50d98 | ||
|
|
cc7bdf9247 | ||
|
|
8cbf6d2d58 | ||
|
|
881f977fe4 | ||
|
|
6e03d9c6ef | ||
|
|
5ecd2271ca | ||
|
|
556ebb0b36 | ||
|
|
3a56e3cf45 | ||
|
|
34dfe7d4b3 | ||
|
|
54468ca0f2 | ||
|
|
a9c8eb3f60 | ||
|
|
04fc367568 | ||
|
|
2b4e88d727 | ||
|
|
c713f3015d | ||
|
|
0a603e41f9 | ||
|
|
8329fedd1a | ||
|
|
e289db874d | ||
|
|
cbc5675e04 | ||
|
|
66686d2d2a | ||
|
|
e67906aa0b | ||
|
|
20fb8252f7 | ||
|
|
97c8098d4a | ||
|
|
fbc3200ec5 | ||
|
|
243f981ff4 | ||
|
|
9979a1c818 | ||
|
|
619bf0d7c9 | ||
|
|
21dbf01888 | ||
|
|
a208dedaea | ||
|
|
6120a15a99 | ||
|
|
b1552e447d | ||
|
|
36ec141c16 | ||
|
|
7940f5c0aa | ||
|
|
cfe9b2ecf3 | ||
|
|
ed7710a890 | ||
|
|
83725ac048 | ||
|
|
af2f8987a3 | ||
|
|
f6250f979a | ||
|
|
87ecee6308 | ||
|
|
476408f6e5 | ||
|
|
e016fdea18 | ||
|
|
d9a6218524 | ||
|
|
2ae338e8a5 | ||
|
|
a6f93ca1ce | ||
|
|
63266d366d | ||
|
|
5671618c9a | ||
|
|
60497174a3 | ||
|
|
704abf7917 | ||
|
|
a1de006055 | ||
|
|
4f51d19e2b | ||
|
|
196ffbc989 | ||
|
|
a6f58cba14 | ||
|
|
977fed0122 | ||
|
|
bd2d4848d2 | ||
|
|
e3ce1f7a41 | ||
|
|
08f092fd15 | ||
|
|
3f7df7be9b | ||
|
|
99e531d8df | ||
|
|
a47c5ff466 | ||
|
|
60b7e2d69e | ||
|
|
01fa230eae | ||
|
|
e823022b19 | ||
|
|
25e503bc83 | ||
|
|
629c54261a | ||
|
|
fb4e05c65f | ||
|
|
ccbd89c908 | ||
|
|
145fce1b30 | ||
|
|
52a92c658f | ||
|
|
557dca9a22 | ||
|
|
bd23cf3e9d | ||
|
|
4514171a3f | ||
|
|
d76f9c4fe4 | ||
|
|
62f71f3fbc | ||
|
|
6daa8f1e31 | ||
|
|
5783d0d931 | ||
|
|
58568c642d | ||
|
|
02329c78c2 | ||
|
|
9f241de1b5 | ||
|
|
7f420d9bec | ||
|
|
80b701d270 | ||
|
|
21175c8c59 | ||
|
|
dd708da235 | ||
|
|
f1758ef9d0 | ||
|
|
0d1fccc3c5 | ||
|
|
6446130b5d |
6
.github/ISSUE_TEMPLATE/bug-report-v3.yml
vendored
6
.github/ISSUE_TEMPLATE/bug-report-v3.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before reporting a bug, please make sure that you have read through our [v3 documentation](https://ui3.nuxt.dev/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui.nuxt.com/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
- type: textarea
|
||||
id: env
|
||||
attributes:
|
||||
@@ -37,14 +37,14 @@ body:
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
placeholder: v3.0.0-alpha.x
|
||||
placeholder: v3.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction
|
||||
description: Please provide a reproduction link using the Nuxt template https://codesandbox.io/p/devbox/nuxt-ui3-n3sxks or the Vue template https://codesandbox.io/p/devbox/nuxt-ui3-vue-4h5gqn. A minimal [reproduction is required](https://antfu.me/posts/why-reproductions-are-required) unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "needs reproduction" label. If no reproduction is provided we might close it.
|
||||
description: Please provide a reproduction link using the Nuxt template https://codesandbox.io/p/devbox/nuxt-ui3-n3sxks or the Vue template https://codesandbox.io/p/devbox/nuxt-ui3-vue-4h5gqn. A minimal [reproduction is required](https://antfu.me/posts/why-reproductions-are-required) unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "needs reproduction" label. If no reproduction is provided, it will be closed automatically after a while.
|
||||
placeholder: https://github.com/my/reproduction
|
||||
validations:
|
||||
required: true
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: textarea
|
||||
id: env
|
||||
attributes:
|
||||
|
||||
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before requesting a feature, please make sure that you have read through our [v3 documentation](https://ui3.nuxt.dev/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui.nuxt.com/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/question-v3.yml
vendored
2
.github/ISSUE_TEMPLATE/question-v3.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before asking a question, please make sure that you have read through our [v3 documentation](https://ui3.nuxt.dev/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
Before asking a question, please make sure that you have read through our [documentation](https://ui.nuxt.com/) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc%20label%3Av3).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/question.yml
vendored
2
.github/ISSUE_TEMPLATE/question.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before asking a question, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before asking a question, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
|
||||
30
.github/reproduire/needs-reproduction.md
vendored
Normal file
30
.github/reproduire/needs-reproduction.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
Would you be able to provide a [reproduction](https://nuxt.com/docs/community/reporting-bugs/#create-a-minimal-reproduction)? 🙏
|
||||
|
||||
<details>
|
||||
<summary>More info</summary>
|
||||
|
||||
### Why do I need to provide a reproduction?
|
||||
|
||||
Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.
|
||||
|
||||
### What will happen?
|
||||
|
||||
If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect.
|
||||
|
||||
If `needs reproduction` labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), they will be closed automatically after a while. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.
|
||||
|
||||
### How can I create a reproduction?
|
||||
|
||||
We have templates to create a minimal reproduction:
|
||||
|
||||
* **Nuxt**: https://codesandbox.io/p/devbox/nuxt-ui3-n3sxks
|
||||
* **Vue**: https://codesandbox.io/p/devbox/nuxt-ui3-vue-4h5gqn
|
||||
|
||||
Please ensure that the reproduction is as **minimal** as possible. See more details [in our guide](https://nuxt.com/docs/community/reporting-bugs/#create-a-minimal-reproduction).
|
||||
|
||||
You might also find these other articles interesting and/or helpful:
|
||||
|
||||
- [The Importance of Reproductions](https://antfu.me/posts/why-reproductions-are-required)
|
||||
- [How to Generate a Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve)
|
||||
|
||||
</details>
|
||||
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -42,6 +42,8 @@ jobs:
|
||||
|
||||
- name: Build application
|
||||
run: pnpm run docs:build
|
||||
env:
|
||||
NODE_OPTIONS: '--max-old-space-size=8192'
|
||||
|
||||
- name: Deploy to NuxtHub
|
||||
uses: nuxt-hub/action@v1
|
||||
|
||||
207
.github/workflows/module.yml
vendored
207
.github/workflows/module.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
os: ${{ github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]') || fromJSON('["ubuntu-latest", "windows-latest"]') }} # macos-latest
|
||||
node: [22]
|
||||
|
||||
env:
|
||||
@@ -50,16 +50,213 @@ jobs:
|
||||
run: pnpm run typecheck
|
||||
|
||||
- name: Test
|
||||
run: pnpm run test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Test (vue)
|
||||
run: pnpm run test:vue
|
||||
run: pnpm run test:vue run
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Build vue fixture
|
||||
run: pnpm run test:vue:build
|
||||
- name: Build playground
|
||||
run: pnpm run dev:build
|
||||
|
||||
- name: Build playground (vue)
|
||||
run: pnpm run dev:vue:build
|
||||
|
||||
- name: Publish
|
||||
# Only publish preview package on ubuntu during PRs
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: pnpx pkg-pr-new publish --compact --no-template --pnpm
|
||||
|
||||
playground:
|
||||
needs: build
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./playground
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [22]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Store commit SHA
|
||||
run: |
|
||||
echo "COMMIT_SHA=$(echo ${{ github.workflow_sha }} | cut -c1-7)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install latest nuxt/ui
|
||||
run: pnpm install https://pkg.pr.new/@nuxt/ui@${{ env.COMMIT_SHA }} --lockfile-only
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --ignore-workspace
|
||||
|
||||
- name: Prepare
|
||||
run: pnpm nuxi prepare
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
starter-nuxt:
|
||||
needs: build
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [22]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: nuxtlabs/nuxt-ui-starter
|
||||
|
||||
- name: Store commit SHA
|
||||
run: |
|
||||
echo "COMMIT_SHA=$(echo ${{ github.workflow_sha }} | cut -c1-7)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install latest nuxt/ui
|
||||
run: pnpm install https://pkg.pr.new/@nuxt/ui@${{ env.COMMIT_SHA }} --lockfile-only
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
starter-vue:
|
||||
needs: build
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [22]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: nuxtlabs/nuxt-ui-vue-starter
|
||||
|
||||
- name: Store commit SHA
|
||||
run: |
|
||||
echo "COMMIT_SHA=$(echo ${{ github.workflow_sha }} | cut -c1-7)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install latest nuxt/ui
|
||||
run: pnpm install https://pkg.pr.new/@nuxt/ui@${{ env.COMMIT_SHA }} --lockfile-only
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
nuxt-ui-pro:
|
||||
needs: build
|
||||
|
||||
# Only run this job if not a fork PR (when push event or PR from same repo)
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [22]
|
||||
|
||||
env:
|
||||
NUXT_UI_PRO_LICENSE: ${{ secrets.NUXT_UI_PRO_LICENSE }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: nuxt/ui-pro
|
||||
token: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
|
||||
- name: Store commit SHA
|
||||
run: |
|
||||
echo "COMMIT_SHA=$(echo ${{ github.workflow_sha }} | cut -c1-7)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- name: Install latest nuxt/ui
|
||||
run: pnpm install https://pkg.pr.new/@nuxt/ui@${{ env.COMMIT_SHA }} --lockfile-only
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Prepare
|
||||
run: pnpm run dev:prepare
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
|
||||
54
.github/workflows/release.yml
vendored
Normal file
54
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v3*'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [22]
|
||||
|
||||
env:
|
||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Prepare
|
||||
run: pnpm run dev:prepare
|
||||
|
||||
- name: Lint
|
||||
run: pnpm run lint
|
||||
|
||||
- name: Typecheck
|
||||
run: pnpm run typecheck
|
||||
|
||||
- name: Test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Test (vue)
|
||||
run: pnpm run test:vue run
|
||||
|
||||
- name: Publish
|
||||
run: ./scripts/release.sh
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||
17
.github/workflows/reproduire.yml
vendored
Normal file
17
.github/workflows/reproduire.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: reproduire
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
reproduire:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: Hebilicious/reproduire@4b686ae9cbb72dad60f001d278b6e3b2ce40a9ac # v0.0.9-mp
|
||||
with:
|
||||
label: needs reproduction
|
||||
16
.github/workflows/stale.yml
vendored
16
.github/workflows/stale.yml
vendored
@@ -10,14 +10,16 @@ jobs:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
exempt-issue-labels: triage,v3
|
||||
stale-issue-message: 'This issue is stale because it has been open for 30 days with no activity.'
|
||||
stale-issue-label: stale
|
||||
stale-pr-label: stale
|
||||
days-before-stale: 30
|
||||
days-before-close: -1
|
||||
days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
|
||||
stale-issue-label: 'needs reproduction' # Label that flags an issue as stale.
|
||||
only-labels: 'needs reproduction' # Only process these issues
|
||||
days-before-issue-close: 7
|
||||
ignore-updates: true
|
||||
remove-stale-when-updated: false
|
||||
close-issue-message: This issue was closed because it was open for 7 days without a reproduction.
|
||||
close-issue-label: closed-by-bot
|
||||
operations-per-run: 300 #default 30
|
||||
|
||||
1
.npmrc
1
.npmrc
@@ -1,4 +1,3 @@
|
||||
shamefully-hoist=true
|
||||
auto-install-peers=true
|
||||
ignore-workspace-root-check=true
|
||||
shell-emulator=true
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
"commitMessage": "chore(release): v${version}",
|
||||
"tagName": "v${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"github": {
|
||||
"release": true,
|
||||
"releaseName": "v${version}",
|
||||
|
||||
229
CHANGELOG.md
229
CHANGELOG.md
@@ -1,5 +1,234 @@
|
||||
# Changelog
|
||||
|
||||
## [3.1.2](https://github.com/nuxt/ui/compare/v3.1.1...v3.1.2) (2025-05-15)
|
||||
|
||||
### Features
|
||||
|
||||
* **Badge:** add `square` prop ([#4008](https://github.com/nuxt/ui/issues/4008)) ([894e8a6](https://github.com/nuxt/ui/commit/894e8a61b6fea3618fc863bd77678385e9d021c2))
|
||||
* **CheckboxGroup:** add `table` variant ([#3997](https://github.com/nuxt/ui/issues/3997)) ([1b6ab27](https://github.com/nuxt/ui/commit/1b6ab271ea3875a7c77ffe9367c7c341083dd53c))
|
||||
* **components:** add `ui` field in items ([#4060](https://github.com/nuxt/ui/issues/4060)) ([b9adc83](https://github.com/nuxt/ui/commit/b9adc83e787db02507e6e7bb1aabc684eccc197b))
|
||||
* **InputNumber:** add `increment-disabled` / `decrement-disabled` props ([#4141](https://github.com/nuxt/ui/issues/4141)) ([c7fba2e](https://github.com/nuxt/ui/commit/c7fba2e0ebfb7153f3bfb727165d653bbd3dbe54))
|
||||
* **locale:** add Slovenian language ([#4140](https://github.com/nuxt/ui/issues/4140)) ([e86dc79](https://github.com/nuxt/ui/commit/e86dc79e51b2773a77ada5f12d4f0964fbc83354))
|
||||
* **NavigationMenu:** add `collapsible` field in items ([2be60cd](https://github.com/nuxt/ui/commit/2be60cddfe10fd1e2466900fd53e21ee0c877227)), closes [#3353](https://github.com/nuxt/ui/issues/3353) [#3911](https://github.com/nuxt/ui/issues/3911)
|
||||
* **NavigationMenu:** handle `tooltip` in items ([46c2987](https://github.com/nuxt/ui/commit/46c2987ebfd30b2b071a96a745b7270e852e96de)), closes [#4050](https://github.com/nuxt/ui/issues/4050)
|
||||
* **Slider:** handle `tooltip` around thumbs ([d140acc](https://github.com/nuxt/ui/commit/d140acc608c6ae11c0a0531fe443588776ea7807)), closes [#1469](https://github.com/nuxt/ui/issues/1469)
|
||||
* **Toast:** add `progress` prop to hide progress bar ([#4125](https://github.com/nuxt/ui/issues/4125)) ([92632e9](https://github.com/nuxt/ui/commit/92632e969eaa11521a166e50e346753929b7f523))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Badge/Button:** handle zero value in label correctly ([#4108](https://github.com/nuxt/ui/issues/4108)) ([f244d15](https://github.com/nuxt/ui/commit/f244d15b96d97cd8ba34ba9c18f23965e17e3cef))
|
||||
* **ButtonGroup:** add `z-index` on focused element ([204953b](https://github.com/nuxt/ui/commit/204953b780bde08dbfde230fc8887674449227b7))
|
||||
* **Calendar:** wrong color for today date with `neutral` color ([7d51a9e](https://github.com/nuxt/ui/commit/7d51a9e479cb6105ea37759c5cd67ff9f7702c49)), closes [#4084](https://github.com/nuxt/ui/issues/4084) [#3629](https://github.com/nuxt/ui/issues/3629)
|
||||
* **Checkbox/RadioGroup:** render correct element without `variant` ([f2fd778](https://github.com/nuxt/ui/commit/f2fd778c0a604f2d65aec9f3fe2d54b6d4e8c3a2)), closes [#3998](https://github.com/nuxt/ui/issues/3998)
|
||||
* **CheckboxGroup:** relative `UCheckbox` import ([7551a85](https://github.com/nuxt/ui/commit/7551a85ad2d92b59e2909396affb862403d5b27a)), closes [#4090](https://github.com/nuxt/ui/issues/4090)
|
||||
* **ColorPicker:** make thumb touch draggable ([#4101](https://github.com/nuxt/ui/issues/4101)) ([cc20a26](https://github.com/nuxt/ui/commit/cc20a26f07268d19119ab4c7c254033143bb63f4))
|
||||
* **components:** `class` should have priority over `ui` prop ([e6e510b](https://github.com/nuxt/ui/commit/e6e510b848d995a286a51d50a120d67483e11232))
|
||||
* **FormField:** block form field injection after use ([#4150](https://github.com/nuxt/ui/issues/4150)) ([d79da9d](https://github.com/nuxt/ui/commit/d79da9d7b60c9972af64acd8e6eef4ae7d6bc3eb))
|
||||
* **FormField:** use `div` for `error` and `help` slots ([459a041](https://github.com/nuxt/ui/commit/459a0410ab729fde60865e84632b36903465f57e))
|
||||
* **inertia:** link always render as anchor tag ([#3989](https://github.com/nuxt/ui/issues/3989)) ([e81464a](https://github.com/nuxt/ui/commit/e81464a43ede4e63ce3dc92429bbfef48614f731))
|
||||
* **inertia:** make `useAppConfig` reactive ([12303a8](https://github.com/nuxt/ui/commit/12303a87be62dae84ef774e3a9795deb0ac90cc7))
|
||||
* **Input/Textarea:** handle generic types ([3c8d6cd](https://github.com/nuxt/ui/commit/3c8d6cd01dfafed5844c376f52adbdda0c814420)), closes [nuxt/ui-pro#887](https://github.com/nuxt/ui-pro/issues/887)
|
||||
* **InputNumber:** handle inside button group ([2e4c308](https://github.com/nuxt/ui/commit/2e4c3082a1e66fa597086dc3431fec37fa29ef62)), closes [#4155](https://github.com/nuxt/ui/issues/4155)
|
||||
* **Link:** consistent behavior between nuxt, vue and inertia ([#4134](https://github.com/nuxt/ui/issues/4134)) ([67da90a](https://github.com/nuxt/ui/commit/67da90a2f638124f640c4271d3376c5ff3fab6a1))
|
||||
* **module:** configure `@nuxt/fonts` with default weights ([276268d](https://github.com/nuxt/ui/commit/276268d311f57715cec47bc600a0ccc3d3885682))
|
||||
* **NavigationMenu:** arrow position conflict ([#4137](https://github.com/nuxt/ui/issues/4137)) ([0dc4678](https://github.com/nuxt/ui/commit/0dc4678c68e4b500be49c38336dc75b73843e38d))
|
||||
* **Select:** support more primitive types in `value` field ([#4105](https://github.com/nuxt/ui/issues/4105)) ([09b4699](https://github.com/nuxt/ui/commit/09b4699aeadaa195ea081509f8e237bb2c346238))
|
||||
* **Slider:** handle generic types ([d7a4d02](https://github.com/nuxt/ui/commit/d7a4d029b77d2dfa0b8efcd2755d482fa5e31fd3))
|
||||
* **Stepper:** use `div` tag for `title` & `description` ([a57844e](https://github.com/nuxt/ui/commit/a57844e41676c13ed1af861424961b88cee7b4da)), closes [#4096](https://github.com/nuxt/ui/issues/4096)
|
||||
* **Tabs:** prevent trigger truncate without parent width ([06e5689](https://github.com/nuxt/ui/commit/06e5689da80b36205d0548d5d6b58510938e4a6e)), closes [#4056](https://github.com/nuxt/ui/issues/4056)
|
||||
* **Tabs:** set `focus:outline-none` with `link` variant ([999a0f8](https://github.com/nuxt/ui/commit/999a0f84671fad20fa3dc50c6774af2e0200b32e))
|
||||
* **templates:** dont write unused variants in theme files ([d3df3bb](https://github.com/nuxt/ui/commit/d3df3bb929fe6732f27b182d1664213884a662ec))
|
||||
* **Toaster:** allow `base` slot override ([c63d2f3](https://github.com/nuxt/ui/commit/c63d2f380aac16f1d1e812516df3dca7fa7c8034))
|
||||
* **vue:** make `useAppConfig` reactive ([869c070](https://github.com/nuxt/ui/commit/869c0708bd351c7be44e5e430c348b19dd316db9)), closes [#3952](https://github.com/nuxt/ui/issues/3952)
|
||||
|
||||
## [3.1.1](https://github.com/nuxt/ui/compare/v3.1.0...v3.1.1) (2025-05-02)
|
||||
|
||||
### Features
|
||||
|
||||
* **useOverlay:** add `closeAll` method ([#3984](https://github.com/nuxt/ui/issues/3984)) ([ac4c194](https://github.com/nuxt/ui/commit/ac4c1946ec399aec59b4bce9d538e3ff67868abf))
|
||||
* **useOverlay:** add `isOpen` method to check overlay state ([#4041](https://github.com/nuxt/ui/issues/4041)) ([a4f3f6d](https://github.com/nuxt/ui/commit/a4f3f6d531f9c0281f99085a6688d296f8f13f2f))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Calendar:** add `place-items-center` to grid row ([#4034](https://github.com/nuxt/ui/issues/4034)) ([8dfdd63](https://github.com/nuxt/ui/commit/8dfdd63ce3b3a0e904f7c013c774cf9aaf46b240))
|
||||
* **defineShortcuts:** bring back `meta` to `ctrl` convert on non macos platforms ([f3b8b17](https://github.com/nuxt/ui/commit/f3b8b17dc5f43936ef7ffb11c1ed7f9a5f94d0bb)), closes [#3869](https://github.com/nuxt/ui/issues/3869) [#3318](https://github.com/nuxt/ui/issues/3318)
|
||||
* **module:** support `nuxt-nightly` ([#3996](https://github.com/nuxt/ui/issues/3996)) ([bc0a296](https://github.com/nuxt/ui/commit/bc0a296f9d68ca72cd991b11cd3489b63c7b13db))
|
||||
* **NavigationMenu:** remove `sm:w-auto` from content slot ([aebf0b3](https://github.com/nuxt/ui/commit/aebf0b3dca50c51c093cb6abf16c4fd995fc1b39)), closes [#3987](https://github.com/nuxt/ui/issues/3987)
|
||||
* **RadioGroup:** improve items `value` field type ([#3995](https://github.com/nuxt/ui/issues/3995)) ([195773e](https://github.com/nuxt/ui/commit/195773ec7dac12ccc3a0a67867751e8ca634cc04))
|
||||
* **templates:** put back args to watch in dev ([#4033](https://github.com/nuxt/ui/issues/4033)) ([c5bdec0](https://github.com/nuxt/ui/commit/c5bdec0f64963ef602975270a09a1ee795cdacf9))
|
||||
* **theme:** add missing `border-bg` / `divide-bg` utilities ([82b5f32](https://github.com/nuxt/ui/commit/82b5f322ebd8a08e63588122bd4ef567dcb8ba8c))
|
||||
* **theme:** add missing `ring-offset-*` utilities ([#3992](https://github.com/nuxt/ui/issues/3992)) ([e5df026](https://github.com/nuxt/ui/commit/e5df0269935be59df759fe0e1378acb2b0d9014a))
|
||||
* **theme:** define default shades for named tailwindcss colors ([8acf3c5](https://github.com/nuxt/ui/commit/8acf3c51db6c2f9443d04be6ba7d9f062c5cf8ab)), closes [#3977](https://github.com/nuxt/ui/issues/3977)
|
||||
* **theme:** improve app config types for `ui` object ([591d59f](https://github.com/nuxt/ui/commit/591d59fe89f1d9bf016c121bf9160f73fe0a290d)), closes [#3579](https://github.com/nuxt/ui/issues/3579)
|
||||
* **theme:** use `[@theme](https://github.com/theme) inline` to properly reference css variables ([6131871](https://github.com/nuxt/ui/commit/6131871a0d124c5942d60dc5dff20981e8542e51)), closes [#4018](https://github.com/nuxt/ui/issues/4018)
|
||||
* **useOverlay:** improve types and docs ([#4012](https://github.com/nuxt/ui/issues/4012)) ([39e29fc](https://github.com/nuxt/ui/commit/39e29fccf1840c723a13237d65002501b2829b70))
|
||||
|
||||
## [3.1.0](https://github.com/nuxt/ui/compare/v3.0.2...v3.1.0) (2025-04-24)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **OverlayProvider:** return an overlay instance from `.open()` (#3829)
|
||||
|
||||
### Features
|
||||
|
||||
* **App:** add global `portal` prop ([#3688](https://github.com/nuxt/ui/issues/3688)) ([29fa462](https://github.com/nuxt/ui/commit/29fa46276d6bf69b5b87880c476c6f778c2820bf))
|
||||
* **Carousel:** add `select` event ([#3678](https://github.com/nuxt/ui/issues/3678)) ([22edfd7](https://github.com/nuxt/ui/commit/22edfd708ae3eeadbd4ff6c830cdfd5632948286))
|
||||
* **CheckboxGroup:** new component ([#3862](https://github.com/nuxt/ui/issues/3862)) ([9c3d53a](https://github.com/nuxt/ui/commit/9c3d53a02d6254f6b5c90e5fed826b8aefcdb042))
|
||||
* **components:** add new `content-top` and `content-bottom` slots ([#3886](https://github.com/nuxt/ui/issues/3886)) ([1a46394](https://github.com/nuxt/ui/commit/1a463946681e152aa18372118d0fef4a7d8055a5))
|
||||
* **Form:** add `attach` prop to opt-out of nested form attachement ([#3939](https://github.com/nuxt/ui/issues/3939)) ([1a0d7a3](https://github.com/nuxt/ui/commit/1a0d7a3103cf7591b019ef3ad685e2f3786ef6f2))
|
||||
* **Form:** export loading state ([#3861](https://github.com/nuxt/ui/issues/3861)) ([fdee252](https://github.com/nuxt/ui/commit/fdee2522bb9d8361ff3e9fdd4aa2350be8e49b05))
|
||||
* **InputMenu/SelectMenu:** handle `resetSearchTermOnSelect` ([cea881a](https://github.com/nuxt/ui/commit/cea881abdc139b39df89b503cf2ab872f4246c8f)), closes [#3782](https://github.com/nuxt/ui/issues/3782)
|
||||
* **InputNumber:** add support for `stepSnapping` & `disableWheelChange` props ([#3731](https://github.com/nuxt/ui/issues/3731)) ([f5e6284](https://github.com/nuxt/ui/commit/f5e62849c9313063396ab0e3a9b7d22d98ef69bc))
|
||||
* **locale:** add Bulgarian language ([#3783](https://github.com/nuxt/ui/issues/3783)) ([a0c9731](https://github.com/nuxt/ui/commit/a0c9731f634020e76aa98a9a68d673591d35e8c9))
|
||||
* **locale:** add Kazakh language ([#3875](https://github.com/nuxt/ui/issues/3875)) ([43153c4](https://github.com/nuxt/ui/commit/43153c4e91034b728059e7a9bed05888e48f8890))
|
||||
* **locale:** add Tajik language ([#3850](https://github.com/nuxt/ui/issues/3850)) ([f42a79b](https://github.com/nuxt/ui/commit/f42a79b5efe8dc65430a83799ebb0ee737773820))
|
||||
* **locale:** add Uyghur language ([#3878](https://github.com/nuxt/ui/issues/3878)) ([b7fc69b](https://github.com/nuxt/ui/commit/b7fc69baa718ff65b3988d0fa9f143306fa8fac4))
|
||||
* **Modal/Popover/Slideover:** add `close:prevent` event ([#3958](https://github.com/nuxt/ui/issues/3958)) ([f486423](https://github.com/nuxt/ui/commit/f4864233812eac0ed37e0a2d076a95c285a22c01))
|
||||
* **module:** define default color shades ([#3916](https://github.com/nuxt/ui/issues/3916)) ([7ac7aa9](https://github.com/nuxt/ui/commit/7ac7aa9ba73b6aca1bc29b0de2e95c60b2700135))
|
||||
* **module:** define neutral utilities ([#3629](https://github.com/nuxt/ui/issues/3629)) ([d49e0da](https://github.com/nuxt/ui/commit/d49e0dadeea2a58e05e60b2c461b29ce1d334d2b))
|
||||
* **module:** dynamic `rounded-*` utilities ([#3906](https://github.com/nuxt/ui/issues/3906)) ([f9737c8](https://github.com/nuxt/ui/commit/f9737c8f401bf8bc5307674fad6defe2aeeeb907))
|
||||
* **OverlayProvider:** return an overlay instance from `.open()` ([#3829](https://github.com/nuxt/ui/issues/3829)) ([f3098df](https://github.com/nuxt/ui/commit/f3098df84a3b7f58f7ccc1233bc8b45eab99ee10))
|
||||
* **PinInput:** add `autofocus` / `autofocus-delay` props ([0456670](https://github.com/nuxt/ui/commit/0456670dac1153340220603c8c116e3b71f72ae7)), closes [#3717](https://github.com/nuxt/ui/issues/3717)
|
||||
* **RadioGroup:** add `card` and `table` variants ([#3178](https://github.com/nuxt/ui/issues/3178)) ([4d138ad](https://github.com/nuxt/ui/commit/4d138ad6719a074f5f994006d12745ca05bec9c4))
|
||||
* **Select:** handle `onSelect` field in items ([8640831](https://github.com/nuxt/ui/commit/864083156a79dfb5d0be868658b7f9fc77570178))
|
||||
* **Table:** conditionally apply classes to `tr` and `td` ([#3866](https://github.com/nuxt/ui/issues/3866)) ([80dfa88](https://github.com/nuxt/ui/commit/80dfa88ea442571ee1dc673317cc7baa8cacd8a3))
|
||||
* **Tabs:** add `list-leading` and `list-trailing` slots ([#3837](https://github.com/nuxt/ui/issues/3837)) ([3447a06](https://github.com/nuxt/ui/commit/3447a062b636a469089d6e9bdcfcb3dce9063ee5))
|
||||
* **Textarea:** add `autoresize-delay` prop ([06414d3](https://github.com/nuxt/ui/commit/06414d344b151ad6e1a3225a9f5f1f76d58d319c)), closes [#3730](https://github.com/nuxt/ui/issues/3730)
|
||||
* **Textarea:** add `icon`, `loading`, etc. props to match Input ([cb193f1](https://github.com/nuxt/ui/commit/cb193f1d25b5c73ca03dcf10864800350dd1c290))
|
||||
* **Textarea:** add `resize-none` class with `autoresize` prop ([ffafd81](https://github.com/nuxt/ui/commit/ffafd81e1ed25074430668c792e5e1c6afc22bd0))
|
||||
* **unplugin:** routing support for inertia ([#3845](https://github.com/nuxt/ui/issues/3845)) ([d059efc](https://github.com/nuxt/ui/commit/d059efca258da7ae5116e829189a492824ac1d87))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Accordion:** use `div` instead of `h3` for header tag ([75e4792](https://github.com/nuxt/ui/commit/75e4792f7f00c55229253289c4f806f2b6fc9854)), closes [#3963](https://github.com/nuxt/ui/issues/3963)
|
||||
* **Alert/Toast:** display actions when using slots ([5086363](https://github.com/nuxt/ui/commit/50863635d653c8083772046ddc5b828fba7047d0)), closes [#3950](https://github.com/nuxt/ui/issues/3950)
|
||||
* **Carousel:** move arrows inside container on mobile ([d339dcb](https://github.com/nuxt/ui/commit/d339dcbfb8fe244bd198d247d8448e3ef856dfef)), closes [#3813](https://github.com/nuxt/ui/issues/3813)
|
||||
* **CheckboxGroup:** proxy slots & `ui` prop ([bc06185](https://github.com/nuxt/ui/commit/bc061852822edd2dfb832a46dd6388123ec5771e))
|
||||
* **CommandPalette:** consistent alignement with other components ([d25265c](https://github.com/nuxt/ui/commit/d25265c8b7d34e01af8827d9af5eccb98bf30e9e))
|
||||
* **CommandPalette:** increase input font size to avoid zoom ([d227a10](https://github.com/nuxt/ui/commit/d227a105d8d409ea0753153afaecf639ddb80fed))
|
||||
* **CommandPalette:** prevent hover background on disabled items ([ba534f1](https://github.com/nuxt/ui/commit/ba534f18b94383c97b2654d892ee4b8b024b3fab))
|
||||
* **components:** refactor types after `@nuxt/module-builder` upgrade ([#3855](https://github.com/nuxt/ui/issues/3855)) ([39c861a](https://github.com/nuxt/ui/commit/39c861a64bbd452256ebd1a14a257b94c35855d4))
|
||||
* **components:** respect `transform-origin` in popper content ([#3919](https://github.com/nuxt/ui/issues/3919)) ([01d8dc7](https://github.com/nuxt/ui/commit/01d8dc72adb0b32ad68bb4a98bf24b17f435a89c))
|
||||
* **ContextMenu/DropdownMenu:** handle RTL mode ([#3744](https://github.com/nuxt/ui/issues/3744)) ([1ae5cc0](https://github.com/nuxt/ui/commit/1ae5cc09cb2eca6b6f53eb04db9dcc731b696cae))
|
||||
* **ContextMenuContent/DropdownMenuContent:** remove unwanted `any` ([#3741](https://github.com/nuxt/ui/issues/3741)) ([97274f1](https://github.com/nuxt/ui/commit/97274f15b8bfe457e7e206f81b32e3febf0f875d))
|
||||
* **Form:** input and output type inference ([#3938](https://github.com/nuxt/ui/issues/3938)) ([f429498](https://github.com/nuxt/ui/commit/f42949820be9be9fca41abc653dc12c033e1eeec))
|
||||
* **Form:** loses focus on submit ([#3796](https://github.com/nuxt/ui/issues/3796)) ([8e78eb1](https://github.com/nuxt/ui/commit/8e78eb15c85beef1c814206c4a192d4eb00a7e86))
|
||||
* **InputMenu/Select/SelectMenu:** add `min-w-fit` to `content` slot ([#3922](https://github.com/nuxt/ui/issues/3922)) ([f6b3761](https://github.com/nuxt/ui/commit/f6b376110c8bee2c41ae3137bb972aad402ebff1))
|
||||
* **InputMenu/SelectMenu:** correctly call `onSelect` events ([#3735](https://github.com/nuxt/ui/issues/3735)) ([f25fed5](https://github.com/nuxt/ui/commit/f25fed58e988b304e79cdb536d544d257395cf89))
|
||||
* **InputMenu/SelectMenu:** prevent `disabled` items to be selected ([8435a0f](https://github.com/nuxt/ui/commit/8435a0fe1622eb5b6863b6e4751c9d2d1be36db9)), closes [#3474](https://github.com/nuxt/ui/issues/3474)
|
||||
* **InputMenu/SelectMenu:** remove `valueKey` string case ([9ca213b](https://github.com/nuxt/ui/commit/9ca213bd3340492d7503a34bd142e1f79a697050)), closes [#3949](https://github.com/nuxt/ui/issues/3949) [#3331](https://github.com/nuxt/ui/issues/3331)
|
||||
* **InputMenu/SelectMenu:** support arbitrary `value` ([#3779](https://github.com/nuxt/ui/issues/3779)) ([52a97e2](https://github.com/nuxt/ui/commit/52a97e2df7903f91e3134931eb0d6bd4c528f71f))
|
||||
* **InputMenu:** emit `change` on multiple item removal ([9d2fed1](https://github.com/nuxt/ui/commit/9d2fed125013e3bbfbf9435678729cd05254a5e8)), closes [#3756](https://github.com/nuxt/ui/issues/3756)
|
||||
* **Link:** proxy `download` property ([#3879](https://github.com/nuxt/ui/issues/3879)) ([47cdc2e](https://github.com/nuxt/ui/commit/47cdc2e1d8cd9803ebc954ccae110d62b9a08779))
|
||||
* **NavigationMenu:** add `sm:w-auto` content slot ([abe0859](https://github.com/nuxt/ui/commit/abe0859691e06564f68335bd82dcd121e976408e)), closes [#3788](https://github.com/nuxt/ui/issues/3788)
|
||||
* **Skeleton:** improve accessibility ([#3613](https://github.com/nuxt/ui/issues/3613)) ([3484832](https://github.com/nuxt/ui/commit/3484832822015a224ce6fbeae5132018875557e6))
|
||||
* **Stepper:** ui prop override on `icon` and `content` slots ([1d45980](https://github.com/nuxt/ui/commit/1d459803dc052a16b8966ee89c71646bf6ef1c16)), closes [#3785](https://github.com/nuxt/ui/issues/3785)
|
||||
* **Table:** improve `data` reactivity ([#3967](https://github.com/nuxt/ui/issues/3967)) ([6e27304](https://github.com/nuxt/ui/commit/6e27304d8ca459a04667bac404084264a8cf58fd))
|
||||
* **Table:** pass header `colspan` to `th` ([#3926](https://github.com/nuxt/ui/issues/3926)) ([122e8ac](https://github.com/nuxt/ui/commit/122e8ac8f41ba093cd350c3ce642263263f77296))
|
||||
* **Tree:** simplify reusable template types ([#3836](https://github.com/nuxt/ui/issues/3836)) ([3deed4c](https://github.com/nuxt/ui/commit/3deed4c271cad4adc2a4c47d5dd02e95a14ce11a))
|
||||
* **types:** allow color identifiers with dashes ([#3896](https://github.com/nuxt/ui/issues/3896)) ([e5a1e26](https://github.com/nuxt/ui/commit/e5a1e26f9db763b54caed4ca313f44d1b5fe269d))
|
||||
* **types:** handle `ClassValue` in `ui` prop ([eea1415](https://github.com/nuxt/ui/commit/eea14155aa612649bc969d806ec5df4295945c70)), closes [#3860](https://github.com/nuxt/ui/issues/3860)
|
||||
* **types:** improve dynamic slots ([#3857](https://github.com/nuxt/ui/issues/3857)) ([8dd9d08](https://github.com/nuxt/ui/commit/8dd9d08209e47a7d9a5654db4fb936b4cbcfc021))
|
||||
* **usePortal:** adjust portal target resolution logic ([#3954](https://github.com/nuxt/ui/issues/3954)) ([db11db6](https://github.com/nuxt/ui/commit/db11db6ff1ce4b27a66aaa03f07870ba36426181))
|
||||
* **vite:** vitest skipping nuxt imports transformations ([#3925](https://github.com/nuxt/ui/issues/3925)) ([c31bffa](https://github.com/nuxt/ui/commit/c31bffad1b8afeda584bca8c73bb7f790eb12a9f))
|
||||
|
||||
## [3.0.2](https://github.com/nuxt/ui/compare/v3.0.1...v3.0.2) (2025-03-28)
|
||||
|
||||
### Features
|
||||
|
||||
* **Calendar:** allow year and month buttons styling ([#3672](https://github.com/nuxt/ui/issues/3672)) ([4a2b77d](https://github.com/nuxt/ui/commit/4a2b77d86c28806234002340eda39de4dc78cce0))
|
||||
* **locale:** add Armenian language ([#3664](https://github.com/nuxt/ui/issues/3664)) ([c76f590](https://github.com/nuxt/ui/commit/c76f5900970e3f5c451192b1207ccea04771e8b3))
|
||||
* **Table:** add `empty` prop ([afff54f](https://github.com/nuxt/ui/commit/afff54fecd31497238461e0a44abd8668ed734c3))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Avatar:** proxy `$attrs` to default slot ([#3712](https://github.com/nuxt/ui/issues/3712)) ([88f349d](https://github.com/nuxt/ui/commit/88f349d0d74eb1c2ce5066818731759c25a9e83e))
|
||||
* **Button:** use `focus:outline-none` instead of `focus:outline-hidden` ([c231fe5](https://github.com/nuxt/ui/commit/c231fe5f26ca7614df46a7ec8a5ce7f4ec8884e7)), closes [#3658](https://github.com/nuxt/ui/issues/3658)
|
||||
* **CommandPalette:** use `group.id` as key ([bc61d29](https://github.com/nuxt/ui/commit/bc61d29cce531715a6279444845f02a002a22af7))
|
||||
* **components:** improve generic types ([#3331](https://github.com/nuxt/ui/issues/3331)) ([b998354](https://github.com/nuxt/ui/commit/b9983549a4b743724ea3ef99cc4a243f5ca41e53))
|
||||
* **Container:** add `w-full` class ([df00149](https://github.com/nuxt/ui/commit/df001495980647cab1e67fd16154f1bc778de5e2))
|
||||
* **defineLocale/defineShortcuts:** remove `@__NO_SIDE_EFFECTS__` ([82e2665](https://github.com/nuxt/ui/commit/82e26655a40782555299516f32a76046fa0dbd3a))
|
||||
* **Drawer:** remove `fadeFromIndex` prop proxy ([f7604e5](https://github.com/nuxt/ui/commit/f7604e565f717001a4d4c2974cf23559a3f01c21))
|
||||
* **Form:** clear dirty state after submit ([#3692](https://github.com/nuxt/ui/issues/3692)) ([3dd88ba](https://github.com/nuxt/ui/commit/3dd88bacecb2945efba8cc3cb4fe59fcbc056e9a))
|
||||
* **FormField:** add `help` to `aria-describedby` attribute ([#3691](https://github.com/nuxt/ui/issues/3691)) ([20c3392](https://github.com/nuxt/ui/commit/20c33920d005332db3c83f33a8c54c7c227ce0a0))
|
||||
* **InputMenu/SelectMenu:** empty search results ([94b6e52](https://github.com/nuxt/ui/commit/94b6e520f5ccf011204e953421fcc5b44b637e51))
|
||||
* **InputMenu:** reset `searchTerm` on `update:open` ([3074632](https://github.com/nuxt/ui/commit/3074632523e67fa6a0ad3d9a71e5692c285bdc3a)), closes [#3620](https://github.com/nuxt/ui/issues/3620)
|
||||
* **Link:** handle `aria-current` like `NuxtLink` / `RouterLink` ([c531d02](https://github.com/nuxt/ui/commit/c531d0248be7863980a1f676643c2dea8301c009))
|
||||
* **Link:** prevent `active="true"` binding on html ([d73768b](https://github.com/nuxt/ui/commit/d73768b70453d60dd4186a996c1cf808b0294bf6))
|
||||
* **Link:** properly pick all `aria-*` & `data-*` attrs ([ade16b7](https://github.com/nuxt/ui/commit/ade16b76cf535924a8d0f402b4d5d65cb67a55eb))
|
||||
* **Link:** proxy `onClick` ([370054b](https://github.com/nuxt/ui/commit/370054b20c0201c9dba84ddfcd1e916594619b93)), closes [#3631](https://github.com/nuxt/ui/issues/3631)
|
||||
* **NavigationMenu:** add `z-index` on viewport ([0095d89](https://github.com/nuxt/ui/commit/0095d8916bf361c0c89972e2f86b79850510c6a9)), closes [#3654](https://github.com/nuxt/ui/issues/3654)
|
||||
* **Switch:** prevent transition on focus outline ([68787b2](https://github.com/nuxt/ui/commit/68787b26fdf2bd5f9d9e812e5bfddb19abe45d1d))
|
||||
* **Table:** wrong condition on `caption` slot ([4ebb94c](https://github.com/nuxt/ui/commit/4ebb94cd7ef909b3547bce0922f75fe3ff74de4c))
|
||||
* **Tabs:** remove `focus:outline-hidden` class ([1769d5e](https://github.com/nuxt/ui/commit/1769d5ed6ea46b1f7eafdc48cb6456512229f98b))
|
||||
* **types:** add missing export for ButtonGroup ([#3709](https://github.com/nuxt/ui/issues/3709)) ([e7e6745](https://github.com/nuxt/ui/commit/e7e674559981177ad08be42418746060d7737df9))
|
||||
* **useOverlay:** refine `open` method type to infer close emit return type ([#3716](https://github.com/nuxt/ui/issues/3716)) ([bd99c2d](https://github.com/nuxt/ui/commit/bd99c2d850d57baccc51e049c0b578a6fc6ab431))
|
||||
* **vue:** mock `nuxtApp.hooks` & `useRuntimeHook` ([23bfeb9](https://github.com/nuxt/ui/commit/23bfeb937004d619187a67fb43e4c76b13d00069))
|
||||
|
||||
## [3.0.1](https://github.com/nuxt/ui/compare/v3.0.0...v3.0.1) (2025-03-21)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **Form:** drop explicit support for `zod` and `valibot` (#3617)
|
||||
|
||||
### Features
|
||||
|
||||
* **components:** handle events in `content` prop ([5dec0e1](https://github.com/nuxt/ui/commit/5dec0e16e28549b8833aaab17a87fada63d6598c))
|
||||
* **locale:** add Catalan language ([#3550](https://github.com/nuxt/ui/issues/3550)) ([53cf1b4](https://github.com/nuxt/ui/commit/53cf1b4c14a2a0e076e1e77688852e6bd0a28a74))
|
||||
* **locale:** add Central Kurdish language ([#3566](https://github.com/nuxt/ui/issues/3566)) ([b2034cc](https://github.com/nuxt/ui/commit/b2034ccc91eec6a2842c6f83d159e5aa6fd5f2fd))
|
||||
* **locale:** add Romanian language ([#3587](https://github.com/nuxt/ui/issues/3587)) ([0229b0f](https://github.com/nuxt/ui/commit/0229b0fd4644a97db7eb3154c3c87a26634dcfbb))
|
||||
* **locale:** add Urdu language ([#3611](https://github.com/nuxt/ui/issues/3611)) ([126ba23](https://github.com/nuxt/ui/commit/126ba2326f8153e155e1013db92c6ee417117610))
|
||||
* **locale:** add Uzbek language ([#3548](https://github.com/nuxt/ui/issues/3548)) ([302e04b](https://github.com/nuxt/ui/commit/302e04bd77ae8b165046b264c8d23626e92f8fb5))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Calendar:** grey out days outside of displayed month ([#3639](https://github.com/nuxt/ui/issues/3639)) ([a516866](https://github.com/nuxt/ui/commit/a5168666b7dff08e714d57f497737e7a670f457c))
|
||||
* **ContextMenu/DropdownMenu:** remove `any` from `proxySlots` ([#3623](https://github.com/nuxt/ui/issues/3623)) ([764c41a](https://github.com/nuxt/ui/commit/764c41a0c60dd1c12d39a86af9f5f11b9e6cdc8c))
|
||||
* **Modal/Slideover/Toast:** prevent unnecessary close instantiation ([f4c417d](https://github.com/nuxt/ui/commit/f4c417d9ef5409b52084bdf9d8cbccee3139709f))
|
||||
* **module:** handle tailwindcss import without `theme(static)` ([#3630](https://github.com/nuxt/ui/issues/3630)) ([ecff9ab](https://github.com/nuxt/ui/commit/ecff9abc720bdda3a279d5bcfb7b477ff885f2e4))
|
||||
* **module:** mark functions used in exports as pure ([#3604](https://github.com/nuxt/ui/issues/3604)) ([57efc78](https://github.com/nuxt/ui/commit/57efc78a3b3fa4a54bcd13df47d570a18fba2bc4))
|
||||
* **RadioGroup:** handle `disabled` on items ([fe0bd83](https://github.com/nuxt/ui/commit/fe0bd83d11b0dfa53b58d423bc917f8e21d73444)), closes [nuxt/ui-pro#911](https://github.com/nuxt/ui-pro/issues/911)
|
||||
* **Table:** allow links to be opened when [@select](https://github.com/select) is used ([#3580](https://github.com/nuxt/ui/issues/3580)) ([e80cc15](https://github.com/nuxt/ui/commit/e80cc1592fb244dd7692486a4c1ca5b1c2008112))
|
||||
* **types:** add missing export for Icon ([#3568](https://github.com/nuxt/ui/issues/3568)) ([5e62493](https://github.com/nuxt/ui/commit/5e624933216db95cbfd1b8034b2eb0f13846ae55))
|
||||
* **unplugin:** include `@compodium/examples` in auto-imports paths ([#3585](https://github.com/nuxt/ui/issues/3585)) ([cc504b8](https://github.com/nuxt/ui/commit/cc504b8a4b69dd76b49659d5c206ef23dcb9e475))
|
||||
* **useLocale:** unique symbol to use in `@nuxt/ui-pro` ([#3603](https://github.com/nuxt/ui/issues/3603)) ([dec2730](https://github.com/nuxt/ui/commit/dec2730aaea1327434837cfa022ea04056757cbf))
|
||||
* **vue:** missing unhead context ([#3589](https://github.com/nuxt/ui/issues/3589)) ([0897e9e](https://github.com/nuxt/ui/commit/0897e9ef05fbee4f021f317bb7c2d0b7007f1b75))
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **Form:** drop explicit support for `zod` and `valibot` ([#3617](https://github.com/nuxt/ui/issues/3617)) ([9a4bb34](https://github.com/nuxt/ui/commit/9a4bb34d7d14add0a3199103f4b583e8307d1d6d))
|
||||
|
||||
## [3.0.0](https://github.com/nuxt/ui/compare/v3.0.0-beta.4...v3.0.0) (2025-03-12)
|
||||
|
||||
## [3.0.0-beta.4](https://github.com/nuxt/ui/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2025-03-12)
|
||||
|
||||
### Features
|
||||
|
||||
* **Form:** global errors ([#3482](https://github.com/nuxt/ui/issues/3482)) ([6e03d9c](https://github.com/nuxt/ui/commit/6e03d9c6efc8f4cfc306813e733d7d3e03706323))
|
||||
* **Input/Textarea:** allow `null` value in model ([#3415](https://github.com/nuxt/ui/issues/3415)) ([cfe9b2e](https://github.com/nuxt/ui/commit/cfe9b2ecf34827bc11a5281a069988ab96030047))
|
||||
* **useLocale:** handle generic messages ([#3100](https://github.com/nuxt/ui/issues/3100)) ([a9c8eb3](https://github.com/nuxt/ui/commit/a9c8eb3f60a10d1a71632991c9db594716b0fba1))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Button:** missing import ([21dbf01](https://github.com/nuxt/ui/commit/21dbf01888a161a9d8ac6eb0d957c1342f6cc30d)), closes [nuxt/ui#3417](https://github.com/nuxt/ui/issues/3417)
|
||||
* **Form:** input blur validation on submit ([#3504](https://github.com/nuxt/ui/issues/3504)) ([97c8098](https://github.com/nuxt/ui/commit/97c8098d4a35c392719ae179d36aa008d6f8f78a))
|
||||
* **vue:** prevent calling `useHead` in colors ([5ecd227](https://github.com/nuxt/ui/commit/5ecd2271ca86087cb805548397d75c38763ad412))
|
||||
|
||||
## [3.0.0-beta.3](https://github.com/nuxt/ui/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2025-03-07)
|
||||
|
||||
### Features
|
||||
|
||||
* **Button:** handle `active` state ([bd2d484](https://github.com/nuxt/ui/commit/bd2d4848d246a3d5930f8059913f5a1a0abe29fd)), closes [#3417](https://github.com/nuxt/ui/issues/3417)
|
||||
* **Table:** add `loading` slot ([99e531d](https://github.com/nuxt/ui/commit/99e531d8dfb7954322b7ab7feda3d8814c6d8d02)), closes [#3444](https://github.com/nuxt/ui/issues/3444)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **InputMenu/SelectMenu:** proxy `required` in root props ([60b7e2d](https://github.com/nuxt/ui/commit/60b7e2d69e80afa7e221855dcec46479d0ca5c6c))
|
||||
* **InputMenu:** wrong `required` in multiple mode ([01fa230](https://github.com/nuxt/ui/commit/01fa230eae4b6623c5fd71cc218d114d9f6f0f25)), closes [#2741](https://github.com/nuxt/ui/issues/2741)
|
||||
* **Pagination:** add missing slots ([a47c5ff](https://github.com/nuxt/ui/commit/a47c5ff46616eafee3158cb9801183965f5f9874)), closes [#3441](https://github.com/nuxt/ui/issues/3441)
|
||||
* **Pagination:** wrong next link ([e823022](https://github.com/nuxt/ui/commit/e823022b19bb172d2e5fabb9144b4a4286a25a5f)), closes [#3008](https://github.com/nuxt/ui/issues/3008)
|
||||
* **templates:** prevent overriding existing colors ([ccbd89c](https://github.com/nuxt/ui/commit/ccbd89c908fe8af54c7d723dd12da5b7f3906c8f)), closes [#3426](https://github.com/nuxt/ui/issues/3426)
|
||||
|
||||
## [3.0.0-beta.2](https://github.com/nuxt/ui/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2025-02-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
39
README.md
39
README.md
@@ -11,31 +11,35 @@
|
||||
[![License][license-src]][license-href]
|
||||
[![Nuxt][nuxt-src]][nuxt-href]
|
||||
|
||||
We're thrilled to introduce Nuxt UI v3, a significant upgrade to our UI library that delivers extensive improvements and robust new capabilities. This major update harnesses the combined strengths of [Reka UI](https://reka-ui.com/), [Tailwind CSS v4](https://tailwindcss.com/), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces.
|
||||
Nuxt UI harnesses the combined strengths of [Reka UI](https://reka-ui.com/), [Tailwind CSS](https://tailwindcss.com/), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces.
|
||||
|
||||
> [!NOTE]
|
||||
> You are on the `v3` development branch, check out the [dev branch](https://github.com/nuxt/ui/tree/dev) for Nuxt UI v2.
|
||||
> You are on the `v3` development branch, check out the [v2 branch](https://github.com/nuxt/ui/tree/v2) for Nuxt UI v2.
|
||||
|
||||
> [!TIP]
|
||||
> **Looking for more components ?**
|
||||
> Check out [Nuxt UI Pro](https://ui.nuxt.com/pro), a collection of premium Vue components, composables, and utilities built on top of Nuxt UI for faster and more powerful app development.
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit https://ui3.nuxt.dev to explore the documentation.
|
||||
Visit https://ui.nuxt.com to explore the documentation.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash [pnpm]
|
||||
pnpm add @nuxt/ui@next
|
||||
pnpm add @nuxt/ui
|
||||
```
|
||||
|
||||
```bash [yarn]
|
||||
yarn add @nuxt/ui@next
|
||||
yarn add @nuxt/ui
|
||||
```
|
||||
|
||||
```bash [npm]
|
||||
npm install @nuxt/ui@next
|
||||
npm install @nuxt/ui
|
||||
```
|
||||
|
||||
```bash [bun]
|
||||
bun add @nuxt/ui@next
|
||||
bun add @nuxt/ui
|
||||
```
|
||||
|
||||
### Nuxt
|
||||
@@ -51,11 +55,11 @@ export default defineNuxtConfig({
|
||||
2. Import Tailwind CSS and Nuxt UI in your CSS:
|
||||
|
||||
```css [assets/css/main.css]
|
||||
@import "tailwindcss" theme(static);
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
```
|
||||
|
||||
Learn more in the [installation guide](https://ui3.nuxt.dev/getting-started/installation/nuxt).
|
||||
Learn more in the [installation guide](https://ui.nuxt.com/getting-started/installation/nuxt).
|
||||
|
||||
### Vue
|
||||
|
||||
@@ -98,11 +102,22 @@ app.mount('#app')
|
||||
3. Import Tailwind CSS and Nuxt UI in your CSS:
|
||||
|
||||
```css [assets/main.css]
|
||||
@import "tailwindcss" theme(static);
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
```
|
||||
|
||||
Learn more in the [installation guide](https://ui3.nuxt.dev/getting-started/installation/vue).
|
||||
Learn more in the [installation guide](https://ui.nuxt.com/getting-started/installation/vue).
|
||||
|
||||
## Contribution
|
||||
|
||||
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/contribution) to share your suggestions.
|
||||
|
||||
## Local Development
|
||||
|
||||
Follow the docs to [set up your local development environment](https://ui.nuxt.com/getting-started/contribution#local-development) and contribute.
|
||||
|
||||
## Credits
|
||||
|
||||
@@ -119,7 +134,7 @@ Learn more in the [installation guide](https://ui3.nuxt.dev/getting-started/inst
|
||||
Licensed under the [MIT license](https://github.com/nuxt/ui/blob/v3/LICENSE.md).
|
||||
|
||||
<!-- Badges -->
|
||||
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/next.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/latest.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
|
||||
|
||||
@@ -7,10 +7,13 @@ export default defineBuildConfig({
|
||||
'./src/vite'
|
||||
],
|
||||
rollup: {
|
||||
emitCJS: true
|
||||
},
|
||||
replace: {
|
||||
'process.env.DEV': 'false'
|
||||
replace: {
|
||||
delimiters: ['', ''],
|
||||
values: {
|
||||
// Used in development to import directly from theme
|
||||
'process.argv.includes(\'--uiDev\')': 'false'
|
||||
}
|
||||
}
|
||||
},
|
||||
hooks: {
|
||||
'mkdist:entry:options'(ctx, entry, options) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"citty": "^0.1.6",
|
||||
"consola": "^3.4.0",
|
||||
"consola": "^3.4.2",
|
||||
"pathe": "^2.0.3",
|
||||
"scule": "^1.3.0"
|
||||
}
|
||||
|
||||
@@ -31,13 +31,10 @@ const component = ({ name, primitive, pro, prose, content }) => {
|
||||
? `
|
||||
<script lang="ts">
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import _appConfig from '#build/app.config'
|
||||
import theme from '#build/${path}/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}'
|
||||
import { tv } from '${pro ? '#ui/utils/tv' : '../utils/tv'}'
|
||||
import type { ComponentConfig } from '../types/utils'
|
||||
|
||||
const appConfig${camelName} = _appConfig as AppConfig & { ${key}: { ${prose ? 'prose: { ' : ''}${camelName}: Partial<typeof theme> } }${prose ? ' }' : ''}
|
||||
|
||||
const ${camelName} = tv({ extend: tv(theme), ...(appConfig${camelName}.${key}?.${prose ? 'prose?.' : ''}${camelName} || {}) })
|
||||
type ${upperName} = ComponentConfig<typeof theme, AppConfig, ${upperName}${pro ? `, '${key}'` : ''}>
|
||||
|
||||
export interface ${upperName}Props {
|
||||
/**
|
||||
@@ -46,7 +43,7 @@ export interface ${upperName}Props {
|
||||
*/
|
||||
as?: any
|
||||
class?: any
|
||||
ui?: Partial<typeof ${camelName}.slots>
|
||||
ui?: ${upperName}['slots']
|
||||
}
|
||||
|
||||
export interface ${upperName}Slots {
|
||||
@@ -55,38 +52,37 @@ export interface ${upperName}Slots {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Primitive } from 'reka-ui'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { tv } from '../utils/tv'
|
||||
|
||||
const props = defineProps<${upperName}Props>()
|
||||
defineSlots<${upperName}Slots>()
|
||||
|
||||
const ui = ${camelName}()
|
||||
const appConfig = useAppConfig() as ${upperName}['AppConfig']
|
||||
|
||||
const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.${camelName} || {}) })())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })">
|
||||
<Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
`
|
||||
: `
|
||||
<script lang="ts">
|
||||
import type { VariantProps } from 'tailwind-variants'
|
||||
import type { ${upperName}RootProps, ${upperName}RootEmits } from 'reka-ui'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import _appConfig from '#build/app.config'
|
||||
import theme from '#build/${path}/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}'
|
||||
import { tv } from '${pro ? '#ui/utils/tv' : '../utils/tv'}'
|
||||
import type { ComponentConfig } from '../types/utils'
|
||||
|
||||
const appConfig${camelName} = _appConfig as AppConfig & { ${key}: { ${prose ? 'prose: { ' : ''}${camelName}: Partial<typeof theme> } }${prose ? ' }' : ''}
|
||||
|
||||
const ${camelName} = tv({ extend: tv(theme), ...(appConfig${camelName}.${key}?.${prose ? 'prose?.' : ''}${camelName} || {}) })
|
||||
|
||||
type ${upperName}Variants = VariantProps<typeof ${camelName}>
|
||||
type ${upperName} = ComponentConfig<typeof theme, AppConfig, ${upperName}${pro ? `, '${key}'` : ''}>
|
||||
|
||||
export interface ${upperName}Props extends Pick<${upperName}RootProps> {
|
||||
class?: any
|
||||
ui?: Partial<typeof ${camelName}.slots>
|
||||
ui?: ${upperName}['slots']
|
||||
}
|
||||
|
||||
export interface ${upperName}Emits extends ${upperName}RootEmits {}
|
||||
@@ -95,20 +91,25 @@ export interface ${upperName}Slots {}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { ${upperName}Root, useForwardPropsEmits } from 'reka-ui'
|
||||
import { reactivePick } from '@vueuse/core'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { tv } from '../utils/tv'
|
||||
|
||||
const props = defineProps<${upperName}Props>()
|
||||
const emits = defineEmits<${upperName}Emits>()
|
||||
const slots = defineSlots<${upperName}Slots>()
|
||||
|
||||
const appConfig = useAppConfig() as ${upperName}['AppConfig']
|
||||
|
||||
const rootProps = useForwardPropsEmits(reactivePick(props), emits)
|
||||
|
||||
const ui = ${camelName}()
|
||||
const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.${camelName} || {}) })())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<${upperName}Root v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })" />
|
||||
<${upperName}Root v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })" />
|
||||
</template>
|
||||
`
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
// import { withoutTrailingSlash } from 'ufo'
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
import colors from 'tailwindcss/colors'
|
||||
// import { debounce } from 'perfect-debounce'
|
||||
|
||||
const route = useRoute()
|
||||
const appConfig = useAppConfig()
|
||||
@@ -12,16 +11,6 @@ const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSe
|
||||
server: false
|
||||
})
|
||||
|
||||
const searchTerm = ref('')
|
||||
|
||||
// watch(searchTerm, debounce((query: string) => {
|
||||
// if (!query) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// useTrackEvent('Search', { props: { query: `${query} - ${searchTerm.value?.commandPaletteRef.results.length} results` } })
|
||||
// }, 500))
|
||||
|
||||
const links = useLinks()
|
||||
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
||||
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
||||
@@ -33,8 +22,8 @@ useHead({
|
||||
{ key: 'theme-color', name: 'theme-color', content: color }
|
||||
],
|
||||
link: [
|
||||
{ rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' }
|
||||
// { rel: 'canonical', href: `https://ui.nuxt.com${withoutTrailingSlash(route.path)}` }
|
||||
// { rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' },
|
||||
{ rel: 'canonical', href: `https://ui.nuxt.com${withoutTrailingSlash(route.path)}` }
|
||||
],
|
||||
style: [
|
||||
{ innerHTML: radius, id: 'nuxt-ui-radius', tagPriority: -2 },
|
||||
@@ -50,7 +39,8 @@ useServerSeoMeta({
|
||||
twitterCard: 'summary_large_image'
|
||||
})
|
||||
|
||||
const { frameworks, modules } = useSharedData()
|
||||
useFaviconFromTheme()
|
||||
|
||||
const { mappedNavigation, filteredNavigation } = useContentNavigation(navigation)
|
||||
|
||||
provide('navigation', mappedNavigation)
|
||||
@@ -73,27 +63,11 @@ provide('navigation', mappedNavigation)
|
||||
<template v-if="!route.path.startsWith('/examples')">
|
||||
<Footer />
|
||||
|
||||
<ClientOnly>
|
||||
<LazyUContentSearch
|
||||
v-model:search-term="searchTerm"
|
||||
:files="files"
|
||||
:groups="[{
|
||||
id: 'framework',
|
||||
label: 'Framework',
|
||||
items: frameworks
|
||||
}, {
|
||||
id: 'module',
|
||||
label: 'Module',
|
||||
items: modules
|
||||
}]"
|
||||
:navigation="filteredNavigation"
|
||||
:fuse="{ resultLimit: 100 }"
|
||||
/>
|
||||
</ClientOnly>
|
||||
<Search :files="files" :navigation="filteredNavigation" />
|
||||
</template>
|
||||
</UApp>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/* Safelist (do not remove): [&>div]:*:my-0 [&>div]:*:w-full h-64 !px-0 !py-0 !pt-0 !pb-0 !p-0 !justify-start !min-h-96 h-136 */
|
||||
/* Safelist (do not remove): [&>div]:*:my-0 [&>div]:*:w-full h-64 !px-0 !py-0 !pt-0 !pb-0 !p-0 !justify-start !justify-end !min-h-96 h-136 max-h-[341px] */
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
@import "tailwindcss" theme(static) source("../../../..");
|
||||
@import "@nuxt/ui-pro";
|
||||
|
||||
@source "../../../content";
|
||||
@source "../../../content/**/*";
|
||||
@source "../../../node_modules/.c12";
|
||||
|
||||
@theme static {
|
||||
--container-8xl: 90rem;
|
||||
|
||||
50
docs/app/components/AdsCarbon.vue
Normal file
50
docs/app/components/AdsCarbon.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
const el = ref<HTMLDivElement | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
if (!el.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const script = document.createElement('script')
|
||||
script.setAttribute('type', 'text/javascript')
|
||||
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CWYIVK3E&placement=uinuxtcom')
|
||||
script.setAttribute('id', '_carbonads_js')
|
||||
|
||||
el.value?.appendChild(script)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="el" class="carbon" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../assets/css/main.css";
|
||||
|
||||
.carbon :deep(#carbonads) {
|
||||
@apply relative border border-default rounded-md hover:bg-elevated/50 w-full transition-colors min-h-[220px] p-2;
|
||||
|
||||
.carbon-img {
|
||||
@apply flex justify-center w-full;
|
||||
|
||||
& > img {
|
||||
@apply !max-w-full w-full rounded-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.carbon-text {
|
||||
@apply text-sm text-muted transition-colors text-center text-pretty flex pt-2;
|
||||
}
|
||||
|
||||
.carbon-poweredby {
|
||||
@apply block text-xs text-center text-muted pt-2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.carbon-text {
|
||||
@apply text-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,18 @@
|
||||
<template>
|
||||
<UBanner icon="i-lucide-construction" :actions="[{ label: 'Go to Nuxt UI v2', to: 'https://ui.nuxt.com', trailingIcon: 'i-lucide-arrow-right' }]" :close="false">
|
||||
<UBanner
|
||||
id="ui3-launch"
|
||||
icon="i-lucide-rocket"
|
||||
:actions="[
|
||||
{
|
||||
label: 'Discover Nuxt UI Pro',
|
||||
to: '/pro/pricing',
|
||||
trailingIcon: 'i-lucide-arrow-right'
|
||||
}
|
||||
]"
|
||||
close
|
||||
>
|
||||
<template #title>
|
||||
You're looking at the documentation for <span class="font-semibold">Nuxt UI v3</span>!
|
||||
<span class="font-semibold">Nuxt UI v3</span> is officially released.
|
||||
</template>
|
||||
</UBanner>
|
||||
</template>
|
||||
|
||||
51
docs/app/components/Countdown.vue
Normal file
51
docs/app/components/Countdown.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
const endDate = new Date('2025-03-14T23:59:59Z')
|
||||
const second = 1000
|
||||
const minute = second * 60
|
||||
const hour = minute * 60
|
||||
const day = hour * 24
|
||||
|
||||
function getCountdown() {
|
||||
const distance = Math.floor((endDate.getTime() - Date.now()))
|
||||
return {
|
||||
day: Math.floor(distance / day),
|
||||
hour: Math.floor((distance % (day)) / (hour)),
|
||||
minute: Math.floor((distance % (hour)) / (minute)),
|
||||
second: Math.floor((distance % (minute)) / (second)),
|
||||
distance
|
||||
}
|
||||
}
|
||||
const countdown = ref(getCountdown())
|
||||
let interval: any
|
||||
if (countdown.value.distance > 0) {
|
||||
onMounted(() => {
|
||||
interval = setInterval(() => {
|
||||
countdown.value = getCountdown()
|
||||
if (countdown.value.distance <= 0) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
const plural = (value: number) => (value === 1 ? '' : 's')
|
||||
const double = (value: number) => (value < 10 ? `0${value}` : value)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p class="font-semibold text-gray-900 dark:text-white text-sm mb-3">
|
||||
Nuxt UI v3 launch offer ends in:
|
||||
</p>
|
||||
|
||||
<div class="flex items-center justify-center gap-2 text-center">
|
||||
<template v-for="(value, key) in countdown" :key="key">
|
||||
<div v-if="key !== 'distance'" class="flex flex-col items-center gap-2">
|
||||
<UBadge color="primary" class="w-14 h-14 font-bold text-2xl flex items-center justify-center tabular-nums" variant="subtle">
|
||||
{{ double(value) }}
|
||||
</UBadge>
|
||||
<span class="text-[10px] font-semibold text-gray-900 dark:text-white tracking-wide tabular-nums uppercase">{{ key }}{{ plural(value) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,7 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
|
||||
const links = [{
|
||||
label: 'Figma',
|
||||
to: '/figma'
|
||||
label: 'Team',
|
||||
to: '/team'
|
||||
}, {
|
||||
label: 'Roadmap',
|
||||
to: '/roadmap'
|
||||
@@ -16,12 +18,12 @@ const links = [{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<USeparator icon="i-simple-icons-nuxtdotjs" class="h-px" />
|
||||
<USeparator :icon="route.path === '/' ? undefined : 'i-simple-icons-nuxtdotjs'" class="h-px" />
|
||||
|
||||
<UFooter>
|
||||
<template #left>
|
||||
<NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-(--ui-text-muted)">
|
||||
Published under <span class="text-(--ui-text-highlighted)">MIT License</span>
|
||||
<NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-muted">
|
||||
Published under <span class="text-highlighted">MIT License</span>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ watch(framework, () => {
|
||||
:content="false"
|
||||
color="neutral"
|
||||
:ui="{
|
||||
indicator: 'bg-(--ui-bg)',
|
||||
trigger: 'px-1 data-[state=active]:text-(--ui-text-highlighted)'
|
||||
indicator: 'bg-default',
|
||||
trigger: 'px-1 data-[state=active]:text-highlighted w-full'
|
||||
}"
|
||||
size="xs"
|
||||
@update:model-value="(framework = $event as string)"
|
||||
|
||||
@@ -22,22 +22,38 @@ onMounted(() => {
|
||||
|
||||
const navigation = inject<Ref<ContentNavigationItem[]>>('navigation')
|
||||
|
||||
const githubLink = computed(() => {
|
||||
return `https://github.com/nuxt/${value.value}`
|
||||
})
|
||||
|
||||
const desktopLinks = computed(() => props.links.map(({ icon, ...link }) => link))
|
||||
const mobileLinks = computed(() => props.links.map(link => ({ ...link, defaultOpen: link.children && route.path.startsWith(link.to as string) })))
|
||||
const mobileLinks = computed(() => [
|
||||
...props.links.map(link => ({ ...link, defaultOpen: link.children && route.path.startsWith(link.to as string) })),
|
||||
{
|
||||
label: 'Open on GitHub',
|
||||
to: githubLink.value,
|
||||
icon: 'i-simple-icons-github',
|
||||
target: '_blank'
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UHeader :ui="{ left: 'min-w-0' }" :menu="{ shouldScaleBackground: true }">
|
||||
<template #left>
|
||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-(--ui-text-highlighted) min-w-0 focus-visible:outline-(--ui-primary) shrink-0" aria-label="Nuxt UI">
|
||||
<LogoPro class="w-auto h-6 shrink-0 ui-pro-only" />
|
||||
<Logo class="w-auto h-6 shrink-0 ui-only" />
|
||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-highlighted min-w-0 focus-visible:outline-primary shrink-0" aria-label="Nuxt UI">
|
||||
<Logo v-if="route.path === '/'" class="w-auto h-6 shrink-0" />
|
||||
<LogoPro v-else-if="route.path.startsWith('/pro')" class="w-auto h-6 shrink-0" />
|
||||
<template v-else>
|
||||
<LogoPro class="w-auto h-6 shrink-0 ui-pro-only" />
|
||||
<Logo class="w-auto h-6 shrink-0 ui-only" />
|
||||
</template>
|
||||
</NuxtLink>
|
||||
|
||||
<UDropdownMenu
|
||||
v-slot="{ open }"
|
||||
:modal="false"
|
||||
:items="[{ label: `v${config.version}`, active: true, color: 'primary', checked: true, type: 'checkbox' }, { label: module === 'ui-pro' ? 'v1.5' : 'v2.19', to: module === 'ui-pro' ? 'https://ui.nuxt.com/pro' : 'https://ui.nuxt.com' }]"
|
||||
:items="[{ label: `v${config.version}`, active: true, color: 'primary', checked: true, type: 'checkbox' }, { label: module === 'ui-pro' ? 'v1.7.1' : 'v2.21.1', to: module === 'ui-pro' ? 'https://ui2.nuxt.com/pro' : 'https://ui2.nuxt.com' }]"
|
||||
:ui="{ content: 'w-(--reka-dropdown-menu-trigger-width) min-w-0' }"
|
||||
size="xs"
|
||||
>
|
||||
@@ -47,7 +63,7 @@ const mobileLinks = computed(() => props.links.map(link => ({ ...link, defaultOp
|
||||
trailing-icon="i-lucide-chevron-down"
|
||||
size="xs"
|
||||
class="-mb-[6px] font-semibold rounded-full truncate"
|
||||
:class="[open && 'bg-(--ui-primary)/15 ']"
|
||||
:class="[open && 'bg-primary/15 ']"
|
||||
:ui="{
|
||||
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined].filter(Boolean).join(' ')
|
||||
}"
|
||||
@@ -69,7 +85,7 @@ const mobileLinks = computed(() => props.links.map(link => ({ ...link, defaultOp
|
||||
:key="value"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
:to="`https://github.com/nuxt/${value}`"
|
||||
:to="githubLink"
|
||||
target="_blank"
|
||||
icon="i-simple-icons-github"
|
||||
aria-label="GitHub"
|
||||
@@ -78,7 +94,7 @@ const mobileLinks = computed(() => props.links.map(link => ({ ...link, defaultOp
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
<UNavigationMenu orientation="vertical" :items="mobileLinks" class="-mx-2.5" default-open />
|
||||
<UNavigationMenu orientation="vertical" :items="mobileLinks" class="-mx-2.5" />
|
||||
|
||||
<USeparator type="dashed" class="mt-4 mb-6" />
|
||||
|
||||
@@ -92,7 +108,7 @@ const mobileLinks = computed(() => props.links.map(link => ({ ...link, defaultOp
|
||||
<span class="inline-flex items-center gap-0.5">
|
||||
{{ link.title }}
|
||||
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-(--ui-primary)">PRO</sup>
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-primary">PRO</sup>
|
||||
</span>
|
||||
</template>
|
||||
</UContentNavigation>
|
||||
|
||||
@@ -19,8 +19,8 @@ watch(module, () => {
|
||||
:content="false"
|
||||
color="neutral"
|
||||
:ui="{
|
||||
indicator: 'bg-(--ui-bg)',
|
||||
trigger: 'px-1 data-[state=active]:text-(--ui-text-highlighted)'
|
||||
indicator: 'bg-default',
|
||||
trigger: 'px-1 data-[state=active]:text-highlighted w-full'
|
||||
}"
|
||||
size="xs"
|
||||
@update:model-value="(module = $event as string)"
|
||||
|
||||
199
docs/app/components/Search.client.vue
Normal file
199
docs/app/components/Search.client.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefineComponent } from 'vue'
|
||||
import type { ContentNavigationItem } from '@nuxt/content'
|
||||
import { useChat } from '@ai-sdk/vue'
|
||||
import ProseStreamPre from './prose/PreStream.vue'
|
||||
|
||||
const components = {
|
||||
pre: ProseStreamPre as unknown as DefineComponent
|
||||
}
|
||||
|
||||
interface ContentSearchFile {
|
||||
id: string
|
||||
title: string
|
||||
titles: string[]
|
||||
level: number
|
||||
content: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
files?: ContentSearchFile[]
|
||||
navigation?: ContentNavigationItem[]
|
||||
}>()
|
||||
|
||||
const { frameworks, modules } = useSharedData()
|
||||
const { messages, input, handleSubmit, status, error, reload, setMessages } = useChat({
|
||||
maxSteps: 2
|
||||
})
|
||||
|
||||
const ai = ref(false)
|
||||
const searchTerm = ref('')
|
||||
|
||||
const links = computed(() => [{
|
||||
label: 'Ask AI',
|
||||
icon: 'i-lucide-bot',
|
||||
onSelect: (e: any) => {
|
||||
e.preventDefault()
|
||||
|
||||
ai.value = true
|
||||
}
|
||||
}, {
|
||||
label: 'Docs',
|
||||
icon: 'i-lucide-square-play',
|
||||
to: '/getting-started'
|
||||
}, {
|
||||
label: 'Components',
|
||||
icon: 'i-lucide-square-code',
|
||||
to: '/components'
|
||||
}, {
|
||||
icon: 'i-lucide-sparkles',
|
||||
label: 'Pro > Features',
|
||||
description: 'A collection of premium Vue components.',
|
||||
to: '/pro'
|
||||
}, {
|
||||
icon: 'i-lucide-credit-card',
|
||||
label: 'Pro > Pricing',
|
||||
description: 'Free in development, buy when ready to launch.',
|
||||
to: '/pro/pricing'
|
||||
}, {
|
||||
icon: 'i-lucide-panels-top-left',
|
||||
label: 'Pro > Templates',
|
||||
description: 'Official templates made with Nuxt UI Pro.',
|
||||
to: '/pro/templates'
|
||||
}, {
|
||||
icon: 'i-lucide-circle-check',
|
||||
label: 'Pro > Activate',
|
||||
description: 'Enable Nuxt UI Pro in your production projects.',
|
||||
to: '/pro/activate'
|
||||
}, {
|
||||
label: 'Figma',
|
||||
icon: 'i-simple-icons-figma',
|
||||
to: '/figma'
|
||||
}, {
|
||||
icon: 'i-lucide-presentation',
|
||||
label: 'Community > Showcase',
|
||||
description: 'Check out some of the amazing projects built with Nuxt UI.',
|
||||
to: '/showcase'
|
||||
}, {
|
||||
label: 'Community > Contribution',
|
||||
description: 'A comprehensive guide on contributing to Nuxt UI, including project structure, development workflow, and best practices.',
|
||||
icon: 'i-lucide-git-pull-request-arrow',
|
||||
to: '/getting-started/contribution'
|
||||
}, {
|
||||
label: 'Community > Roadmap',
|
||||
description: 'Track our development progress in real-time.',
|
||||
icon: 'i-lucide-map',
|
||||
to: '/roadmap'
|
||||
}, {
|
||||
label: 'Community > Devtools',
|
||||
description: 'Integrate Nuxt UI with Nuxt Devtools with Compodium.',
|
||||
icon: 'i-lucide-code',
|
||||
to: 'https://github.com/romhml/compodium',
|
||||
target: '_blank'
|
||||
}, {
|
||||
label: 'Community > Team',
|
||||
description: 'Meet the team behind Nuxt UI.',
|
||||
icon: 'i-lucide-users',
|
||||
to: '/team'
|
||||
}, {
|
||||
label: 'Releases',
|
||||
icon: 'i-lucide-rocket',
|
||||
to: 'https://github.com/nuxt/ui/releases',
|
||||
target: '_blank'
|
||||
}])
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'ai',
|
||||
label: 'AI',
|
||||
ignoreFilter: true,
|
||||
items: [{
|
||||
label: searchTerm.value ? `Ask Nuxt AI for “${searchTerm.value}”` : 'Ask Nuxt AI',
|
||||
icon: 'i-lucide-bot',
|
||||
onSelect: (e: any) => {
|
||||
e.preventDefault()
|
||||
|
||||
ai.value = true
|
||||
|
||||
if (searchTerm.value) {
|
||||
setMessages([{
|
||||
id: '1',
|
||||
role: 'user',
|
||||
content: searchTerm.value
|
||||
}])
|
||||
|
||||
reload()
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
id: 'framework',
|
||||
label: 'Framework',
|
||||
items: frameworks.value
|
||||
}, {
|
||||
id: 'module',
|
||||
label: 'Module',
|
||||
items: modules.value
|
||||
}])
|
||||
|
||||
function onClose(e: Event) {
|
||||
console.log('onClose')
|
||||
e.preventDefault()
|
||||
|
||||
ai.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LazyUContentSearch
|
||||
v-model:search-term="searchTerm"
|
||||
:links="links"
|
||||
:files="files"
|
||||
:groups="groups"
|
||||
:navigation="navigation"
|
||||
:fuse="{ resultLimit: 100 }"
|
||||
>
|
||||
<template v-if="ai" #content>
|
||||
<UChatPalette>
|
||||
<UChatMessages
|
||||
:messages="messages"
|
||||
:status="status"
|
||||
:user="{ side: 'left', variant: 'naked', icon: 'i-lucide-user' }"
|
||||
:assistant="{ icon: 'i-lucide-bot' }"
|
||||
>
|
||||
<template #content="{ message }">
|
||||
<MDCCached
|
||||
v-if="message.toolInvocations?.[0]?.state === 'result'"
|
||||
:value="message.toolInvocations?.[0]?.result"
|
||||
:cache-key="message.id"
|
||||
unwrap="p"
|
||||
:components="components"
|
||||
:parser-options="{ highlight: false }"
|
||||
/>
|
||||
<MDCCached
|
||||
v-else-if="message.content.length > 0"
|
||||
:value="message.content"
|
||||
:cache-key="message.id"
|
||||
unwrap="p"
|
||||
:components="components"
|
||||
:parser-options="{ highlight: false }"
|
||||
/>
|
||||
<span v-else class="italic font-light">
|
||||
Searching documentation...
|
||||
</span>
|
||||
</template>
|
||||
</UChatMessages>
|
||||
|
||||
<template #prompt>
|
||||
<UChatPrompt
|
||||
v-model="input"
|
||||
icon="i-lucide-search"
|
||||
variant="naked"
|
||||
:error="error"
|
||||
@submit="handleSubmit"
|
||||
@close="onClose"
|
||||
/>
|
||||
</template>
|
||||
</UChatPalette>
|
||||
</template>
|
||||
</LazyUContentSearch>
|
||||
</template>
|
||||
95
docs/app/components/SkyBg.vue
Normal file
95
docs/app/components/SkyBg.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<script setup lang="ts">
|
||||
import { kebabCase } from 'scule'
|
||||
|
||||
interface Star {
|
||||
x: number
|
||||
y: number
|
||||
size: number
|
||||
twinkleDelay: number
|
||||
id: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
starCount?: number
|
||||
color?: string
|
||||
size?: { min: number, max: number }
|
||||
speed?: 'slow' | 'normal' | 'fast'
|
||||
isIndex?: boolean
|
||||
}>(), {
|
||||
starCount: 50,
|
||||
color: 'var(--ui-primary)',
|
||||
size: () => ({
|
||||
min: 1,
|
||||
max: 3
|
||||
}),
|
||||
speed: 'normal',
|
||||
isIndex: false
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// Generate random stars
|
||||
const generateStars = (count: number): Star[] => {
|
||||
return Array.from({ length: count }, () => {
|
||||
const x = Math.floor(Math.random() * 100)
|
||||
const y = Math.floor(Math.random() * 100)
|
||||
const size = Math.random() * (props.size.max - props.size.min) + props.size.min
|
||||
const twinkleDelay = Math.random() * 5
|
||||
|
||||
return { x, y, size, twinkleDelay, id: Math.random().toString(36).substring(2, 9) }
|
||||
})
|
||||
}
|
||||
|
||||
// Generate all stars
|
||||
const stars = useState<Star[]>(`${kebabCase(route.path)}-sky`, () => generateStars(props.starCount))
|
||||
|
||||
// Compute twinkle animation duration based on speed
|
||||
const twinkleDuration = computed(() => {
|
||||
const speedMap: Record<string, string> = {
|
||||
slow: '4s',
|
||||
normal: '2s',
|
||||
fast: '1s'
|
||||
}
|
||||
return speedMap[props.speed]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="absolute pointer-events-none z-[-1] overflow-hidden" :class="isIndex ? 'inset-y-0 left-4 right-4 lg:right-[50%]' : 'inset-0'">
|
||||
<div
|
||||
v-for="star in stars"
|
||||
:key="star.id"
|
||||
class="star absolute"
|
||||
:style="{
|
||||
'left': `${star.x}%`,
|
||||
'top': `${star.y}%`,
|
||||
'transform': 'translate(-50%, -50%)',
|
||||
'--star-size': `${star.size}px`,
|
||||
'--star-color': color,
|
||||
'--twinkle-delay': `${star.twinkleDelay}s`,
|
||||
'--twinkle-duration': twinkleDuration
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.star {
|
||||
width: var(--star-size);
|
||||
height: var(--star-size);
|
||||
background-color: var(--star-color);
|
||||
border-radius: 50%;
|
||||
animation: twinkle var(--twinkle-duration) ease-in-out infinite;
|
||||
animation-delay: var(--twinkle-delay);
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
@keyframes twinkle {
|
||||
0%, 100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,6 @@
|
||||
<!-- eslint-disable no-useless-escape -->
|
||||
<script setup lang="ts">
|
||||
import type { ChipProps } from '@nuxt/ui'
|
||||
import json5 from 'json5'
|
||||
import { upperFirst, camelCase, kebabCase } from 'scule'
|
||||
import { hash } from 'ohash'
|
||||
@@ -53,6 +54,8 @@ const props = defineProps<{
|
||||
hide?: string[]
|
||||
/** List of props to externalize in script setup */
|
||||
external?: string[]
|
||||
/** The types of the externalized props */
|
||||
externalTypes?: string[]
|
||||
/** List of props to use with `v-model` */
|
||||
model?: string[]
|
||||
/** List of props to cast from code and selection */
|
||||
@@ -150,7 +153,8 @@ const options = computed(() => {
|
||||
const items = propItems.length
|
||||
? propItems.map((item: any) => ({
|
||||
value: item,
|
||||
label: String(item)
|
||||
label: String(item),
|
||||
chip: key.toLowerCase().endsWith('color') ? { color: item } : undefined
|
||||
}))
|
||||
: prop?.type === 'boolean' || prop?.type === 'boolean | undefined'
|
||||
? [{ value: true, label: 'true' }, { value: false, label: 'false' }]
|
||||
@@ -209,11 +213,21 @@ ${props.slots?.default}
|
||||
code += `
|
||||
<script setup lang="ts">
|
||||
`
|
||||
for (const key of props.external) {
|
||||
if (props.externalTypes?.length) {
|
||||
const removeArrayBrackets = (type: string): string => type.endsWith('[]') ? removeArrayBrackets(type.slice(0, -2)) : type
|
||||
|
||||
const types = props.externalTypes.map(type => removeArrayBrackets(type))
|
||||
code += `import type { ${types.join(', ')} } from '@nuxt/ui${props.pro ? '-pro' : ''}'
|
||||
|
||||
`
|
||||
}
|
||||
|
||||
for (const [i, key] of props.external.entries()) {
|
||||
const cast = props.cast?.[key]
|
||||
const value = cast ? castMap[cast]!.template(componentProps[key]) : json5.stringify(componentProps[key], null, 2)?.replace(/,([ |\t\n]+[}|\]])/g, '$1')
|
||||
const type = props.externalTypes?.[i] ? `<${props.externalTypes[i]}>` : ''
|
||||
|
||||
code += `const ${key === 'modelValue' ? 'value' : key} = ref(${value})
|
||||
code += `const ${key === 'modelValue' ? 'value' : key} = ref${type}(${value})
|
||||
`
|
||||
}
|
||||
code += `<\/script>
|
||||
@@ -315,16 +329,16 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div>
|
||||
<div v-if="options.length" class="flex flex-wrap items-center gap-2.5 border border-(--ui-border-muted) border-b-0 relative rounded-t-[calc(var(--ui-radius)*1.5)] px-4 py-2.5 overflow-x-auto">
|
||||
<div class="relative">
|
||||
<div v-if="options.length" class="flex flex-wrap items-center gap-2.5 border border-muted 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"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-(--ui-radius)"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-(--ui-radius) flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
@@ -335,7 +349,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
value-key="value"
|
||||
color="neutral"
|
||||
variant="soft"
|
||||
class="rounded-(--ui-radius) rounded-l-none min-w-12"
|
||||
class="rounded-sm rounded-l-none min-w-12"
|
||||
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
|
||||
:ui="{ itemLeadingChip: 'size-2' }"
|
||||
@update:model-value="setComponentProp(option.name, $event)"
|
||||
@@ -346,7 +360,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
inset
|
||||
standalone
|
||||
:color="(modelValue as any)"
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
|
||||
class="size-2"
|
||||
/>
|
||||
</template>
|
||||
@@ -357,14 +371,14 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
:model-value="getComponentProp(option.name)"
|
||||
color="neutral"
|
||||
variant="soft"
|
||||
:ui="{ base: 'rounded-(--ui-radius) rounded-l-none min-w-12' }"
|
||||
:ui="{ base: 'rounded-sm rounded-l-none min-w-12' }"
|
||||
@update:model-value="setComponentProp(option.name, $event)"
|
||||
/>
|
||||
</UFormField>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="component" class="flex justify-center border border-b-0 border-(--ui-border-muted) relative p-4 z-[1]" :class="[!options.length && 'rounded-t-[calc(var(--ui-radius)*1.5)]', props.class, { 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="component" class="flex justify-center border border-b-0 border-muted relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class, { 'overflow-hidden': props.overflowHidden }]">
|
||||
<component :is="component" v-bind="{ ...componentProps, ...componentEvents }">
|
||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
||||
<slot :name="slot" mdc-unwrap="p">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { ChipProps } from '@nuxt/ui'
|
||||
import { camelCase } from 'scule'
|
||||
import { useElementSize } from '@vueuse/core'
|
||||
import { get, set } from '#ui/utils'
|
||||
@@ -149,8 +150,8 @@ const urlSearchParams = computed(() => {
|
||||
<template>
|
||||
<div ref="el" class="my-5">
|
||||
<template v-if="preview">
|
||||
<div class="border border-(--ui-border-muted) relative z-[1]" :class="[{ 'border-b-0 rounded-t-[calc(var(--ui-radius)*1.5)]': props.source, 'rounded-[calc(var(--ui-radius)*1.5)]': !props.source, 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-(--ui-border-muted)">
|
||||
<div class="border border-muted relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source, 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-muted">
|
||||
<slot name="options" />
|
||||
|
||||
<UFormField
|
||||
@@ -159,10 +160,10 @@ const urlSearchParams = computed(() => {
|
||||
:label="option.label"
|
||||
:name="option.name"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-(--ui-radius)"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-(--ui-radius) flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
@@ -174,7 +175,7 @@ const urlSearchParams = computed(() => {
|
||||
:value-key="option.name.toLowerCase().endsWith('color') ? 'value' : undefined"
|
||||
color="neutral"
|
||||
variant="soft"
|
||||
class="rounded-(--ui-radius) rounded-l-none min-w-12"
|
||||
class="rounded-sm rounded-l-none min-w-12"
|
||||
:multiple="option.multiple"
|
||||
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
|
||||
:ui="{ itemLeadingChip: 'size-2' }"
|
||||
@@ -185,7 +186,7 @@ const urlSearchParams = computed(() => {
|
||||
inset
|
||||
standalone
|
||||
:color="(modelValue as any)"
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
|
||||
class="size-2"
|
||||
/>
|
||||
</template>
|
||||
@@ -195,7 +196,7 @@ const urlSearchParams = computed(() => {
|
||||
:model-value="get(optionsValues, option.name)"
|
||||
color="neutral"
|
||||
variant="soft"
|
||||
:ui="{ base: 'rounded-(--ui-radius) rounded-l-none min-w-12' }"
|
||||
:ui="{ base: 'rounded-sm rounded-l-none min-w-12' }"
|
||||
@update:model-value="set(optionsValues, option.name, $event)"
|
||||
/>
|
||||
</UFormField>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { upperFirst, camelCase } from 'scule'
|
||||
import { upperFirst, camelCase, kebabCase } from 'scule'
|
||||
import type { ComponentMeta } from 'vue-component-meta'
|
||||
import * as theme from '#build/ui'
|
||||
import * as themePro from '#build/ui-pro'
|
||||
@@ -112,7 +112,7 @@ const metaProps: ComputedRef<ComponentMeta['props']> = computed(() => {
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="prop.type" :type="prop.type" />
|
||||
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-(--ui-text-toned) mt-1" />
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-toned mt-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-description`" />
|
||||
|
||||
<ComponentPropsLinks v-if="prop.tags?.length" :prop="prop" />
|
||||
<ComponentPropsSchema v-if="prop.schema" :prop="prop" :ignore="ignore" />
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import { kebabCase } from 'scule'
|
||||
import type { PropertyMeta } from 'vue-component-meta'
|
||||
|
||||
const props = defineProps<{
|
||||
prop: PropertyMeta
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const links = computed(() => props.prop.tags?.filter((tag: any) => tag.name === 'link'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseUl v-if="links?.length">
|
||||
<ProseLi v-for="link in links" :key="link.name">
|
||||
<MDC :value="link.text ?? ''" class="my-1" />
|
||||
<ProseLi v-for="(link, index) in links" :key="index">
|
||||
<MDC :value="link.text ?? ''" class="my-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-link-${index}`" />
|
||||
</ProseLi>
|
||||
</ProseUl>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { kebabCase } from 'scule'
|
||||
import type { PropertyMeta } from 'vue-component-meta'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -6,6 +7,8 @@ const props = defineProps<{
|
||||
ignore?: string[]
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
function getSchemaProps(schema: PropertyMeta['schema']): any {
|
||||
if (!schema || typeof schema === 'string' || !schema.schema) {
|
||||
return []
|
||||
@@ -35,12 +38,12 @@ const schemaProps = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseCollapsible v-if="schemaProps?.length" class="mt-1">
|
||||
<ProseCollapsible v-if="schemaProps?.length" class="mt-1 mb-0">
|
||||
<ProseUl>
|
||||
<ProseLi v-for="schemaProp in schemaProps" :key="schemaProp.name">
|
||||
<HighlightInlineType :type="`${schemaProp.name}${schemaProp.required === false ? '?' : ''}: ${schemaProp.type}`" />
|
||||
|
||||
<MDC v-if="schemaProp.description" :value="schemaProp.description" class="text-(--ui-text-muted) my-1" />
|
||||
<MDC v-if="schemaProp.description" :value="schemaProp.description" class="text-muted my-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-${schemaProp.name}-description`" />
|
||||
</ProseLi>
|
||||
</ProseUl>
|
||||
</ProseCollapsible>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { upperFirst, camelCase } from 'scule'
|
||||
import { upperFirst, camelCase, kebabCase } from 'scule'
|
||||
|
||||
const props = defineProps<{
|
||||
prose?: boolean
|
||||
@@ -36,7 +36,7 @@ const meta = await fetchComponentMeta(name as any)
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="slot.type" :type="slot.type" />
|
||||
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-(--ui-text-toned) mt-1" />
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-toned mt-1" :cache-key="`${kebabCase(route.path)}-${slot.name}-description`" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { murmurHash } from 'ohash'
|
||||
import { hash } from 'ohash'
|
||||
|
||||
const props = defineProps<{
|
||||
type: string
|
||||
@@ -23,7 +23,7 @@ const type = computed(() => {
|
||||
return type
|
||||
})
|
||||
|
||||
const { data: ast } = await useAsyncData(`hightlight-inline-code-${murmurHash(type.value)}`, () => parseMarkdown(`\`${type.value}\`{lang="ts-type"}`))
|
||||
const { data: ast } = await useAsyncData(`hightlight-inline-code-${hash(type.value).slice(0, 10)}`, () => parseMarkdown(`\`${type.value}\`{lang="ts-type"}`))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden rounded-(--ui-radius) border border-dashed border-(--ui-border-accented) opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-(--ui-border-inverted)/10" fill="none">
|
||||
<div class="relative overflow-hidden rounded-sm border border-dashed border-accented opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-inverted/10" fill="none">
|
||||
<defs>
|
||||
<pattern
|
||||
id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
|
||||
|
||||
@@ -9,21 +9,28 @@ const props = withDefaults(defineProps<{
|
||||
|
||||
function getEmojiFlag(locale: string): string {
|
||||
const languageToCountry: Record<string, string> = {
|
||||
ar: 'sa',
|
||||
bn: 'bd',
|
||||
cs: 'cz',
|
||||
da: 'dk',
|
||||
el: 'gr',
|
||||
et: 'ee',
|
||||
en: 'gb',
|
||||
hi: 'in',
|
||||
ja: 'jp',
|
||||
km: 'kh',
|
||||
ko: 'kr',
|
||||
nb: 'no',
|
||||
sv: 'se',
|
||||
uk: 'ua',
|
||||
vi: 'vn'
|
||||
ar: 'sa', // Arabic -> Saudi Arabia
|
||||
bn: 'bd', // Bengali -> Bangladesh
|
||||
ca: 'es', // Catalan -> Spain
|
||||
ckb: 'iq', // Central Kurdish -> Iraq
|
||||
cs: 'cz', // Czech -> Czech Republic (note: modern country code is actually 'cz')
|
||||
da: 'dk', // Danish -> Denmark
|
||||
el: 'gr', // Greek -> Greece
|
||||
en: 'gb', // English -> Great Britain
|
||||
et: 'ee', // Estonian -> Estonia
|
||||
he: 'il', // Hebrew -> Israel
|
||||
hi: 'in', // Hindi -> India
|
||||
hy: 'am', // Armenian -> Armenia
|
||||
ja: 'jp', // Japanese -> Japan
|
||||
kk: 'kz', // Kazakh -> Kazakhstan
|
||||
km: 'kh', // Khmer -> Cambodia
|
||||
ko: 'kr', // Korean -> South Korea
|
||||
nb: 'no', // Norwegian Bokmål -> Norway
|
||||
sl: 'si', // Slovenian -> Slovenia
|
||||
sv: 'se', // Swedish -> Sweden
|
||||
uk: 'ua', // Ukrainian -> Ukraine
|
||||
ur: 'pk', // Urdu -> Pakistan
|
||||
vi: 'vn' // Vietnamese -> Vietnam
|
||||
}
|
||||
|
||||
const baseLanguage = locale.split('-')[0]?.toLowerCase() || locale
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { AccordionItem } from '@nuxt/ui'
|
||||
|
||||
const items: AccordionItem[] = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-lucide-smile'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { AccordionItem } from '@nuxt/ui'
|
||||
|
||||
const items: AccordionItem[] = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-lucide-smile'
|
||||
@@ -18,7 +20,7 @@ const items = [
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #content="{ item }">
|
||||
<p class="pb-3.5 text-sm text-(--ui-text-muted)">
|
||||
<p class="pb-3.5 text-sm text-muted">
|
||||
This is the {{ item.label }} panel.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { AccordionItem } from '@nuxt/ui'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: 'Icons',
|
||||
@@ -8,7 +10,7 @@ const items = [
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-lucide-swatch-book',
|
||||
slot: 'colors',
|
||||
slot: 'colors' as const,
|
||||
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
|
||||
},
|
||||
{
|
||||
@@ -16,13 +18,13 @@ const items = [
|
||||
icon: 'i-lucide-box',
|
||||
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
|
||||
}
|
||||
]
|
||||
] satisfies AccordionItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #colors="{ item }">
|
||||
<p class="text-sm pb-3.5 text-(--ui-primary)">
|
||||
<p class="text-sm pb-3.5 text-primary">
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import type { AccordionItem } from '@nuxt/ui'
|
||||
import { useSortable } from '@vueuse/integrations/useSortable'
|
||||
|
||||
const items = shallowRef<AccordionItem[]>([
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-lucide-smile',
|
||||
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
|
||||
},
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-lucide-swatch-book',
|
||||
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-lucide-box',
|
||||
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
|
||||
}
|
||||
])
|
||||
|
||||
const accordion = useTemplateRef<HTMLElement>('accordion')
|
||||
|
||||
useSortable(accordion, items, {
|
||||
animation: 150
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion ref="accordion" :items="items" />
|
||||
</template>
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { AccordionItem } from '@nuxt/ui'
|
||||
|
||||
const items: AccordionItem[] = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-lucide-smile',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<ULink
|
||||
to="https://github.com/benjamincanac"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
@@ -15,7 +15,7 @@
|
||||
<ULink
|
||||
to="https://github.com/romhml"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
@@ -27,7 +27,7 @@
|
||||
<ULink
|
||||
to="https://github.com/noook"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
|
||||
@@ -1,24 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
}, {
|
||||
slot: 'dropdown',
|
||||
icon: 'i-lucide-ellipsis',
|
||||
children: [{
|
||||
label: 'Documentation'
|
||||
}, {
|
||||
label: 'Themes'
|
||||
}, {
|
||||
label: 'GitHub'
|
||||
}]
|
||||
}, {
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
}, {
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}]
|
||||
import type { BreadcrumbItem } from '@nuxt/ui'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
},
|
||||
{
|
||||
slot: 'dropdown' as const,
|
||||
icon: 'i-lucide-ellipsis',
|
||||
children: [
|
||||
{
|
||||
label: 'Documentation'
|
||||
},
|
||||
{
|
||||
label: 'Themes'
|
||||
},
|
||||
{
|
||||
label: 'GitHub'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
},
|
||||
{
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}
|
||||
] satisfies BreadcrumbItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
}, {
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
}, {
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}]
|
||||
import type { BreadcrumbItem } from '@nuxt/ui'
|
||||
|
||||
const items: BreadcrumbItem[] = [
|
||||
{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
},
|
||||
{
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UBreadcrumb :items="items">
|
||||
<template #separator>
|
||||
<span class="mx-2 text-(--ui-text-muted)">/</span>
|
||||
<span class="mx-2 text-muted">/</span>
|
||||
</template>
|
||||
</UBreadcrumb>
|
||||
</template>
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Team',
|
||||
icon: 'i-lucide-users'
|
||||
}, {
|
||||
label: 'Invite users',
|
||||
icon: 'i-lucide-user-plus',
|
||||
children: [{
|
||||
label: 'Invite by email',
|
||||
icon: 'i-lucide-send-horizontal'
|
||||
}, {
|
||||
label: 'Invite by link',
|
||||
icon: 'i-lucide-link'
|
||||
}]
|
||||
}, {
|
||||
label: 'New team',
|
||||
icon: 'i-lucide-plus'
|
||||
}]
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items: DropdownMenuItem[] = [
|
||||
{
|
||||
label: 'Team',
|
||||
icon: 'i-lucide-users'
|
||||
},
|
||||
{
|
||||
label: 'Invite users',
|
||||
icon: 'i-lucide-user-plus',
|
||||
children: [
|
||||
{
|
||||
label: 'Invite by email',
|
||||
icon: 'i-lucide-send-horizontal'
|
||||
},
|
||||
{
|
||||
label: 'Invite by link',
|
||||
icon: 'i-lucide-link'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'New team',
|
||||
icon: 'i-lucide-plus'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
|
||||
const date = shallowRef(new CalendarDate(2025, 4, 2))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<UCalendar v-model="date" :month-controls="false" :year-controls="false" />
|
||||
|
||||
<div class="flex justify-between gap-4">
|
||||
<UButton color="neutral" variant="outline" @click="date = date.subtract({ months: 1 })">
|
||||
Prev
|
||||
</UButton>
|
||||
|
||||
<UButton color="neutral" variant="outline" @click="date = date.add({ months: 1 })">
|
||||
Next
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { CalendarDate, HebrewCalendar } from '@internationalized/date'
|
||||
|
||||
const hebrewDate = shallowRef(new CalendarDate(new HebrewCalendar(), 5781, 1, 1))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCalendar v-model="hebrewDate" />
|
||||
</template>
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
'https://picsum.photos/640/640?random=1',
|
||||
'https://picsum.photos/640/640?random=2',
|
||||
'https://picsum.photos/640/640?random=3',
|
||||
'https://picsum.photos/640/640?random=4',
|
||||
'https://picsum.photos/640/640?random=5',
|
||||
'https://picsum.photos/640/640?random=6'
|
||||
]
|
||||
|
||||
const carousel = useTemplateRef('carousel')
|
||||
const activeIndex = ref(0)
|
||||
|
||||
function onClickPrev() {
|
||||
activeIndex.value--
|
||||
}
|
||||
function onClickNext() {
|
||||
activeIndex.value++
|
||||
}
|
||||
function onSelect(index: number) {
|
||||
activeIndex.value = index
|
||||
}
|
||||
|
||||
function select(index: number) {
|
||||
activeIndex.value = index
|
||||
|
||||
carousel.value?.emblaApi?.scrollTo(index)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1 w-full">
|
||||
<UCarousel
|
||||
ref="carousel"
|
||||
v-slot="{ item }"
|
||||
arrows
|
||||
:items="items"
|
||||
:prev="{ onClick: onClickPrev }"
|
||||
:next="{ onClick: onClickNext }"
|
||||
class="w-full max-w-xs mx-auto"
|
||||
@select="onSelect"
|
||||
>
|
||||
<img :src="item" width="320" height="320" class="rounded-lg">
|
||||
</UCarousel>
|
||||
|
||||
<div class="flex gap-1 justify-between pt-4 max-w-xs mx-auto">
|
||||
<div
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
|
||||
:class="{ 'opacity-100': activeIndex === index }"
|
||||
@click="select(index)"
|
||||
>
|
||||
<img :src="item" width="44" height="44" class="rounded-lg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,76 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
const groups = [{
|
||||
id: 'settings',
|
||||
items: [
|
||||
{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user',
|
||||
kbds: ['meta', 'P']
|
||||
},
|
||||
{
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card',
|
||||
kbds: ['meta', 'B'],
|
||||
slot: 'billing'
|
||||
},
|
||||
{
|
||||
label: 'Notifications',
|
||||
icon: 'i-lucide-bell'
|
||||
},
|
||||
{
|
||||
label: 'Security',
|
||||
icon: 'i-lucide-lock'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
id: 'users',
|
||||
label: 'Users',
|
||||
slot: 'users',
|
||||
items: [
|
||||
{
|
||||
label: 'Benjamin Canac',
|
||||
suffix: 'benjamincanac',
|
||||
to: 'https://github.com/benjamincanac',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Sylvain Marroufin',
|
||||
suffix: 'smarroufin',
|
||||
to: 'https://github.com/smarroufin',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Sébastien Chopin',
|
||||
suffix: 'atinux',
|
||||
to: 'https://github.com/atinux',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Romain Hamel',
|
||||
suffix: 'romhml',
|
||||
to: 'https://github.com/romhml',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Haytham A. Salama',
|
||||
suffix: 'Haythamasalama',
|
||||
to: 'https://github.com/Haythamasalama',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Daniel Roe',
|
||||
suffix: 'danielroe',
|
||||
to: 'https://github.com/danielroe',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Neil Richter',
|
||||
suffix: 'noook',
|
||||
to: 'https://github.com/noook',
|
||||
target: '_blank'
|
||||
}
|
||||
]
|
||||
}]
|
||||
const groups = [
|
||||
{
|
||||
id: 'settings',
|
||||
items: [
|
||||
{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user',
|
||||
kbds: ['meta', 'P']
|
||||
},
|
||||
{
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card',
|
||||
kbds: ['meta', 'B'],
|
||||
slot: 'billing' as const
|
||||
},
|
||||
{
|
||||
label: 'Notifications',
|
||||
icon: 'i-lucide-bell'
|
||||
},
|
||||
{
|
||||
label: 'Security',
|
||||
icon: 'i-lucide-lock'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'users',
|
||||
label: 'Users',
|
||||
slot: 'users' as const,
|
||||
items: [
|
||||
{
|
||||
label: 'Benjamin Canac',
|
||||
suffix: 'benjamincanac',
|
||||
to: 'https://github.com/benjamincanac',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Sylvain Marroufin',
|
||||
suffix: 'smarroufin',
|
||||
to: 'https://github.com/smarroufin',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Sébastien Chopin',
|
||||
suffix: 'atinux',
|
||||
to: 'https://github.com/atinux',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Romain Hamel',
|
||||
suffix: 'romhml',
|
||||
to: 'https://github.com/romhml',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Haytham A. Salama',
|
||||
suffix: 'Haythamasalama',
|
||||
to: 'https://github.com/Haythamasalama',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Daniel Roe',
|
||||
suffix: 'danielroe',
|
||||
to: 'https://github.com/danielroe',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'Neil Richter',
|
||||
suffix: 'noook',
|
||||
to: 'https://github.com/noook',
|
||||
target: '_blank'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'command-palette-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}` } })) || []
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'command-palette-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}` } })) || []
|
||||
},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { refDebounced } from '@vueuse/core'
|
||||
|
||||
const searchTerm = ref('')
|
||||
const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ const items = [
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
id: '/getting-started#reka-ui-radix-vue',
|
||||
id: '/getting-started#reka-ui',
|
||||
label: 'Reka UI',
|
||||
level: 3
|
||||
},
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { ContextMenuItem } from '@nuxt/ui'
|
||||
|
||||
const showSidebar = ref(true)
|
||||
const showToolbar = ref(false)
|
||||
|
||||
const items = computed(() => [{
|
||||
const items = computed<ContextMenuItem[]>(() => [{
|
||||
label: 'View',
|
||||
type: 'label' as const
|
||||
}, {
|
||||
@@ -33,7 +35,7 @@ const items = computed(() => [{
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { ContextMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items: ContextMenuItem[][] = [
|
||||
[
|
||||
{
|
||||
label: 'View',
|
||||
@@ -26,7 +28,7 @@ const items = [
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import type { ContextMenuItem } from '@nuxt/ui'
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
const items = [{
|
||||
label: 'Refresh the Page',
|
||||
slot: 'refresh'
|
||||
}, {
|
||||
label: 'Clear Cookies and Refresh'
|
||||
}, {
|
||||
label: 'Clear Cache and Refresh'
|
||||
}]
|
||||
const items = [
|
||||
{
|
||||
label: 'Refresh the Page',
|
||||
slot: 'refresh' as const
|
||||
},
|
||||
{
|
||||
label: 'Clear Cookies and Refresh'
|
||||
},
|
||||
{
|
||||
label: 'Clear Cache and Refresh'
|
||||
}
|
||||
] satisfies ContextMenuItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
|
||||
@@ -22,7 +28,7 @@ const items = [{
|
||||
</template>
|
||||
|
||||
<template #refresh-trailing>
|
||||
<UIcon v-if="loading" name="i-lucide-refresh-cw" class="shrink-0 size-5 text-(--ui-primary) animate-spin" />
|
||||
<UIcon v-if="loading" name="i-lucide-refresh-cw" class="shrink-0 size-5 text-primary animate-spin" />
|
||||
</template>
|
||||
</UContextMenu>
|
||||
</template>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'command-palette-users',
|
||||
params: { q: searchTerm },
|
||||
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}` } })) || []
|
||||
|
||||
@@ -7,7 +7,7 @@ const open = ref(false)
|
||||
<UButton label="Open" color="neutral" variant="subtle" trailing-icon="i-lucide-chevron-up" />
|
||||
|
||||
<template #header>
|
||||
<h2 class="text-(--ui-text-highlighted) font-semibold">
|
||||
<h2 class="text-highlighted font-semibold">
|
||||
Drawer non-dismissible
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<script lang="ts" setup>
|
||||
import { createReusableTemplate, useMediaQuery } from '@vueuse/core'
|
||||
|
||||
const [DefineFormTemplate, ReuseFormTemplate] = createReusableTemplate()
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
const state = reactive({
|
||||
email: undefined
|
||||
})
|
||||
|
||||
const title = 'Edit profile'
|
||||
const description = 'Make changes to your profile here. Click save when you\'re done.'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DefineFormTemplate>
|
||||
<UForm :state="state" class="space-y-4">
|
||||
<UFormField label="Email" name="email" required>
|
||||
<UInput v-model="state.email" placeholder="shadcn@example.com" required />
|
||||
</UFormField>
|
||||
|
||||
<UButton label="Save changes" type="submit" />
|
||||
</UForm>
|
||||
</DefineFormTemplate>
|
||||
|
||||
<UModal v-if="isDesktop" v-model:open="open" :title="title" :description="description">
|
||||
<UButton label="Edit profile" color="neutral" variant="outline" />
|
||||
|
||||
<template #body>
|
||||
<ReuseFormTemplate />
|
||||
</template>
|
||||
</UModal>
|
||||
|
||||
<UDrawer v-else v-model:open="open" :title="title" :description="description">
|
||||
<UButton label="Edit profile" color="neutral" variant="outline" />
|
||||
|
||||
<template #body>
|
||||
<ReuseFormTemplate />
|
||||
</template>
|
||||
</UDrawer>
|
||||
</template>
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
|
||||
const showBookmarks = ref(true)
|
||||
const showHistory = ref(false)
|
||||
const showDownloads = ref(false)
|
||||
@@ -36,7 +38,7 @@ const items = computed(() => [{
|
||||
onUpdateChecked(checked: boolean) {
|
||||
showDownloads.value = checked
|
||||
}
|
||||
}])
|
||||
}] satisfies DropdownMenuItem[])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items: DropdownMenuItem[][] = [
|
||||
[
|
||||
{
|
||||
label: 'View',
|
||||
@@ -17,7 +19,7 @@ const items = [
|
||||
[
|
||||
{
|
||||
label: 'Delete',
|
||||
color: 'error' as const,
|
||||
color: 'error',
|
||||
icon: 'i-lucide-trash'
|
||||
}
|
||||
]
|
||||
@@ -27,9 +29,5 @@ const items = [
|
||||
<template>
|
||||
<UDropdownMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
|
||||
|
||||
<template #profile-trailing>
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-(--ui-primary)" />
|
||||
</template>
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user',
|
||||
slot: 'profile'
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-lucide-cog'
|
||||
}]
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user',
|
||||
slot: 'profile' as const
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-lucide-cog'
|
||||
}
|
||||
] satisfies DropdownMenuItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -17,7 +21,7 @@ const items = [{
|
||||
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
|
||||
|
||||
<template #profile-trailing>
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-(--ui-primary)" />
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-primary" />
|
||||
</template>
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
|
||||
const items = [{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user'
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-lucide-cog'
|
||||
}]
|
||||
const items: DropdownMenuItem[] = [
|
||||
{
|
||||
label: 'Profile',
|
||||
icon: 'i-lucide-user'
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-lucide-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-lucide-cog'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -14,7 +14,7 @@ const validate = (state: any): FormError[] => {
|
||||
}
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<typeof state>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,9 @@ const schema = z.object({
|
||||
radioGroup: z.string().refine(value => value === 'option-2', {
|
||||
message: 'Select Option 2'
|
||||
}),
|
||||
checkboxGroup: z.any().refine(values => !!values?.find((option: any) => option === 'option-2'), {
|
||||
message: 'Include Option 2'
|
||||
}),
|
||||
slider: z.number().max(20, { message: 'Must be less than 20' }),
|
||||
pin: z.string().regex(/^\d$/).array().length(5)
|
||||
})
|
||||
@@ -47,7 +50,7 @@ const items = [
|
||||
]
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
@@ -101,11 +104,14 @@ async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
<UFormField label="Textarea" name="textarea">
|
||||
<UTextarea v-model="state.textarea" class="w-full" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="radioGroup">
|
||||
<URadioGroup v-model="state.radioGroup" legend="Radio group" :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<div class="flex gap-4">
|
||||
<UFormField name="radioGroup">
|
||||
<URadioGroup v-model="state.radioGroup" legend="Radio group" :items="items" />
|
||||
</UFormField>
|
||||
<UFormField name="checkboxGroup">
|
||||
<UCheckboxGroup v-model="state.checkboxGroup" legend="Checkbox group" :items="items" />
|
||||
</UFormField>
|
||||
</div>
|
||||
<UFormField name="pin" label="Pin Input" :error-pattern="/(pin)\..*/">
|
||||
<UPinInput v-model="state.pin" />
|
||||
</UFormField>
|
||||
|
||||
@@ -15,7 +15,7 @@ const state = reactive({
|
||||
})
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<typeof state>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ type NestedSchema = z.output<typeof nestedSchema>
|
||||
const state = reactive<Partial<Schema & NestedSchema>>({ })
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
@@ -39,7 +39,7 @@ async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
<UCheckbox v-model="state.news" name="news" label="Register to our newsletter" @update:model-value="state.email = undefined" />
|
||||
</div>
|
||||
|
||||
<UForm v-if="state.news" :state="state" :schema="nestedSchema">
|
||||
<UForm v-if="state.news" :state="state" :schema="nestedSchema" attach>
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
|
||||
@@ -34,7 +34,7 @@ function removeItem() {
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
@@ -51,7 +51,14 @@ async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
<UInput v-model="state.customer" placeholder="Wonka Industries" />
|
||||
</UFormField>
|
||||
|
||||
<UForm v-for="item, count in state.items" :key="count" :state="item" :schema="itemSchema" class="flex gap-2">
|
||||
<UForm
|
||||
v-for="item, count in state.items"
|
||||
:key="count"
|
||||
:state="item"
|
||||
:schema="itemSchema"
|
||||
attach
|
||||
class="flex gap-2"
|
||||
>
|
||||
<UFormField :label="!count ? 'Description' : undefined" name="description">
|
||||
<UInput v-model="item.description" />
|
||||
</UFormField>
|
||||
|
||||
@@ -14,7 +14,7 @@ const validate = (state: any): FormError[] => {
|
||||
}
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
async function onSubmit(event: FormSubmitEvent<typeof state>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })
|
||||
console.log(event.data)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="v.safeParser(schema)" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormField>
|
||||
|
||||
@@ -16,7 +16,7 @@ function onOpen() {
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="countries || []"
|
||||
:items="countries"
|
||||
:loading="status === 'pending'"
|
||||
label-key="name"
|
||||
:search-input="{ icon: 'i-lucide-search' }"
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-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
|
||||
})
|
||||
@@ -13,7 +16,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
@@ -22,7 +25,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-users-email',
|
||||
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
|
||||
})
|
||||
@@ -14,7 +17,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
:filter-fields="['label', 'email']"
|
||||
icon="i-lucide-user"
|
||||
@@ -25,7 +28,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
@@ -33,7 +36,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-(--ui-text-muted)">
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { refDebounced } from '@vueuse/core'
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const searchTerm = ref('')
|
||||
const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
|
||||
@@ -9,7 +12,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
}))
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
@@ -18,7 +21,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template>
|
||||
<UInputMenu
|
||||
v-model:search-term="searchTerm"
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
ignore-filter
|
||||
icon="i-lucide-user"
|
||||
@@ -28,7 +31,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { InputMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'benjamincanac',
|
||||
@@ -23,8 +25,16 @@ const items = ref([
|
||||
src: 'https://github.com/noook.png',
|
||||
alt: 'noook'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'sandros94',
|
||||
value: 'sandros94',
|
||||
avatar: {
|
||||
src: 'https://github.com/sandros94.png',
|
||||
alt: 'sandros94'
|
||||
}
|
||||
}
|
||||
])
|
||||
] satisfies InputMenuItem[])
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import type { InputMenuItem, ChipProps } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'bug',
|
||||
value: 'bug',
|
||||
chip: {
|
||||
color: 'error' as const
|
||||
color: 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'feature',
|
||||
value: 'feature',
|
||||
chip: {
|
||||
color: 'success' as const
|
||||
color: 'success'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'enhancement',
|
||||
value: 'enhancement',
|
||||
chip: {
|
||||
color: 'info' as const
|
||||
color: 'info'
|
||||
}
|
||||
}
|
||||
])
|
||||
] satisfies InputMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
@@ -33,7 +36,7 @@ const value = ref(items.value[0])
|
||||
v-bind="modelValue.chip"
|
||||
inset
|
||||
standalone
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
|
||||
:class="ui.itemLeadingChip()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { InputMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'Backlog',
|
||||
@@ -20,7 +22,8 @@ const items = ref([
|
||||
value: 'done',
|
||||
icon: 'i-lucide-circle-check'
|
||||
}
|
||||
])
|
||||
] satisfies InputMenuItem[])
|
||||
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const domain = ref(domains[0])
|
||||
}"
|
||||
>
|
||||
<template #leading>
|
||||
<p class="text-sm text-(--ui-text-muted)">
|
||||
<p class="text-sm text-muted">
|
||||
https://
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -13,7 +13,7 @@ const maxLength = 15
|
||||
<template #trailing>
|
||||
<div
|
||||
id="character-count"
|
||||
class="text-xs text-(--ui-text-muted) tabular-nums"
|
||||
class="text-xs text-muted tabular-nums"
|
||||
aria-live="polite"
|
||||
role="status"
|
||||
>
|
||||
|
||||
@@ -4,8 +4,8 @@ const value = ref('')
|
||||
|
||||
<template>
|
||||
<UInput v-model="value" placeholder="" :ui="{ base: 'peer' }">
|
||||
<label class="pointer-events-none absolute left-0 -top-2.5 text-(--ui-text-highlighted) text-xs font-medium px-1.5 transition-all peer-focus:-top-2.5 peer-focus:text-(--ui-text-highlighted) peer-focus:text-xs peer-focus:font-medium peer-placeholder-shown:text-sm peer-placeholder-shown:text-(--ui-text-dimmed) peer-placeholder-shown:top-1.5 peer-placeholder-shown:font-normal">
|
||||
<span class="inline-flex bg-(--ui-bg) px-1">Email address</span>
|
||||
<label class="pointer-events-none absolute left-0 -top-2.5 text-highlighted text-xs font-medium px-1.5 transition-all peer-focus:-top-2.5 peer-focus:text-highlighted peer-focus:text-xs peer-focus:font-medium peer-placeholder-shown:text-sm peer-placeholder-shown:text-dimmed peer-placeholder-shown:top-1.5 peer-placeholder-shown:font-normal">
|
||||
<span class="inline-flex bg-default px-1">Email address</span>
|
||||
</label>
|
||||
</UInput>
|
||||
</template>
|
||||
|
||||
@@ -77,7 +77,7 @@ const text = computed(() => {
|
||||
v-for="(req, index) in strength"
|
||||
:key="index"
|
||||
class="flex items-center gap-0.5"
|
||||
:class="req.met ? 'text-(--ui-success)' : 'text-(--ui-text-muted)'"
|
||||
:class="req.met ? 'text-success' : 'text-muted'"
|
||||
>
|
||||
<UIcon :name="req.met ? 'i-lucide-circle-check' : 'i-lucide-circle-x'" class="size-4 shrink-0" />
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'command-palette-users',
|
||||
params: { q: searchTerm },
|
||||
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}` } })) || []
|
||||
|
||||
@@ -13,7 +13,9 @@ const modal = overlay.create(LazyModalExample, {
|
||||
})
|
||||
|
||||
async function open() {
|
||||
const shouldIncrement = await modal.open()
|
||||
const instance = modal.open()
|
||||
|
||||
const shouldIncrement = await instance.result
|
||||
|
||||
if (shouldIncrement) {
|
||||
count.value++
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: 'Docs',
|
||||
icon: 'i-lucide-book-open',
|
||||
slot: 'docs',
|
||||
slot: 'docs' as const,
|
||||
children: [
|
||||
{
|
||||
label: 'Icons',
|
||||
@@ -22,7 +24,7 @@ const items = [
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-lucide-box',
|
||||
slot: 'components',
|
||||
slot: 'components' as const,
|
||||
children: [
|
||||
{
|
||||
label: 'Link',
|
||||
@@ -54,7 +56,7 @@ const items = [
|
||||
label: 'GitHub',
|
||||
icon: 'i-simple-icons-github'
|
||||
}
|
||||
]
|
||||
] satisfies NavigationMenuItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -63,6 +65,7 @@ const items = [
|
||||
class="w-full justify-center"
|
||||
:ui="{
|
||||
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
|
||||
content: 'sm:w-auto',
|
||||
childList: 'sm:w-96',
|
||||
childLinkDescription: 'text-balance line-clamp-2'
|
||||
}"
|
||||
@@ -74,11 +77,11 @@ const items = [
|
||||
</li>
|
||||
|
||||
<li v-for="child in item.children" :key="child.label">
|
||||
<ULink class="text-sm text-left rounded-md p-3 transition-colors hover:bg-(--ui-bg-elevated)/50">
|
||||
<p class="font-medium text-(--ui-text-highlighted)">
|
||||
<ULink class="text-sm text-left rounded-md p-3 transition-colors hover:bg-elevated/50">
|
||||
<p class="font-medium text-highlighted">
|
||||
{{ child.label }}
|
||||
</p>
|
||||
<p class="text-(--ui-text-muted) line-clamp-2">
|
||||
<p class="text-muted line-clamp-2">
|
||||
{{ child.description }}
|
||||
</p>
|
||||
</ULink>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: 'Guide',
|
||||
icon: 'i-lucide-book-open'
|
||||
|
||||
},
|
||||
{
|
||||
label: 'Composables',
|
||||
icon: 'i-lucide-database'
|
||||
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-lucide-box',
|
||||
slot: 'components'
|
||||
slot: 'components' as const
|
||||
}
|
||||
]
|
||||
] satisfies NavigationMenuItem[]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items: NavigationMenuItem[] = [
|
||||
{
|
||||
label: 'Guide',
|
||||
icon: 'i-lucide-book-open',
|
||||
|
||||
@@ -40,7 +40,7 @@ const label = ref([])
|
||||
multiple
|
||||
placeholder="Search labels..."
|
||||
:groups="[{ id: 'labels', items }]"
|
||||
:ui="{ input: '[&>input]:h-8' }"
|
||||
:ui="{ input: '[&>input]:h-8 [&>input]:text-sm' }"
|
||||
/>
|
||||
</template>
|
||||
</UPopover>
|
||||
|
||||
@@ -8,7 +8,7 @@ const open = ref(false)
|
||||
|
||||
<template #content>
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<h2 class="text-(--ui-text-highlighted) font-semibold">
|
||||
<h2 class="text-highlighted font-semibold">
|
||||
Popover non-dismissible
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ const { data: countries, status, execute } = await useLazyFetch<{
|
||||
code: string
|
||||
emoji: string
|
||||
}[]>('/api/countries.json', {
|
||||
immediate: false,
|
||||
default: () => []
|
||||
immediate: false
|
||||
})
|
||||
|
||||
function onOpen() {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-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
|
||||
})
|
||||
@@ -13,7 +16,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
|
||||
<template>
|
||||
<USelectMenu
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
@@ -23,7 +26,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-users-email',
|
||||
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
|
||||
})
|
||||
@@ -14,7 +17,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
|
||||
<template>
|
||||
<USelectMenu
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
:filter-fields="['label', 'email']"
|
||||
icon="i-lucide-user"
|
||||
@@ -25,7 +28,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
@@ -33,7 +36,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-(--ui-text-muted)">
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { refDebounced } from '@vueuse/core'
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const searchTerm = ref('')
|
||||
const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
|
||||
@@ -9,7 +12,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
}))
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
@@ -18,7 +21,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template>
|
||||
<USelectMenu
|
||||
v-model:search-term="searchTerm"
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
ignore-filter
|
||||
icon="i-lucide-user"
|
||||
@@ -29,7 +32,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'benjamincanac',
|
||||
@@ -23,8 +25,16 @@ const items = ref([
|
||||
src: 'https://github.com/noook.png',
|
||||
alt: 'noook'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'sandros94',
|
||||
value: 'sandros94',
|
||||
avatar: {
|
||||
src: 'https://github.com/sandros94.png',
|
||||
alt: 'sandros94'
|
||||
}
|
||||
}
|
||||
])
|
||||
] satisfies SelectMenuItem[])
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectMenuItem, ChipProps } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'bug',
|
||||
value: 'bug',
|
||||
chip: {
|
||||
color: 'error' as const
|
||||
color: 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'feature',
|
||||
value: 'feature',
|
||||
chip: {
|
||||
color: 'success' as const
|
||||
color: 'success'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'enhancement',
|
||||
value: 'enhancement',
|
||||
chip: {
|
||||
color: 'info' as const
|
||||
color: 'info'
|
||||
}
|
||||
}
|
||||
])
|
||||
] satisfies SelectMenuItem[])
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
@@ -33,7 +35,7 @@ const value = ref(items.value[0])
|
||||
v-bind="modelValue.chip"
|
||||
inset
|
||||
standalone
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
|
||||
:class="ui.itemLeadingChip()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectMenuItem } from '@nuxt/ui'
|
||||
|
||||
const items = ref([
|
||||
{
|
||||
label: 'Backlog',
|
||||
@@ -20,7 +22,7 @@ const items = ref([
|
||||
value: 'done',
|
||||
icon: 'i-lucide-circle-check'
|
||||
}
|
||||
])
|
||||
] satisfies SelectMenuItem[])
|
||||
const value = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { AvatarProps } from '@nuxt/ui'
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
key: 'typicode-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
|
||||
})
|
||||
@@ -17,17 +20,18 @@ function getUserAvatar(value: string) {
|
||||
|
||||
<template>
|
||||
<USelect
|
||||
:items="users || []"
|
||||
:items="users"
|
||||
:loading="status === 'pending'"
|
||||
icon="i-lucide-user"
|
||||
placeholder="Select user"
|
||||
class="w-48"
|
||||
value-key="value"
|
||||
>
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="getUserAvatar(modelValue as string)"
|
||||
:size="ui.leadingAvatarSize()"
|
||||
v-bind="getUserAvatar(modelValue)"
|
||||
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
|
||||
:class="ui.leadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user