mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 20:48:12 +01:00
Compare commits
1026 Commits
v2.17.0
...
v3.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc6db6f14b | ||
|
|
1f9abdae61 | ||
|
|
f54f607413 | ||
|
|
08db1c68b3 | ||
|
|
725833c4a9 | ||
|
|
6a6c43378b | ||
|
|
10ab4ce06d | ||
|
|
afd9b8f2b9 | ||
|
|
6aac821e80 | ||
|
|
f4e135d07a | ||
|
|
ef4a3a09c9 | ||
|
|
c738bd9d53 | ||
|
|
aeccf30a92 | ||
|
|
673fef1595 | ||
|
|
0ed13f33b5 | ||
|
|
30c33c7113 | ||
|
|
fd0ecc6d96 | ||
|
|
6863254d89 | ||
|
|
d2e075bb4a | ||
|
|
6f0b7309c9 | ||
|
|
30d9a2653b | ||
|
|
fac52fa933 | ||
|
|
5f77aac368 | ||
|
|
5b62a8c8ca | ||
|
|
04a2f2b7a0 | ||
|
|
ad3dc26e41 | ||
|
|
fd6c1b02ea | ||
|
|
19362a9302 | ||
|
|
4e2b957882 | ||
|
|
83ee05dd0e | ||
|
|
5591854ed4 | ||
|
|
db754740ef | ||
|
|
2c7c41bd04 | ||
|
|
9edb23080d | ||
|
|
fb8e6a6a66 | ||
|
|
183207c2b8 | ||
|
|
237e7a4e0e | ||
|
|
cac41137ae | ||
|
|
eb0756674a | ||
|
|
9cb863bc21 | ||
|
|
9125a2d467 | ||
|
|
0297361319 | ||
|
|
749bf90dd1 | ||
|
|
d283887407 | ||
|
|
d7e46e3637 | ||
|
|
713021f12d | ||
|
|
1aff74e985 | ||
|
|
5b3cda741c | ||
|
|
a61e7656c2 | ||
|
|
85b21381e8 | ||
|
|
44b98bc7c9 | ||
|
|
6c285977bd | ||
|
|
4c39fa8b0f | ||
|
|
e584941df9 | ||
|
|
991e725b1a | ||
|
|
b638521ffa | ||
|
|
2ec978ed0d | ||
|
|
b7f9422091 | ||
|
|
d921b764de | ||
|
|
b83ecc9a6f | ||
|
|
40f1161b04 | ||
|
|
d419f0a9cb | ||
|
|
7bd06ecfd9 | ||
|
|
cac33c87b2 | ||
|
|
5e55e15ddf | ||
|
|
09d453b5cf | ||
|
|
4f5a8ee4f6 | ||
|
|
cfe4e0bd65 | ||
|
|
1932aa2671 | ||
|
|
cc8fa471e9 | ||
|
|
19bfc36976 | ||
|
|
7d754c0015 | ||
|
|
8709717a32 | ||
|
|
32ac575d56 | ||
|
|
c39996c0fe | ||
|
|
235f1cc330 | ||
|
|
f45b39937b | ||
|
|
a70ba04fc3 | ||
|
|
500b4727e8 | ||
|
|
d36576b1fe | ||
|
|
6498f8a0c1 | ||
|
|
96c9246d83 | ||
|
|
e45398f6ce | ||
|
|
a32d2c034a | ||
|
|
f52310d4a1 | ||
|
|
a6ae1dcb1d | ||
|
|
2e954467c4 | ||
|
|
d3317d828e | ||
|
|
2c3032e363 | ||
|
|
dd6bf5694f | ||
|
|
a8b26eb1a8 | ||
|
|
df72003516 | ||
|
|
1f5372baba | ||
|
|
d4efd13307 | ||
|
|
87c0a0f9c1 | ||
|
|
d5339d3ebe | ||
|
|
ff8eefdce7 | ||
|
|
2346f52cbf | ||
|
|
d0a669ee2e | ||
|
|
7e672bd041 | ||
|
|
ed18e74549 | ||
|
|
6f20f243fb | ||
|
|
ce91b5d75a | ||
|
|
d9b14bc325 | ||
|
|
d0ac6f95a4 | ||
|
|
8f76caa7f8 | ||
|
|
336631434c | ||
|
|
319fce136f | ||
|
|
1667e5a655 | ||
|
|
ad77a0e82d | ||
|
|
5076b8cc9e | ||
|
|
2fc6e18179 | ||
|
|
8898a5d675 | ||
|
|
7c2adf2f7f | ||
|
|
523493105e | ||
|
|
26e5ac80b6 | ||
|
|
a83e3821a4 | ||
|
|
ea8a083d84 | ||
|
|
cf92c5f3f0 | ||
|
|
594bc9bb2e | ||
|
|
7e87f05840 | ||
|
|
942f087a67 | ||
|
|
13975da684 | ||
|
|
4198a42dff | ||
|
|
21609aa884 | ||
|
|
82771673f2 | ||
|
|
4f83a2829e | ||
|
|
debf9cc853 | ||
|
|
40b3570343 | ||
|
|
95d2b7a56e | ||
|
|
c6171d0f8d | ||
|
|
625c4efa03 | ||
|
|
d8d7b8fcc5 | ||
|
|
c578acbb88 | ||
|
|
3e30775fd4 | ||
|
|
ec84f777ea | ||
|
|
a2a303f527 | ||
|
|
3d0e1eb288 | ||
|
|
175229384f | ||
|
|
9ddfec123e | ||
|
|
1f0e515c33 | ||
|
|
3e28c8f35a | ||
|
|
9d8bb80892 | ||
|
|
8b8ec22af7 | ||
|
|
4b09358ce0 | ||
|
|
4f339be363 | ||
|
|
7d28d99f10 | ||
|
|
71428da3dc | ||
|
|
4a7433d628 | ||
|
|
8c886279b2 | ||
|
|
62a2643a80 | ||
|
|
7cd3cc4aa6 | ||
|
|
07b0cf9979 | ||
|
|
c94041d656 | ||
|
|
97d05936cd | ||
|
|
a03a55cf8d | ||
|
|
1716ba0f5e | ||
|
|
a8b5bff8c6 | ||
|
|
84186e52e9 | ||
|
|
7fe7ff6fe2 | ||
|
|
aa34e3c141 | ||
|
|
d989ceb09d | ||
|
|
403d3b2718 | ||
|
|
08039c1dcd | ||
|
|
d107ba1e7a | ||
|
|
a6e5db477d | ||
|
|
0b7a724d5f | ||
|
|
eb85fa8353 | ||
|
|
e36a48c684 | ||
|
|
2934a280e8 | ||
|
|
9af06e95cc | ||
|
|
843f822b8c | ||
|
|
de0133e177 | ||
|
|
9c4e8f2dba | ||
|
|
5ede4033be | ||
|
|
b8f815ccca | ||
|
|
c710cf0ddc | ||
|
|
4b168a887e | ||
|
|
2c30025ca1 | ||
|
|
47ad74d029 | ||
|
|
59201e3a67 | ||
|
|
fba4d6a385 | ||
|
|
85d172339f | ||
|
|
d63ab0892e | ||
|
|
29a9be2fdf | ||
|
|
7c18232932 | ||
|
|
e91cba741c | ||
|
|
045c44c139 | ||
|
|
577436d190 | ||
|
|
efd1a81184 | ||
|
|
54814a2562 | ||
|
|
b3de942696 | ||
|
|
eb2667fa81 | ||
|
|
9f49796bd7 | ||
|
|
fe78529640 | ||
|
|
b6cb72de64 | ||
|
|
c2b9948a07 | ||
|
|
52e2fd75c2 | ||
|
|
6b79b4fd22 | ||
|
|
850e84c0e0 | ||
|
|
9c1171f61d | ||
|
|
be383e415d | ||
|
|
6f4fdb163c | ||
|
|
0e355d323b | ||
|
|
dee404f24f | ||
|
|
2aa4358d32 | ||
|
|
dd1452a452 | ||
|
|
9ceb4cc6c1 | ||
|
|
2a20a0a541 | ||
|
|
7673e51e20 | ||
|
|
9dd9d5126a | ||
|
|
99f5a66090 | ||
|
|
a261028f6e | ||
|
|
6a10b27b98 | ||
|
|
6ac63b5034 | ||
|
|
1d1d88d6ee | ||
|
|
60f2b0d8fb | ||
|
|
4b641f7c23 | ||
|
|
d430256271 | ||
|
|
daf430b10d | ||
|
|
5428005512 | ||
|
|
7b278b041c | ||
|
|
1ef977fb8c | ||
|
|
d558b3e29c | ||
|
|
8dfac7fd57 | ||
|
|
92f4d38cc3 | ||
|
|
b7382f2057 | ||
|
|
ac0267b14c | ||
|
|
c3000d5ce6 | ||
|
|
b838dd1458 | ||
|
|
b4568b31cf | ||
|
|
561c1fb665 | ||
|
|
55cbc65825 | ||
|
|
283b3c9ac0 | ||
|
|
695085cac4 | ||
|
|
88e94cc10b | ||
|
|
71d27152ed | ||
|
|
9af6d7dc59 | ||
|
|
5d2d198aae | ||
|
|
daa98c56fa | ||
|
|
5e294e7e21 | ||
|
|
db8c0e7433 | ||
|
|
39a63e8e3f | ||
|
|
8d560bdd21 | ||
|
|
d13e27eb5b | ||
|
|
10bb9b486a | ||
|
|
279f55ee2c | ||
|
|
8da6a1c0e2 | ||
|
|
68afba8f3c | ||
|
|
24f24e9d8e | ||
|
|
34ba466c15 | ||
|
|
8f5e8170e6 | ||
|
|
e70aee4d69 | ||
|
|
15cee52003 | ||
|
|
13738d574b | ||
|
|
fff3d04415 | ||
|
|
b1bcaabd19 | ||
|
|
e598ca5b40 | ||
|
|
787ab001bd | ||
|
|
372d902f7e | ||
|
|
e94461d1fa | ||
|
|
9963d71fbc | ||
|
|
5366e228bb | ||
|
|
789fcb6566 | ||
|
|
a23c3140df | ||
|
|
d93e151194 | ||
|
|
b9f4bcbbc9 | ||
|
|
973560e6f1 | ||
|
|
9426513a59 | ||
|
|
6ea576c558 | ||
|
|
836007dfa6 | ||
|
|
00575f55c9 | ||
|
|
8f48883a2d | ||
|
|
74a6bca2b3 | ||
|
|
c3ee509c65 | ||
|
|
b9e3fcb0f1 | ||
|
|
0635c5434c | ||
|
|
007a0cf85e | ||
|
|
c4ef5c4db8 | ||
|
|
4eea9f54c0 | ||
|
|
4eb1732545 | ||
|
|
a6d5e188a3 | ||
|
|
9a8d44c46b | ||
|
|
8f82a65f03 | ||
|
|
cae27d5206 | ||
|
|
0ddadc9b3b | ||
|
|
a90935b6aa | ||
|
|
2c6295d479 | ||
|
|
4dd799748b | ||
|
|
bcaca46ccc | ||
|
|
2f57c43361 | ||
|
|
aca319bc36 | ||
|
|
3a1ba1dfa3 | ||
|
|
09f76e75a9 | ||
|
|
b9249c0c3d | ||
|
|
a6c4ffa013 | ||
|
|
839b97a9dc | ||
|
|
ce28607d7d | ||
|
|
3319144962 | ||
|
|
9569339c91 | ||
|
|
42f4f8d337 | ||
|
|
8bac288687 | ||
|
|
3c1d8162ca | ||
|
|
f1193c35c5 | ||
|
|
7757d330b0 | ||
|
|
5114136d25 | ||
|
|
5176bf92bc | ||
|
|
30de2373c5 | ||
|
|
aa301af926 | ||
|
|
102fb2316d | ||
|
|
c00e0fa3db | ||
|
|
e1b0936105 | ||
|
|
ecad41a7fa | ||
|
|
1d9ac2b75b | ||
|
|
023a5215bf | ||
|
|
4825b754fc | ||
|
|
be8bf691c3 | ||
|
|
fb6eae3f62 | ||
|
|
ec0f599565 | ||
|
|
d6950d3df8 | ||
|
|
640de11ec7 | ||
|
|
f4db34bf1c | ||
|
|
c1ac3a9f9d | ||
|
|
6cc635a8a7 | ||
|
|
0ad74794ed | ||
|
|
dc3d714ded | ||
|
|
a7e73f86de | ||
|
|
b28b0f9d8c | ||
|
|
78f8740369 | ||
|
|
ca8e9e77ab | ||
|
|
5317c5724f | ||
|
|
35f72351d0 | ||
|
|
8364de98c9 | ||
|
|
368054456b | ||
|
|
067e2d346e | ||
|
|
01ac65f07d | ||
|
|
d7c1158f97 | ||
|
|
b194c5e49a | ||
|
|
c824f300c3 | ||
|
|
82ea62bb23 | ||
|
|
ff678d6004 | ||
|
|
0c4b79f92e | ||
|
|
0dfd8b3248 | ||
|
|
70b964f3a0 | ||
|
|
3b5a7c5c58 | ||
|
|
eff468fe9c | ||
|
|
98a802bfed | ||
|
|
6db7b056ae | ||
|
|
9c56917714 | ||
|
|
8ae8993db4 | ||
|
|
9620d903c5 | ||
|
|
e9832b95f5 | ||
|
|
b5bfb61816 | ||
|
|
da42c0489a | ||
|
|
b0e0b87c79 | ||
|
|
df6e2a6378 | ||
|
|
59b3873c73 | ||
|
|
c3f747aee5 | ||
|
|
dd532bb110 | ||
|
|
11b4dfefa7 | ||
|
|
a155e7c1a7 | ||
|
|
8ba5637f61 | ||
|
|
09c6fce8eb | ||
|
|
4e99ebf605 | ||
|
|
8563ea157b | ||
|
|
59a84f2ace | ||
|
|
9420a686bb | ||
|
|
e7e1b2339f | ||
|
|
a890528550 | ||
|
|
795621746b | ||
|
|
96e18ef233 | ||
|
|
57e62f36c4 | ||
|
|
b9319c0fbc | ||
|
|
810ea32bf8 | ||
|
|
c712e2e682 | ||
|
|
c1ed04f722 | ||
|
|
6a13c7fa01 | ||
|
|
a73d1c6ae6 | ||
|
|
c1ddedf67a | ||
|
|
612a9e930d | ||
|
|
bfeba51b8a | ||
|
|
40d17f7b03 | ||
|
|
bc633c6687 | ||
|
|
8e5547f26d | ||
|
|
a889c054d3 | ||
|
|
813fdfd646 | ||
|
|
982e12f2b8 | ||
|
|
f16eb2310d | ||
|
|
26f68fc31d | ||
|
|
6aa0ea306f | ||
|
|
db30284e7a | ||
|
|
781047eacb | ||
|
|
5a13e1bf41 | ||
|
|
bdc3217571 | ||
|
|
5c12d428c4 | ||
|
|
9d0db51ccc | ||
|
|
eeec9676cd | ||
|
|
06e8a9e912 | ||
|
|
7fd38a8cb8 | ||
|
|
182d4dd81a | ||
|
|
eba8b4b31a | ||
|
|
e1f385ee76 | ||
|
|
9078da5279 | ||
|
|
c7536a7af9 | ||
|
|
510433568a | ||
|
|
d94f8b7452 | ||
|
|
12e9ec28ae | ||
|
|
c018c23224 | ||
|
|
18c5ead1bd | ||
|
|
6f535ade9c | ||
|
|
a4e86d6d42 | ||
|
|
5f40773fa4 | ||
|
|
235556d3e0 | ||
|
|
5a22c62b2a | ||
|
|
5cc4457a74 | ||
|
|
52146dc260 | ||
|
|
cacd853d1e | ||
|
|
1eaec0ff56 | ||
|
|
b61696cdca | ||
|
|
57a49877ae | ||
|
|
f4c9f530b8 | ||
|
|
aa832f32a0 | ||
|
|
bad2e49de9 | ||
|
|
ca029a4b6c | ||
|
|
c8e353e599 | ||
|
|
18311d32d8 | ||
|
|
d2be8fdf7d | ||
|
|
ccbaf6ea15 | ||
|
|
30bc3a1d76 | ||
|
|
a39cbd3a7f | ||
|
|
509bf6fec6 | ||
|
|
2eb6a234c3 | ||
|
|
4362de48a7 | ||
|
|
fbb82c29cd | ||
|
|
20acc92eec | ||
|
|
225d28d279 | ||
|
|
e3da411014 | ||
|
|
f9c69a7837 | ||
|
|
8113c2163c | ||
|
|
88aace9263 | ||
|
|
84cc647f83 | ||
|
|
ec08ed9e2e | ||
|
|
ef2b270a04 | ||
|
|
673064dee5 | ||
|
|
c9f9a248b7 | ||
|
|
fae627ed65 | ||
|
|
7dd90f2bb7 | ||
|
|
24618b8a5e | ||
|
|
4ef81991f2 | ||
|
|
db45bafaed | ||
|
|
a44abb738f | ||
|
|
a0559d4163 | ||
|
|
f85eb8ed40 | ||
|
|
369e0b1952 | ||
|
|
84d814f88b | ||
|
|
1d61d8d152 | ||
|
|
b5f42cdd3a | ||
|
|
0b3ce24eb6 | ||
|
|
c63b3cec6a | ||
|
|
3097da486f | ||
|
|
c72cb58441 | ||
|
|
cd7cc0d9a3 | ||
|
|
ea288e9624 | ||
|
|
bdecefa2d1 | ||
|
|
86f5884f08 | ||
|
|
5f7872f06e | ||
|
|
b22aedd9d7 | ||
|
|
0bdfc26734 | ||
|
|
0b8bfa887b | ||
|
|
11ef256db7 | ||
|
|
dc1913b40d | ||
|
|
a5b3608938 | ||
|
|
dfa99362d4 | ||
|
|
5b2e7d8bad | ||
|
|
6a72ef06d0 | ||
|
|
34cf395f1a | ||
|
|
865b57f97c | ||
|
|
5a0d70e33d | ||
|
|
06e041c374 | ||
|
|
cd7888cac7 | ||
|
|
20d49d9e16 | ||
|
|
0c6720be73 | ||
|
|
38fb22af19 | ||
|
|
8f1402f780 | ||
|
|
bedb863fc6 | ||
|
|
20995aa6d3 | ||
|
|
ceee9b2e11 | ||
|
|
ee3d2aa30f | ||
|
|
655d9b2c97 | ||
|
|
e4eef89767 | ||
|
|
d160278283 | ||
|
|
884a14c3d2 | ||
|
|
e5695e78bc | ||
|
|
33713b200d | ||
|
|
c630625e83 | ||
|
|
90bcc23576 | ||
|
|
1d303ab909 | ||
|
|
b56151e144 | ||
|
|
0f2da5bb15 | ||
|
|
d8189052be | ||
|
|
a2114c5874 | ||
|
|
f2d3e53dec | ||
|
|
9dd9b3426c | ||
|
|
9d5f9a7010 | ||
|
|
2b6965211d | ||
|
|
5694823a41 | ||
|
|
5511e21eeb | ||
|
|
12ba480d34 | ||
|
|
efb7582b37 | ||
|
|
b503876e20 | ||
|
|
6a1b97add0 | ||
|
|
b886150147 | ||
|
|
20476f4b9a | ||
|
|
4e17da21f3 | ||
|
|
09e4cb77f1 | ||
|
|
e29cf793cb | ||
|
|
dc761a8e3e | ||
|
|
15e707c4ad | ||
|
|
0ee60c015b | ||
|
|
ada68a6637 | ||
|
|
5f4fd972ff | ||
|
|
3f2b1b12cd | ||
|
|
ecc2240df0 | ||
|
|
f70b63970a | ||
|
|
188d2bcd89 | ||
|
|
2de38b317b | ||
|
|
88eb4cac97 | ||
|
|
82ffc1ed57 | ||
|
|
57b32ca9b6 | ||
|
|
ad70bb9a59 | ||
|
|
b1879ea6d1 | ||
|
|
e051ef682a | ||
|
|
c6880c2036 | ||
|
|
f975fb64bd | ||
|
|
eb1a60d320 | ||
|
|
395b8305e1 | ||
|
|
ed2c45ac76 | ||
|
|
85c4226bd0 | ||
|
|
5a6a827b42 | ||
|
|
3fc06ed1da | ||
|
|
ff77967fd7 | ||
|
|
dfc63b1bc0 | ||
|
|
627688cab5 | ||
|
|
c838b3a040 | ||
|
|
440593c5e4 | ||
|
|
2bf99e1eb4 | ||
|
|
cf38e7ed78 | ||
|
|
0bdd6dfe86 | ||
|
|
af43b5df25 | ||
|
|
ec6ebbacbe | ||
|
|
1af449d6e0 | ||
|
|
bcab07a32c | ||
|
|
88926091d5 | ||
|
|
c9c685a01c | ||
|
|
51f4ffc953 | ||
|
|
a8dfa0ff29 | ||
|
|
316eeea482 | ||
|
|
072f2c64f7 | ||
|
|
5c5676edf9 | ||
|
|
e8dee1efe1 | ||
|
|
d2442a1e47 | ||
|
|
b497e427df | ||
|
|
034062df65 | ||
|
|
9970f0ea6b | ||
|
|
f1b9e27ff7 | ||
|
|
08c91fe8f1 | ||
|
|
633a39452a | ||
|
|
2e174c7d20 | ||
|
|
39144b6515 | ||
|
|
138cb2d12d | ||
|
|
9037a1d94c | ||
|
|
f833628751 | ||
|
|
c753da3cbe | ||
|
|
fe3ab652b4 | ||
|
|
27ffb8d8ab | ||
|
|
7a376b5e49 | ||
|
|
8baee1292f | ||
|
|
c00ec5e2f2 | ||
|
|
ff9fd9f657 | ||
|
|
8b8b7ca40f | ||
|
|
659d5e2c5a | ||
|
|
45454fae45 | ||
|
|
52cf471099 | ||
|
|
810d278ea7 | ||
|
|
2480efe6e5 | ||
|
|
1942b8e117 | ||
|
|
4a123906d0 | ||
|
|
43066fd9ea | ||
|
|
2c5d7ccf70 | ||
|
|
e398637174 | ||
|
|
15cb9a023d | ||
|
|
99f20a4154 | ||
|
|
f409395297 | ||
|
|
a9a1746486 | ||
|
|
63822c3cf6 | ||
|
|
4ac7a7e3e9 | ||
|
|
e5bec87488 | ||
|
|
dcf83261f3 | ||
|
|
68202d80ec | ||
|
|
a1b78bf619 | ||
|
|
063a30916c | ||
|
|
ec142c3c20 | ||
|
|
e8358ea967 | ||
|
|
8a2efd9b51 | ||
|
|
1069e226ee | ||
|
|
30a4f06e86 | ||
|
|
e5f0063dba | ||
|
|
f039d1a7dd | ||
|
|
d0017bf847 | ||
|
|
559a8cba58 | ||
|
|
46bd407b91 | ||
|
|
fb783d22b6 | ||
|
|
0450f6b4a9 | ||
|
|
67a15686e5 | ||
|
|
2363b0a4f1 | ||
|
|
fc50996ccf | ||
|
|
aed4100a41 | ||
|
|
72ac394476 | ||
|
|
f90f7d7b7c | ||
|
|
16071846a8 | ||
|
|
65e916d09a | ||
|
|
36cf8ccf21 | ||
|
|
58da6ebe83 | ||
|
|
ce28e662d6 | ||
|
|
def5f7c10b | ||
|
|
26bfdfc54d | ||
|
|
65a3b0a2d0 | ||
|
|
51872bef6c | ||
|
|
2d157090c0 | ||
|
|
26491afcd1 | ||
|
|
5a84095da6 | ||
|
|
3708dfaea6 | ||
|
|
e36345c4db | ||
|
|
f48755f116 | ||
|
|
ebdaacfb9f | ||
|
|
67661174b0 | ||
|
|
a5bb25dd95 | ||
|
|
7d67b4d000 | ||
|
|
7da566e7f2 | ||
|
|
f0627f700e | ||
|
|
c6a93f71f2 | ||
|
|
6d377d1f4b | ||
|
|
f9259f6857 | ||
|
|
142affb9a7 | ||
|
|
a44a24962b | ||
|
|
0424405ff6 | ||
|
|
f076019f8f | ||
|
|
89ff6b6702 | ||
|
|
814437255e | ||
|
|
e1ab903109 | ||
|
|
54060f686c | ||
|
|
80b413a724 | ||
|
|
ae2aaa9d1a | ||
|
|
76e3d0b9f3 | ||
|
|
dc6f830785 | ||
|
|
be53873c1a | ||
|
|
69539a62b4 | ||
|
|
30debff9cb | ||
|
|
3cbcc0f09a | ||
|
|
1b941ede36 | ||
|
|
3c89d6b2c5 | ||
|
|
fc3d42d5ea | ||
|
|
c36bae4b21 | ||
|
|
7d736c3812 | ||
|
|
d3c79912d8 | ||
|
|
3e7665626e | ||
|
|
b4a736d668 | ||
|
|
1dcc1f5074 | ||
|
|
ea19a3061f | ||
|
|
d56d3a13e3 | ||
|
|
6f88f355fa | ||
|
|
e54dd55053 | ||
|
|
0f69f2bd4b | ||
|
|
ab83053fef | ||
|
|
02da03b4a8 | ||
|
|
3651c7ec41 | ||
|
|
83049fd23e | ||
|
|
7aa353d8cc | ||
|
|
7154d96e10 | ||
|
|
0f10d98820 | ||
|
|
735f81e771 | ||
|
|
b78ca9c56a | ||
|
|
13a53f4cfb | ||
|
|
53a2bc0264 | ||
|
|
298ac68447 | ||
|
|
f302a15972 | ||
|
|
78e45600de | ||
|
|
820417956e | ||
|
|
f664f69097 | ||
|
|
cd214f91db | ||
|
|
6236953ed0 | ||
|
|
6ce70b768b | ||
|
|
d92022fb8d | ||
|
|
1e65933d9c | ||
|
|
84847965af | ||
|
|
2fe91f3847 | ||
|
|
1535313596 | ||
|
|
514d17048f | ||
|
|
48ddf39188 | ||
|
|
c83054bd73 | ||
|
|
cbd58ee707 | ||
|
|
239e0a5ac1 | ||
|
|
a72649f3c9 | ||
|
|
af52fde119 | ||
|
|
1d2e1caaf5 | ||
|
|
9a42338da3 | ||
|
|
cfb4cfdd7b | ||
|
|
a31d4cffb5 | ||
|
|
557bdb7297 | ||
|
|
abb7580f71 | ||
|
|
74a640ceca | ||
|
|
290e4ce150 | ||
|
|
9993b6727a | ||
|
|
a5e06a3960 | ||
|
|
9529f8c1dd | ||
|
|
02d55b0edb | ||
|
|
786ee8e7e2 | ||
|
|
be49abb2cd | ||
|
|
c3ed18beb6 | ||
|
|
4dcb74e0a9 | ||
|
|
d726e4ddac | ||
|
|
7350e8e46b | ||
|
|
5e6275fcff | ||
|
|
bc2d9ab620 | ||
|
|
2a2e3953cb | ||
|
|
d15c8c21da | ||
|
|
a8c1340fa7 | ||
|
|
432256dc67 | ||
|
|
74feb3a8cb | ||
|
|
3611f07d93 | ||
|
|
4b29828e9d | ||
|
|
a391c60aa0 | ||
|
|
8d76a8b195 | ||
|
|
78d5b32fd3 | ||
|
|
46d6545eb3 | ||
|
|
3da1e1a518 | ||
|
|
90f18a3505 | ||
|
|
80a8c2d772 | ||
|
|
bde7a30a73 | ||
|
|
bf0a04eb8b | ||
|
|
d43c29b4df | ||
|
|
d545a927a1 | ||
|
|
c0ab0cdde0 | ||
|
|
2a524b1772 | ||
|
|
ebb7c074af | ||
|
|
2dfaea580a | ||
|
|
bb42594ea4 | ||
|
|
2cc41dedcf | ||
|
|
06ea029ef6 | ||
|
|
78613d8811 | ||
|
|
35596fbdbf | ||
|
|
58a29911dd | ||
|
|
92e1d09990 | ||
|
|
774858187e | ||
|
|
b43fff6b07 | ||
|
|
b712a2c31c | ||
|
|
b99482913e | ||
|
|
bc85d70924 | ||
|
|
e360ab3084 | ||
|
|
39cd67a5e3 | ||
|
|
61851f838b | ||
|
|
7caeb0a635 | ||
|
|
4a409fdf8b | ||
|
|
ea29cc238c | ||
|
|
56da54b440 | ||
|
|
550c89d92c | ||
|
|
c36940a221 | ||
|
|
5f2a9ddc2e | ||
|
|
17c7256864 | ||
|
|
659c58b49f | ||
|
|
47e32a13ca | ||
|
|
0b29cf5aa3 | ||
|
|
f3c690ebd8 | ||
|
|
ab9fc3eebb | ||
|
|
54aa892bf0 | ||
|
|
48fc683831 | ||
|
|
2fb2a507b4 | ||
|
|
e29b514f8d | ||
|
|
80a3a0c28f | ||
|
|
864cd83520 | ||
|
|
cff37bf211 | ||
|
|
b471547eb7 | ||
|
|
10b56bb16c | ||
|
|
74cfb3d18f | ||
|
|
8234bc6a15 | ||
|
|
5fcd6d1bea | ||
|
|
44033508a7 | ||
|
|
2fbf47e1fc | ||
|
|
4ba4f9ee6d | ||
|
|
ee1d6ed08f | ||
|
|
4301821473 | ||
|
|
20caea1cd7 | ||
|
|
d00084c54c | ||
|
|
c060b461e9 | ||
|
|
e8419fac01 | ||
|
|
36a3279228 | ||
|
|
508ae0806f | ||
|
|
fe4892e030 | ||
|
|
74325441e9 | ||
|
|
1ddca46fa4 | ||
|
|
85c693e3ba | ||
|
|
f3fec877c5 | ||
|
|
bfd5988358 | ||
|
|
8fd369372b | ||
|
|
c9f09992b7 | ||
|
|
01bcca3dd7 | ||
|
|
8688653bc9 | ||
|
|
b5b3e97f5f | ||
|
|
afc270589c | ||
|
|
03fb75f256 | ||
|
|
bed62520a9 | ||
|
|
d5fe5b3f4d | ||
|
|
c726f13ac2 | ||
|
|
3a89661c66 | ||
|
|
2ca6973337 | ||
|
|
d23e3e1c76 | ||
|
|
4a281b3093 | ||
|
|
fbe3a40668 | ||
|
|
091f8e91c4 | ||
|
|
cd1073d938 | ||
|
|
245e9941c0 | ||
|
|
f0f89272a0 | ||
|
|
6063d9d1b9 | ||
|
|
09b5752cd2 | ||
|
|
a057945ca4 | ||
|
|
2fefa8ab74 | ||
|
|
4bd0d71875 | ||
|
|
147c452e7e | ||
|
|
77fe06d446 | ||
|
|
349780dae1 | ||
|
|
e3ef0c59b9 | ||
|
|
2f200d51f8 | ||
|
|
6946c2dfec | ||
|
|
167127861f | ||
|
|
f086f2662e | ||
|
|
52eef36baa | ||
|
|
a03b21fdb8 | ||
|
|
1c1a39bcce | ||
|
|
c8bedf8458 | ||
|
|
3ed5a08518 | ||
|
|
b2b4804e78 | ||
|
|
4ba76f5a3f | ||
|
|
4ae45abd63 | ||
|
|
d1aa6e3fd9 | ||
|
|
594c835f14 | ||
|
|
a21648a191 | ||
|
|
98920e549e | ||
|
|
7e1196c62c | ||
|
|
89ab141376 | ||
|
|
f4a1d4a7c3 | ||
|
|
2756d35458 | ||
|
|
5b789a5397 | ||
|
|
a7cc288513 | ||
|
|
a78b0965e8 | ||
|
|
03edad885d | ||
|
|
de8100af3a | ||
|
|
418ffb8426 | ||
|
|
6e10a0942f | ||
|
|
e4882e6804 | ||
|
|
bef0e38344 | ||
|
|
802a15990d | ||
|
|
68f3da8816 | ||
|
|
0d4d86d79d | ||
|
|
5a2a31092a | ||
|
|
46c066d791 | ||
|
|
aaf2a2d8ad | ||
|
|
6cd7c8a5fb | ||
|
|
961e6af9c8 | ||
|
|
0920099362 | ||
|
|
f8b50a3571 | ||
|
|
cf91171f6c | ||
|
|
de62676647 | ||
|
|
1cec712fb8 | ||
|
|
f46f8327c4 | ||
|
|
0a33db835c | ||
|
|
1976ecef17 | ||
|
|
2f09d1915f | ||
|
|
0c0ff7b100 | ||
|
|
fe467da9bf | ||
|
|
3cdbb27635 | ||
|
|
9254f3972b | ||
|
|
3e8a99244e | ||
|
|
da9ea7ac17 | ||
|
|
a9188d870a | ||
|
|
81cbd2a1d6 | ||
|
|
cdf6ebdafb | ||
|
|
38eb932b53 | ||
|
|
a7cb28a50e | ||
|
|
73880f798d | ||
|
|
d73a16f551 | ||
|
|
5d76539f3c | ||
|
|
5d1d5b33e8 | ||
|
|
ec95ae664d | ||
|
|
35a50ae60d | ||
|
|
7ff5cba9be | ||
|
|
fa2f752053 | ||
|
|
cecfb58445 | ||
|
|
d2949310ee | ||
|
|
c85a8cfe0b | ||
|
|
5d3ad6b93e | ||
|
|
431255e0fe | ||
|
|
6dfd696092 | ||
|
|
53755da835 | ||
|
|
a12ccbc052 | ||
|
|
f5c0259961 | ||
|
|
25300a10c8 | ||
|
|
73977e6d19 | ||
|
|
63f752a4a8 | ||
|
|
138eabda6b | ||
|
|
13d389fd39 | ||
|
|
6e42ee1e2a | ||
|
|
a86dc836b8 | ||
|
|
6c5354edde | ||
|
|
e5af5aeb34 | ||
|
|
870d8c1cd6 | ||
|
|
cdd9b178f3 | ||
|
|
9a42fa415f | ||
|
|
34d6e18638 | ||
|
|
0a00387688 | ||
|
|
ebbd931db1 | ||
|
|
7d2d3b9c0f | ||
|
|
d6bebd5ef9 | ||
|
|
e07088068f | ||
|
|
959b1295f2 | ||
|
|
4d3bab71e5 | ||
|
|
c4419fa113 | ||
|
|
e2fb25309f | ||
|
|
4b3a9855ac | ||
|
|
2d340d2054 | ||
|
|
7b8960124f | ||
|
|
78908c3d64 | ||
|
|
69b281c408 | ||
|
|
bc2dba5d71 | ||
|
|
c131ce955f | ||
|
|
c384ec94a2 | ||
|
|
0e0c708883 | ||
|
|
a026ae176e | ||
|
|
93aefaefd3 | ||
|
|
c8bdb51f68 | ||
|
|
4446531d04 | ||
|
|
44d0ceccba | ||
|
|
194b451467 | ||
|
|
158f0d2646 | ||
|
|
cd5b23a1f6 | ||
|
|
55c47288a5 | ||
|
|
37c14186a0 | ||
|
|
f547db3535 | ||
|
|
d0c7b8fad3 | ||
|
|
83f311a004 | ||
|
|
037a2fc8fa | ||
|
|
bc2dbbbbd0 | ||
|
|
924551e546 | ||
|
|
78fc16aa18 | ||
|
|
82cb00ce52 | ||
|
|
aaedabda3b | ||
|
|
4f344437e2 | ||
|
|
ef43eb406b | ||
|
|
b41de5b6dc | ||
|
|
978595ce88 | ||
|
|
7823139a35 | ||
|
|
6765eed733 | ||
|
|
2297fc1479 | ||
|
|
f89cf66efc | ||
|
|
c49521ca6e | ||
|
|
312a177ba8 | ||
|
|
e151be4734 | ||
|
|
f9cc5e4f8e | ||
|
|
31da519650 | ||
|
|
7479270c41 | ||
|
|
1cbce7f2f2 | ||
|
|
2288400eca | ||
|
|
1ccd14ee0e | ||
|
|
2f631845c3 | ||
|
|
4b75ec265b | ||
|
|
320821984d | ||
|
|
39b879c972 | ||
|
|
e3874e0dd0 | ||
|
|
c10737c0c6 | ||
|
|
7b3d6636f4 | ||
|
|
c6381c183c | ||
|
|
2f65c2eeca | ||
|
|
6edc0cf27b | ||
|
|
bcde20ce3e | ||
|
|
c65a623151 | ||
|
|
b0222e5531 | ||
|
|
361e47b03c | ||
|
|
622d582426 | ||
|
|
9592ca9f72 | ||
|
|
c3903f0da1 | ||
|
|
58ce6e86d0 | ||
|
|
11dd34c15d | ||
|
|
b08d2bd3c6 | ||
|
|
46e27304e8 | ||
|
|
c3db2499e7 | ||
|
|
075eee860d | ||
|
|
7e19c30f80 | ||
|
|
c79e6f188d | ||
|
|
0d1e17ef74 | ||
|
|
842acdf4b3 | ||
|
|
9711b4db5e | ||
|
|
a861961724 | ||
|
|
05e93387b9 | ||
|
|
c90cea55a7 | ||
|
|
1530e82235 | ||
|
|
e257a43964 | ||
|
|
6f37f02d8d | ||
|
|
22c42c402d | ||
|
|
0d1f8528c8 | ||
|
|
ce267954e0 | ||
|
|
57c2cc0ef4 | ||
|
|
66cf178cc3 | ||
|
|
7d29ff2b7a | ||
|
|
5449d2aa5f | ||
|
|
d95556ebda | ||
|
|
d69817a128 | ||
|
|
d0c1892a14 | ||
|
|
e51320bac0 | ||
|
|
3c2f5e9733 | ||
|
|
beb1bf2f0d | ||
|
|
38a36f4e48 | ||
|
|
b67fddeef8 | ||
|
|
8aefde231a | ||
|
|
17ea7efd3b | ||
|
|
f76ec5a376 | ||
|
|
3c716219cf | ||
|
|
f5e60a00ba |
@@ -1,14 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
.nuxt
|
||||
coverage
|
||||
*.log*
|
||||
.DS_Store
|
||||
.code
|
||||
*.iml
|
||||
package-lock.json
|
||||
templates/*
|
||||
sw.js
|
||||
|
||||
# Templates
|
||||
src/templates
|
||||
@@ -1,45 +0,0 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@nuxt/eslint-config'],
|
||||
rules: {
|
||||
// General
|
||||
semi: ['error', 'never'],
|
||||
quotes: ['error', 'single'],
|
||||
'comma-dangle': ['error', 'never'],
|
||||
'comma-spacing': ['error', { before: false, after: true }],
|
||||
'keyword-spacing': ['error', { before: true, after: true }],
|
||||
'space-before-function-paren': ['error', 'always'],
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'arrow-spacing': ['error', { before: true, after: true }],
|
||||
'key-spacing': ['error', { beforeColon: false, afterColon: true, mode: 'strict' }],
|
||||
'space-before-blocks': ['error', 'always'],
|
||||
'space-infix-ops': ['error', { int32Hint: false }],
|
||||
'no-multi-spaces': ['error', { ignoreEOLComments: true }],
|
||||
|
||||
// Typescript
|
||||
'@typescript-eslint/type-annotation-spacing': 'error',
|
||||
|
||||
// Vuejs
|
||||
'vue/multi-word-component-names': 0,
|
||||
'vue/html-indent': ['error', 2],
|
||||
'vue/comma-spacing': ['error', { before: false, after: true }],
|
||||
'vue/script-indent': ['error', 2, { baseIndent: 0 }],
|
||||
'vue/keyword-spacing': ['error', { before: true, after: true }],
|
||||
'vue/object-curly-spacing': ['error', 'always'],
|
||||
'vue/key-spacing': ['error', { beforeColon: false, afterColon: true, mode: 'strict' }],
|
||||
'vue/arrow-spacing': ['error', { before: true, after: true }],
|
||||
'vue/array-bracket-spacing': ['error', 'never'],
|
||||
'vue/block-spacing': ['error', 'always'],
|
||||
'vue/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
|
||||
'vue/space-infix-ops': ['error', { int32Hint: false }],
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
singleline: {
|
||||
max: 5
|
||||
}
|
||||
}
|
||||
],
|
||||
'vue/padding-line-between-blocks': ['error', 'always']
|
||||
}
|
||||
}
|
||||
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: "🐛 Bug report"
|
||||
description: Report a bug to help us improve the module.
|
||||
labels: ["bug"]
|
||||
labels: ["triage", "bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,5 +4,5 @@ contact_links:
|
||||
url: https://ui.nuxt.com
|
||||
about: Check the documentation for guides and examples.
|
||||
- name: 📚 Discord
|
||||
url: https://discord.com/channels/473401852243869706/1153996761426300948
|
||||
about: Consider asking questions in the `#ui` channel.
|
||||
url: https://go.nuxt.com/discord
|
||||
about: Consider asking questions in the help channel.
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: "🚀 Feature request"
|
||||
description: Suggest an idea or enhancement for the module.
|
||||
labels: ["enhancement"]
|
||||
labels: ["triage", "enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
87
.github/workflows/ci-dev.yml
vendored
87
.github/workflows/ci-dev.yml
vendored
@@ -1,87 +0,0 @@
|
||||
name: ci-dev
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [18]
|
||||
|
||||
env:
|
||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- 'src/**'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
- 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: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Release Edge
|
||||
if: github.event_name == 'push' && steps.changes.outputs.src == 'true'
|
||||
run: ./scripts/release-edge.sh
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
||||
56
.github/workflows/ci-v3.yml
vendored
Normal file
56
.github/workflows/ci-v3.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: ci-v3
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v3
|
||||
pull_request:
|
||||
branches:
|
||||
- v3
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [20]
|
||||
|
||||
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
|
||||
|
||||
- name: Build
|
||||
run: pnpm run build
|
||||
77
.github/workflows/ci.yml
vendored
77
.github/workflows/ci.yml
vendored
@@ -1,77 +0,0 @@
|
||||
name: ci-main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [18]
|
||||
|
||||
env:
|
||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- 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: Build
|
||||
run: pnpm run build
|
||||
|
||||
- name: Test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Version Check
|
||||
id: check
|
||||
uses: EndBug/version-check@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release
|
||||
if: github.event_name == 'push' && steps.check.outputs.changed == 'true'
|
||||
run: ./scripts/release.sh
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||
23
.github/workflows/stale.yml
vendored
Normal file
23
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: stale
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
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
|
||||
32
.gitignore
vendored
32
.gitignore
vendored
@@ -1,12 +1,24 @@
|
||||
node_modules
|
||||
*.log
|
||||
.nuxt
|
||||
nuxt.d.ts
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
dist
|
||||
.DS_Store
|
||||
.history
|
||||
.vercel
|
||||
.idea
|
||||
.env
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.fleet
|
||||
.idea
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
"commitMessage": "chore(release): v${version}",
|
||||
"tagName": "v${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"github": {
|
||||
"release": true,
|
||||
"releaseName": "v${version}",
|
||||
"web": true
|
||||
},
|
||||
"hooks": {
|
||||
"before:init": ["pnpm lint", "pnpm typecheck"]
|
||||
},
|
||||
"plugins": {
|
||||
"@release-it/conventional-changelog": {
|
||||
"preset": {
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"prettier.enable": false
|
||||
}
|
||||
422
CHANGELOG.md
422
CHANGELOG.md
@@ -1,5 +1,427 @@
|
||||
# Changelog
|
||||
|
||||
## [3.0.0-alpha.4](https://github.com/nuxt/ui/compare/v3.0.0-alpha.3...v3.0.0-alpha.4) (2024-10-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Drawer:** handle `direction` + `handle` props ([5f77aac](https://github.com/nuxt/ui/commit/5f77aac368448c7c45a0f9238d2dc3a5b0de825e))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Accordion:** missing `min-w-0` on trigger ([6c28597](https://github.com/nuxt/ui/commit/6c285977bd175d4866ca601bca47132ebb2d3440))
|
||||
* **build.config:** disable mkdist `addRelativeDeclarationExtensions` option ([f54f607](https://github.com/nuxt/ui/commit/f54f6074131db0f68eab1edcde3a4b2a7ecaba92))
|
||||
* **CommandPalette:** missing `min-w-0` on root ([a61e765](https://github.com/nuxt/ui/commit/a61e7656c25b26409cab77178e67d1cb9ec22dbd))
|
||||
* **Drawer:** improve max-width on mobile ([fac52fa](https://github.com/nuxt/ui/commit/fac52fa933aeb02f0855d20be37c4214efba0ab7))
|
||||
* **InputMenu:** missing `group` on trailing ([2c7c41b](https://github.com/nuxt/ui/commit/2c7c41bd046a961d398bbe8ee4a5945cd1fbaeab))
|
||||
* **README:** npm badge link ([#2271](https://github.com/nuxt/ui/issues/2271)) ([30c33c7](https://github.com/nuxt/ui/commit/30c33c71134ccbea4258949a851eaf8b26213b60))
|
||||
* **templates:** app config colors type ([96c9246](https://github.com/nuxt/ui/commit/96c9246d83b54637ceb2e2dd77542e435690c387))
|
||||
* **Toast:** improve focus styles ([1f9abda](https://github.com/nuxt/ui/commit/1f9abdae614acbfa0be868a599071a601406f0f5))
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* Revert "chore(deps): refresh lock" ([b83ecc9](https://github.com/nuxt/ui/commit/b83ecc9a6f309d37d3f096667143a4ed7700db6d))
|
||||
|
||||
## [3.0.0-alpha.3](https://github.com/nuxt/ui/compare/v3.0.0-alpha.2...v3.0.0-alpha.3) (2024-09-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **module:** move `colors` options into `theme.colors` ([2e95446](https://github.com/nuxt/ui/commit/2e954467c4679d70b68d3155ae34eca300508e38))
|
||||
|
||||
## [3.0.0-alpha.2](https://github.com/nuxt/ui/compare/v3.0.0-alpha.1...v3.0.0-alpha.2) (2024-09-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Button:** loading-auto ([#2198](https://github.com/nuxt/ui/issues/2198)) ([ed18e74](https://github.com/nuxt/ui/commit/ed18e7454986ed104fc73b77e88573b3c1df8566))
|
||||
* **module:** improve options ([5076b8c](https://github.com/nuxt/ui/commit/5076b8cc9e908cf289150c668b1707dc1397dba3))
|
||||
* **module:** install `@nuxt/fonts` by default ([8898a5d](https://github.com/nuxt/ui/commit/8898a5d6758b1047e35bcdf648362c42de387488))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Button:** button link not showing disabled classes ([#2189](https://github.com/nuxt/ui/issues/2189)) ([7c2adf2](https://github.com/nuxt/ui/commit/7c2adf2f7fc88174897cc775c752414a8b84f3a9))
|
||||
* **Button:** duplicate click handlers ([#2213](https://github.com/nuxt/ui/issues/2213)) ([dd6bf56](https://github.com/nuxt/ui/commit/dd6bf5694ff05ed1eeb9df8c42f833f51dbec66e))
|
||||
* **playground:** typecheck ([cf92c5f](https://github.com/nuxt/ui/commit/cf92c5f3f0e0f329844ee60772773a844ea1cc71))
|
||||
|
||||
## [3.0.0-alpha.1](https://github.com/nuxt/ui/compare/v3.0.0-alpha.0...v3.0.0-alpha.1) (2024-09-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **module:** hard-code css file to be imported anywhere ([62a2643](https://github.com/nuxt/ui/commit/62a2643a80e7ab6c6e154ba59801d393d9a53c40))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ContextMenu/DropdownMenu:** lint unused var ([a03a55c](https://github.com/nuxt/ui/commit/a03a55cf8d89c45fba6607f83b67367cfd419c3e))
|
||||
* import from `../types/index` ([3e28c8f](https://github.com/nuxt/ui/commit/3e28c8f35a64a7c19ce18f36dbe580503f2050bc))
|
||||
* **Link:** only bind necessary slot props ([7fe7ff6](https://github.com/nuxt/ui/commit/7fe7ff6fe2055d29b7fd54793ca52850842294e3))
|
||||
* **NavigationMenu:** handle open state hover effect ([84186e5](https://github.com/nuxt/ui/commit/84186e52e997a4dd55f98bf7bc0199656943b9c9))
|
||||
* **plugins:** infer type from `[#app](https://github.com/nuxt/ui/issues/app)` to remove build warning ([debf9cc](https://github.com/nuxt/ui/commit/debf9cc85339b7b162ac34392757214a16dad977))
|
||||
* **README:** license link ([71428da](https://github.com/nuxt/ui/commit/71428da3dc9c6f17a6e21b2bd889f6090be127d6))
|
||||
* **templates:** augment `@nuxt/schema` rather than `nuxt/schema` ([40b3570](https://github.com/nuxt/ui/commit/40b3570343dc68684d3ecf03e1a439e815f57ba3))
|
||||
* **types:** no longer need to import types with `/index` suffix ([8277167](https://github.com/nuxt/ui/commit/82771673f20b6ece7e126a4f8914311473d687e3))
|
||||
* **useButtonGroup:** lint ([97d0593](https://github.com/nuxt/ui/commit/97d05936cd198026e6c4d66920266e0b4b85242c))
|
||||
|
||||
## [3.0.0-alpha.0](https://github.com/nuxt/ui/compare/v2.15.0...v3.0.0-alpha.0) (2024-09-05)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **module:** move `primary` and `gray` inside `colors` object
|
||||
* **Link:** expose `active` instead of `isActive` in default slot
|
||||
|
||||
### Features
|
||||
|
||||
* **Accordion:** add `body` slot to solve animation flick ([85d1723](https://github.com/nuxt/ui/commit/85d172339f690aeb83a7ae7d3ad812938bb6e000))
|
||||
* **Accordion:** add `trailingIcon` prop ([fc3d42d](https://github.com/nuxt/ui/commit/fc3d42d5eaba9491ae21f05025899219346f5ca4))
|
||||
* **Accordion:** new component ([a21648a](https://github.com/nuxt/ui/commit/a21648a1918584b3f4036da96604be66e560b71c))
|
||||
* add `transition-colors` on hover effects ([633a394](https://github.com/nuxt/ui/commit/633a39452aa28afe4a523f458787fc5102d28ee6))
|
||||
* **Alert/CommandPalette/Modal/Slideover/Toast:** handle `closeIcon` and uniformize `close` prop ([e4eef89](https://github.com/nuxt/ui/commit/e4eef8976742ac5de418af0fe80d79bfd32fa83f))
|
||||
* **Alert:** add `actions` slot ([2d15709](https://github.com/nuxt/ui/commit/2d157090c029afb715706e7b464d37c0c377ea82))
|
||||
* **Alert:** new component ([1535313](https://github.com/nuxt/ui/commit/1535313596cd144886b887ede295da980f394082)), closes [#23](https://github.com/nuxt/ui/issues/23)
|
||||
* **Avatar:** bind `as` to image to support `NuxtImg` ([cff37bf](https://github.com/nuxt/ui/commit/cff37bf211ddcf67a67ef66dc526ba6cd780ff21))
|
||||
* **AvatarGroup:** new component ([#71](https://github.com/nuxt/ui/issues/71)) ([def5f7c](https://github.com/nuxt/ui/commit/def5f7c10bd28fbfea5fb8a3c7314ff8592c5335))
|
||||
* **Avatar:** new component ([978595c](https://github.com/nuxt/ui/commit/978595ce88bfef959f3cd6f405b405727e3929e0))
|
||||
* **Breacrumb/ContextMenu/DropdownMenu/NavigationMenu:** bind item `class` on link ([d13e27e](https://github.com/nuxt/ui/commit/d13e27eb5bd75227f6e67cbcdfdfe31dcf59e2e4))
|
||||
* **Breadcrumb:** new component ([53a2bc0](https://github.com/nuxt/ui/commit/53a2bc02642ec9ccecc71fa60cdd2913a4de5214)), closes [#22](https://github.com/nuxt/ui/issues/22)
|
||||
* **Breadcrumb:** rename `links` to `items` + improve slots ([d56d3a1](https://github.com/nuxt/ui/commit/d56d3a13e3240fedeadcbd8bcadb5c732b7ce2bc))
|
||||
* **Button:** add `subtle` variant ([1d2e1ca](https://github.com/nuxt/ui/commit/1d2e1caaf5edcbad55bc5c3c75da8afc90ab7a94))
|
||||
* **ButtonGroup:** new component ([#88](https://github.com/nuxt/ui/issues/88)) ([43066fd](https://github.com/nuxt/ui/commit/43066fd9ea971c6b6c3bf5d58383bb2c9cd076a3))
|
||||
* **Button:** use `useComponentIcons` ([6e10a09](https://github.com/nuxt/ui/commit/6e10a0942fb408c7092a95f9251ff763a8c3b2d0))
|
||||
* **Card:** new component ([78908c3](https://github.com/nuxt/ui/commit/78908c3d64a6759a915b5a8b772e750f928740e4))
|
||||
* **Checkbox/Progress/RadioGroup/Slider/Switch:** add `black` color ([08c91fe](https://github.com/nuxt/ui/commit/08c91fe8f1b7b8d0571bd140e05363e4b71ab6d8))
|
||||
* **Checkbox:** new component ([#67](https://github.com/nuxt/ui/issues/67)) ([bfd5988](https://github.com/nuxt/ui/commit/bfd59883584aee4c1a0a88952f4277c52afdf2ca))
|
||||
* **Chip:** new component ([d6bebd5](https://github.com/nuxt/ui/commit/d6bebd5ef9fb40e946a6e6a34c44aff8639c4290))
|
||||
* **cli:** `init` command ([cdd9b17](https://github.com/nuxt/ui/commit/cdd9b178f32b9807c451734b85c4cfb9f5e8438d))
|
||||
* **CommandPalette:** handle `filter` false and `postFilter` ([1ef977f](https://github.com/nuxt/ui/commit/1ef977fb8c3a754a909a82733f31b1b45577f021))
|
||||
* **CommandPalette:** implement group `filter` function ([e29cf79](https://github.com/nuxt/ui/commit/e29cf793cbc46a960dd66241f3bb716887038d18))
|
||||
* **CommandPalette:** improve theme and performance ([20476f4](https://github.com/nuxt/ui/commit/20476f4b9a95817598fb2e2ae5cb383b0d1411e2))
|
||||
* **CommandPalette:** new component ([#80](https://github.com/nuxt/ui/issues/80)) ([d0017bf](https://github.com/nuxt/ui/commit/d0017bf847c05f64c3bd131b9e57b2f90009fbe3))
|
||||
* **components:** allow override of sizes through `ui` prop ([6aa0ea3](https://github.com/nuxt/ui/commit/6aa0ea306f2b89a900c86b1a411217d108d399c0))
|
||||
* **components:** uniformize colors and variants ([#141](https://github.com/nuxt/ui/issues/141)) ([c018c23](https://github.com/nuxt/ui/commit/c018c23224167df3594f39157d3cb35f0118534b))
|
||||
* **ContextMenu:** handle `size` prop ([#130](https://github.com/nuxt/ui/issues/130)) ([aa832f3](https://github.com/nuxt/ui/commit/aa832f32a0ddfc6068537f6322603c0fa6f8b1df))
|
||||
* **ContextMenu:** new component ([65a3b0a](https://github.com/nuxt/ui/commit/65a3b0a2d0f8a4e32b9c0ce4707f22268b32e3dc)), closes [#18](https://github.com/nuxt/ui/issues/18)
|
||||
* **defineShortcuts:** migrate with reactivity ([#72](https://github.com/nuxt/ui/issues/72)) ([80b413a](https://github.com/nuxt/ui/commit/80b413a724d0702d66df9488b9a974f0d7ba0d41))
|
||||
* **Drawer:** implement with `vaul-vue` ([5e6275f](https://github.com/nuxt/ui/commit/5e6275fcff151f3607939b1503ff60f970375564)), closes [#53](https://github.com/nuxt/ui/issues/53)
|
||||
* **DropdownMenu:** add `[#item](https://github.com/nuxt/ui/issues/item)` slot for consistency ([1dcc1f5](https://github.com/nuxt/ui/commit/1dcc1f50740c1b4ed17c77a22562ccd662c85d15))
|
||||
* **DropdownMenu:** handle `size` prop ([#125](https://github.com/nuxt/ui/issues/125)) ([dfa9936](https://github.com/nuxt/ui/commit/dfa99362d4d70ac76c43a1b1c3e815272bee9a25))
|
||||
* **DropdownMenu:** handle item type `separator` ([a5bb25d](https://github.com/nuxt/ui/commit/a5bb25dd95be81d34564c5b5c4e3174ec126dbdb))
|
||||
* **DropdownMenu:** new component ([#37](https://github.com/nuxt/ui/issues/37)) ([4403350](https://github.com/nuxt/ui/commit/44033508a7347a5c75204d359b641a6f2da2cff9))
|
||||
* **DropdownMenu:** pass `index` to slots ([735f81e](https://github.com/nuxt/ui/commit/735f81e771d3673f444be99b93cff1ef93c3ac6c))
|
||||
* expose `open` state to slots ([ed2c45a](https://github.com/nuxt/ui/commit/ed2c45ac76285bb394fa16970fca27690d3de454))
|
||||
* **Form:** `Select` and `InputMenu` integration ([#97](https://github.com/nuxt/ui/issues/97)) ([52cf471](https://github.com/nuxt/ui/commit/52cf471099a78737e13f755fd89ff38c8c761aea))
|
||||
* **Form:** nested form validation ([#23](https://github.com/nuxt/ui/issues/23)) ([1671278](https://github.com/nuxt/ui/commit/167127861f117ece8a54421b5000f50d8d611b39))
|
||||
* **Form:** new component ([#4](https://github.com/nuxt/ui/issues/4)) ([de62676](https://github.com/nuxt/ui/commit/de62676647531c4d0a40c4696f9a7a3b75af32ff))
|
||||
* **Form:** support for `valibot@33` ([#132](https://github.com/nuxt/ui/issues/132)) ([20acc92](https://github.com/nuxt/ui/commit/20acc92eecbd17b9a6ea16ed688fe39af94708a2))
|
||||
* **Icon:** use `@antfu/nuxt-icon-poc` ([#76](https://github.com/nuxt/ui/issues/76)) ([142affb](https://github.com/nuxt/ui/commit/142affb9a72faa07bb9b448a95042c13aec09623))
|
||||
* **Input/Textarea:** expose ref ([74a6bca](https://github.com/nuxt/ui/commit/74a6bca2b334f54b99294be8848f345e69ff1141))
|
||||
* **Input:** handle icons ([de8100a](https://github.com/nuxt/ui/commit/de8100af3a36253d32d449a9bd445a761386b724))
|
||||
* **InputMenu/Select/SelectMenu:** introduce `valueKey` prop ([eeec967](https://github.com/nuxt/ui/commit/eeec9676cde0201736d70739847ee820fb80657c)), closes [#108](https://github.com/nuxt/ui/issues/108)
|
||||
* **InputMenu:** expose `modelValue` and `open` to slots ([659d5e2](https://github.com/nuxt/ui/commit/659d5e2c5a9164c684cb49429d5045bdae11eac6))
|
||||
* **InputMenu:** handle `multiple` ([fe3ab65](https://github.com/nuxt/ui/commit/fe3ab652b4b9258cd02c48ded5b8858001818e03)), closes [#91](https://github.com/nuxt/ui/issues/91)
|
||||
* **InputMenu:** handle `size` prop ([#131](https://github.com/nuxt/ui/issues/131)) ([18c5ead](https://github.com/nuxt/ui/commit/18c5ead1bd1f253524da587305c234a88c56ed25))
|
||||
* **InputMenu:** new component ([#86](https://github.com/nuxt/ui/issues/86)) ([99f20a4](https://github.com/nuxt/ui/commit/99f20a4154b26f75fbec0762d5a02a08b5a319a7))
|
||||
* **Input:** set `autocomplete` to `off` by default ([eba8b4b](https://github.com/nuxt/ui/commit/eba8b4b31a3d83d4dcb67246eed0fc21fb46dce7))
|
||||
* **Input:** use `defineModel` ([#61](https://github.com/nuxt/ui/issues/61)) ([091f8e9](https://github.com/nuxt/ui/commit/091f8e91c45039391800de80807ce77db3656500))
|
||||
* **Kbd:** add `color` prop ([2cc41de](https://github.com/nuxt/ui/commit/2cc41dedcfe73183a285a5ce5e7192290926771b))
|
||||
* **Link:** break component in two with `custom` prop ([3ed5a08](https://github.com/nuxt/ui/commit/3ed5a085181be75d25178640d686274745e54aa3))
|
||||
* **Link:** style with app config ([349780d](https://github.com/nuxt/ui/commit/349780dae18e3acc4cd1dda8152ae6d0377004ba))
|
||||
* **Modal:** new component ([5d1d5b3](https://github.com/nuxt/ui/commit/5d1d5b33e8fe959644e5f93986c9c7630ea288cc))
|
||||
* **Modal:** open programmatically ([#78](https://github.com/nuxt/ui/issues/78)) ([2bf99e1](https://github.com/nuxt/ui/commit/2bf99e1eb4df7333a46df666c446ba7af4e54e93))
|
||||
* **module:** add `[@source](https://github.com/source)` when `@nuxt/content` is present ([8dfac7f](https://github.com/nuxt/ui/commit/8dfac7fd574bef3ea714e21b852c50aafd6feff4))
|
||||
* **module:** add option to disable transitions ([5f4fd97](https://github.com/nuxt/ui/commit/5f4fd972ff2251863751549271a9e80123fdbfc8))
|
||||
* **module:** allow `tailwind.css` customization ([8d560bd](https://github.com/nuxt/ui/commit/8d560bdd212bbbf25a7d4a706a99cc57721d593e))
|
||||
* **module:** move `primary` and `gray` inside `colors` object ([ccbaf6e](https://github.com/nuxt/ui/commit/ccbaf6ea150e0902d7150585bd09f132fc26ff89))
|
||||
* **NavigationMenu:** handle content, `color`, `variant`, etc. ([1af449d](https://github.com/nuxt/ui/commit/1af449d6e0e2cd454425d8bc6bf1482e5dac99fd))
|
||||
* **NavigationMenu:** improve theme with `line` variant and border ([ec6ebba](https://github.com/nuxt/ui/commit/ec6ebbacbe1a0797ec86fe85197a98b084e27e5d))
|
||||
* **NavigationMenu:** new component ([0d4d86d](https://github.com/nuxt/ui/commit/0d4d86d79db488b79ca2baf7d620b415a36cb135))
|
||||
* **NavigationMenu:** pass `index` to slots ([0f10d98](https://github.com/nuxt/ui/commit/0f10d9882099256a77b86e5786a7e2ee71c83d46))
|
||||
* **NavigationMenu:** rename `links` to `items` + improve slots ([ea19a30](https://github.com/nuxt/ui/commit/ea19a3061fb49960fe3b9d28d05cec8fd7f6647e))
|
||||
* **NavigationMenu:** replace `line` variant with `highlight` prop ([af43b5d](https://github.com/nuxt/ui/commit/af43b5df250fb65bf9696b5b3fb6cb507b2184a1))
|
||||
* **Pagination:** allow using pagination buttons as links ([#114](https://github.com/nuxt/ui/issues/114)) ([5c5676e](https://github.com/nuxt/ui/commit/5c5676edf957230bf3ac53fa527b1b4b4373750f))
|
||||
* **Pagination:** new component ([c36bae4](https://github.com/nuxt/ui/commit/c36bae4b21e4a6c899be39800ca90051f79db1e0)), closes [#11](https://github.com/nuxt/ui/issues/11)
|
||||
* **Popover:** handle `hover` mode ([7b89601](https://github.com/nuxt/ui/commit/7b8960124fcf24a5d3869e3913ea5220af3a76bf))
|
||||
* **Popover:** new ([c131ce9](https://github.com/nuxt/ui/commit/c131ce955f23ce2613f5493689df8352de3cd4b6))
|
||||
* **Progress:** new component ([#75](https://github.com/nuxt/ui/issues/75)) ([138cb2d](https://github.com/nuxt/ui/commit/138cb2d12d9414813beed22dcedcee61e3d4f6de))
|
||||
* **RadioGroup:** handle `horizontal` orientation ([#74](https://github.com/nuxt/ui/issues/74)) ([8144372](https://github.com/nuxt/ui/commit/814437255e47d6be40cd00420e2ab579ab76f5b9))
|
||||
* **RadioGroup:** handle `value-key` prop ([850e84c](https://github.com/nuxt/ui/commit/850e84c0e0ce11bdc90be1ae652dec6723012243))
|
||||
* **RadioGroup:** new component ([#41](https://github.com/nuxt/ui/issues/41)) ([e29b514](https://github.com/nuxt/ui/commit/e29b514f8d114a56eee76a29388fe050eb5c2722))
|
||||
* **Select/SelectMenu:** handle `size` prop ([#133](https://github.com/nuxt/ui/issues/133)) ([b61696c](https://github.com/nuxt/ui/commit/b61696cdca77cc2f671dcbf330e731230ec97ba3))
|
||||
* **SelectMenu:** add prop to disable search ([db30284](https://github.com/nuxt/ui/commit/db30284e7a24f14544c2c3b758c7912e98d3768a))
|
||||
* **SelectMenu:** handle `multiple` prop ([27ffb8d](https://github.com/nuxt/ui/commit/27ffb8d8abc466d2a4bbb9a313b0c4f6a3a97501)), closes [#102](https://github.com/nuxt/ui/issues/102)
|
||||
* **SelectMenu:** new component ([#103](https://github.com/nuxt/ui/issues/103)) ([7a376b5](https://github.com/nuxt/ui/commit/7a376b5e49baf11eb09c1b58326441cb240f7cb7))
|
||||
* **Select:** new component ([#92](https://github.com/nuxt/ui/issues/92)) ([1942b8e](https://github.com/nuxt/ui/commit/1942b8e117bdae745049b088afe7487b6a9095f9))
|
||||
* **Separator:** new component ([#46](https://github.com/nuxt/ui/issues/46)) ([8d76a8b](https://github.com/nuxt/ui/commit/8d76a8b1957d6910cdf25c66a966b808cf8525c7))
|
||||
* **Skeleton:** new component ([e2fb253](https://github.com/nuxt/ui/commit/e2fb25309f13068c7a49de1b507f258013c72e11))
|
||||
* **Slideover:** add `top` / `bottom` sides ([3e8a992](https://github.com/nuxt/ui/commit/3e8a99244e550f9ed68a30182c9ec0753d240138))
|
||||
* **Slideover:** new component ([38eb932](https://github.com/nuxt/ui/commit/38eb932b538abb08d10e564308d92538ee345463))
|
||||
* **Slideover:** open programmatically ([#122](https://github.com/nuxt/ui/issues/122)) ([b886150](https://github.com/nuxt/ui/commit/b886150147afbde882003fb5dc710a5975b633cd))
|
||||
* **Slider:** new component ([#57](https://github.com/nuxt/ui/issues/57)) ([78e4560](https://github.com/nuxt/ui/commit/78e45600de9ac6a3e197baa7fed4fb4a46164c33))
|
||||
* **Switch:** add ` label` and ` description` props ([#60](https://github.com/nuxt/ui/issues/60)) ([2fe91f3](https://github.com/nuxt/ui/commit/2fe91f3847198e4415edfda36cb977458866bbd9))
|
||||
* **Switch:** form integration ([#48](https://github.com/nuxt/ui/issues/48)) ([ebb7c07](https://github.com/nuxt/ui/commit/ebb7c074afb583e6da8e1e06f12318faa1bf552c))
|
||||
* **Switch:** handle `loading` and `loadingIcon` ([8fd3693](https://github.com/nuxt/ui/commit/8fd369372ba54d7ac2efa3d0186498d8e1608c41)), closes [#65](https://github.com/nuxt/ui/issues/65)
|
||||
* **Switch:** new component ([cd1073d](https://github.com/nuxt/ui/commit/cd1073d93876c6f15f71bcd8d5c4c4bc76492330))
|
||||
* **Tabs:** handle `avatar` ([bf0a04e](https://github.com/nuxt/ui/commit/bf0a04eb8bda666df2c88f7d0ea121c135f7d065))
|
||||
* **Tabs:** handle `color` and `variant` props ([82ffc1e](https://github.com/nuxt/ui/commit/82ffc1ed574d741be03c43dfa300fefca0d042e0)), closes [#116](https://github.com/nuxt/ui/issues/116)
|
||||
* **Tabs:** handle `content` prop as `boolean` ([e051ef6](https://github.com/nuxt/ui/commit/e051ef682aa7d4ec91b7145c1d96bb1d9913ad2d))
|
||||
* **Tabs:** handle `size` prop ([#124](https://github.com/nuxt/ui/issues/124)) ([2b69652](https://github.com/nuxt/ui/commit/2b6965211dd9193026b85576d292f9f5138f99e6))
|
||||
* **Tabs:** handle items `icon` ([06ea029](https://github.com/nuxt/ui/commit/06ea029ef624116792230fdb57cdcee13b610fc0))
|
||||
* **Tabs:** new component ([13d389f](https://github.com/nuxt/ui/commit/13d389fd3979f089e37006741f51400168e58631))
|
||||
* **Textarea:** new component ([#62](https://github.com/nuxt/ui/issues/62)) ([2ca6973](https://github.com/nuxt/ui/commit/2ca697333790efe3304f1f03b12be53912bdaf2d))
|
||||
* **Toast:** actions `color` defaults from prop ([9a42338](https://github.com/nuxt/ui/commit/9a42338da377cc538fddad3c37143a6d74527a9b))
|
||||
* **Toast:** add `actions` slot ([51872be](https://github.com/nuxt/ui/commit/51872bef6c7187450b63a4b88e4f6e714efd146a))
|
||||
* **Toast:** implement progress duration ([d726e4d](https://github.com/nuxt/ui/commit/d726e4ddacc68c8bd63084bfbd32893e292d3846)), closes [#51](https://github.com/nuxt/ui/issues/51)
|
||||
* **Toast:** new component ([#50](https://github.com/nuxt/ui/issues/50)) ([3da1e1a](https://github.com/nuxt/ui/commit/3da1e1a5183852011beadb91af4edbeb3f233e39))
|
||||
* uniformize components sizes ([#68](https://github.com/nuxt/ui/issues/68)) ([f302a15](https://github.com/nuxt/ui/commit/f302a159727e44dce8f12909c3fbe316efe8b1e4))
|
||||
* **useComponentIcons:** extract repetitive logic ([e4882e6](https://github.com/nuxt/ui/commit/e4882e6804394ab448dbdbb3673adadb80faafe2))
|
||||
* **useKbd:** new composable ([#73](https://github.com/nuxt/ui/issues/73)) ([f076019](https://github.com/nuxt/ui/commit/f076019f8f84f2c71c66bfa806d7861ccf8fb959))
|
||||
* **useToast:** add `clear` method ([89ff6b6](https://github.com/nuxt/ui/commit/89ff6b6702179fde2fff3294a1909463883378ae))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Accordion:** dont set a `default-value` ([c36940a](https://github.com/nuxt/ui/commit/c36940a2210219aa36076b480740c044a536634f))
|
||||
* **Accordion:** handle `disabled` through variants ([6236953](https://github.com/nuxt/ui/commit/6236953ed068721348f912b9033b1fa1beb378ab))
|
||||
* **Alert:** add missing `close` slot ([26491af](https://github.com/nuxt/ui/commit/26491afcd10509f0f7d4cf8ea6e108f08f525f64))
|
||||
* **Avatar:** bind `$attrs` on image ([da42c04](https://github.com/nuxt/ui/commit/da42c0489a501724e5bbcfedc76103df3d84f35d))
|
||||
* **AvatarGroup:** default size to `md` ([9620d90](https://github.com/nuxt/ui/commit/9620d903c5471b76da3d7465d702d0e347c83892))
|
||||
* **AvatarGroup:** handle deep children ([e9832b9](https://github.com/nuxt/ui/commit/e9832b95f56f97665be82ffe16e7cad72dc62f90))
|
||||
* **Avatar:** improve sizes ([c726f13](https://github.com/nuxt/ui/commit/c726f13ac2a57a3de36d2c596d5a6ac086fa1a95))
|
||||
* **Avatar:** increase gray on light mode ([fe467da](https://github.com/nuxt/ui/commit/fe467da9bfec5890bde8130832d4f89f954c84e8))
|
||||
* **Badge:** handle `label` as `number` ([6cd7c8a](https://github.com/nuxt/ui/commit/6cd7c8a5fbe17c40610163258800f2034a2ba6ad))
|
||||
* **Breadcrumb:** only apply `aria-current="page"` when link is active ([e5695e7](https://github.com/nuxt/ui/commit/e5695e78bc04827a1f774c4a39d9428eb31941e7))
|
||||
* **Button:** extend now works with compound variants ([53755da](https://github.com/nuxt/ui/commit/53755da8359d8d5ffa4426b4f696489ebbe51f47))
|
||||
* **ButtonGroup:** define its own `size` variant ([0dfd8b3](https://github.com/nuxt/ui/commit/0dfd8b3248d2f0fe6422ff4f03f027427282639b))
|
||||
* **Button:** invalid icon size for `lg` ([f0f8927](https://github.com/nuxt/ui/commit/f0f89272a0992bdd1bba32e3458c864f665d5f58))
|
||||
* **Button:** loading on trailing ([c8bdb51](https://github.com/nuxt/ui/commit/c8bdb51f68a308169f7ce10ede70612f968fa676))
|
||||
* **Button:** move span with `truncate` inside default slot ([561c1fb](https://github.com/nuxt/ui/commit/561c1fb6652fe413497f8a04f563c1ed98f754ba))
|
||||
* **Card:** improve body padding ([cecfb58](https://github.com/nuxt/ui/commit/cecfb58445affccf0d52f975d0329acbcbd3d9c2))
|
||||
* **Card:** missing slots definition ([02da03b](https://github.com/nuxt/ui/commit/02da03b4a8fc9fd2c8d95a86812e746f789ebe1a))
|
||||
* **Checkbox:** icon render ([fc50996](https://github.com/nuxt/ui/commit/fc50996ccfeaa2602f53c2f2683300462cf12992))
|
||||
* **Checkbox:** reduce icon size ([3c89d6b](https://github.com/nuxt/ui/commit/3c89d6b2c5ad5cb0081c4607660760f7460a585e))
|
||||
* **Chip:** extend now works with compound variants ([6dfd696](https://github.com/nuxt/ui/commit/6dfd696092e6a9633be62ec7d1a7fb2a24dc8657))
|
||||
* **Chip:** improve sizes ([d5fe5b3](https://github.com/nuxt/ui/commit/d5fe5b3f4da1a834c14a6aae768163967c817a34))
|
||||
* **Chip:** size injection ([#105](https://github.com/nuxt/ui/issues/105)) ([8baee12](https://github.com/nuxt/ui/commit/8baee1292f62ee7c4380ddb57b69bb9a23dbc2e0))
|
||||
* **Collapsible:** ensure default slot exists ([c85a8cf](https://github.com/nuxt/ui/commit/c85a8cfe0b8f2e2b4a2ac15d3239c842b91b5bc0))
|
||||
* **CommandPalette/InputMenu/Select/SelectMenu:** adapt chip size ([bdc3217](https://github.com/nuxt/ui/commit/bdc32175719b538828b4f63ad952dbd6f81b99b9))
|
||||
* **CommandPalette:** ts errors ([d558b3e](https://github.com/nuxt/ui/commit/d558b3e29c6649bae2762c7412544d5d82b382bf))
|
||||
* **components:** `ui` prop override with class ([#136](https://github.com/nuxt/ui/issues/136)) ([235556d](https://github.com/nuxt/ui/commit/235556d3e00b7a008fe16beba3f370b4af8bbb56))
|
||||
* **components:** allow override of `root` through `ui.root` ([47ad74d](https://github.com/nuxt/ui/commit/47ad74d029f03c9013a76b8ee0a4b6cc37072cc5))
|
||||
* **components:** declare `ui` prop with `PartialString` when arrays in theme slots ([5cc4457](https://github.com/nuxt/ui/commit/5cc4457a743fadbc775b11c41f7bb1fb89b5a728))
|
||||
* **Container:** missing slots definition ([ab83053](https://github.com/nuxt/ui/commit/ab83053fef1571b0d0bf8519fb3c874b15cfef51))
|
||||
* **ContextMenu/DropdownMenu:** move `open` and `default-open` props to `Sub` ([9af6d7d](https://github.com/nuxt/ui/commit/9af6d7dc5924f8c73036397e772fcbddf106e1af))
|
||||
* **ContextMenu:** remove `arrow` prop ([4ac7a7e](https://github.com/nuxt/ui/commit/4ac7a7e3e97c28b0faf0cd1240f9aa6c385399ca))
|
||||
* define empty props in slots for `nuxt-component-meta` parsing ([369e0b1](https://github.com/nuxt/ui/commit/369e0b195206277dbd8b39514f1bcb4a833512f3))
|
||||
* **Divider:** add `w-full` only on horizontal wrapper ([#1565](https://github.com/nuxt/ui/issues/1565)) ([bd8b737](https://github.com/nuxt/ui/commit/bd8b737642280e6a83b67f9a27dd7a823a77e963))
|
||||
* **DropdownMenu:** add overflow scroll if height is added ([80a8c2d](https://github.com/nuxt/ui/commit/80a8c2d772adf188eefa24dfdb1783bbb3fb98b7))
|
||||
* **DropdownMenu:** handle disabled with data attribute for links ([cd214f9](https://github.com/nuxt/ui/commit/cd214f91dbe25828a99b26b8e908456743ae2cfc))
|
||||
* **Dropdown:** missing `mouseenter` event on container ([7288953](https://github.com/nuxt/ui/commit/72889535e7e9763e7ebf59498f22c39bf09d6477))
|
||||
* dynamic slots autocomplete ([#77](https://github.com/nuxt/ui/issues/77)) ([c6a93f7](https://github.com/nuxt/ui/commit/c6a93f71f2b0b9c2d3f89b1de2ae5ee254579ad0))
|
||||
* **FormField:** added a utility type to fix some type errors ([#81](https://github.com/nuxt/ui/issues/81)) ([559a8cb](https://github.com/nuxt/ui/commit/559a8cba5814194b679de5beb3a66d5bda87e25b))
|
||||
* **FormField:** allow `error` prop as boolean ([a23c314](https://github.com/nuxt/ui/commit/a23c3140dfef9bead862a4296a8cbfb05868a00e))
|
||||
* **FormField:** generics ([a78b096](https://github.com/nuxt/ui/commit/a78b0965e8c936b315ac0e51d4955e28941f8a34))
|
||||
* **Form:** inconsistent validation events for `InputMenu` and `Select` ([#123](https://github.com/nuxt/ui/issues/123)) ([a2114c5](https://github.com/nuxt/ui/commit/a2114c587435af901d5bbea047a297169bc7abfb))
|
||||
* **fuse:** prevent indices highlight of a single char ([7b278b0](https://github.com/nuxt/ui/commit/7b278b041c4f09b512fc498a2eb54aef3cab845c))
|
||||
* **Input/SelectMenu:** handle `file` type and `change` events ([#1570](https://github.com/nuxt/ui/issues/1570)) ([878f707](https://github.com/nuxt/ui/commit/878f7078a28c5e70a662682d1293db466d518c7d))
|
||||
* **Input/Textarea:** remove useless gap ([67a1568](https://github.com/nuxt/ui/commit/67a15686e5adafbe5345253d06394f896e93e6f8))
|
||||
* **Input:** invalid `xs` size ([4a281b3](https://github.com/nuxt/ui/commit/4a281b30939b0ccecbcfb213bb1102b21d959791))
|
||||
* **InputMenu/Select/SelectMenu:** use `defuFn` to override base slot ([2aa4358](https://github.com/nuxt/ui/commit/2aa4358d328e7c8e1a1dca718acad391a09280fc))
|
||||
* **InputMenu:** bind `searchTerm` with `defineModel` ([ff9fd9f](https://github.com/nuxt/ui/commit/ff9fd9f657c8e37a658136301ff4a1872842b956))
|
||||
* **Input:** missing `file:` selector on dark mode ([f9259f6](https://github.com/nuxt/ui/commit/f9259f685777e5d6a5e5b5326e56579b24cf40d4))
|
||||
* **Input:** use `pl` / `pr` instead of `ps` / `pe` ([a31d4cf](https://github.com/nuxt/ui/commit/a31d4cffb540db30a8689a170d941620bf4993c3)), closes [#32](https://github.com/nuxt/ui/issues/32)
|
||||
* **Input:** use `ring` instead of `ring-1` ([0920099](https://github.com/nuxt/ui/commit/0920099362c9a2a8493a9715a9d84f4192d80a36))
|
||||
* **Input:** wrong type for `type` prop ([3651c7e](https://github.com/nuxt/ui/commit/3651c7ec4135a05061b5aa613fa62867c2e0602f))
|
||||
* **Kbd:** optional `value` prop when using default slot ([40d17f7](https://github.com/nuxt/ui/commit/40d17f7b03f2ce1306a8f3a9368744fbc1906ae1))
|
||||
* **Link:** active class ([c384ec9](https://github.com/nuxt/ui/commit/c384ec94a2b5d4a7f92c98ce56c484e440a6afaf))
|
||||
* **Link:** add missing `slots` definition ([76e3d0b](https://github.com/nuxt/ui/commit/76e3d0b9f3f582f84983f2813430e4d8eae40c84))
|
||||
* **Link:** allow `ariaLabel` to be picked ([c1ac3a9](https://github.com/nuxt/ui/commit/c1ac3a9f9d5357bc3a7b125d8793d69d8d518bd3))
|
||||
* **Link:** expose `active` instead of `isActive` in default slot ([46c066d](https://github.com/nuxt/ui/commit/46c066d79146bfad5ecc74769407b0f13595ec03))
|
||||
* **Link:** improve `type` prop ([802a159](https://github.com/nuxt/ui/commit/802a15990d6c4c192c43730ceb46022fd19c7d61))
|
||||
* **module:** add `isolate` class on root node ([0c6720b](https://github.com/nuxt/ui/commit/0c6720be7304af94dc3cb54fd772e40845875393))
|
||||
* **module:** handle theme HMR on dev ([#84](https://github.com/nuxt/ui/issues/84)) ([12ba480](https://github.com/nuxt/ui/commit/12ba480d347f081bc0fac54e49b37b8f1513762f))
|
||||
* **module:** inject options in `nuxt.options.ui` ([cf38e7e](https://github.com/nuxt/ui/commit/cf38e7ed78037001a159c794b097d2995a6d3f86))
|
||||
* **module:** prevent `colors` option merge ([c4419fa](https://github.com/nuxt/ui/commit/c4419fa113c04c73e02c613a25fdbdde11cfbc32))
|
||||
* **module:** prevent override of `rootAttrs.class` ([3097da4](https://github.com/nuxt/ui/commit/3097da486fe0891641d81fefcd38d9b31284a8b0))
|
||||
* **module:** typo in `fuchsia` color ([7fd38a8](https://github.com/nuxt/ui/commit/7fd38a8cb829c1f19a7da2f80f2a1cc4f1ca257e))
|
||||
* **module:** use `@tailwindcss/postcss` ([cdf6ebd](https://github.com/nuxt/ui/commit/cdf6ebdafbf3174d27b8a3a29c22df2f5160ac51))
|
||||
* **module:** use relative imports to components / composables ([42f4f8d](https://github.com/nuxt/ui/commit/42f4f8d3370ab0dd94e09d8960e87076afbb1035))
|
||||
* **NavigationMenu:** `highlightColor` defaults to `color` prop ([0bdd6df](https://github.com/nuxt/ui/commit/0bdd6dfe8609d1c951023b6785c4ff87a813b2f6))
|
||||
* **NavigationMenu:** `label` doesn't need to be typed as `number` ([ee1d6ed](https://github.com/nuxt/ui/commit/ee1d6ed08fdcf00ad11ea2ef15869b861ae8a688))
|
||||
* **NavigationMenu:** add default `highlightColor` ([c838b3a](https://github.com/nuxt/ui/commit/c838b3a040d090aeeab297fca451ea8d80942728))
|
||||
* **NavigationMenu:** handle `disabled` through variants + `isolate` list + use separator instead of divide ([f664f69](https://github.com/nuxt/ui/commit/f664f690970058088ebfa975297ca2721c03316f))
|
||||
* **NavigationMenu:** handle `truncate` on vertical orientation ([298ac68](https://github.com/nuxt/ui/commit/298ac68447046a0a37d1857db24fe815cc02fbab))
|
||||
* **NavigationMenu:** optional `links` ([4301821](https://github.com/nuxt/ui/commit/4301821473b0cca086e634146cc6d9f440ca151b))
|
||||
* **NavigationMenu:** prevent err without links ([03edad8](https://github.com/nuxt/ui/commit/03edad885d082a38688e0d34efe12c3f86fc0291))
|
||||
* **NavigationMenu:** use `ULink` with `custom` ([c8bedf8](https://github.com/nuxt/ui/commit/c8bedf84585ad119599a89faa23185a1b94120da))
|
||||
* **Pagination:** center text when link ([440593c](https://github.com/nuxt/ui/commit/440593c5e43eac3ede2acf257e1862a648b02d40))
|
||||
* **plugins:** add missing `type` ([63f752a](https://github.com/nuxt/ui/commit/63f752a4a8e4a5966bbe938e65dfdf706c706a07))
|
||||
* **plugins:** use `import.meta` ([c9f0999](https://github.com/nuxt/ui/commit/c9f09992b7ac9ef2c34d5957fb31fd2aa5db3791))
|
||||
* **Popover:** ensure default slot exists ([5d3ad6b](https://github.com/nuxt/ui/commit/5d3ad6b93ef5fa583a5dcbee102a7391426308f3))
|
||||
* **Popover:** missing `mouseenter` event on container ([8517897](https://github.com/nuxt/ui/commit/8517897c34adaa9e3624f867b43106deb59fcbe8)), closes [#1564](https://github.com/nuxt/ui/issues/1564)
|
||||
* **Popover:** split reactive props with `mode` ([7d2d3b9](https://github.com/nuxt/ui/commit/7d2d3b9c0ffc4e58021639e8b7ea0d23addb4493))
|
||||
* **Popover:** use `scale-in` / `scale-out` animations ([f90f7d7](https://github.com/nuxt/ui/commit/f90f7d7b7c0d81cf42b2232e9c12597210cd5791))
|
||||
* **Progress:** initial indicator style when percent is 0 ([d2442a1](https://github.com/nuxt/ui/commit/d2442a1e4793d3869bfc938197b00f21b4033d19))
|
||||
* **RadioGroup:** missing `as` prop binding ([d3c7991](https://github.com/nuxt/ui/commit/d3c79912d8b9c02fee267958cd34e4fbeb0d3de7))
|
||||
* **RadioGroup:** style `legend` based on size ([b1bcaab](https://github.com/nuxt/ui/commit/b1bcaabd19eb3087d222dc53a37a520735b2f4ed))
|
||||
* remove `IconProps` usage ([6d377d1](https://github.com/nuxt/ui/commit/6d377d1f4bb0b29f9bec346a31dbfb29fbdc57fe))
|
||||
* **SelectMenu:** adapt input size ([5c12d42](https://github.com/nuxt/ui/commit/5c12d428c4e39a5c28b5d0107c0091f8299bca50))
|
||||
* **SelectMenu:** display `modelValue` even if false ([813fdfd](https://github.com/nuxt/ui/commit/813fdfd646dd4f2cb574653dc6a4e993f5025e10))
|
||||
* **SelectMenu:** input before empty ([bedb863](https://github.com/nuxt/ui/commit/bedb863fc68fd8b687a5094aa16da6aed21b5959))
|
||||
* **Select:** missing comma in ` ` ([c00ec5e](https://github.com/nuxt/ui/commit/c00ec5e2f255d83296cfd71f991cca04b00bfa26))
|
||||
* **Select:** wrong button group variants ([5b2e7d8](https://github.com/nuxt/ui/commit/5b2e7d8bad6531795c00cdaa37e21d769dee452e))
|
||||
* **Skeleton:** increase gray on light mode ([3cdbb27](https://github.com/nuxt/ui/commit/3cdbb276357a2a167079507975b285f9c714462f))
|
||||
* specify pnpm version ([#85](https://github.com/nuxt/ui/issues/85)) ([e5f0063](https://github.com/nuxt/ui/commit/e5f0063dbac29f7d27d8ad5a3d42a4c7ee71dcab))
|
||||
* **Switch:** improve sizes ([3a89661](https://github.com/nuxt/ui/commit/3a89661c663998b1de440f3f9925564434b43f2e))
|
||||
* **Tabs:** `force-mount` content ([d294931](https://github.com/nuxt/ui/commit/d2949310eeeea323b1d066f2ccf34b7597b12e32))
|
||||
* **Tabs:** `horizontal` orientation ([1e65933](https://github.com/nuxt/ui/commit/1e65933d9ca12b91b24e58ddd1273848fe11057c))
|
||||
* **Tabs:** add missing slots definition ([b78ca9c](https://github.com/nuxt/ui/commit/b78ca9c56a60941d6a2a1d1c6e2234fbc5980e7d))
|
||||
* **Tabs:** align `link` variant left when vertical ([9d5f9a7](https://github.com/nuxt/ui/commit/9d5f9a70101bcc75f05dc59a3d4dc2d368106b5f))
|
||||
* **Tabs:** broken design ([80a3a0c](https://github.com/nuxt/ui/commit/80a3a0c28f81656b8c144146b72ceca45d2e99b7))
|
||||
* **Tabs:** improve config ([88eb4ca](https://github.com/nuxt/ui/commit/88eb4cac974194b13a34281f76d4771f125685a2))
|
||||
* **Tabs:** missing props pick ([f086f26](https://github.com/nuxt/ui/commit/f086f2662e659e5522adcfbad453d4f44b9be9d1))
|
||||
* **Tabs:** optional `items` ([20caea1](https://github.com/nuxt/ui/commit/20caea1cd7b896e443c846766865174234a25d20))
|
||||
* **Tabs:** specific transition ([48ddf39](https://github.com/nuxt/ui/commit/48ddf39188467b3c4d346c22c0a60e4acd4b025d))
|
||||
* **Tabs:** use `shrink-0` ([f8b50a3](https://github.com/nuxt/ui/commit/f8b50a357152a600ccab784796d8cf11e1eb039d))
|
||||
* **Tabs:** use `transition-all` ([92e1d09](https://github.com/nuxt/ui/commit/92e1d09990d88ed43eec74d313f76a1c2b7eb565))
|
||||
* **Tabs:** wrong text color with `pill` colored ([f70b639](https://github.com/nuxt/ui/commit/f70b63970a9791533f7ae29dfc56a12001119e2d))
|
||||
* **templates:** add `error` in `AppConfig` type ([c7536a7](https://github.com/nuxt/ui/commit/c7536a7af963319ed6307701b38ff2b006b2a3ac))
|
||||
* **templates:** dont override `AppConfig` type ([e151be4](https://github.com/nuxt/ui/commit/e151be4734d8c9a53cf33f6040994912cce24a67))
|
||||
* **templates:** export types in dev mode ([1eaec0f](https://github.com/nuxt/ui/commit/1eaec0ff568bcdff78a0aae0fa824f8b7d1c63e6))
|
||||
* **templates:** handle `-` in regexp ([0a00387](https://github.com/nuxt/ui/commit/0a00387688923fc0cfacbd70c335c664d8d04cc0))
|
||||
* **templates:** import from `[#build](https://github.com/nuxt/ui/issues/build)/ui.css` no longer works ([eb85fa8](https://github.com/nuxt/ui/commit/eb85fa8353ac791b4c889ec103c7247e60bfd81a))
|
||||
* **templates:** missing command in keyframes ([6a1b97a](https://github.com/nuxt/ui/commit/6a1b97add00e481bcc6b06d46e17f4d4f6a97468))
|
||||
* **templates:** pass options to theme in dev mode ([5694823](https://github.com/nuxt/ui/commit/5694823a416fbb70d10702a023420837d31046d6))
|
||||
* **templates:** unshift css ([e1ab903](https://github.com/nuxt/ui/commit/e1ab9031097d96f0459621c677e1522c49f9297d))
|
||||
* **Textarea:** invalid `xs` size ([bed6252](https://github.com/nuxt/ui/commit/bed62520a988cc2e9337d3eb72f2e512df40cf14))
|
||||
* **Textarea:** same `size` as input ([e398637](https://github.com/nuxt/ui/commit/e398637174008cc1bcb8519169bc3c539157cbae))
|
||||
* **Toast:** add missing slots ([cfb4cfd](https://github.com/nuxt/ui/commit/cfb4cfdd7b81302fb3c3f9cd4b4e3a7c80e28779))
|
||||
* **Toaster:** add missing transition on `translate` ([239e0a5](https://github.com/nuxt/ui/commit/239e0a5ac1315a37b52a16bb7a024cefa28dac23))
|
||||
* **Toaster:** increase container height to prevent animation blink ([4dcb74e](https://github.com/nuxt/ui/commit/4dcb74e0a9feea074c6cb56aa73a28107deddc38))
|
||||
* **Toaster:** proxy slot from `App` ([4b29828](https://github.com/nuxt/ui/commit/4b29828e9ddb2602ad7195a4c21ea7963377248e))
|
||||
* **Toaster:** wrong leave animation when collapsed ([c3ed18b](https://github.com/nuxt/ui/commit/c3ed18beb64369fe8a5e0ffee0b749f40c9fc736))
|
||||
* **Toast:** prevent progress bar to blink on leave ([83049fd](https://github.com/nuxt/ui/commit/83049fd23ed4eb829a64061a08be846aefab4b98))
|
||||
* **Tooltip:** ensure default slot exists ([431255e](https://github.com/nuxt/ui/commit/431255e0fec90555f1b5e8e0fc1f039ed853eb75))
|
||||
* **Tooltip:** missing conditions on slots ([d00084c](https://github.com/nuxt/ui/commit/d00084c54cebe239f738af0bfdc159124bb85903))
|
||||
* **Tooltip:** missing root props proxy ([be8bf69](https://github.com/nuxt/ui/commit/be8bf691c3883845582b788b15c99be7fabb3c29))
|
||||
* **Tooltip:** put back close animation ([34cf395](https://github.com/nuxt/ui/commit/34cf395f1a688404030c2a5f37417fae9b2f38d9))
|
||||
* **Tooltip:** remove content max-width ([6c5354e](https://github.com/nuxt/ui/commit/6c5354edde42f51cc1c642c2ae5b17ea0886dae2))
|
||||
* **Tooltip:** use `scale-in` / `scale-out` animations ([0450f6b](https://github.com/nuxt/ui/commit/0450f6b4a91d0af38ff6094fb590915b7164d9e0))
|
||||
* **types:** useless import ([5f7872f](https://github.com/nuxt/ui/commit/5f7872f06e81e03443e2d1c27a654cfe32c55fb3))
|
||||
* **useComponentIcons:** reactivity when using `defu` ([45454fa](https://github.com/nuxt/ui/commit/45454fae45b8571a9691284bd6a13a838e8ea1c9))
|
||||
|
||||
## [2.18.6](https://github.com/nuxt/ui/compare/v2.18.5...v2.18.6) (2024-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **components:** accept partial config in `ui` prop ([#2235](https://github.com/nuxt/ui/issues/2235)) ([eecf4f7](https://github.com/nuxt/ui/commit/eecf4f7ed8a32a874f00afd7bff2964a1366e0b5))
|
||||
* **Modal/Slideover:** bind transition class to `TransitionChild` for Vue 3.5 ([#2227](https://github.com/nuxt/ui/issues/2227)) ([803c20a](https://github.com/nuxt/ui/commit/803c20ad92e8a31fefd6d300856735b0e9adbdf9))
|
||||
* **SelectMenu:** wrong placeholder color with multiple ([#2218](https://github.com/nuxt/ui/issues/2218)) ([28ad5cf](https://github.com/nuxt/ui/commit/28ad5cf98251c6a8acec8d0bf4f0fd07ff6b7066))
|
||||
* **Table:** colspan with expand ([#2217](https://github.com/nuxt/ui/issues/2217)) ([56118c4](https://github.com/nuxt/ui/commit/56118c4a794f3d763dad7b65e044814cf7ef11cf))
|
||||
* **Tabs:** handle icon `margin` in RTL mode ([#2233](https://github.com/nuxt/ui/issues/2233)) ([ea05414](https://github.com/nuxt/ui/commit/ea05414930fe3f5e6805c8aa25bbe8f746bcc86e))
|
||||
* **useFormField:** optional property access ([#2226](https://github.com/nuxt/ui/issues/2226)) ([0a054a5](https://github.com/nuxt/ui/commit/0a054a52b64b4f774041c40223e18e7e056cfd80))
|
||||
|
||||
## [2.18.5](https://github.com/nuxt/ui/compare/v2.18.4...v2.18.5) (2024-09-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Form:** add errors slot prop ([#2188](https://github.com/nuxt/ui/issues/2188)) ([67c6a74](https://github.com/nuxt/ui/commit/67c6a74ed15db1ee8a40e9c74ecfef0d3c3e374a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Button:** button link not showing disabled classes ([#2185](https://github.com/nuxt/ui/issues/2185)) ([e8ea84a](https://github.com/nuxt/ui/commit/e8ea84a5736759d953664f8f397a2339c212b294))
|
||||
* **Carousel:** remove trailing space in next button icon ([#2088](https://github.com/nuxt/ui/issues/2088)) ([1282a5f](https://github.com/nuxt/ui/commit/1282a5f6c001aa05597d458800bafcf6b6419634))
|
||||
* **FormGroup:** remove id when used with `RadioGroup` ([#2152](https://github.com/nuxt/ui/issues/2152)) ([7aec42c](https://github.com/nuxt/ui/commit/7aec42ca15aaa0ccc63c520b484cba203fd3232b))
|
||||
* **Input:** avoid binding value when type is `file` ([#2047](https://github.com/nuxt/ui/issues/2047)) ([82313e8](https://github.com/nuxt/ui/commit/82313e862cbf21ae631156af4cd057f1383db634))
|
||||
* **module:** allow CSS variables in tailwind colors ([#2014](https://github.com/nuxt/ui/issues/2014)) ([7f50c70](https://github.com/nuxt/ui/commit/7f50c7031fecb5ab26a6d0f58b576b2fd0860487))
|
||||
* **module:** augment `@nuxt/schema` rather than `nuxt/schema` ([#2171](https://github.com/nuxt/ui/issues/2171)) ([ead904f](https://github.com/nuxt/ui/commit/ead904fd2f2bbb29fd60ccde063bf02daa2cbdbb))
|
||||
* **module:** consider user tailwind `configPath` for module as string ([#2074](https://github.com/nuxt/ui/issues/2074)) ([e4ba4f7](https://github.com/nuxt/ui/commit/e4ba4f7c729f99dde51891636605793864812d30))
|
||||
* **Pagination:** use links on prev and next button ([#2179](https://github.com/nuxt/ui/issues/2179)) ([c850f85](https://github.com/nuxt/ui/commit/c850f85aaa40c7abbe8cc4dc1bd4705bf7677390))
|
||||
* **README:** update license link ([#2154](https://github.com/nuxt/ui/issues/2154)) ([8d79eea](https://github.com/nuxt/ui/commit/8d79eea19b3276b1f1e069d33b98b311e9b91cfd))
|
||||
* **Slideover:** bind `rounded` class to panel ([#2187](https://github.com/nuxt/ui/issues/2187)) ([bf32baa](https://github.com/nuxt/ui/commit/bf32baaab01dc4150622f67b3b4a8d02d21b922c))
|
||||
* **Slideover:** bind `shadow` class to panel ([#2201](https://github.com/nuxt/ui/issues/2201)) ([d22526c](https://github.com/nuxt/ui/commit/d22526c0c10735a92e63b7d086e7b8534a08d768))
|
||||
* **Table:** checkbox can emit the `[@select](https://github.com/select)` event ([#2072](https://github.com/nuxt/ui/issues/2072)) ([b1f691f](https://github.com/nuxt/ui/commit/b1f691f28ca8c94f6b658dcb61eeff06951bd1d0))
|
||||
* **Table:** select all rows reactivity issue ([#2200](https://github.com/nuxt/ui/issues/2200)) ([68124de](https://github.com/nuxt/ui/commit/68124de5106e55cb2987a6ba4ec1120d79b51788))
|
||||
* **Tabs:** recalculate marker if items change ([#2101](https://github.com/nuxt/ui/issues/2101)) ([82c4926](https://github.com/nuxt/ui/commit/82c4926c090ce7fac48022a93b1b05b877bb48dd))
|
||||
* **Textarea:** resolve row count calculation errors caused by scrollbar ([#2040](https://github.com/nuxt/ui/issues/2040)) ([8210936](https://github.com/nuxt/ui/commit/8210936f22fcf6b7eb5b9711e2c29be38956b8d6))
|
||||
|
||||
## [2.18.4](https://github.com/nuxt/ui/compare/v2.18.3...v2.18.4) (2024-08-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Form:** submit event data ([#2012](https://github.com/nuxt/ui/issues/2012)) ([4d61936](https://github.com/nuxt/ui/commit/4d61936e7e90b664846a8f265825612c509511d7))
|
||||
* **module:** handle nested colors from ui config ([#2008](https://github.com/nuxt/ui/issues/2008)) ([1cc7e2a](https://github.com/nuxt/ui/commit/1cc7e2a306e0f3f666b9a588f6ed02e7eabc0272))
|
||||
* **module:** reduce css bundle size by fixing safelist regex ([#2005](https://github.com/nuxt/ui/issues/2005)) ([8ac9ca4](https://github.com/nuxt/ui/commit/8ac9ca49789a9a7281f7a40926e7e9a8068cc395))
|
||||
* **module:** suffix types imports with `/index` ([7e37668](https://github.com/nuxt/ui/commit/7e37668940d06c5aa20b60d9bfd600d50a171014)), closes [#2018](https://github.com/nuxt/ui/issues/2018)
|
||||
* **Tabs:** use `nextTick` before marker calc ([#2020](https://github.com/nuxt/ui/issues/2020)) ([9c04969](https://github.com/nuxt/ui/commit/9c049690227af8aba61a1f7c002b00c5dfeb63ff))
|
||||
* **useFormGroup:** app config default input size ([#2011](https://github.com/nuxt/ui/issues/2011)) ([3485092](https://github.com/nuxt/ui/commit/3485092edb55f9ef2ca038a8c137431866d6c28a))
|
||||
|
||||
## [2.18.3](https://github.com/nuxt/ui/compare/v2.18.2...v2.18.3) (2024-07-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Link:** define `rel` as any ([69f605f](https://github.com/nuxt/ui/commit/69f605fa724454e4be9e4cee9666a5d57f43a129))
|
||||
* **types:** only use `.ts` for index ([93ddf1d](https://github.com/nuxt/ui/commit/93ddf1d60b0ea5f99f564f3d3969c397ad91cc72))
|
||||
|
||||
## [2.18.2](https://github.com/nuxt/ui/compare/v2.18.1...v2.18.2) (2024-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Tabs:** add missing `UIcon` import ([4fd1be2](https://github.com/nuxt/ui/commit/4fd1be28922bf39584005c14982e5cd9a7d0c624))
|
||||
|
||||
## [2.18.1](https://github.com/nuxt/ui/compare/v2.18.0...v2.18.1) (2024-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **components:** use relative imports ([ea721a3](https://github.com/nuxt/ui/commit/ea721a3705cfbcef3075f8c9c1f4acf359974597))
|
||||
|
||||
## [2.18.0](https://github.com/nuxt/ui/compare/v2.17.0...v2.18.0) (2024-07-25)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **Icon:** migrate from `@egoist/tailwindcss-icons` to new `@nuxt/icon` (#1789)
|
||||
|
||||
### Features
|
||||
|
||||
* **Checkbox/Radio/RadioGroup:** add `help` slot ([c3122f7](https://github.com/nuxt/ui/commit/c3122f776daa6d68f201f22c37e0084aac37ed06)), closes [#1957](https://github.com/nuxt/ui/issues/1957)
|
||||
* **CommandPalette:** handle `static` groups ([#1458](https://github.com/nuxt/ui/issues/1458)) ([b264ad2](https://github.com/nuxt/ui/commit/b264ad2ebdc8d4ee4aab5c994df968025207021f))
|
||||
* **Icon:** migrate from `@egoist/tailwindcss-icons` to new `@nuxt/icon` ([#1789](https://github.com/nuxt/ui/issues/1789)) ([c904604](https://github.com/nuxt/ui/commit/c904604c23987c2535e0e91e9c4fec50477f6b34))
|
||||
* **module:** improve app config types autocomplete ([#1870](https://github.com/nuxt/ui/issues/1870)) ([3f8ea5d](https://github.com/nuxt/ui/commit/3f8ea5dbded7b6836495103739688905ff26fe22))
|
||||
* **RadioGroup:** add `selected` to label slot props ([#1587](https://github.com/nuxt/ui/issues/1587)) ([d18477d](https://github.com/nuxt/ui/commit/d18477def58171d51bdb7d00e31e2807b2e7015b))
|
||||
* **SelectMenu:** add selected to `label` / `leading` / `trailing` slots props ([#1349](https://github.com/nuxt/ui/issues/1349)) ([6b216ca](https://github.com/nuxt/ui/commit/6b216cab1ba3bb69cb317254dfd562ab020c5e92))
|
||||
* **SelectMenu:** handle function in `showCreateOptionWhen` prop ([#1853](https://github.com/nuxt/ui/issues/1853)) ([7e974b5](https://github.com/nuxt/ui/commit/7e974b55d72b8ac0ab42ef722a2d1904c3e4e091))
|
||||
* **Skeleton:** add `as` prop ([#1955](https://github.com/nuxt/ui/issues/1955)) ([bce94db](https://github.com/nuxt/ui/commit/bce94db9fdb2c29a4f2e5981e5dce49a44a4ac8a))
|
||||
* **Table:** expand row ([#1036](https://github.com/nuxt/ui/issues/1036)) ([7155318](https://github.com/nuxt/ui/commit/71553180294c53024c28de9bbebf4ea69f616da7))
|
||||
* **Table:** handle `rowClass` property in `columns` ([#1632](https://github.com/nuxt/ui/issues/1632)) ([748e491](https://github.com/nuxt/ui/commit/748e49175da37b85bd18d62a8455875990866d5b))
|
||||
* **Tabs:** handle `icon` in items ([#1798](https://github.com/nuxt/ui/issues/1798)) ([e8eb394](https://github.com/nuxt/ui/commit/e8eb3941ad4c1c306ccbe9e11d979d5f6c808330))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Accordion:** truncate buttons ([5db18c0](https://github.com/nuxt/ui/commit/5db18c00565f9d2bb9f2768c2de2ab291a55bcae)), closes [#1909](https://github.com/nuxt/ui/issues/1909)
|
||||
* **Alert/Notification:** missing margin on description ([2c55fb6](https://github.com/nuxt/ui/commit/2c55fb63365ee7cc1e993ebd5aa5f83ddadcd26a)), closes [#1959](https://github.com/nuxt/ui/issues/1959)
|
||||
* **Breadcrumb:** use `rotate` on rtl icon ([53003fc](https://github.com/nuxt/ui/commit/53003fcd07d67d13ada0759ff6c5cd3635fba0e3))
|
||||
* **ButtonGroup/FormGroup:** pass default sizes to children ([#1875](https://github.com/nuxt/ui/issues/1875)) ([6b6b03d](https://github.com/nuxt/ui/commit/6b6b03d59f5ab3096b731c59d18a1085d25b5e8e))
|
||||
* **Carousel:** remove `mix-blend-overlay` on indicators ([#1714](https://github.com/nuxt/ui/issues/1714)) ([f74f1df](https://github.com/nuxt/ui/commit/f74f1df6ca5f93e11e542245b611c1aa7c4b8308))
|
||||
* **FormGroup:** don't check for `error` slot so `help` slot can render ([#1888](https://github.com/nuxt/ui/issues/1888)) ([99c52e5](https://github.com/nuxt/ui/commit/99c52e50082d5e99440894c7a077a17510f0de50))
|
||||
* **InputMenu/SelectMenu:** invalid `label` with `value-attribute` and async search ([4d5f250](https://github.com/nuxt/ui/commit/4d5f2509022e4fb74fc268d5479f7cc8f0415040)), closes [#1780](https://github.com/nuxt/ui/issues/1780)
|
||||
* **InputMenu/SelectMenu:** prevent double filter with async search ([e2881d3](https://github.com/nuxt/ui/commit/e2881d3801c54c49d66d41d4f0ba312a7b3ebce7)), closes [#1966](https://github.com/nuxt/ui/issues/1966)
|
||||
* **Link:** allow `ariaLabel` to be picked ([720c44d](https://github.com/nuxt/ui/commit/720c44dd5ee90bb3b30aef32f01ff6eae1397aa4)), closes [#1934](https://github.com/nuxt/ui/issues/1934)
|
||||
* **Progress:** pass down attrs to `<progress>` to improve accessibility ([#1881](https://github.com/nuxt/ui/issues/1881)) ([abd13f1](https://github.com/nuxt/ui/commit/abd13f1f8fd4c8b10069174534c5fdec6c83576e))
|
||||
* **RadioGroup:** allow boolean in `modelValue` prop ([#1913](https://github.com/nuxt/ui/issues/1913)) ([8eca5a0](https://github.com/nuxt/ui/commit/8eca5a0d627e22f42350a060f09c4e44b6de422f))
|
||||
|
||||
## [2.17.0](https://github.com/nuxt/ui/compare/v2.16.0...v2.17.0) (2024-06-13)
|
||||
|
||||
|
||||
|
||||
82
README.md
82
README.md
@@ -1,83 +1,79 @@
|
||||
[](https://ui.nuxt.com)
|
||||
|
||||
# Nuxt UI
|
||||
# Nuxt UI v3
|
||||
|
||||
[![npm version][npm-version-src]][npm-version-href]
|
||||
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
||||
[![License][license-src]][license-href]
|
||||
[![Nuxt][nuxt-src]][nuxt-href]
|
||||
|
||||
Nuxt UI is a module that provides a set of Vue components and composables built with [Tailwind CSS](https://tailwindcss.com/) and [Headless UI](https://headlessui.dev/) to help you build beautiful and accessible user interfaces.
|
||||
|
||||
Its goal is to provide everything related to UI when building a Nuxt app. This includes components, icons, colors, dark mode but also keyboard shortcuts.
|
||||
|
||||
## Features
|
||||
|
||||
- Built with [Headless UI](https://headlessui.dev/) and [Tailwind CSS](https://tailwindcss.com/)
|
||||
- HMR support through Nuxt App Config
|
||||
- Dark mode support
|
||||
- Support for LTR and RTL languages
|
||||
- Keyboard shortcuts
|
||||
- Bundled icons
|
||||
- Fully typed
|
||||
- [Figma Kit](https://www.figma.com/community/file/1288455405058138934)
|
||||
|
||||
Read more on [ui.nuxt.com](https://ui.nuxt.com)
|
||||
We're thrilled to introduce Nuxt UI v3, a significant upgrade to our UI library that delivers extensive improvements and robust new capabilities. This major update harnesses the combined strengths of [Radix Vue](https://www.radix-vue.com/), [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4-alpha), and [Tailwind Variants](https://www.tailwind-variants.org/) to offer developers an unparalleled set of tools for creating sophisticated, accessible, and highly performant user interfaces.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npx nuxi@latest module add ui
|
||||
1. Install the Nuxt UI v3 alpha package:
|
||||
|
||||
```bash [pnpm]
|
||||
pnpm add @nuxt/ui@next
|
||||
```
|
||||
|
||||
If you want latest updates, please use `@nuxt/ui-edge` in your `package.json`:
|
||||
```bash [yarn]
|
||||
yarn add @nuxt/ui@next
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
||||
}
|
||||
}
|
||||
```bash [npm]
|
||||
npm install @nuxt/ui@next
|
||||
```
|
||||
|
||||
```bash [bun]
|
||||
bun add @nuxt/ui@next
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Make sure you have `typescript` installed in your dev dependencies.
|
||||
|
||||
2. Register the Nuxt UI module in your `nuxt.config.ts`:
|
||||
|
||||
```ts [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
modules: ['@nuxt/ui']
|
||||
})
|
||||
```
|
||||
|
||||
3. Import Tailwind and Nuxt UI in your `app.vue` or in your [CSS](https://nuxt.com/docs/getting-started/styling#the-css-property):
|
||||
|
||||
```css [main.css]
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit https://ui.nuxt.com to explore the documentation.
|
||||
Visit https://ui3.nuxt.com to explore the documentation.
|
||||
|
||||
## Credits
|
||||
|
||||
- [nuxt/nuxt](https://github.com/nuxt/nuxt)
|
||||
- [nuxt/icon](https://github.com/nuxt/icon)
|
||||
- [nuxt/fonts](https://github.com/nuxt/fonts)
|
||||
- [nuxt-modules/color-mode](https://github.com/nuxt-modules/color-mode)
|
||||
- [nuxt-modules/tailwindcss](https://github.com/nuxt-modules/tailwindcss)
|
||||
- [radix-vue/radix-vue](https://github.com/radix-vue/radix-vue)
|
||||
- [tailwindlabs/tailwindcss](https://github.com/tailwindlabs/tailwindcss)
|
||||
- [tailwindlabs/headlessui](https://github.com/tailwindlabs/headlessui)
|
||||
- [vueuse/vueuse](https://github.com/vueuse/vueuse)
|
||||
- [egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons)
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to Nuxt UI. Here are a few ways you can get involved:
|
||||
|
||||
- Reporting Bugs: If you come across any bugs or issues, please check out the reporting bugs guide to learn how to submit a bug report.
|
||||
- Suggestions: Have any thoughts to enhance Nuxt UI? We'd love to hear them! Check out the [contribution guide](https://ui.nuxt.com/getting-started/contributing) to share your suggestions.
|
||||
|
||||
## Local Development
|
||||
|
||||
Follow the docs to [Set up your local development environment](https://ui.nuxt.com/getting-started/contributing#_2-local-development-setup) and contribute.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the [MIT license](https://github.com/nuxt/ui/blob/dev/LICENSE.md).
|
||||
|
||||
<!-- Badges -->
|
||||
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/next.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
[npm-version-href]: https://npmjs.com/package/@nuxt/ui
|
||||
|
||||
[npm-downloads-src]: https://img.shields.io/npm/dm/@nuxt/ui.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
[npm-downloads-href]: https://npmjs.com/package/@nuxt/ui
|
||||
|
||||
[license-src]: https://img.shields.io/github/license/nuxt/ui.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
[license-href]: https://github.com/nuxt/ui/blob/main/LICENSE
|
||||
[license-href]: https://github.com/nuxt/ui/blob/main/LICENSE.md
|
||||
|
||||
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
|
||||
[nuxt-href]: https://nuxt.com
|
||||
|
||||
12
build.config.ts
Normal file
12
build.config.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { defineBuildConfig } from 'unbuild'
|
||||
|
||||
export default defineBuildConfig({
|
||||
replace: {
|
||||
'process.env.DEV': 'false'
|
||||
},
|
||||
hooks: {
|
||||
'mkdist:entry:options'(ctx, entry, options) {
|
||||
options.addRelativeDeclarationExtensions = false
|
||||
}
|
||||
}
|
||||
})
|
||||
83
cli/commands/init.mjs
Normal file
83
cli/commands/init.mjs
Normal file
@@ -0,0 +1,83 @@
|
||||
import { existsSync, promises as fsp } from 'node:fs'
|
||||
import { resolve } from 'pathe'
|
||||
import { defineCommand } from 'citty'
|
||||
import { consola } from 'consola'
|
||||
import { splitByCase, upperFirst, camelCase, kebabCase } from 'scule'
|
||||
import { appendFile, sortFile } from '../utils.mjs'
|
||||
import templates from '../templates.mjs'
|
||||
|
||||
export default defineCommand({
|
||||
meta: {
|
||||
name: 'init',
|
||||
description: 'Init a new component.'
|
||||
},
|
||||
args: {
|
||||
name: {
|
||||
type: 'positional',
|
||||
required: true,
|
||||
description: 'Name of the component.'
|
||||
},
|
||||
primitive: {
|
||||
type: 'boolean',
|
||||
description: 'Create a primitive component.'
|
||||
},
|
||||
pro: {
|
||||
type: 'boolean',
|
||||
description: 'Create a pro component.'
|
||||
},
|
||||
prose: {
|
||||
type: 'boolean',
|
||||
description: 'Create a prose component (with --pro).'
|
||||
},
|
||||
content: {
|
||||
type: 'boolean',
|
||||
description: 'Create a content component (with --pro).'
|
||||
}
|
||||
},
|
||||
async setup({ args }) {
|
||||
const name = args.name
|
||||
if (!name) {
|
||||
consola.error('`name` argument is missing!')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (args.prose && !args.pro) {
|
||||
consola.error('`--prose` flag can only be used with `--pro` flag!')
|
||||
process.exit(1)
|
||||
}
|
||||
if (args.content && !args.pro) {
|
||||
consola.error('`--content` flag can only be used with `--pro` flag!')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const path = resolve('.')
|
||||
|
||||
for (const template of Object.keys(templates)) {
|
||||
const { filename, contents } = templates[template](args)
|
||||
if (!contents) {
|
||||
continue
|
||||
}
|
||||
|
||||
const filePath = resolve(path, filename)
|
||||
|
||||
if (existsSync(filePath)) {
|
||||
consola.error(`🚨 ${filePath} already exists!`)
|
||||
continue
|
||||
}
|
||||
|
||||
await fsp.writeFile(filePath, contents.trim() + '\n')
|
||||
|
||||
consola.success(`🪄 Generated ${filePath}!`)
|
||||
}
|
||||
|
||||
const themePath = resolve(path, `src/theme/${args.prose ? 'prose/' : ''}${args.content ? 'content/' : ''}index.ts`)
|
||||
await appendFile(themePath, `export { default as ${camelCase(name)} } from './${kebabCase(name)}'`)
|
||||
await sortFile(themePath)
|
||||
|
||||
if (!args.prose) {
|
||||
const typesPath = resolve(path, 'src/runtime/types/index.ts')
|
||||
await appendFile(typesPath, `export * from '../components/${args.content ? 'content/' : ''}${splitByCase(name).map(p => upperFirst(p)).join('')}.vue'`)
|
||||
await sortFile(typesPath)
|
||||
}
|
||||
}
|
||||
})
|
||||
15
cli/index.mjs
Executable file
15
cli/index.mjs
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
import { defineCommand, runMain } from 'citty'
|
||||
import init from './commands/init.mjs'
|
||||
|
||||
const main = defineCommand({
|
||||
meta: {
|
||||
name: 'nuxt-ui',
|
||||
description: 'Nuxt UI CLI'
|
||||
},
|
||||
subCommands: {
|
||||
init
|
||||
}
|
||||
})
|
||||
|
||||
runMain(main)
|
||||
13
cli/package.json
Normal file
13
cli/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@nuxt/ui-cli",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"citty": "^0.1.6",
|
||||
"consola": "^3.2.3",
|
||||
"pathe": "^1.1.2",
|
||||
"scule": "^1.3.0"
|
||||
}
|
||||
}
|
||||
171
cli/templates.mjs
Normal file
171
cli/templates.mjs
Normal file
@@ -0,0 +1,171 @@
|
||||
import { splitByCase, upperFirst, camelCase, kebabCase } from 'scule'
|
||||
|
||||
const playground = ({ name, pro }) => {
|
||||
const upperName = splitByCase(name).map(p => upperFirst(p)).join('')
|
||||
const kebabName = kebabCase(name)
|
||||
|
||||
return {
|
||||
filename: `playground/app/pages/components/${kebabName}.vue`,
|
||||
contents: pro
|
||||
? undefined
|
||||
: `
|
||||
<template>
|
||||
<div>
|
||||
<U${upperName} />
|
||||
</div>
|
||||
</template>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
const component = ({ name, primitive, pro, prose, content }) => {
|
||||
const upperName = splitByCase(name).map(p => upperFirst(p)).join('')
|
||||
const camelName = camelCase(name)
|
||||
const kebabName = kebabCase(name)
|
||||
const key = pro ? 'uiPro' : 'ui'
|
||||
const path = pro ? 'ui-pro' : 'ui'
|
||||
|
||||
return {
|
||||
filename: `src/runtime/components/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${upperName}.vue`,
|
||||
contents: primitive
|
||||
? `
|
||||
<script lang="ts">
|
||||
import { tv } from 'tailwind-variants'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import _appConfig from '#build/app.config'
|
||||
import theme from '#build/${path}/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}'
|
||||
|
||||
const appConfig = _appConfig as AppConfig & { ${key}: { ${prose ? 'prose: { ' : ''}${camelName}: Partial<typeof theme> } }${prose ? ' }' : ''}
|
||||
|
||||
const ${camelName} = tv({ extend: tv(theme), ...(appConfig.${key}?.${prose ? 'prose?.' : ''}${camelName} || {}) })
|
||||
|
||||
export interface ${upperName}Props {
|
||||
/**
|
||||
* The element or component this component should render as.
|
||||
* @defaultValue \`div\`
|
||||
*/
|
||||
as?: any
|
||||
class?: any
|
||||
ui?: Partial<typeof ${camelName}.slots>
|
||||
}
|
||||
|
||||
export interface ${upperName}Slots {
|
||||
default(props?: {}): any
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Primitive } from 'radix-vue'
|
||||
|
||||
const props = withDefaults(defineProps<${upperName}Props>(), { as: 'div' })
|
||||
defineSlots<${upperName}Slots>()
|
||||
|
||||
const ui = ${camelName}()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })">
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
`
|
||||
: `
|
||||
<script lang="ts">
|
||||
import { tv, type VariantProps } from 'tailwind-variants'
|
||||
import type { ${upperName}RootProps, ${upperName}RootEmits } from 'radix-vue'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import _appConfig from '#build/app.config'
|
||||
import theme from '#build/${path}/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}'
|
||||
|
||||
const appConfig = _appConfig as AppConfig & { ${key}: { ${prose ? 'prose: { ' : ''}${camelName}: Partial<typeof theme> } }${prose ? ' }' : ''}
|
||||
|
||||
const ${camelName} = tv({ extend: tv(theme), ...(appConfig.${key}?.${prose ? 'prose?.' : ''}${camelName} || {}) })
|
||||
|
||||
type ${upperName}Variants = VariantProps<typeof ${camelName}>
|
||||
|
||||
export interface ${upperName}Props extends Pick<${upperName}RootProps> {
|
||||
class?: any
|
||||
ui?: Partial<typeof ${camelName}.slots>
|
||||
}
|
||||
|
||||
export interface ${upperName}Emits extends ${upperName}RootEmits {}
|
||||
|
||||
export interface ${upperName}Slots {}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ${upperName}Root, useForwardPropsEmits } from 'radix-vue'
|
||||
import { reactivePick } from '@vueuse/core'
|
||||
|
||||
const props = defineProps<${upperName}Props>()
|
||||
const emits = defineEmits<${upperName}Emits>()
|
||||
const slots = defineSlots<${upperName}Slots>()
|
||||
|
||||
const rootProps = useForwardPropsEmits(reactivePick(props), emits)
|
||||
|
||||
const ui = ${camelName}()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<${upperName}Root v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })" />
|
||||
</template>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
const theme = ({ name, prose, content }) => {
|
||||
const kebabName = kebabCase(name)
|
||||
|
||||
return {
|
||||
filename: `src/theme/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}.ts`,
|
||||
contents: prose
|
||||
? `
|
||||
export default {
|
||||
base: ''
|
||||
}
|
||||
`
|
||||
: `
|
||||
export default {
|
||||
slots: {
|
||||
root: ''
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
const test = ({ name, prose, content }) => {
|
||||
const upperName = splitByCase(name).map(p => upperFirst(p)).join('')
|
||||
|
||||
return {
|
||||
filename: `test/components/${content ? 'content/' : ''}${upperName}.spec.ts`,
|
||||
contents: prose
|
||||
? undefined
|
||||
: `
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import ${upperName}, { type ${upperName}Props, type ${upperName}Slots } from '../../${content ? '../' : ''}src/runtime/components/${content ? 'content/' : ''}${upperName}.vue'
|
||||
import ComponentRender from '../${content ? '../' : ''}component-render'
|
||||
|
||||
describe('${upperName}', () => {
|
||||
it.each([
|
||||
// Props
|
||||
['with as', { props: { as: 'div' } }],
|
||||
['with class', { props: { class: '' } }],
|
||||
['with ui', { props: { ui: {} } }],
|
||||
// Slots
|
||||
['with default slot', { slots: { default: () => 'Default slot' } }]
|
||||
])('renders %s correctly', async (nameOrHtml: string, options: { props?: ${upperName}Props, slots?: Partial<${upperName}Slots> }) => {
|
||||
const html = await ComponentRender(nameOrHtml, options, ${upperName})
|
||||
expect(html).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
playground,
|
||||
component,
|
||||
theme,
|
||||
test
|
||||
}
|
||||
17
cli/utils.mjs
Normal file
17
cli/utils.mjs
Normal file
@@ -0,0 +1,17 @@
|
||||
import { promises as fsp } from 'node:fs'
|
||||
|
||||
export async function sortFile(path) {
|
||||
const file = await fsp.readFile(path, 'utf-8')
|
||||
|
||||
const lines = file.trim().split('\n').sort()
|
||||
|
||||
await fsp.writeFile(path, lines.join('\n') + '\n')
|
||||
}
|
||||
|
||||
export async function appendFile(path, contents) {
|
||||
const file = await fsp.readFile(path, 'utf-8')
|
||||
|
||||
if (!file.includes(contents)) {
|
||||
await fsp.writeFile(path, file.trim() + '\n' + contents + '\n')
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
primary: 'green',
|
||||
gray: 'slate'
|
||||
}
|
||||
})
|
||||
123
docs/app.vue
123
docs/app.vue
@@ -1,123 +0,0 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<template>
|
||||
<div>
|
||||
<NuxtLoadingIndicator />
|
||||
|
||||
<Banner v-if="!$route.path.startsWith('/examples')" />
|
||||
|
||||
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />
|
||||
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
|
||||
<Footer v-if="!$route.path.startsWith('/examples')" />
|
||||
|
||||
<ClientOnly>
|
||||
<LazyUContentSearch ref="searchRef" :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 42 }" />
|
||||
</ClientOnly>
|
||||
|
||||
<UNotifications>
|
||||
<template #title="{ title }">
|
||||
<span v-html="title" />
|
||||
</template>
|
||||
</UNotifications>
|
||||
<UModals />
|
||||
<USlideovers />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
import { debounce } from 'perfect-debounce'
|
||||
import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
|
||||
|
||||
const searchRef = ref()
|
||||
|
||||
const route = useRoute()
|
||||
const colorMode = useColorMode()
|
||||
const { branch } = useContentSource()
|
||||
|
||||
const { data: nav } = await useAsyncData('navigation', () => fetchContentNavigation())
|
||||
const { data: files } = useLazyFetch<ParsedContent[]>('/api/search.json', { default: () => [], server: false })
|
||||
|
||||
// Computed
|
||||
|
||||
const navigation = computed(() => {
|
||||
if (branch.value?.name === 'dev') {
|
||||
const dev = nav.value.find(item => item._path === '/dev')?.children
|
||||
const pro = nav.value.find(item => item._path === '/pro')
|
||||
|
||||
return [
|
||||
...dev,
|
||||
...(pro ? [pro] : [])
|
||||
]
|
||||
}
|
||||
|
||||
return nav.value?.filter(item => item._path !== '/dev') || []
|
||||
})
|
||||
|
||||
const color = computed(() => colorMode.value === 'dark' ? '#18181b' : 'white')
|
||||
|
||||
const links = computed(() => {
|
||||
return [{
|
||||
label: 'Docs',
|
||||
icon: 'i-heroicons-book-open',
|
||||
to: branch.value?.name === 'dev' ? '/dev/getting-started' : '/getting-started',
|
||||
active: branch.value?.name === 'dev' ? (route.path.startsWith('/dev/getting-started') || route.path.startsWith('/dev/components')) : (route.path.startsWith('/getting-started') || route.path.startsWith('/components'))
|
||||
}, ...(navigation.value.find(item => item._path === '/pro') ? [{
|
||||
label: 'Pro',
|
||||
icon: 'i-heroicons-square-3-stack-3d',
|
||||
to: '/pro',
|
||||
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
||||
}, {
|
||||
label: 'Pricing',
|
||||
icon: 'i-heroicons-ticket',
|
||||
to: '/pro/pricing'
|
||||
}, {
|
||||
label: 'Templates',
|
||||
icon: 'i-heroicons-computer-desktop',
|
||||
to: '/pro/templates'
|
||||
}] : []), {
|
||||
label: 'Releases',
|
||||
icon: 'i-heroicons-rocket-launch',
|
||||
to: '/releases'
|
||||
}].filter(Boolean)
|
||||
})
|
||||
|
||||
// Watch
|
||||
|
||||
watch(() => searchRef.value?.commandPaletteRef?.query, debounce((query: string) => {
|
||||
if (!query) {
|
||||
return
|
||||
}
|
||||
|
||||
useTrackEvent('Search', { props: { query: `${query} - ${searchRef.value?.commandPaletteRef.results.length} results` } })
|
||||
}, 500))
|
||||
|
||||
// Head
|
||||
|
||||
useHead({
|
||||
meta: [
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ 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)}` }
|
||||
],
|
||||
htmlAttrs: {
|
||||
lang: 'en'
|
||||
}
|
||||
})
|
||||
|
||||
useServerSeoMeta({
|
||||
ogSiteName: 'Nuxt UI',
|
||||
twitterCard: 'summary_large_image'
|
||||
})
|
||||
|
||||
// Provide
|
||||
|
||||
provide('navigation', navigation)
|
||||
provide('files', files)
|
||||
</script>
|
||||
13
docs/app/app.config.ts
Normal file
13
docs/app/app.config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export default defineAppConfig({
|
||||
toaster: {
|
||||
position: 'bottom-right' as const,
|
||||
expand: true,
|
||||
duration: 5000
|
||||
},
|
||||
ui: {
|
||||
colors: {
|
||||
primary: 'green',
|
||||
gray: 'slate'
|
||||
}
|
||||
}
|
||||
})
|
||||
126
docs/app/app.vue
Normal file
126
docs/app/app.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<script setup lang="ts">
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
// import { debounce } from 'perfect-debounce'
|
||||
// import type { ContentSearchFile } from '@nuxt/ui-pro'
|
||||
|
||||
const route = useRoute()
|
||||
const appConfig = useAppConfig()
|
||||
// const colorMode = useColorMode()
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const { integrity, api } = runtimeConfig.public.content
|
||||
|
||||
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation(), { default: () => [] })
|
||||
const { data: files } = await useLazyFetch<any[]>(`${api.baseURL}/search${integrity ? '-' + integrity : ''}`, { default: () => [] })
|
||||
|
||||
const searchTerm = ref('')
|
||||
|
||||
// watch(searchTerm, debounce((query: string) => {
|
||||
// if (!query) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// useTrackEvent('Search', { props: { query: `${query} - ${searchTerm.value?.commandPaletteRef.results.length} results` } })
|
||||
// }, 500))
|
||||
|
||||
const links = computed(() => {
|
||||
return [{
|
||||
label: 'Docs',
|
||||
icon: 'i-heroicons-book-open',
|
||||
to: '/getting-started',
|
||||
active: route.path.startsWith('/getting-started') || route.path.startsWith('/components')
|
||||
}, ...(navigation.value.find(item => item._path === '/pro')
|
||||
? [{
|
||||
label: 'Pro',
|
||||
icon: 'i-heroicons-square-3-stack-3d',
|
||||
to: '/pro',
|
||||
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
||||
}, {
|
||||
label: 'Pricing',
|
||||
icon: 'i-heroicons-credit-card',
|
||||
to: '/pro/pricing'
|
||||
}, {
|
||||
label: 'Templates',
|
||||
icon: 'i-heroicons-computer-desktop',
|
||||
to: '/pro/templates'
|
||||
}]
|
||||
: []), {
|
||||
label: 'Releases',
|
||||
icon: 'i-heroicons-rocket-launch',
|
||||
to: '/releases'
|
||||
}].filter(Boolean)
|
||||
})
|
||||
|
||||
// const color = computed(() => colorMode.value === 'dark' ? '#18181b' : 'white')
|
||||
|
||||
useHead({
|
||||
meta: [
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||
// { 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)}` }
|
||||
],
|
||||
htmlAttrs: {
|
||||
lang: 'en'
|
||||
}
|
||||
})
|
||||
|
||||
useServerSeoMeta({
|
||||
ogSiteName: 'Nuxt UI',
|
||||
twitterCard: 'summary_large_image'
|
||||
})
|
||||
|
||||
provide('navigation', navigation)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UApp :toaster="appConfig.toaster">
|
||||
<NuxtLoadingIndicator color="#FFF" />
|
||||
|
||||
<template v-if="!route.path.startsWith('/examples')">
|
||||
<Banner />
|
||||
|
||||
<Header :links="links" />
|
||||
</template>
|
||||
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
|
||||
<template v-if="!route.path.startsWith('/examples')">
|
||||
<Footer />
|
||||
|
||||
<ClientOnly>
|
||||
<LazyUContentSearch v-model:search-term="searchTerm" :files="files" :navigation="navigation" :fuse="{ resultLimit: 42 }" />
|
||||
</ClientOnly>
|
||||
</template>
|
||||
</UApp>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui-pro";
|
||||
|
||||
@source "../content/**/*.md";
|
||||
|
||||
@theme {
|
||||
--font-family-sans: 'Public Sans', sans-serif;
|
||||
|
||||
--color-green-50: #EFFDF5;
|
||||
--color-green-100: #D9FBE8;
|
||||
--color-green-200: #B3F5D1;
|
||||
--color-green-300: #75EDAE;
|
||||
--color-green-400: #00DC82;
|
||||
--color-green-500: #00C16A;
|
||||
--color-green-600: #00A155;
|
||||
--color-green-700: #007F45;
|
||||
--color-green-800: #016538;
|
||||
--color-green-900: #0A5331;
|
||||
--color-green-950: #052E16;
|
||||
}
|
||||
|
||||
:root {
|
||||
--container-width: 90rem;
|
||||
}
|
||||
</style>
|
||||
34
docs/app/assets/icons/radix-vue.svg
Normal file
34
docs/app/assets/icons/radix-vue.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<svg width="290" height="290" viewBox="0 0 290 290" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M226.269 52.4044L226.274 52.4067C237.406 58.2619 245.614 66.3008 250.94 76.5218C256.285 86.7776 258.969 98.4614 258.969 111.596C258.969 124.732 256.285 136.34 250.943 146.446C245.618 156.521 237.447 164.451 226.389 170.234C221.59 172.712 219.355 178.881 222.459 183.542L257.922 236.789C261.773 242.571 257.628 250.311 250.681 250.311H196.906C193.806 250.311 190.939 248.661 189.382 245.98L79.3991 56.5686C76.0313 50.7687 80.2159 43.5 86.9227 43.5H183.394C200.888 43.5 215.161 46.4896 226.269 52.4044Z" fill="url(#paint0_linear_30_25)" stroke="url(#paint1_linear_30_25)" stroke-width="1.93333"/>
|
||||
<path d="M116.722 247.228C113.004 253.687 103.684 253.687 99.9661 247.228L26.2042 119.085C22.4947 112.64 27.1462 104.596 34.5821 104.596L182.106 104.596C189.542 104.596 194.193 112.64 190.484 119.085L116.722 247.228Z" fill="url(#paint2_radial_30_25)"/>
|
||||
<path d="M116.722 247.228C113.004 253.687 103.684 253.687 99.9661 247.228L26.2042 119.085C22.4947 112.64 27.1462 104.596 34.5821 104.596L182.106 104.596C189.542 104.596 194.193 112.64 190.484 119.085L116.722 247.228Z" fill="url(#paint3_radial_30_25)" fill-opacity="0.5"/>
|
||||
<path d="M100.804 246.745L27.042 118.602C23.7034 112.802 27.8898 105.562 34.5821 105.562L182.106 105.562C188.798 105.562 192.985 112.802 189.646 118.602L115.884 246.745C112.538 252.558 104.15 252.558 100.804 246.745Z" fill="url(#paint4_radial_30_25)" fill-opacity="0.5" stroke="url(#paint5_linear_30_25)" stroke-width="1.93333" stroke-linejoin="round"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_30_25" x1="241.666" y1="264.867" x2="88.9331" y2="7.73334" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00996C"/>
|
||||
<stop offset="1" stop-color="#7AFFD8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_30_25" x1="192.366" y1="289.033" x2="233.933" y2="42.5333" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.56"/>
|
||||
<stop offset="0.494792" stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint2_radial_30_25" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(185.6 110.2) rotate(147.858) scale(129.006 128.619)">
|
||||
<stop offset="0.48614" stop-color="#00C58A"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.21"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint3_radial_30_25" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(108.266 160.467) rotate(90) scale(191.4 190.827)">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint4_radial_30_25" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(108.266 181.733) rotate(-90) scale(129.533 129.145)">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint5_linear_30_25" x1="105.366" y1="105.367" x2="105.366" y2="261" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.6"/>
|
||||
<stop offset="0.494792" stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
7
docs/app/components/Banner.vue
Normal file
7
docs/app/components/Banner.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<UBanner icon="i-heroicons-wrench-screwdriver" :actions="[{ label: 'Go to Nuxt UI v2', to: 'https://ui.nuxt.com', trailingIcon: 'i-heroicons-arrow-right-20-solid', class: 'rounded-full' }]" :close="false">
|
||||
<template #title>
|
||||
You're looking at the documentation for <span class="font-semibold">Nuxt UI v3</span>!
|
||||
</template>
|
||||
</UBanner>
|
||||
</template>
|
||||
71
docs/app/components/Footer.vue
Normal file
71
docs/app/components/Footer.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
|
||||
// const items = [{
|
||||
// label: 'Figma Kit',
|
||||
// to: 'https://www.figma.com/community/file/1288455405058138934',
|
||||
// target: '_blank'
|
||||
// }, {
|
||||
// label: 'Playground',
|
||||
// to: 'https://stackblitz.com/edit/nuxt-ui',
|
||||
// target: '_blank'
|
||||
// }, {
|
||||
// label: 'Roadmap',
|
||||
// to: '/roadmap'
|
||||
// }, {
|
||||
// label: 'Releases',
|
||||
// to: '/releases'
|
||||
// }]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<USeparator icon="i-simple-icons-nuxtdotjs" class="h-px" />
|
||||
|
||||
<UFooter>
|
||||
<template #left>
|
||||
<NuxtLink v-if="route.path.startsWith('/pro')" to="https://ui.nuxt.com/pro/purchase" target="_blank" class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Purchase <span class="text-gray-900 dark:text-white">Nuxt UI Pro</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink v-else to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Published under <span class="text-gray-900 dark:text-white">MIT License</span>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<!-- <UNavigationMenu :items="items" variant="link" color="gray" /> -->
|
||||
|
||||
<template #right>
|
||||
<UButton
|
||||
aria-label="Nuxt Website"
|
||||
icon="i-simple-icons-nuxtdotjs"
|
||||
to="https://nuxt.com"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
/>
|
||||
<UButton
|
||||
aria-label="Nuxt UI on Discord"
|
||||
icon="i-simple-icons-discord"
|
||||
to="https://chat.nuxt.dev"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
/>
|
||||
<UButton
|
||||
aria-label="Nuxt on X"
|
||||
icon="i-simple-icons-x"
|
||||
to="https://x.com/nuxt_js"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
/>
|
||||
<UButton
|
||||
aria-label="Nuxt UI on GitHub"
|
||||
icon="i-simple-icons-github"
|
||||
to="https://github.com/nuxt/ui"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
/>
|
||||
</template>
|
||||
</UFooter>
|
||||
</template>
|
||||
55
docs/app/components/Header.vue
Normal file
55
docs/app/components/Header.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import type { NavItem } from '@nuxt/content'
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
defineProps<{
|
||||
links: NavigationMenuItem[]
|
||||
}>()
|
||||
|
||||
const config = useRuntimeConfig().public
|
||||
|
||||
const navigation = inject<Ref<NavItem[]>>('navigation')
|
||||
|
||||
// const items = computed(() => props.links.map(({ icon, ...link }) => link))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UHeader :ui="{ left: 'min-w-0' }">
|
||||
<template #left>
|
||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-gray-900 dark:text-white min-w-0" aria-label="Nuxt UI">
|
||||
<Logo class="w-auto h-6 shrink-0" />
|
||||
|
||||
<UBadge :label="`v${config.version}`" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold truncate" />
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<!-- <UNavigationMenu :items="items" variant="link" /> -->
|
||||
|
||||
<template #right>
|
||||
<ColorPicker />
|
||||
|
||||
<UTooltip text="Search" :kbds="['meta', 'K']">
|
||||
<UContentSearchButton />
|
||||
</UTooltip>
|
||||
|
||||
<!-- <UColorModeButton /> -->
|
||||
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
to="https://github.com/nuxt/ui"
|
||||
target="_blank"
|
||||
icon="i-simple-icons-github"
|
||||
aria-label="GitHub"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<!-- <UNavigationMenu orientation="vertical" :items="items" class="-ml-2.5" />
|
||||
|
||||
<USeparator type="dashed" class="my-4" /> -->
|
||||
|
||||
<UContentNavigation :navigation="navigation" />
|
||||
</template>
|
||||
</UHeader>
|
||||
</template>
|
||||
@@ -4,8 +4,8 @@
|
||||
<path d="M726 92H739C742.314 92 745 89.3137 745 86V60H773V92H800V116H773V159C773 169.5 778.057 174 787 174H800V200H783C759.948 200 745 185.071 745 160V116H726V92Z" fill="currentColor" />
|
||||
<path d="M591 92V154C591 168.004 585.742 179.809 578 188C570.258 196.191 559.566 200 545 200C530.434 200 518.742 196.191 511 188C503.389 179.809 498 168.004 498 154V92H514C517.412 92 520.769 92.622 523 95C525.231 97.2459 526 98.5652 526 102V154C526 162.059 526.457 167.037 530 171C533.543 174.831 537.914 176 545 176C552.217 176 555.457 174.831 559 171C562.543 167.037 563 162.059 563 154V102C563 98.5652 563.769 96.378 566 94C567.96 91.9107 570.028 91.9599 573 92C573.411 92.0055 574.586 92 575 92H591Z" fill="currentColor" />
|
||||
<path d="M676 144L710 92H684C680.723 92 677.812 93.1758 676 96L660 120L645 97C643.188 94.1758 639.277 92 636 92H611L645 143L608 200H634C637.25 200 640.182 196.787 642 194L660 167L679 195C680.818 197.787 683.75 200 687 200H713L676 144Z" fill="currentColor" />
|
||||
<path d="M168 200H279C282.542 200 285.932 198.756 289 197C292.068 195.244 295.23 193.041 297 190C298.77 186.959 300.002 183.51 300 179.999C299.998 176.488 298.773 173.04 297 170.001L222 41C220.23 37.96 218.067 35.7552 215 34C211.933 32.2448 207.542 31 204 31C200.458 31 197.067 32.2448 194 34C190.933 35.7552 188.77 37.96 187 41L168 74L130 9.99764C128.228 6.95784 126.068 3.75491 123 2C119.932 0.245087 116.542 0 113 0C109.458 0 106.068 0.245087 103 2C99.9323 3.75491 96.7717 6.95784 95 9.99764L2 170.001C0.226979 173.04 0.00154312 176.488 1.90993e-06 179.999C-0.0015393 183.51 0.229648 186.959 2 190C3.77035 193.04 6.93245 195.244 10 197C13.0675 198.756 16.4578 200 20 200H90C117.737 200 137.925 187.558 152 164L186 105L204 74L259 168H186L168 200ZM89 168H40L113 42L150 105L125.491 147.725C116.144 163.01 105.488 168 89 168Z" fill="rgb(var(--color-primary-DEFAULT))" />
|
||||
<path d="M958 60.0001H938C933.524 60.0001 929.926 59.9395 927 63C924.074 65.8905 925 67.5792 925 72V141C925 151.372 923.648 156.899 919 162C914.352 166.931 908.468 169 899 169C889.705 169 882.648 166.931 878 162C873.352 156.899 873 151.372 873 141V72.0001C873 67.5793 872.926 65.8906 870 63.0001C867.074 59.9396 863.476 60.0001 859 60.0001H840V141C840 159.023 845.016 173.458 855 184C865.156 194.542 879.893 200 899 200C918.107 200 932.844 194.542 943 184C953.156 173.458 958 159.023 958 141V60.0001Z" fill="rgb(var(--color-primary-DEFAULT))" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1000 60.0233L1020 60V77L1020 128V156.007L1020 181L1020 189.004C1020 192.938 1019.98 194.429 1017 197.001C1014.02 199.725 1009.56 200 1005 200H986.001V181.006L986 130.012V70.0215C986 66.1576 986.016 64.5494 989 62.023C991.819 59.6358 995.437 60.0233 1000 60.0233Z" fill="rgb(var(--color-primary-DEFAULT))" />
|
||||
<path d="M168 200H279C282.542 200 285.932 198.756 289 197C292.068 195.244 295.23 193.041 297 190C298.77 186.959 300.002 183.51 300 179.999C299.998 176.488 298.773 173.04 297 170.001L222 41C220.23 37.96 218.067 35.7552 215 34C211.933 32.2448 207.542 31 204 31C200.458 31 197.067 32.2448 194 34C190.933 35.7552 188.77 37.96 187 41L168 74L130 9.99764C128.228 6.95784 126.068 3.75491 123 2C119.932 0.245087 116.542 0 113 0C109.458 0 106.068 0.245087 103 2C99.9323 3.75491 96.7717 6.95784 95 9.99764L2 170.001C0.226979 173.04 0.00154312 176.488 1.90993e-06 179.999C-0.0015393 183.51 0.229648 186.959 2 190C3.77035 193.04 6.93245 195.244 10 197C13.0675 198.756 16.4578 200 20 200H90C117.737 200 137.925 187.558 152 164L186 105L204 74L259 168H186L168 200ZM89 168H40L113 42L150 105L125.491 147.725C116.144 163.01 105.488 168 89 168Z" fill="var(--color-primary-DEFAULT)" />
|
||||
<path d="M958 60.0001H938C933.524 60.0001 929.926 59.9395 927 63C924.074 65.8905 925 67.5792 925 72V141C925 151.372 923.648 156.899 919 162C914.352 166.931 908.468 169 899 169C889.705 169 882.648 166.931 878 162C873.352 156.899 873 151.372 873 141V72.0001C873 67.5793 872.926 65.8906 870 63.0001C867.074 59.9396 863.476 60.0001 859 60.0001H840V141C840 159.023 845.016 173.458 855 184C865.156 194.542 879.893 200 899 200C918.107 200 932.844 194.542 943 184C953.156 173.458 958 159.023 958 141V60.0001Z" fill="var(--color-primary-DEFAULT)" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1000 60.0233L1020 60V77L1020 128V156.007L1020 181L1020 189.004C1020 192.938 1019.98 194.429 1017 197.001C1014.02 199.725 1009.56 200 1005 200H986.001V181.006L986 130.012V70.0215C986 66.1576 986.016 64.5494 989 62.023C991.819 59.6358 995.437 60.0233 1000 60.0233Z" fill="var(--color-primary-DEFAULT)" />
|
||||
</svg>
|
||||
</template>
|
||||
62
docs/app/components/color-picker/ColorPicker.vue
Normal file
62
docs/app/components/color-picker/ColorPicker.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<UPopover mode="hover" :ui="{ content: 'p-2' }">
|
||||
<template #default="{ open }">
|
||||
<UButton
|
||||
icon="i-heroicons-swatch-20-solid"
|
||||
color="gray"
|
||||
:variant="open ? 'soft' : 'ghost'"
|
||||
square
|
||||
aria-label="Color picker"
|
||||
:ui="{ leadingIcon: 'text-primary-500 dark:text-primary-400' }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<fieldset class="grid grid-cols-5 gap-px">
|
||||
<legend class="text-[11px] font-bold mb-1">
|
||||
Primary
|
||||
</legend>
|
||||
|
||||
<ColorPickerPill v-for="color in primaryColors" :key="color" :color="color" :selected="primary" @select="primary = color" />
|
||||
</fieldset>
|
||||
|
||||
<USeparator class="my-2" type="dashed" />
|
||||
|
||||
<fieldset class="grid grid-cols-5 gap-px">
|
||||
<legend class="text-[11px] font-bold mb-1">
|
||||
Gray
|
||||
</legend>
|
||||
|
||||
<ColorPickerPill v-for="color in grayColors" :key="color" :color="color" :selected="gray" @select="gray = color" />
|
||||
</fieldset>
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const appConfig = useAppConfig()
|
||||
|
||||
// Computed
|
||||
|
||||
const primaryColors = ['red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose']
|
||||
const primary = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.primary
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.primary = option
|
||||
window.localStorage.setItem('nuxt-ui-primary', appConfig.ui.colors.primary)
|
||||
}
|
||||
})
|
||||
|
||||
const grayColors = ['slate', 'cool', 'zinc', 'neutral', 'stone']
|
||||
const gray = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.gray
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.gray = option
|
||||
window.localStorage.setItem('nuxt-ui-gray', appConfig.ui.colors.gray)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
24
docs/app/components/color-picker/ColorPickerPill.vue
Normal file
24
docs/app/components/color-picker/ColorPickerPill.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<UTooltip :text="color" class="capitalize" :portal="false">
|
||||
<UButton
|
||||
color="gray"
|
||||
square
|
||||
:variant="color === selected ? 'soft' : 'ghost'"
|
||||
@click.stop.prevent="$emit('select')"
|
||||
>
|
||||
<span
|
||||
class="inline-block w-3 h-3 rounded-full"
|
||||
:class="`bg-[--color-light] dark:bg-[--color-dark]`"
|
||||
:style="{
|
||||
'--color-light': `var(--color-${color}-500)`,
|
||||
'--color-dark': `var(--color-${color}-400)`
|
||||
}"
|
||||
/>
|
||||
</UButton>
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ color: string, selected: string }>()
|
||||
defineEmits(['select'])
|
||||
</script>
|
||||
279
docs/app/components/content/ComponentCode.vue
Normal file
279
docs/app/components/content/ComponentCode.vue
Normal file
@@ -0,0 +1,279 @@
|
||||
<!-- eslint-disable no-useless-escape -->
|
||||
<script setup lang="ts">
|
||||
import json5 from 'json5'
|
||||
import { upperFirst, camelCase, kebabCase } from 'scule'
|
||||
import { hash } from 'ohash'
|
||||
import * as theme from '#build/ui'
|
||||
import { get, set } from '#ui/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
/** Override the slug taken from the route */
|
||||
slug?: string
|
||||
class?: any
|
||||
/** List of props to ignore in selection */
|
||||
ignore?: string[]
|
||||
/** List of props to hide from code and selection */
|
||||
hide?: string[]
|
||||
/** List of props to externalize in script setup */
|
||||
external?: string[]
|
||||
/** List of props to use with `v-model` */
|
||||
model?: string[]
|
||||
/** List of items for each prop */
|
||||
items?: { [key: string]: string[] }
|
||||
props?: { [key: string]: any }
|
||||
slots?: { [key: string]: any }
|
||||
/**
|
||||
* Whether to format the code with Prettier
|
||||
* @defaultValue false
|
||||
*/
|
||||
prettier?: boolean
|
||||
/**
|
||||
* Whether to collapse the code block
|
||||
* @defaultValue false
|
||||
*/
|
||||
collapse?: boolean
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
const { $prettier } = useNuxtApp()
|
||||
|
||||
const camelName = camelCase(props.slug ?? route.params.slug?.[route.params.slug.length - 1] ?? '')
|
||||
const name = `U${upperFirst(camelName)}`
|
||||
|
||||
const componentProps = reactive({ ...(props.props || {}) })
|
||||
const componentEvents = reactive({
|
||||
...Object.fromEntries((props.model || []).map(key => [`onUpdate:${key}`, (e: any) => setComponentProp(key, e)])),
|
||||
...(componentProps.modelValue ? { [`onUpdate:modelValue`]: (e: any) => setComponentProp('modelValue', e) } : {})
|
||||
})
|
||||
|
||||
function getComponentProp(name: string) {
|
||||
return get(componentProps, name) ?? undefined
|
||||
}
|
||||
|
||||
function setComponentProp(name: string, value: any) {
|
||||
set(componentProps, name, value)
|
||||
}
|
||||
|
||||
const componentTheme = (theme as any)[camelName]
|
||||
const meta = await fetchComponentMeta(name as any)
|
||||
|
||||
function mapKeys(obj: object, parentKey = ''): any {
|
||||
return Object.entries(obj || {}).flatMap(([key, value]: [string, any]) => {
|
||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||
return mapKeys(value, key)
|
||||
}
|
||||
|
||||
const fullKey = parentKey ? `${parentKey}.${key}` : key
|
||||
|
||||
return !props.ignore?.includes(fullKey) && !props.hide?.includes(fullKey) ? fullKey : undefined
|
||||
}).filter(Boolean)
|
||||
}
|
||||
|
||||
const options = computed(() => {
|
||||
const keys = mapKeys(props.props || {})
|
||||
|
||||
return keys.map((key: string) => {
|
||||
const prop = meta?.meta?.props?.find((prop: any) => prop.name === key)
|
||||
const propItems = get(props.items, key, [])
|
||||
const items = propItems.length
|
||||
? propItems.map((item: any) => ({
|
||||
value: item,
|
||||
label: item
|
||||
}))
|
||||
: prop?.type === 'boolean' || prop?.type === 'boolean | undefined'
|
||||
? [{ value: true, label: 'true' }, { value: false, label: 'false' }]
|
||||
: Object.keys(componentTheme?.variants?.[key] || {}).map(variant => ({
|
||||
value: variant,
|
||||
label: variant,
|
||||
chip: key.toLowerCase().endsWith('color') ? { color: variant } : undefined
|
||||
})).filter(variant => key.toLowerCase().endsWith('color') ? !['error'].includes(variant.value) : true)
|
||||
|
||||
return {
|
||||
name: key,
|
||||
label: key,
|
||||
type: prop?.type,
|
||||
items
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const code = computed(() => {
|
||||
let code = ''
|
||||
|
||||
if (props.collapse) {
|
||||
code += `::code-collapse
|
||||
`
|
||||
}
|
||||
|
||||
code += `\`\`\`vue`
|
||||
|
||||
if (props.external?.length) {
|
||||
code += `
|
||||
<script setup lang="ts">
|
||||
`
|
||||
for (const key of props.external) {
|
||||
code += `const ${key === 'modelValue' ? 'value' : key} = ref(${json5.stringify(componentProps[key], null, 2).replace(/,([ |\t\n]+[}|\]])/g, '$1')})
|
||||
`
|
||||
}
|
||||
code += `<\/script>
|
||||
`
|
||||
}
|
||||
|
||||
code += `
|
||||
<template>
|
||||
<${name}`
|
||||
for (const [key, value] of Object.entries(componentProps)) {
|
||||
if (key === 'modelValue') {
|
||||
code += ` v-model="value"`
|
||||
continue
|
||||
}
|
||||
|
||||
if (props.model?.includes(key)) {
|
||||
code += ` v-model:${key}="${key}"`
|
||||
continue
|
||||
}
|
||||
|
||||
if (value === undefined || value === null || value === '' || props.hide?.includes(key)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const prop = meta?.meta?.props?.find((prop: any) => prop.name === key)
|
||||
const name = kebabCase(key)
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
if (value && prop?.default === 'true') {
|
||||
continue
|
||||
}
|
||||
if (!value && (!prop?.default || prop.default === 'false')) {
|
||||
continue
|
||||
}
|
||||
|
||||
code += value ? ` ${name}` : ` :${key}="false"`
|
||||
} else if (typeof value === 'object') {
|
||||
const parsedValue = !props.external?.includes(key) ? json5.stringify(value, null, 2).replace(/,([ |\t\n]+[}|\])])/g, '$1') : key
|
||||
|
||||
code += ` :${name}="${parsedValue}"`
|
||||
} else {
|
||||
const propDefault = prop && (prop.default ?? prop.tags?.find(tag => tag.name === 'defaultValue')?.text ?? componentTheme?.defaultVariants?.[prop.name])
|
||||
if (propDefault === value) {
|
||||
continue
|
||||
}
|
||||
|
||||
code += ` ${prop?.type.includes('number') ? ':' : ''}${name}="${value}"`
|
||||
}
|
||||
}
|
||||
|
||||
if (props.slots) {
|
||||
code += `>`
|
||||
for (const [key, value] of Object.entries(props.slots)) {
|
||||
if (key === 'default') {
|
||||
code += props.slots.default
|
||||
} else {
|
||||
code += `
|
||||
<template #${key}>
|
||||
${value}
|
||||
</template>`
|
||||
}
|
||||
}
|
||||
code += (Object.keys(props.slots).length > 1 ? '\n' : '') + `</${name}>`
|
||||
} else {
|
||||
code += ' />'
|
||||
}
|
||||
code += `\n</template>
|
||||
\`\`\`
|
||||
`
|
||||
|
||||
if (props.collapse) {
|
||||
code += `
|
||||
::`
|
||||
}
|
||||
|
||||
return code
|
||||
})
|
||||
|
||||
const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props: componentProps, slots: props.slots })}`, async () => {
|
||||
if (!props.prettier) {
|
||||
return parseMarkdown(code.value)
|
||||
}
|
||||
|
||||
let formatted = ''
|
||||
try {
|
||||
formatted = await $prettier.format(code.value, {
|
||||
trailingComma: 'none',
|
||||
semi: false,
|
||||
singleQuote: true
|
||||
})
|
||||
} catch {
|
||||
formatted = code.value
|
||||
}
|
||||
|
||||
return parseMarkdown(formatted)
|
||||
}, { watch: [code] })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div>
|
||||
<div v-if="options.length" class="flex items-center gap-2.5 border border-gray-200 dark:border-gray-700 border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
|
||||
<template v-for="option in options" :key="option.name">
|
||||
<UFormField
|
||||
:label="option.label"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-gray-300 dark:ring-gray-700 rounded"
|
||||
:ui="{
|
||||
wrapper: 'bg-gray-50 dark:bg-gray-800/50 rounded-l flex border-r border-gray-300 dark:border-gray-700',
|
||||
label: 'text-gray-500 dark:text-gray-400 px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
<USelectMenu
|
||||
v-if="option.items?.length"
|
||||
:model-value="getComponentProp(option.name)"
|
||||
:items="option.items"
|
||||
value-key="value"
|
||||
color="gray"
|
||||
variant="soft"
|
||||
class="rounded rounded-l-none min-w-12"
|
||||
:search-input="false"
|
||||
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
|
||||
:ui="{ itemLeadingChip: 'size-2' }"
|
||||
@update:model-value="setComponentProp(option.name, $event)"
|
||||
>
|
||||
<template v-if="option.name.toLowerCase().endsWith('color')" #leading="{ modelValue, ui }">
|
||||
<UChip
|
||||
v-if="modelValue"
|
||||
inset
|
||||
standalone
|
||||
:color="(modelValue as any)"
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
class="size-2"
|
||||
/>
|
||||
</template>
|
||||
</USelectMenu>
|
||||
<UInput
|
||||
v-else
|
||||
:type="option.type?.includes('number') ? 'number' : 'text'"
|
||||
:model-value="getComponentProp(option.name)"
|
||||
color="gray"
|
||||
variant="soft"
|
||||
:ui="{ base: 'rounded rounded-l-none min-w-12' }"
|
||||
@update:model-value="setComponentProp(option.name, $event)"
|
||||
/>
|
||||
</UFormField>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center border border-b-0 border-gray-200 dark:border-gray-700 relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class]">
|
||||
<component :is="name" v-bind="{ ...componentProps, ...componentEvents }">
|
||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
||||
<ContentSlot :name="slot" unwrap="p">
|
||||
{{ slots?.[slot] }}
|
||||
</ContentSlot>
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MDCRenderer v-if="ast" :body="ast.body" :data="ast.data" class="[&_pre]:!rounded-t-none [&_div.my-5]:!mt-0" />
|
||||
</div>
|
||||
</template>
|
||||
37
docs/app/components/content/ComponentEmits.vue
Normal file
37
docs/app/components/content/ComponentEmits.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { upperFirst, camelCase } from 'scule'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const camelName = camelCase(route.params.slug?.[route.params.slug.length - 1] ?? '')
|
||||
const name = `U${upperFirst(camelName)}`
|
||||
|
||||
const meta = await fetchComponentMeta(name as any)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseTable>
|
||||
<ProseThead>
|
||||
<ProseTr>
|
||||
<ProseTh>
|
||||
Event
|
||||
</ProseTh>
|
||||
<ProseTh>
|
||||
Type
|
||||
</ProseTh>
|
||||
</ProseTr>
|
||||
</ProseThead>
|
||||
<ProseTbody>
|
||||
<ProseTr v-for="event in (meta?.meta?.events || [])" :key="event.name">
|
||||
<ProseTd>
|
||||
<ProseCodeInline>
|
||||
{{ event.name }}
|
||||
</ProseCodeInline>
|
||||
</ProseTd>
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="event.type" :type="event.type" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
</ProseTable>
|
||||
</template>
|
||||
177
docs/app/components/content/ComponentExample.vue
Normal file
177
docs/app/components/content/ComponentExample.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<script setup lang="ts">
|
||||
import { camelCase } from 'scule'
|
||||
import { get, set } from '#ui/utils'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
name: string
|
||||
class?: any
|
||||
props?: { [key: string]: any }
|
||||
/**
|
||||
* Whether to format the code with Prettier
|
||||
* @defaultValue false
|
||||
*/
|
||||
prettier?: boolean
|
||||
/**
|
||||
* Whether to collapse the code block
|
||||
* @defaultValue false
|
||||
*/
|
||||
collapse?: boolean
|
||||
/**
|
||||
* Whether to show the preview
|
||||
* When `false`, the filename will be shown instead
|
||||
* @defaultValue true
|
||||
*/
|
||||
preview?: boolean
|
||||
|
||||
/**
|
||||
* Whether to show the source code
|
||||
* @defaultValue true
|
||||
*/
|
||||
source?: boolean
|
||||
|
||||
/**
|
||||
* A list of variable props to link to the component.
|
||||
*/
|
||||
options?: Array<{
|
||||
alias?: string
|
||||
name: string
|
||||
label: string
|
||||
items?: any[]
|
||||
default: any
|
||||
multiple?: boolean
|
||||
}>
|
||||
}>(), {
|
||||
preview: true,
|
||||
source: true
|
||||
})
|
||||
|
||||
const slots = defineSlots<{
|
||||
options(props?: {}): any
|
||||
}>()
|
||||
|
||||
const { $prettier } = useNuxtApp()
|
||||
|
||||
const camelName = camelCase(props.name)
|
||||
|
||||
const data = await fetchComponentExample(camelName)
|
||||
|
||||
const componentProps = reactive({ ...(props.props || {}) })
|
||||
|
||||
const code = computed(() => {
|
||||
let code = ''
|
||||
|
||||
if (props.collapse) {
|
||||
code += `::code-collapse
|
||||
`
|
||||
}
|
||||
|
||||
code += `\`\`\`vue${props.preview ? '' : ` [${data.pascalName}.vue]`}
|
||||
${data?.code ?? ''}
|
||||
\`\`\``
|
||||
|
||||
if (props.collapse) {
|
||||
code += `
|
||||
::`
|
||||
}
|
||||
|
||||
return code
|
||||
})
|
||||
|
||||
const { data: ast } = await useAsyncData(`component-example-${camelName}`, async () => {
|
||||
if (!props.prettier) {
|
||||
return parseMarkdown(code.value)
|
||||
}
|
||||
|
||||
let formatted = ''
|
||||
try {
|
||||
formatted = await $prettier.format(code.value, {
|
||||
trailingComma: 'none',
|
||||
semi: false,
|
||||
singleQuote: true
|
||||
})
|
||||
} catch {
|
||||
formatted = code.value
|
||||
}
|
||||
|
||||
return parseMarkdown(formatted)
|
||||
}, { watch: [code] })
|
||||
|
||||
const optionsValues = ref(props.options?.reduce((acc, option) => {
|
||||
if (option.name) {
|
||||
acc[option.alias || option.name] = option.default
|
||||
}
|
||||
if (option.name.toLowerCase().endsWith('color') && option.items?.length) {
|
||||
option.items = option.items.map((item: any) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
chip: { color: item }
|
||||
}))
|
||||
}
|
||||
return acc
|
||||
}, {} as Record<string, any>) || {})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div v-if="preview">
|
||||
<div class="border border-gray-200 dark:border-gray-700 relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-gray-200 dark:border-gray-700">
|
||||
<slot name="options" />
|
||||
|
||||
<UFormField
|
||||
v-for="option in props.options"
|
||||
:key="option.name"
|
||||
:label="option.label"
|
||||
:name="option.name"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-gray-300 dark:ring-gray-700 rounded"
|
||||
:ui="{
|
||||
wrapper: 'bg-gray-50 dark:bg-gray-800/50 rounded-l flex border-r border-gray-300 dark:border-gray-700',
|
||||
label: 'text-gray-500 dark:text-gray-400 px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
<USelectMenu
|
||||
v-if="option.items?.length"
|
||||
:model-value="get(optionsValues, option.name)"
|
||||
:items="option.items"
|
||||
:search-input="false"
|
||||
:value-key="option.name.toLowerCase().endsWith('color') ? 'value' : undefined"
|
||||
color="gray"
|
||||
variant="soft"
|
||||
class="rounded rounded-l-none min-w-12"
|
||||
:multiple="option.multiple"
|
||||
:class="[option.name.toLowerCase().endsWith('color') && 'pl-6']"
|
||||
:ui="{ itemLeadingChip: 'size-2' }"
|
||||
@update:model-value="set(optionsValues, option.name, $event)"
|
||||
>
|
||||
<template v-if="option.name.toLowerCase().endsWith('color')" #leading="{ modelValue, ui }">
|
||||
<UChip
|
||||
inset
|
||||
standalone
|
||||
:color="(modelValue as any)"
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
class="size-2"
|
||||
/>
|
||||
</template>
|
||||
</USelectMenu>
|
||||
<UInput
|
||||
v-else
|
||||
:model-value="get(optionsValues, option.name)"
|
||||
color="gray"
|
||||
variant="soft"
|
||||
:ui="{ base: 'rounded rounded-l-none min-w-12' }"
|
||||
@update:model-value="set(optionsValues, option.name, $event)"
|
||||
/>
|
||||
</UFormField>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center p-4" :class="props.class">
|
||||
<component :is="camelName" v-bind="{ ...componentProps, ...optionsValues }" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MDCRenderer v-if="ast && props.source" :body="ast.body" :data="ast.data" class="[&_pre]:!rounded-t-none [&_div.my-5]:!mt-0" />
|
||||
</div>
|
||||
</template>
|
||||
87
docs/app/components/content/ComponentProps.vue
Normal file
87
docs/app/components/content/ComponentProps.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<script setup lang="ts">
|
||||
import { upperFirst, camelCase } from 'scule'
|
||||
import type { ComponentMeta } from 'vue-component-meta'
|
||||
import * as theme from '#build/ui'
|
||||
|
||||
const props = defineProps<{
|
||||
ignore?: string[]
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const camelName = camelCase(route.params.slug?.[route.params.slug.length - 1] ?? '')
|
||||
const name = `U${upperFirst(camelName)}`
|
||||
|
||||
const componentTheme = (theme as any)[camelName]
|
||||
const meta = await fetchComponentMeta(name as any)
|
||||
|
||||
const metaProps: ComputedRef<ComponentMeta['props']> = computed(() => {
|
||||
if (!meta?.meta?.props?.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
return meta.meta.props.filter((prop) => {
|
||||
return !props.ignore?.includes(prop.name)
|
||||
}).map((prop) => {
|
||||
prop.default = prop.default ?? prop.tags?.find(tag => tag.name === 'defaultValue')?.text ?? componentTheme?.defaultVariants?.[prop.name]
|
||||
// @ts-expect-error - Type is not correct
|
||||
prop.type = !prop.type.startsWith('boolean') && prop.schema?.kind === 'enum' && Object.keys(prop.schema.schema)?.length ? Object.values(prop.schema.schema).map(schema => schema?.type ? schema.type : schema).join(' | ') : prop.type
|
||||
return prop
|
||||
}).sort((a, b) => {
|
||||
if (a.name === 'as') {
|
||||
return -1
|
||||
}
|
||||
|
||||
if (b.name === 'as') {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (a.name === 'ui') {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (b.name === 'ui') {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseTable>
|
||||
<ProseThead>
|
||||
<ProseTr>
|
||||
<ProseTh>
|
||||
Prop
|
||||
</ProseTh>
|
||||
<ProseTh>
|
||||
Default
|
||||
</ProseTh>
|
||||
<ProseTh>
|
||||
Type
|
||||
</ProseTh>
|
||||
</ProseTr>
|
||||
</ProseThead>
|
||||
<ProseTbody>
|
||||
<ProseTr v-for="prop in metaProps" :key="prop.name">
|
||||
<ProseTd>
|
||||
<ProseCodeInline>
|
||||
{{ prop.name }}
|
||||
</ProseCodeInline>
|
||||
</ProseTd>
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="prop.default" :type="prop.default" />
|
||||
</ProseTd>
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="prop.type" :type="prop.type" />
|
||||
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-gray-600 dark:text-gray-300 mt-1" />
|
||||
|
||||
<ComponentPropsSchema v-if="prop.schema" :prop="prop" :ignore="ignore" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
</ProseTable>
|
||||
</template>
|
||||
47
docs/app/components/content/ComponentPropsSchema.vue
Normal file
47
docs/app/components/content/ComponentPropsSchema.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
import type { PropertyMeta } from 'vue-component-meta'
|
||||
|
||||
const props = defineProps<{
|
||||
prop: PropertyMeta
|
||||
ignore?: string[]
|
||||
}>()
|
||||
|
||||
function getSchemaProps(schema: PropertyMeta['schema']): any {
|
||||
if (!schema || typeof schema === 'string' || !schema.schema) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (schema.kind === 'object') {
|
||||
return Object.values(schema.schema).filter(prop => !props.ignore?.includes(prop.name))
|
||||
}
|
||||
|
||||
return (Array.isArray(schema.schema) ? schema.schema : Object.values(schema.schema)).flatMap(getSchemaProps as any)
|
||||
}
|
||||
|
||||
const schemaProps = computed(() => {
|
||||
return getSchemaProps(props.prop.schema).map((prop: any) => {
|
||||
const defaultValue = prop.default ?? prop.tags?.find((tag: any) => tag.name === 'defaultValue')?.text
|
||||
let description = prop.description
|
||||
if (defaultValue) {
|
||||
description = description ? `${description} Defaults to \`${defaultValue}\`{lang="ts-type"}.` : `Defaults to \`${defaultValue}\`{lang="ts-type"}.`
|
||||
}
|
||||
|
||||
return {
|
||||
...prop,
|
||||
description
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Collapsible v-if="schemaProps?.length" class="mt-1">
|
||||
<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-gray-500 dark:text-gray-400 my-1" />
|
||||
</ProseLi>
|
||||
</ProseUl>
|
||||
</Collapsible>
|
||||
</template>
|
||||
39
docs/app/components/content/ComponentSlots.vue
Normal file
39
docs/app/components/content/ComponentSlots.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import { upperFirst, camelCase } from 'scule'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const camelName = camelCase(route.params.slug?.[route.params.slug.length - 1] ?? '')
|
||||
const name = `U${upperFirst(camelName)}`
|
||||
|
||||
const meta = await fetchComponentMeta(name as any)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseTable>
|
||||
<ProseThead>
|
||||
<ProseTr>
|
||||
<ProseTh>
|
||||
Slot
|
||||
</ProseTh>
|
||||
<ProseTh>
|
||||
Type
|
||||
</ProseTh>
|
||||
</ProseTr>
|
||||
</ProseThead>
|
||||
<ProseTbody>
|
||||
<ProseTr v-for="slot in (meta?.meta?.slots || [])" :key="slot.name">
|
||||
<ProseTd>
|
||||
<ProseCodeInline>
|
||||
{{ slot.name }}
|
||||
</ProseCodeInline>
|
||||
</ProseTd>
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="slot.type" :type="slot.type" />
|
||||
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-gray-600 dark:text-gray-300 mt-1" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
</ProseTable>
|
||||
</template>
|
||||
69
docs/app/components/content/ComponentTheme.vue
Normal file
69
docs/app/components/content/ComponentTheme.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import json5 from 'json5'
|
||||
import { camelCase } from 'scule'
|
||||
import * as theme from '#build/ui'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const name = camelCase(route.params.slug?.[route.params.slug.length - 1] ?? '')
|
||||
|
||||
const strippedCompoundVariants = ref(false)
|
||||
|
||||
function stripCompoundVariants(component?: any) {
|
||||
if (component?.compoundVariants) {
|
||||
component.compoundVariants = component.compoundVariants.filter((compoundVariant: any) => {
|
||||
if (compoundVariant.color) {
|
||||
if (!['primary', 'gray'].includes(compoundVariant.color)) {
|
||||
strippedCompoundVariants.value = true
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (compoundVariant.highlightColor) {
|
||||
if (!['primary', 'gray'].includes(compoundVariant.highlightColor)) {
|
||||
strippedCompoundVariants.value = true
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return component
|
||||
}
|
||||
|
||||
const component = computed(() => {
|
||||
return {
|
||||
ui: {
|
||||
[name]: stripCompoundVariants((theme as any)[name])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const { data: ast } = await useAsyncData(`component-theme-${name}`, async () => {
|
||||
const md = `
|
||||
::code-collapse
|
||||
\`\`\`ts [app.config.ts]
|
||||
export default defineAppConfig(${json5.stringify(component.value, null, 2).replace(/,([ |\t\n]+[}|\])])/g, '$1')})
|
||||
\`\`\`\
|
||||
|
||||
::
|
||||
|
||||
${strippedCompoundVariants.value
|
||||
? `
|
||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/v3/src/theme/${name}.ts"}
|
||||
Some colors in \`compoundVariants\` are omitted for readability. Check out the source code on GitHub.
|
||||
::`
|
||||
: ''}
|
||||
`
|
||||
|
||||
return parseMarkdown(md)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<MDCRenderer v-if="ast" :body="ast.body" :data="ast.data" />
|
||||
</template>
|
||||
31
docs/app/components/content/HighlightInlineType.vue
Normal file
31
docs/app/components/content/HighlightInlineType.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { murmurHash } from 'ohash'
|
||||
|
||||
const props = defineProps<{
|
||||
type: string
|
||||
}>()
|
||||
|
||||
const type = computed(() => {
|
||||
let type = props.type
|
||||
if (type.includes(', "as" | "asChild" | "forceMount">')) {
|
||||
type = type.replace(`, "as" | "asChild" | "forceMount">`, ``).replace('Omit<', '')
|
||||
}
|
||||
if (type.includes(', "as" | "asChild">')) {
|
||||
type = type.replace(', "as" | "asChild">', '').replace('Omit<', '')
|
||||
}
|
||||
if (type.startsWith('undefined |')) {
|
||||
type = type.replace('undefined |', '')
|
||||
}
|
||||
if (type.endsWith('| undefined')) {
|
||||
type = type.replace('| undefined', '')
|
||||
}
|
||||
|
||||
return type
|
||||
})
|
||||
|
||||
const { data: ast } = await useAsyncData(`hightlight-inline-code-${murmurHash(type.value)}`, () => parseMarkdown(`\`${type.value}\`{lang="ts-type"}`))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<MDCRenderer v-if="ast" :body="ast.body" :data="ast.data" />
|
||||
</template>
|
||||
22
docs/app/components/content/IconsTheme.vue
Normal file
22
docs/app/components/content/IconsTheme.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import json5 from 'json5'
|
||||
import icons from '../../../../src/theme/icons'
|
||||
|
||||
const { data: ast } = await useAsyncData(`icons-theme`, async () => {
|
||||
const md = `
|
||||
\`\`\`ts [app.config.ts]
|
||||
export default defineAppConfig(${json5.stringify({
|
||||
ui: {
|
||||
icons
|
||||
}
|
||||
}, null, 2).replace(/,([ |\t\n]+[}|\])])/g, '$1')})
|
||||
\`\`\`\
|
||||
`
|
||||
|
||||
return parseMarkdown(md)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<MDCRenderer v-if="ast" :body="ast.body" :data="ast.data" />
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-heroicons-face-smile'
|
||||
},
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-heroicons-swatch'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-heroicons-cube-transparent'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #body="{ item }">
|
||||
This is the {{ item.label }} panel.
|
||||
</template>
|
||||
</UAccordion>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-heroicons-face-smile'
|
||||
},
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-heroicons-swatch'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-heroicons-cube-transparent'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #content="{ item }">
|
||||
<p class="pb-3.5 text-sm text-gray-500 dark:text-gray-400">
|
||||
This is the {{ item.label }} panel.
|
||||
</p>
|
||||
</template>
|
||||
</UAccordion>
|
||||
</template>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-heroicons-face-smile',
|
||||
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
|
||||
},
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-heroicons-swatch',
|
||||
slot: 'colors',
|
||||
content: 'Choose a primary and a gray color from your Tailwind CSS theme.'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-heroicons-cube-transparent',
|
||||
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #colors="{ item }">
|
||||
<p class="text-sm pb-3.5 text-primary-500 dark:text-primary-400">
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
</UAccordion>
|
||||
</template>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
const items = [
|
||||
{
|
||||
label: 'Icons',
|
||||
icon: 'i-heroicons-face-smile',
|
||||
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
|
||||
},
|
||||
{
|
||||
label: 'Colors',
|
||||
icon: 'i-heroicons-swatch',
|
||||
content: 'Choose a primary and a gray color from your Tailwind CSS theme.'
|
||||
},
|
||||
{
|
||||
label: 'Components',
|
||||
icon: 'i-heroicons-cube-transparent',
|
||||
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
|
||||
}
|
||||
]
|
||||
|
||||
const active = ref('0')
|
||||
|
||||
// Note: This is for demonstration purposes only. Don't do this at home.
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
active.value = String((Number(active.value) + 1) % items.length)
|
||||
}, 2000)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UAccordion v-model="active" :items="items" />
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<UAvatarGroup>
|
||||
<UChip inset color="green">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/739984?v=4"
|
||||
alt="Benjamin Canac"
|
||||
/>
|
||||
</UChip>
|
||||
|
||||
<UChip inset color="amber">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/25613751?v=4"
|
||||
alt="Romain Hamel"
|
||||
/>
|
||||
</UChip>
|
||||
|
||||
<UChip inset color="red">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/19751938?v=4"
|
||||
alt="Neil Richter"
|
||||
/>
|
||||
</UChip>
|
||||
</UAvatarGroup>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<UAvatarGroup>
|
||||
<ULink
|
||||
to="https://github.com/benjamincanac"
|
||||
target="_blank"
|
||||
class="hover:ring-primary-500 dark:hover:ring-primary-400 transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/739984?v=4"
|
||||
alt="Benjamin Canac"
|
||||
/>
|
||||
</ULink>
|
||||
|
||||
<ULink
|
||||
to="https://github.com/romhml"
|
||||
target="_blank"
|
||||
class="hover:ring-primary-500 dark:hover:ring-primary-400 transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/25613751?v=4"
|
||||
alt="Romain Hamel"
|
||||
/>
|
||||
</ULink>
|
||||
|
||||
<ULink
|
||||
to="https://github.com/noook"
|
||||
target="_blank"
|
||||
class="hover:ring-primary-500 dark:hover:ring-primary-400 transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/19751938?v=4"
|
||||
alt="Neil Richter"
|
||||
/>
|
||||
</ULink>
|
||||
</UAvatarGroup>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<UAvatarGroup>
|
||||
<UTooltip text="benjamincanac">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/739984?v=4"
|
||||
alt="Benjamin Canac"
|
||||
/>
|
||||
</UTooltip>
|
||||
|
||||
<UTooltip text="romhml">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/25613751?v=4"
|
||||
alt="Romain Hamel"
|
||||
/>
|
||||
</UTooltip>
|
||||
|
||||
<UTooltip text="noook">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/19751938?v=4"
|
||||
alt="Neil Richter"
|
||||
/>
|
||||
</UTooltip>
|
||||
</UAvatarGroup>
|
||||
</template>
|
||||
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<UChip inset>
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/739984?v=4"
|
||||
alt="Benjamin Canac"
|
||||
/>
|
||||
</UChip>
|
||||
</template>
|
||||
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<UTooltip text="Benjamin Canac">
|
||||
<UAvatar
|
||||
src="https://avatars.githubusercontent.com/u/739984?v=4"
|
||||
alt="Benjamin Canac"
|
||||
/>
|
||||
</UTooltip>
|
||||
</template>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
}, {
|
||||
slot: 'dropdown',
|
||||
icon: 'i-heroicons-ellipsis-horizontal',
|
||||
children: [{
|
||||
label: 'Documentation'
|
||||
}, {
|
||||
label: 'Themes'
|
||||
}, {
|
||||
label: 'GitHub'
|
||||
}]
|
||||
}, {
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
}, {
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UBreadcrumb :items="items">
|
||||
<template #dropdown="{ item }">
|
||||
<UDropdownMenu :items="item.children">
|
||||
<UButton :icon="item.icon" color="gray" variant="link" class="p-0.5" />
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
</UBreadcrumb>
|
||||
</template>
|
||||
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Home',
|
||||
to: '/'
|
||||
}, {
|
||||
label: 'Components',
|
||||
to: '/components'
|
||||
}, {
|
||||
label: 'Breadcrumb',
|
||||
to: '/components/breadcrumb'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UBreadcrumb :items="items">
|
||||
<template #separator>
|
||||
<span class="mx-2 text-gray-500 dark:text-gray-400">/</span>
|
||||
</template>
|
||||
</UBreadcrumb>
|
||||
</template>
|
||||
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Team',
|
||||
icon: 'i-heroicons-users'
|
||||
}, {
|
||||
label: 'Invite users',
|
||||
icon: 'i-heroicons-user-plus',
|
||||
children: [{
|
||||
label: 'Invite by email',
|
||||
icon: 'i-heroicons-paper-airplane'
|
||||
}, {
|
||||
label: 'Invite by link',
|
||||
icon: 'i-heroicons-link'
|
||||
}]
|
||||
}, {
|
||||
label: 'New team',
|
||||
icon: 'i-heroicons-plus'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UButtonGroup>
|
||||
<UButton color="gray" variant="subtle" label="Settings" />
|
||||
|
||||
<UDropdownMenu :items="items">
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="outline"
|
||||
icon="i-heroicons-chevron-down-20-solid"
|
||||
/>
|
||||
</UDropdownMenu>
|
||||
</UButtonGroup>
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<UButtonGroup>
|
||||
<UInput color="gray" variant="outline" placeholder="Enter token" />
|
||||
|
||||
<UTooltip text="Copy to clipboard">
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
icon="i-heroicons-clipboard-document"
|
||||
/>
|
||||
</UTooltip>
|
||||
</UButtonGroup>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
async function onClick() {
|
||||
return new Promise<void>(res => setTimeout(res, 1000))
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UButton loading-auto @click="onClick">
|
||||
Button
|
||||
</UButton>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const state = reactive({ fullName: '' })
|
||||
|
||||
async function onSubmit() {
|
||||
return new Promise<void>(res => setTimeout(res, 1000))
|
||||
}
|
||||
|
||||
async function validate(data: Partial<typeof state>) {
|
||||
if (!data.fullName?.length) return [{ name: 'fullName', message: 'Required' }]
|
||||
return []
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :state="state" :validate="validate" @submit="onSubmit">
|
||||
<UFormField name="fullName" label="Full name">
|
||||
<UInput v-model="state.fullName" />
|
||||
</UFormField>
|
||||
<UButton type="submit" class="mt-2" loading-auto>
|
||||
Submit
|
||||
</UButton>
|
||||
</UForm>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const statuses = ['online', 'away', 'busy', 'offline']
|
||||
const status = ref(statuses[0])
|
||||
|
||||
const color = computed(() => status.value ? { online: 'green', away: 'amber', busy: 'red', offline: 'gray' }[status.value] as any : 'online')
|
||||
|
||||
const show = computed(() => status.value !== 'offline')
|
||||
|
||||
// Note: This is for demonstration purposes only. Don't do this at home.
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
if (status.value) {
|
||||
status.value = statuses[(statuses.indexOf(status.value) + 1) % statuses.length]
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UChip :color="color" :show="show" inset>
|
||||
<UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" />
|
||||
</UChip>
|
||||
</template>
|
||||
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<UCollapsible class="w-48">
|
||||
<UButton
|
||||
class="group"
|
||||
label="Open"
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
trailing-icon="i-heroicons-chevron-down-20-solid"
|
||||
:ui="{
|
||||
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
|
||||
}"
|
||||
block
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<Placeholder class="h-48" />
|
||||
</template>
|
||||
</UCollapsible>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(true)
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCollapsible v-model:open="open" class="w-48">
|
||||
<UButton
|
||||
label="Open"
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
trailing-icon="i-heroicons-chevron-down-20-solid"
|
||||
block
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<Placeholder class="h-48" />
|
||||
</template>
|
||||
</UCollapsible>
|
||||
</template>
|
||||
@@ -0,0 +1,48 @@
|
||||
<script setup lang="ts">
|
||||
const groups = [{
|
||||
id: 'settings',
|
||||
items: [{
|
||||
label: 'Profile',
|
||||
icon: 'i-heroicons-user',
|
||||
kbds: ['meta', 'P']
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-heroicons-credit-card',
|
||||
kbds: ['meta', 'B'],
|
||||
slot: 'billing'
|
||||
}, {
|
||||
label: 'Notifications',
|
||||
icon: 'i-heroicons-bell'
|
||||
}, {
|
||||
label: 'Security',
|
||||
icon: 'i-heroicons-lock-closed'
|
||||
}]
|
||||
}, {
|
||||
id: 'users',
|
||||
label: 'Users',
|
||||
slot: 'users',
|
||||
items: [
|
||||
{ id: 1, label: 'Durward Reynolds' },
|
||||
{ id: 2, label: 'Kenton Towne' },
|
||||
{ id: 3, label: 'Therese Wunsch' },
|
||||
{ id: 4, label: 'Benedict Kessler' },
|
||||
{ id: 5, label: 'Katelyn Rohan' }
|
||||
]
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette :groups="groups" class="flex-1 h-80">
|
||||
<template #users-leading="{ index }">
|
||||
<UAvatar :src="`https://i.pravatar.cc/120?img=${index}`" size="2xs" />
|
||||
</template>
|
||||
|
||||
<template #billing-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<UBadge variant="subtle" size="sm">
|
||||
50% off
|
||||
</UBadge>
|
||||
</template>
|
||||
</UCommandPalette>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'users',
|
||||
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
|
||||
items: users.value || []
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
:groups="groups"
|
||||
class="flex-1 h-80"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('')
|
||||
const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
params: { q: searchTermDebounced },
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'users',
|
||||
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
|
||||
items: users.value || [],
|
||||
filter: false
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
:groups="groups"
|
||||
class="flex-1 h-80"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({ id: user.id, label: user.name, suffix: user.email, avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` } })) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
:groups="[{ id: 'users', items: users || [] }]"
|
||||
:fuse="{ fuseOptions: { includeMatches: true } }"
|
||||
class="flex-1 h-80"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
const users = [
|
||||
{ id: 1, label: 'Durward Reynolds' },
|
||||
{ id: 2, label: 'Kenton Towne' },
|
||||
{ id: 3, label: 'Therese Wunsch' },
|
||||
{ id: 4, label: 'Benedict Kessler' },
|
||||
{ id: 5, label: 'Katelyn Rohan' }
|
||||
]
|
||||
|
||||
const selected = ref(users[0])
|
||||
|
||||
function onSelect(item: any) {
|
||||
console.log(item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
v-model="selected"
|
||||
:groups="[{ id: 'users', items: users }]"
|
||||
class="flex-1"
|
||||
@update:model-value="onSelect"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
const users = [
|
||||
{ id: 1, label: 'Durward Reynolds' },
|
||||
{ id: 2, label: 'Kenton Towne' },
|
||||
{ id: 3, label: 'Therese Wunsch' },
|
||||
{ id: 4, label: 'Benedict Kessler' },
|
||||
{ id: 5, label: 'Katelyn Rohan' }
|
||||
]
|
||||
|
||||
const selected = ref([users[0], users[1]])
|
||||
|
||||
function onSelect(items: any) {
|
||||
console.log(items)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
v-model="selected"
|
||||
multiple
|
||||
:groups="[{ id: 'users', items: users }]"
|
||||
class="flex-1"
|
||||
@update:model-value="onSelect"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
|
||||
const users = [
|
||||
{ id: 1, label: 'Durward Reynolds' },
|
||||
{ id: 2, label: 'Kenton Towne' },
|
||||
{ id: 3, label: 'Therese Wunsch' },
|
||||
{ id: 4, label: 'Benedict Kessler' },
|
||||
{ id: 5, label: 'Katelyn Rohan' }
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal v-model:open="open">
|
||||
<UButton
|
||||
label="Search users..."
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<UCommandPalette
|
||||
close
|
||||
:groups="[{ id: 'users', items: users }]"
|
||||
@update:open="open = $event"
|
||||
/>
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
id: '/',
|
||||
label: 'Introduction',
|
||||
level: 1
|
||||
}, {
|
||||
id: '/getting-started#whats-new-in-v3',
|
||||
label: 'What\'s new in v3?',
|
||||
level: 2
|
||||
}, {
|
||||
id: '/getting-started#radix-vue-3',
|
||||
label: 'Radix Vue',
|
||||
level: 3
|
||||
}, {
|
||||
id: '/getting-started#tailwind-css-v4',
|
||||
label: 'Tailwind CSS v4',
|
||||
level: 3
|
||||
}, {
|
||||
id: '/getting-started#tailwind-variants',
|
||||
label: 'Tailwind Variants',
|
||||
level: 3
|
||||
}, {
|
||||
id: '/getting-started/installation',
|
||||
label: 'Installation',
|
||||
level: 1
|
||||
}]
|
||||
|
||||
function postFilter(searchTerm: string, items: any[]) {
|
||||
// Filter only first level items if no searchTerm
|
||||
if (!searchTerm) {
|
||||
return items?.filter(item => item.level === 1)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette :groups="[{ id: 'files', items, postFilter }]" class="flex-1" />
|
||||
</template>
|
||||
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
const users = [
|
||||
{ id: 1, label: 'Durward Reynolds' },
|
||||
{ id: 2, label: 'Kenton Towne' },
|
||||
{ id: 3, label: 'Therese Wunsch' },
|
||||
{ id: 4, label: 'Benedict Kessler' },
|
||||
{ id: 5, label: 'Katelyn Rohan' }
|
||||
]
|
||||
|
||||
const searchTerm = ref('Th')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCommandPalette
|
||||
v-model:search-term="searchTerm"
|
||||
:groups="[{ id: 'users', items: users }]"
|
||||
class="flex-1"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
const loading = ref(true)
|
||||
|
||||
const items = [{
|
||||
label: 'Refresh the Page',
|
||||
slot: 'refresh'
|
||||
}, {
|
||||
label: 'Clear Cookies and Refresh'
|
||||
}, {
|
||||
label: 'Clear Cache and Refresh'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" class="w-48">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-gray-300 dark:border-gray-700 text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
|
||||
<template #refresh-label>
|
||||
{{ loading ? 'Refreshing...' : 'Refresh the Page' }}
|
||||
</template>
|
||||
|
||||
<template #refresh-trailing>
|
||||
<UIcon v-if="loading" name="i-heroicons-arrow-path-20-solid" class="shrink-0 size-5 text-primary-500 dark:text-primary-400 animate-spin" />
|
||||
</template>
|
||||
</UContextMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/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}` } })) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'users',
|
||||
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
|
||||
items: users.value || [],
|
||||
filter: false
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDrawer>
|
||||
<UButton
|
||||
label="Search users..."
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<UCommandPalette
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
:groups="groups"
|
||||
placeholder="Search users..."
|
||||
class="h-96 border-t border-gray-200 dark:border-gray-800"
|
||||
/>
|
||||
</template>
|
||||
</UDrawer>
|
||||
</template>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDrawer v-model:open="open" title="Drawer with footer" description="This is useful when you want a form in a Drawer." :ui="{ container: 'max-w-xl mx-auto' }">
|
||||
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-48" />
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<UButton label="Submit" color="gray" class="justify-center" />
|
||||
<UButton label="Cancel" color="gray" variant="outline" class="justify-center" @click="open = false" />
|
||||
</template>
|
||||
</UDrawer>
|
||||
</template>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDrawer v-model:open="open">
|
||||
<UButton label="Open" color="gray" variant="subtle" trailing-icon="i-heroicons-chevron-up-20-solid" />
|
||||
|
||||
<template #content>
|
||||
<Placeholder class="h-48 m-4" />
|
||||
</template>
|
||||
</UDrawer>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const items = [{
|
||||
label: 'Profile',
|
||||
icon: 'i-heroicons-user',
|
||||
slot: 'profile'
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-heroicons-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-heroicons-cog'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDropdownMenu :items="items" class="w-48">
|
||||
<UButton label="Open" color="gray" variant="outline" icon="i-heroicons-bars-3" />
|
||||
|
||||
<template #profile-trailing>
|
||||
<UIcon name="i-heroicons-check-badge" class="shrink-0 size-5 text-primary-500 dark:text-primary-400" />
|
||||
</template>
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
|
||||
const items = [{
|
||||
label: 'Profile',
|
||||
icon: 'i-heroicons-user'
|
||||
}, {
|
||||
label: 'Billing',
|
||||
icon: 'i-heroicons-credit-card'
|
||||
}, {
|
||||
label: 'Settings',
|
||||
icon: 'i-heroicons-cog'
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDropdownMenu v-model:open="open" :items="items" class="w-48">
|
||||
<UButton label="Open" color="gray" variant="outline" icon="i-heroicons-bars-3" />
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
@@ -8,26 +8,27 @@ const state = reactive({
|
||||
|
||||
const validate = (state: any): FormError[] => {
|
||||
const errors = []
|
||||
if (!state.email) errors.push({ path: 'email', message: 'Required' })
|
||||
if (!state.password) errors.push({ path: 'password', message: 'Required' })
|
||||
if (!state.email) errors.push({ name: 'email', message: 'Required' })
|
||||
if (!state.password) errors.push({ name: 'password', message: 'Required' })
|
||||
return errors
|
||||
}
|
||||
|
||||
async function onSubmit (event: FormSubmitEvent<any>) {
|
||||
// Do something with data
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :validate="validate" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UFormGroup label="Password" name="password">
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
@@ -0,0 +1,115 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent, Form } from '@nuxt/ui'
|
||||
|
||||
const schema = z.object({
|
||||
input: z.string().min(10),
|
||||
inputMenu: z.any().refine(option => option?.value === 'option-2', {
|
||||
message: 'Select Option 2'
|
||||
}),
|
||||
inputMenuMultiple: z.any().refine(values => !!values?.find((option: any) => option.value === 'option-2'), {
|
||||
message: 'Include Option 2'
|
||||
}),
|
||||
textarea: z.string().min(10),
|
||||
select: z.string().refine(value => value === 'option-2', {
|
||||
message: 'Select Option 2'
|
||||
}),
|
||||
selectMenu: z.any().refine(option => option?.value === 'option-2', {
|
||||
message: 'Select Option 2'
|
||||
}),
|
||||
selectMenuMultiple: z.any().refine(values => !!values?.find((option: any) => option.value === 'option-2'), {
|
||||
message: 'Include Option 2'
|
||||
}),
|
||||
switch: z.boolean().refine(value => value === true, {
|
||||
message: 'Toggle me'
|
||||
}),
|
||||
checkbox: z.boolean().refine(value => value === true, {
|
||||
message: 'Check me'
|
||||
}),
|
||||
radioGroup: z.string().refine(value => value === 'option-2', {
|
||||
message: 'Select Option 2'
|
||||
}),
|
||||
slider: z.number().max(20, { message: 'Must be less than 20' })
|
||||
})
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const state = reactive<Partial<Schema>>({})
|
||||
const form = ref<Form<Schema>>()
|
||||
|
||||
const items = [
|
||||
{ label: 'Option 1', value: 'option-1' },
|
||||
{ label: 'Option 2', value: 'option-2' },
|
||||
{ label: 'Option 3', value: 'option-3' }
|
||||
]
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm ref="form" :state="state" :schema="schema" @submit="onSubmit">
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<UFormField label="Input" name="input">
|
||||
<UInput v-model="state.input" placeholder="john@lennon.com" class="w-40" />
|
||||
</UFormField>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<UFormField name="switch">
|
||||
<USwitch v-model="state.switch" label="Switch me" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="checkbox">
|
||||
<UCheckbox v-model="state.checkbox" label="Check me" />
|
||||
</UFormField>
|
||||
</div>
|
||||
|
||||
<UFormField name="slider" label="Slider">
|
||||
<USlider v-model="state.slider" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="select" label="Select">
|
||||
<USelect v-model="state.select" :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="selectMenu" label="Select Menu">
|
||||
<USelectMenu v-model="state.selectMenu" :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="selectMenuMultiple" label="Select Menu (Multiple)">
|
||||
<USelectMenu v-model="state.selectMenuMultiple" multiple :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="inputMenu" label="Input Menu">
|
||||
<UInputMenu v-model="state.inputMenu" :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="inputMenuMultiple" label="Input Menu (Multiple)">
|
||||
<UInputMenu v-model="state.inputMenuMultiple" multiple :items="items" />
|
||||
</UFormField>
|
||||
|
||||
<span />
|
||||
|
||||
<UFormField label="Textarea" name="textarea">
|
||||
<UTextarea v-model="state.textarea" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField name="radioGroup">
|
||||
<URadioGroup v-model="state.radioGroup" legend="Radio group" :items="items" />
|
||||
</UFormField>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-8">
|
||||
<UButton color="gray" type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
|
||||
<UButton color="gray" variant="outline" @click="form?.clear()">
|
||||
Clear
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</template>
|
||||
@@ -14,21 +14,22 @@ const state = reactive({
|
||||
password: undefined
|
||||
})
|
||||
|
||||
async function onSubmit (event: FormSubmitEvent<any>) {
|
||||
// Do something with event.data
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UFormGroup label="Password" name="password">
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
@@ -0,0 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().min(2),
|
||||
news: z.boolean()
|
||||
})
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const nestedSchema = z.object({
|
||||
email: z.string().email()
|
||||
})
|
||||
|
||||
type NestedSchema = z.output<typeof nestedSchema>
|
||||
|
||||
const state = reactive<Partial<Schema & NestedSchema>>({ })
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm
|
||||
:state="state"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<UFormField label="Name" name="name">
|
||||
<UInput v-model="state.name" placeholder="John Lennon" />
|
||||
</UFormField>
|
||||
|
||||
<div>
|
||||
<UCheckbox v-model="state.news" name="news" label="Register to our newsletter" />
|
||||
</div>
|
||||
|
||||
<UForm v-if="state.news" :state="state" :schema="nestedSchema">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" placeholder="john@lennon.com" />
|
||||
</UFormField>
|
||||
</UForm>
|
||||
|
||||
<div>
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</template>
|
||||
@@ -0,0 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const schema = z.object({
|
||||
customer: z.string().min(2)
|
||||
})
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const itemSchema = z.object({
|
||||
description: z.string().min(1),
|
||||
price: z.number().min(0)
|
||||
})
|
||||
|
||||
type ItemSchema = z.output<typeof itemSchema>
|
||||
|
||||
const state = reactive<Partial<Schema & { items: Partial<ItemSchema>[] }>>({
|
||||
items: [{}]
|
||||
})
|
||||
|
||||
function addItem() {
|
||||
if (!state.items) {
|
||||
state.items = []
|
||||
}
|
||||
state.items.push({})
|
||||
}
|
||||
|
||||
function removeItem() {
|
||||
if (state.items) {
|
||||
state.items.pop()
|
||||
}
|
||||
}
|
||||
const formItemRef = ref()
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm
|
||||
ref="formItemRef"
|
||||
:state="state"
|
||||
:schema="schema"
|
||||
class="gap-4 flex flex-col w-60"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<UFormField label="Customer" name="customer">
|
||||
<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">
|
||||
<UFormField :label="!count ? 'Description' : undefined" name="description">
|
||||
<UInput v-model="item.description" />
|
||||
</UFormField>
|
||||
<UFormField :label="!count ? 'Price' : undefined" name="price" class="w-20">
|
||||
<UInput v-model="item.price" type="number" />
|
||||
</UFormField>
|
||||
</UForm>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<UButton color="gray" variant="subtle" size="sm" @click="addItem()">
|
||||
Add Item
|
||||
</UButton>
|
||||
|
||||
<UButton color="gray" variant="ghost" size="sm" @click="removeItem()">
|
||||
Remove Item
|
||||
</UButton>
|
||||
</div>
|
||||
<div>
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</div>
|
||||
</UForm>
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormError, FormErrorEvent, FormSubmitEvent } from '#ui/types'
|
||||
|
||||
const state = reactive({
|
||||
email: undefined,
|
||||
password: undefined
|
||||
})
|
||||
|
||||
const validate = (state: any): FormError[] => {
|
||||
const errors = []
|
||||
if (!state.email) errors.push({ name: 'email', message: 'Required' })
|
||||
if (!state.password) errors.push({ name: 'password', message: 'Required' })
|
||||
return errors
|
||||
}
|
||||
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<any>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
|
||||
async function onError(event: FormErrorEvent) {
|
||||
if (event?.errors?.[0]?.id) {
|
||||
const element = document.getElementById(event.errors[0].id)
|
||||
element?.focus()
|
||||
element?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :validate="validate" :state="state" class="space-y-4" @submit="onSubmit" @error="onError">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormField>
|
||||
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
</UButton>
|
||||
</UForm>
|
||||
</template>
|
||||
@@ -14,21 +14,22 @@ const state = reactive({
|
||||
password: ''
|
||||
})
|
||||
|
||||
async function onSubmit (event: FormSubmitEvent<Schema>) {
|
||||
// Do something with event.data
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="v.safeParser(schema)" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UFormGroup label="Password" name="password">
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
@@ -16,21 +16,22 @@ const state = reactive({
|
||||
password: undefined
|
||||
})
|
||||
|
||||
async function onSubmit (event: FormSubmitEvent<Schema>) {
|
||||
// Do something with event.data
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UFormGroup label="Password" name="password">
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
@@ -9,26 +9,27 @@ const schema = z.object({
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const state = reactive({
|
||||
const state = reactive<Partial<Schema>>({
|
||||
email: undefined,
|
||||
password: undefined
|
||||
})
|
||||
|
||||
async function onSubmit (event: FormSubmitEvent<Schema>) {
|
||||
// Do something with data
|
||||
const toast = useToast()
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'green' })
|
||||
console.log(event.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UFormField label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UFormGroup label="Password" name="password">
|
||||
<UFormField label="Password" name="password">
|
||||
<UInput v-model="state.password" type="password" />
|
||||
</UFormGroup>
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit">
|
||||
Submit
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
transform: (data: { id: number, name: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="users || []"
|
||||
:loading="status === 'pending'"
|
||||
icon="i-heroicons-user"
|
||||
placeholder="Select user"
|
||||
class="w-48"
|
||||
>
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.itemLeadingAvatarSize()"
|
||||
:class="ui.itemLeadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('')
|
||||
const searchTermDebounced = refDebounced(searchTerm, 200)
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
params: { q: searchTermDebounced },
|
||||
transform: (data: { id: number, name: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
v-model:search-term="searchTerm"
|
||||
:items="users || []"
|
||||
:loading="status === 'pending'"
|
||||
:filter="false"
|
||||
icon="i-heroicons-user"
|
||||
placeholder="Select user"
|
||||
class="w-48"
|
||||
>
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.itemLeadingAvatarSize()"
|
||||
:class="ui.itemLeadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
|
||||
transform: (data: { id: number, name: string, email: string }[]) => {
|
||||
return data?.map(user => ({
|
||||
label: user.name,
|
||||
email: user.email,
|
||||
value: String(user.id),
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
:items="users || []"
|
||||
:loading="status === 'pending'"
|
||||
:filter="['name', 'email']"
|
||||
icon="i-heroicons-user"
|
||||
placeholder="Select user"
|
||||
class="w-80"
|
||||
>
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.itemLeadingAvatarSize()"
|
||||
:class="ui.itemLeadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-gray-500 dark:text-gray-400">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
|
||||
const selected = ref('Backlog')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
v-model="selected"
|
||||
:items="items"
|
||||
:ui="{
|
||||
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
const items = ref([
|
||||
{
|
||||
label: 'benjamincanac',
|
||||
value: 'benjamincanac',
|
||||
avatar: {
|
||||
src: 'https://github.com/benjamincanac.png',
|
||||
alt: 'benjamincanac'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'romhml',
|
||||
value: 'romhml',
|
||||
avatar: {
|
||||
src: 'https://github.com/romhml.png',
|
||||
alt: 'romhml'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'noook',
|
||||
value: 'noook',
|
||||
avatar: {
|
||||
src: 'https://github.com/noook.png',
|
||||
alt: 'noook'
|
||||
}
|
||||
}
|
||||
])
|
||||
const selected = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu v-model="selected" :items="items" class="w-40">
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UAvatar
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.avatar"
|
||||
:size="ui.itemLeadingAvatarSize()"
|
||||
:class="ui.itemLeadingAvatar()"
|
||||
/>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
const items = ref([
|
||||
{
|
||||
label: 'bug',
|
||||
value: 'bug',
|
||||
chip: {
|
||||
color: 'red' as const
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'enhancement',
|
||||
value: 'enhancement',
|
||||
chip: {
|
||||
color: 'blue' as const
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'feature',
|
||||
value: 'feature',
|
||||
chip: {
|
||||
color: 'violet' as const
|
||||
}
|
||||
}
|
||||
])
|
||||
const selected = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu v-model="selected" :items="items" class="w-40">
|
||||
<template #leading="{ modelValue, ui }">
|
||||
<UChip
|
||||
v-if="modelValue"
|
||||
v-bind="modelValue.chip"
|
||||
inset
|
||||
standalone
|
||||
:size="ui.itemLeadingChipSize()"
|
||||
:class="ui.itemLeadingChip()"
|
||||
/>
|
||||
</template>
|
||||
</UInputMenu>
|
||||
</template>
|
||||
@@ -0,0 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
const items = ref([
|
||||
{
|
||||
label: 'Backlog',
|
||||
value: 'backlog',
|
||||
icon: 'i-heroicons-question-mark-circle'
|
||||
},
|
||||
{
|
||||
label: 'Todo',
|
||||
value: 'todo',
|
||||
icon: 'i-heroicons-plus-circle'
|
||||
},
|
||||
{
|
||||
label: 'In Progress',
|
||||
value: 'in_progress',
|
||||
icon: 'i-heroicons-arrow-up-circle'
|
||||
},
|
||||
{
|
||||
label: 'Done',
|
||||
value: 'done',
|
||||
icon: 'i-heroicons-check-circle'
|
||||
}
|
||||
])
|
||||
const selected = ref(items.value[0])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu v-model="selected" :icon="selected?.icon" :items="items" class="w-40" />
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
|
||||
const selected = ref('Backlog')
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu v-model="selected" v-model:open="open" :items="items" />
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('D')
|
||||
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
|
||||
const selected = ref('Backlog')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu v-model="selected" v-model:search-term="searchTerm" :items="items" />
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
const searchTerm = ref('')
|
||||
|
||||
const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/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}` } })) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
const groups = computed(() => [{
|
||||
id: 'users',
|
||||
label: searchTerm.value ? `Users matching “${searchTerm.value}”...` : 'Users',
|
||||
items: users.value || [],
|
||||
filter: false
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal>
|
||||
<UButton
|
||||
label="Search users..."
|
||||
color="gray"
|
||||
variant="subtle"
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
/>
|
||||
|
||||
<template #content>
|
||||
<UCommandPalette
|
||||
v-model:search-term="searchTerm"
|
||||
:loading="status === 'pending'"
|
||||
:groups="groups"
|
||||
placeholder="Search users..."
|
||||
class="h-96"
|
||||
/>
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
15
docs/app/components/content/examples/modal/ModalExample.vue
Normal file
15
docs/app/components/content/examples/modal/ModalExample.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
const modal = useModal()
|
||||
|
||||
defineProps<{
|
||||
count: number
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal :title="`This modal was opened programmatically ${count} times`">
|
||||
<template #footer>
|
||||
<UButton color="gray" label="Close" @click="modal.close()" />
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal v-model:open="open" title="Modal with footer" description="This is useful when you want a form in a Modal." :ui="{ footer: 'justify-end' }">
|
||||
<UButton label="Open" color="gray" variant="subtle" />
|
||||
|
||||
<template #body>
|
||||
<Placeholder class="h-48" />
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<UButton label="Cancel" color="gray" variant="outline" @click="open = false" />
|
||||
<UButton label="Submit" color="gray" />
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const first = ref(false)
|
||||
const second = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal v-model:open="first" title="First modal" :ui="{ footer: 'justify-end' }">
|
||||
<UButton color="gray" variant="subtle" label="Open" />
|
||||
|
||||
<template #footer>
|
||||
<UButton label="Close" color="gray" variant="outline" @click="first = false" />
|
||||
|
||||
<UModal v-model:open="second" title="Second modal" :ui="{ footer: 'justify-end' }">
|
||||
<UButton label="Open second" color="gray" />
|
||||
|
||||
<template #footer>
|
||||
<UButton label="Close" color="gray" variant="outline" @click="second = false" />
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
const open = ref(false)
|
||||
|
||||
defineShortcuts({
|
||||
o: () => open.value = !open.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal v-model:open="open">
|
||||
<UButton label="Open" color="gray" variant="subtle" />
|
||||
|
||||
<template #content>
|
||||
<Placeholder class="h-48 m-4" />
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user