mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-18 22:11:43 +01:00
Compare commits
235 Commits
issue-1987
...
v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13be8f1c83 | ||
|
|
48f68de4ca | ||
|
|
13bd3f3804 | ||
|
|
65735e787f | ||
|
|
6b971b8e6c | ||
|
|
1598d8fc72 | ||
|
|
2176e30113 | ||
|
|
1f3e9789fe | ||
|
|
b797690483 | ||
|
|
f7303d5c94 | ||
|
|
346031f279 | ||
|
|
dae6d77cf2 | ||
|
|
c1d5bcc1ac | ||
|
|
1bc44f8594 | ||
|
|
9ee68d20fc | ||
|
|
d5f50be354 | ||
|
|
03ab56c9bd | ||
|
|
9985fd5af4 | ||
|
|
fb2a835a78 | ||
|
|
2d5100044b | ||
|
|
7903d2adc2 | ||
|
|
cd9ee1ff99 | ||
|
|
29208f1877 | ||
|
|
f9f505b0c0 | ||
|
|
7361914715 | ||
|
|
88923bb678 | ||
|
|
212154d0d0 | ||
|
|
b9037e166f | ||
|
|
58fc563d63 | ||
|
|
11569bc7e0 | ||
|
|
1934063763 | ||
|
|
b6de20104f | ||
|
|
2971a31242 | ||
|
|
30068da217 | ||
|
|
44734f717e | ||
|
|
77cc1f3670 | ||
|
|
e55a27a503 | ||
|
|
45f5e628ea | ||
|
|
e47bba9a05 | ||
|
|
fcbedd1244 | ||
|
|
3a964d5a4b | ||
|
|
b7c9c83dfa | ||
|
|
43ee099fbe | ||
|
|
4bc9878ef4 | ||
|
|
bb8d7aa48e | ||
|
|
8c727f21d7 | ||
|
|
48fabbcdeb | ||
|
|
c46b952022 | ||
|
|
c0e14d006e | ||
|
|
a58efd23aa | ||
|
|
ec2b51b59e | ||
|
|
e2dc287dbb | ||
|
|
dbe8b34b6e | ||
|
|
091725f940 | ||
|
|
c21fbe5ec6 | ||
|
|
cff1282f30 | ||
|
|
86a7da03b1 | ||
|
|
252189de0a | ||
|
|
4451768415 | ||
|
|
8e67cab77a | ||
|
|
d113c31844 | ||
|
|
18e4b4ff4e | ||
|
|
1c8ec1d857 | ||
|
|
d7872a149c | ||
|
|
9104a4d54d | ||
|
|
0506c0cc6a | ||
|
|
2bef1e26c6 | ||
|
|
02694db29c | ||
|
|
b8a7a47620 | ||
|
|
bd732d3b34 | ||
|
|
93406d26b8 | ||
|
|
b034a5679c | ||
|
|
c7b1fc32ad | ||
|
|
3b0dbfe473 | ||
|
|
1454149c97 | ||
|
|
5af04bad5f | ||
|
|
f242c7243e | ||
|
|
5a864e8d6f | ||
|
|
ee373629d5 | ||
|
|
63b5f2bc2f | ||
|
|
4e96dcca42 | ||
|
|
b131b1168b | ||
|
|
3c849b98a6 | ||
|
|
714e0ff250 | ||
|
|
74c77f9bac | ||
|
|
54fda9eef8 | ||
|
|
c3567a34a4 | ||
|
|
d210d18a2f | ||
|
|
7aeecea599 | ||
|
|
70e889813c | ||
|
|
2b9696f4d3 | ||
|
|
188184b674 | ||
|
|
b0d1da8dc2 | ||
|
|
fec5f3f3ce | ||
|
|
05509b7ed1 | ||
|
|
88b17cd93c | ||
|
|
0eca0fd201 | ||
|
|
420fcb003a | ||
|
|
f607140941 | ||
|
|
40da32588d | ||
|
|
264373b499 | ||
|
|
bb70218568 | ||
|
|
402f508e7d | ||
|
|
0d69747c9d | ||
|
|
760eb467be | ||
|
|
b830f63c89 | ||
|
|
71dac5e5b0 | ||
|
|
7b81bfa1ae | ||
|
|
bf1c9e7c94 | ||
|
|
23d9b51a58 | ||
|
|
2e6ba71e89 | ||
|
|
ea4007c62d | ||
|
|
69d6997210 | ||
|
|
6565472570 | ||
|
|
ee408e522e | ||
|
|
461e6173a9 | ||
|
|
b824f0682e | ||
|
|
7ce6af4870 | ||
|
|
b4cc9a5ab4 | ||
|
|
06eceff68b | ||
|
|
40f3e3b486 | ||
|
|
a5458765dc | ||
|
|
ac574b239b | ||
|
|
feb716c941 | ||
|
|
15da5cf71e | ||
|
|
125a28190b | ||
|
|
569fa7619b | ||
|
|
0ff2448655 | ||
|
|
a6c3daa363 | ||
|
|
e16eeee8c1 | ||
|
|
53ac62eae5 | ||
|
|
9c36d37b84 | ||
|
|
0462edb84e | ||
|
|
91e77bb09c | ||
|
|
84e35d1a79 | ||
|
|
28f29e98b8 | ||
|
|
81d7ca0cd1 | ||
|
|
89d3766835 | ||
|
|
9104213d35 | ||
|
|
d699558e38 | ||
|
|
7cbc3913d9 | ||
|
|
d2ceeadae7 | ||
|
|
c7f64b64c7 | ||
|
|
72ab47e77d | ||
|
|
5b187d6fbd | ||
|
|
f9e61fc422 | ||
|
|
1291e95e1c | ||
|
|
f943203770 | ||
|
|
f2d387622a | ||
|
|
b02dc4d5b7 | ||
|
|
6dddadc370 | ||
|
|
d89ecce472 | ||
|
|
efb74668bd | ||
|
|
e065734d58 | ||
|
|
0c5bea5f11 | ||
|
|
f6d4dd3b88 | ||
|
|
d9d4f1915a | ||
|
|
c70d29702e | ||
|
|
a0d8935f64 | ||
|
|
04aefcf81f | ||
|
|
e68b9795be | ||
|
|
b8c8718560 | ||
|
|
2a33a8171d | ||
|
|
23cfc046e7 | ||
|
|
e68cb53ab6 | ||
|
|
109b857472 | ||
|
|
ea15e21cdc | ||
|
|
b7153cd879 | ||
|
|
5047d448ed | ||
|
|
a0fee0fa73 | ||
|
|
b762d29220 | ||
|
|
98c19be71a | ||
|
|
8cf9f27d53 | ||
|
|
c0455c831f | ||
|
|
0360ea7a3c | ||
|
|
711539f3ce | ||
|
|
80d6d89467 | ||
|
|
d573fb636f | ||
|
|
1d08d319a7 | ||
|
|
b654c93e93 | ||
|
|
b7e04db645 | ||
|
|
e6034a2765 | ||
|
|
a8c38224c6 | ||
|
|
a9ef6406ea | ||
|
|
96e846ddee | ||
|
|
16dbc1b536 | ||
|
|
c6b2ae45e5 | ||
|
|
547c657ee7 | ||
|
|
b16b434041 | ||
|
|
fb12323304 | ||
|
|
0a404615ff | ||
|
|
cbf0f22efd | ||
|
|
4cde571e38 | ||
|
|
023497d144 | ||
|
|
56d4ca3b74 | ||
|
|
11b8c3d9db | ||
|
|
419a24f703 | ||
|
|
854bb81295 | ||
|
|
bf8e3954a4 | ||
|
|
637ec4d27b | ||
|
|
f3632ddee5 | ||
|
|
dbd2aed20b | ||
|
|
51c8b8e3e5 | ||
|
|
588a908358 | ||
|
|
d692a81b1e | ||
|
|
ec98d415b4 | ||
|
|
c80d2e6c12 | ||
|
|
ce61a2b6db | ||
|
|
eee5bb9939 | ||
|
|
d3804157ec | ||
|
|
03e24f4583 | ||
|
|
d0e626c551 | ||
|
|
670d8bfbac | ||
|
|
64b703df8d | ||
|
|
976b03f241 | ||
|
|
35e3b8c720 | ||
|
|
07ef771b17 | ||
|
|
5c75b5c490 | ||
|
|
53df9d9a8c | ||
|
|
0d1a76e3c6 | ||
|
|
b2ed4662af | ||
|
|
423c48879d | ||
|
|
acecff40ec | ||
|
|
1fd5fac295 | ||
|
|
b23f2decfc | ||
|
|
7154254ac2 | ||
|
|
49f85d55c5 | ||
|
|
97037864b3 | ||
|
|
0abccabc26 | ||
|
|
ac323c4ccc | ||
|
|
d4e408cfd8 | ||
|
|
f3bf69c233 | ||
|
|
d6daf466ac | ||
|
|
6e66990372 | ||
|
|
56e28d80db |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @benjamincanac
|
||||||
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -5,7 +5,7 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
Before reporting a bug, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: env
|
id: env
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
11
.github/ISSUE_TEMPLATE/bug-v3.yml
vendored
11
.github/ISSUE_TEMPLATE/bug-v3.yml
vendored
@@ -29,11 +29,20 @@ body:
|
|||||||
- Build Modules: `-`
|
- Build Modules: `-`
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: package
|
||||||
|
attributes:
|
||||||
|
label: Is this bug related to Nuxt or Vue?
|
||||||
|
options:
|
||||||
|
- Nuxt
|
||||||
|
- Vue
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: Version
|
label: Version
|
||||||
placeholder: v3.0.0-alpha.5
|
placeholder: v3.0.0-alpha.x
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
4
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
4
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -5,14 +5,14 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
Before requesting a feature, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: For what version of Nuxt UI are you suggesting this?
|
label: For what version of Nuxt UI are you suggesting this?
|
||||||
options:
|
options:
|
||||||
- v2.x
|
- v2.x
|
||||||
- v3-alpha
|
- v3.0.0-alpha.x
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
4
.github/ISSUE_TEMPLATE/question.yml
vendored
4
.github/ISSUE_TEMPLATE/question.yml
vendored
@@ -5,14 +5,14 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Before asking a question, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
Before asking a question, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: For what version of Nuxt UI are you asking this question?
|
label: For what version of Nuxt UI are you asking this question?
|
||||||
options:
|
options:
|
||||||
- v2.x
|
- v2.x
|
||||||
- v3-alpha
|
- v3.0.0-alpha.x
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
name: ci-dev
|
name: module
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- v2
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- v2
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
build:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||||
node: [20]
|
node: [22]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||||
@@ -37,16 +37,6 @@ jobs:
|
|||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Filter changes
|
|
||||||
uses: dorny/paths-filter@v3
|
|
||||||
id: changes
|
|
||||||
with:
|
|
||||||
filters: |
|
|
||||||
src:
|
|
||||||
- 'src/**'
|
|
||||||
- 'package.json'
|
|
||||||
- 'pnpm-lock.yaml'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
@@ -65,8 +55,5 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm run test run
|
run: pnpm run test run
|
||||||
|
|
||||||
- name: Release Edge
|
- name: Publish
|
||||||
if: github.event_name == 'push' && steps.changes.outputs.src == 'true'
|
run: pnpx pkg-pr-new publish --compact --no-template --pnpm
|
||||||
run: ./scripts/release-edge.sh
|
|
||||||
env:
|
|
||||||
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
name: ci-main
|
name: release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
tags:
|
||||||
- main
|
- 'v2*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
publish:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||||
node: [20]
|
node: [22]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||||
@@ -48,14 +48,7 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm run test run
|
run: pnpm run test run
|
||||||
|
|
||||||
- name: Version Check
|
- name: Publish
|
||||||
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
|
run: ./scripts/release.sh
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||||
23
.github/workflows/stale.yml
vendored
23
.github/workflows/stale.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
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
|
|
||||||
80
CHANGELOG.md
80
CHANGELOG.md
@@ -1,5 +1,85 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.22.1](https://github.com/nuxt/ui/compare/v2.22.0...v2.22.1) (2025-07-16)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Badge/Button:** support numeric zero as visible label ([#4116](https://github.com/nuxt/ui/issues/4116)) ([2971a31](https://github.com/nuxt/ui/commit/2971a3124299e927ddb506bb0fc61b906aa0cfeb))
|
||||||
|
|
||||||
|
## [2.22.0](https://github.com/nuxt/ui/compare/v2.21.1...v2.22.0) (2025-04-22)
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* **Form:** drop explicit support for `zod` and `valibot` (#3618)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Link:** properly pick all `aria-*` & `data-*` attrs ([2bef1e2](https://github.com/nuxt/ui/commit/2bef1e26c6dfd5ee81b11f6da76e257861fc0bef)), closes [#3007](https://github.com/nuxt/ui/issues/3007)
|
||||||
|
* **Table:** checkbox still emit `[@select](https://github.com/select)` event ([#3269](https://github.com/nuxt/ui/issues/3269)) ([c0e14d0](https://github.com/nuxt/ui/commit/c0e14d006ea39965e805adbf9698f5cb95e7c965))
|
||||||
|
* **Table:** remove type annotation in template ([4e96dcc](https://github.com/nuxt/ui/commit/4e96dcca4213bbb56f1dd465ad7d47374e83bc9a)), closes [#3146](https://github.com/nuxt/ui/issues/3146)
|
||||||
|
|
||||||
|
### Code Refactoring
|
||||||
|
|
||||||
|
* **Form:** drop explicit support for `zod` and `valibot` ([#3618](https://github.com/nuxt/ui/issues/3618)) ([ee37362](https://github.com/nuxt/ui/commit/ee373629d5a9800921301dcbab309f884eaf83fb))
|
||||||
|
|
||||||
|
## [2.21.1](https://github.com/nuxt/ui/compare/v2.21.0...v2.21.1) (2025-03-08)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Form:** add standard schema support ([#2880](https://github.com/nuxt/ui/issues/2880)) ([9c36d37](https://github.com/nuxt/ui/commit/9c36d37b847468d1cbd76eea38ac00cbc22549ca))
|
||||||
|
* **module:** add `colorMode` option ([d2ceead](https://github.com/nuxt/ui/commit/d2ceeadae796254128697d94a3e317234bc2ecda)), closes [#3143](https://github.com/nuxt/ui/issues/3143)
|
||||||
|
* **SelectMenu:** add inputTargetForm prop to handle input validation ([#3107](https://github.com/nuxt/ui/issues/3107)) ([feb716c](https://github.com/nuxt/ui/commit/feb716c941f1e7315009b53861a4dc0c2f233052))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Alert/Notification:** allow description ui override ([125a281](https://github.com/nuxt/ui/commit/125a28190b1a83e2456457e7a4ec618384b2446c)), closes [#2554](https://github.com/nuxt/ui/issues/2554)
|
||||||
|
* **Table:** revert [#2600](https://github.com/nuxt/ui/issues/2600) to fix excessive column data slot re-renders ([#3375](https://github.com/nuxt/ui/issues/3375)) ([23d9b51](https://github.com/nuxt/ui/commit/23d9b51a5861f5d1f32f68a3141a600655a0598a))
|
||||||
|
|
||||||
|
## [2.21.0](https://github.com/nuxt/ui/compare/v2.20.0...v2.21.0) (2025-01-14)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **module:** handle `tailwindMerge` config from `app.config` ([#2902](https://github.com/nuxt/ui/issues/2902)) ([ea15e21](https://github.com/nuxt/ui/commit/ea15e21cdcba00e21302415829113e8c6def8a6e))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Table:** `v-model` causing first column missing ([#2890](https://github.com/nuxt/ui/issues/2890)) ([d573fb6](https://github.com/nuxt/ui/commit/d573fb636f7f749ce95b93c5fb1ae2a053eeeeb0))
|
||||||
|
* **Table:** remove `[@select](https://github.com/select)` event on checkbox ([#3042](https://github.com/nuxt/ui/issues/3042)) ([d9d4f19](https://github.com/nuxt/ui/commit/d9d4f1915aac586ae1abf3ebe67ca9aff65b9be0))
|
||||||
|
* **tailwind:** use mjs template ([#2945](https://github.com/nuxt/ui/issues/2945)) ([8cf9f27](https://github.com/nuxt/ui/commit/8cf9f27d537bad5ffe4e136f52ff71548a451c5f))
|
||||||
|
|
||||||
|
## [2.20.0](https://github.com/nuxt/ui/compare/v2.19.2...v2.20.0) (2024-12-09)
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* **Form:** resolve async validation in yup & issue directly mutate state (#2701)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Accordion:** add `close` event ([#2750](https://github.com/nuxt/ui/issues/2750)) ([419a24f](https://github.com/nuxt/ui/commit/419a24f7034cefda2c6669f3c26742552e500f63))
|
||||||
|
* **Badge:** handle `icon` prop ([#2594](https://github.com/nuxt/ui/issues/2594)) ([0d1a76e](https://github.com/nuxt/ui/commit/0d1a76e3c69e08534abb295b96548e67cfbea00c))
|
||||||
|
* **InputMenu/SelectMenu:** add support for `dot notation` in `by` prop ([#2607](https://github.com/nuxt/ui/issues/2607)) ([53df9d9](https://github.com/nuxt/ui/commit/53df9d9a8cd6850803bdafc7ef6efe4e7404d334))
|
||||||
|
* **Link:** allow partial query match for `activeClass` ([#2663](https://github.com/nuxt/ui/issues/2663)) ([03e24f4](https://github.com/nuxt/ui/commit/03e24f45836bdddd94b30cbaecc2288a78b56b0b))
|
||||||
|
* **Notification:** add `pauseTimeoutOnHover` prop ([#2661](https://github.com/nuxt/ui/issues/2661)) ([11b8c3d](https://github.com/nuxt/ui/commit/11b8c3d9db1ec62b1c3557703c7ab5c99cb42df5))
|
||||||
|
* **Table:** add contextmenu handling to table rows ([#2283](https://github.com/nuxt/ui/issues/2283)) ([c9e6256](https://github.com/nuxt/ui/commit/c9e6256e7f2c06da8bfda13700f56f6994e76eab))
|
||||||
|
* **Table:** add custom `[@select](https://github.com/select):all` event ([#2581](https://github.com/nuxt/ui/issues/2581)) ([ac323c4](https://github.com/nuxt/ui/commit/ac323c4cccd930f2cd8c1f54b325bd509acd40bf))
|
||||||
|
* **Table:** allow dynamically render `checkbox` ([#2549](https://github.com/nuxt/ui/issues/2549)) ([d6daf46](https://github.com/nuxt/ui/commit/d6daf466ace42b828151c45b18cd47179e85d66d))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **AvatarGroup/ButtonGroup/MeterGroup:** allow deeply partial `ui` config ([#2542](https://github.com/nuxt/ui/issues/2542)) ([bf58086](https://github.com/nuxt/ui/commit/bf580863af11d6a1a4c6c6774b44ec37b082e933))
|
||||||
|
* **Carousel:** wrong `ui` type with `strategy` ([07ef771](https://github.com/nuxt/ui/commit/07ef771b17c72e275508a273371454a5e8a62257))
|
||||||
|
* **components:** replace `as const` with correct type in config ([#2652](https://github.com/nuxt/ui/issues/2652)) ([51c8b8e](https://github.com/nuxt/ui/commit/51c8b8e3e59d7eceff72625650a199fcf7c6feca))
|
||||||
|
* **date-picker:** undefined `dayIndex` ([#2545](https://github.com/nuxt/ui/issues/2545)) ([ce955d2](https://github.com/nuxt/ui/commit/ce955d24f1dfd222e87ce88428c0612c3f13cd50))
|
||||||
|
* **Form:** resolve async validation in yup & issue directly mutate state ([#2701](https://github.com/nuxt/ui/issues/2701)) ([f3632dd](https://github.com/nuxt/ui/commit/f3632ddee511f0fccb24d4fc37403421e84ffdae))
|
||||||
|
* **Form:** use parsed value from `joi` instead of original state ([#2587](https://github.com/nuxt/ui/issues/2587)) ([acecff4](https://github.com/nuxt/ui/commit/acecff40ec0156e45b4934c5d10c4dfa7c135f8e))
|
||||||
|
* **InputMenu/SelectMenu:** use `by` prop to compare objects & support dot notation in `value-attribute` ([#2566](https://github.com/nuxt/ui/issues/2566)) ([7154254](https://github.com/nuxt/ui/commit/7154254ac22830f651ec200f7f3af2f5577f2de0))
|
||||||
|
* **Link:** `exactQuery` prop type ([#2781](https://github.com/nuxt/ui/issues/2781)) ([4cde571](https://github.com/nuxt/ui/commit/4cde571e387775a9b12759f6f8c99117c84cbcff))
|
||||||
|
* **Notification:** element renders even when no `notification` is present ([#2561](https://github.com/nuxt/ui/issues/2561)) ([d4e408c](https://github.com/nuxt/ui/commit/d4e408cfd8e2ef26021519f2f30f57e9120e1939))
|
||||||
|
* **Table:** data outdated when rows change ([#2600](https://github.com/nuxt/ui/issues/2600)) ([b23f2de](https://github.com/nuxt/ui/commit/b23f2decfc9607555a315d0d087d0a042f03a938))
|
||||||
|
* **Table:** missing type on props `loadingState` ([#2551](https://github.com/nuxt/ui/issues/2551)) ([6e66990](https://github.com/nuxt/ui/commit/6e66990372ef6bd7c109a64c753d9b50e96a450b))
|
||||||
|
* **Table:** prevent `onClick` while blocking element ([#2592](https://github.com/nuxt/ui/issues/2592)) ([9703786](https://github.com/nuxt/ui/commit/97037864b39749db228fa5f51981f19e4a9c29dd))
|
||||||
|
* **types:** improve `DeepPartial` type for App Config ([#2621](https://github.com/nuxt/ui/issues/2621)) ([976b03f](https://github.com/nuxt/ui/commit/976b03f241ef9626a6338685e43c844a8b3953fd))
|
||||||
|
|
||||||
## [2.19.2](https://github.com/nuxt/ui/compare/v2.19.1...v2.19.2) (2024-11-05)
|
## [2.19.2](https://github.com/nuxt/ui/compare/v2.19.1...v2.19.2) (2024-11-05)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
35
README.md
35
README.md
@@ -1,4 +1,4 @@
|
|||||||
[](https://ui.nuxt.com)
|
[](https://ui2.nuxt.com)
|
||||||
|
|
||||||
# Nuxt UI
|
# Nuxt UI
|
||||||
|
|
||||||
@@ -20,29 +20,34 @@ Its goal is to provide everything related to UI when building a Nuxt app. This i
|
|||||||
- Keyboard shortcuts
|
- Keyboard shortcuts
|
||||||
- Bundled icons
|
- Bundled icons
|
||||||
- Fully typed
|
- Fully typed
|
||||||
- [Figma Kit](https://www.figma.com/community/file/1288455405058138934)
|
- [Figma Kit](https://www.figma.com/community/file/1436401057300493073)
|
||||||
|
|
||||||
Read more on [ui.nuxt.com](https://ui.nuxt.com)
|
Read more on [ui2.nuxt.com](https://ui2.nuxt.com)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx nuxi@latest module add ui
|
# npm
|
||||||
|
npm install @nuxt/ui@2
|
||||||
|
# yarn
|
||||||
|
yarn add @nuxt/ui@2
|
||||||
|
# pnpm
|
||||||
|
pnpm add @nuxt/ui@2
|
||||||
|
# bun
|
||||||
|
bun add @nuxt/ui@2
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want latest updates, please use `@nuxt/ui-edge` in your `package.json`:
|
Next, register the `@nuxt/ui` module in your `nuxt.config.ts`:
|
||||||
|
|
||||||
```json
|
```ts
|
||||||
{
|
export default defineNuxtConfig({
|
||||||
"devDependencies": {
|
modules: ['@nuxt/ui']
|
||||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Visit https://ui.nuxt.com to explore the documentation.
|
Visit https://ui2.nuxt.com to explore the documentation.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
@@ -59,15 +64,15 @@ Visit https://ui.nuxt.com to explore the documentation.
|
|||||||
Thank you for considering contributing to Nuxt UI. Here are a few ways you can get involved:
|
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.
|
- 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.
|
- Suggestions: Have any thoughts to enhance Nuxt UI? We'd love to hear them! Check out the [contribution guide](https://ui2.nuxt.com/getting-started/contributing) to share your suggestions.
|
||||||
|
|
||||||
## Local Development
|
## 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.
|
Follow the docs to [Set up your local development environment](https://ui2.nuxt.com/getting-started/contributing#_2-local-development-setup) and contribute.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under the [MIT license](https://github.com/nuxt/ui/blob/dev/LICENSE.md).
|
Licensed under the [MIT license](https://github.com/nuxt/ui/blob/v2/LICENSE.md).
|
||||||
|
|
||||||
<!-- Badges -->
|
<!-- 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/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ useHead({
|
|||||||
],
|
],
|
||||||
link: [
|
link: [
|
||||||
{ rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' },
|
{ rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' },
|
||||||
{ rel: 'canonical', href: `https://ui.nuxt.com${withoutTrailingSlash(route.path)}` }
|
{ rel: 'canonical', href: `https://ui2.nuxt.com${withoutTrailingSlash(route.path)}` }
|
||||||
],
|
],
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: 'en'
|
lang: 'en'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const id = 'nuxt-ui-banner-2'
|
const id = 'nuxt-ui-banner-4'
|
||||||
const to = 'https://ui3.nuxt.dev'
|
const to = 'https://ui.nuxt.com'
|
||||||
|
|
||||||
const hideBanner = () => {
|
const hideBanner = () => {
|
||||||
localStorage.setItem(id, 'true')
|
localStorage.setItem(id, 'true')
|
||||||
@@ -30,7 +30,6 @@ if (import.meta.server) {
|
|||||||
:to="to"
|
:to="to"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="focus:outline-none"
|
class="focus:outline-none"
|
||||||
aria-label="Nuxt UI Pro pricing"
|
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span class="absolute inset-0 " aria-hidden="true" />
|
<span class="absolute inset-0 " aria-hidden="true" />
|
||||||
@@ -40,19 +39,19 @@ if (import.meta.server) {
|
|||||||
<div class="lg:flex-1 hidden lg:flex items-center" />
|
<div class="lg:flex-1 hidden lg:flex items-center" />
|
||||||
|
|
||||||
<p class="text-sm font-medium text-white dark:text-gray-900 truncate">
|
<p class="text-sm font-medium text-white dark:text-gray-900 truncate">
|
||||||
<UIcon name="i-heroicons-rocket-launch" class="w-5 h-5 align-top flex-shrink-0 pointer-events-none mr-2" />
|
<UIcon name="i-lucide-rocket" class="size-5 align-top flex-shrink-0 pointer-events-none mr-1.5" />
|
||||||
<span class="font-semibold">Nuxt UI v3-alpha</span> has been released!
|
<span class="font-bold">Nuxt UI v3</span> is officially released!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<UButton
|
<!-- <UButton
|
||||||
to="https://ui3.nuxt.dev"
|
:to="to"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
label="Try it out"
|
label="Buy now"
|
||||||
color="black"
|
color="black"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
size="2xs"
|
size="2xs"
|
||||||
trailing-icon="i-heroicons-arrow-right-20-solid"
|
trailing-icon="i-heroicons-arrow-right-20-solid"
|
||||||
/>
|
/> -->
|
||||||
|
|
||||||
<div class="flex items-center justify-end lg:flex-1">
|
<div class="flex items-center justify-end lg:flex-1">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const { $ui } = useNuxtApp()
|
|||||||
const links = [{
|
const links = [{
|
||||||
icon: 'i-simple-icons-figma',
|
icon: 'i-simple-icons-figma',
|
||||||
label: 'Figma Kit',
|
label: 'Figma Kit',
|
||||||
to: 'https://www.figma.com/community/file/1288455405058138934',
|
to: 'https://www.figma.com/community/file/1436401057300493073',
|
||||||
target: '_blank'
|
target: '_blank'
|
||||||
}, {
|
}, {
|
||||||
label: 'Playground',
|
label: 'Playground',
|
||||||
|
|||||||
@@ -10,12 +10,34 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #left>
|
<template #left>
|
||||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-gray-900 dark:text-white min-w-0" aria-label="Nuxt UI">
|
<NuxtLink to="/" class="flex items-end gap-2 text-xl text-gray-900 dark:text-white min-w-0 shrink-0" aria-label="Nuxt UI">
|
||||||
<LogoPro v-if="$route.path.startsWith('/pro')" class="w-auto h-6 shrink-0" />
|
<LogoPro v-if="$route.path.startsWith('/pro')" class="w-auto h-6 shrink-0" />
|
||||||
<Logo v-else class="w-auto h-6 shrink-0" />
|
<Logo v-else class="w-auto h-6 shrink-0" />
|
||||||
|
|
||||||
<UBadge :label="$route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`" variant="subtle" size="xs" class="-mb-[2px] rounded font-semibold truncate hidden sm:inline-flex" />
|
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
||||||
|
<UDropdown
|
||||||
|
:items="[[{ label: $route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`, class: 'text-primary-500 dark:text-primary-400' }, { label: 'v3.x', to: 'https://ui.nuxt.com' }]]"
|
||||||
|
:popper="{ strategy: 'absolute', offsetDistance: 11, placement: 'bottom-start' }"
|
||||||
|
:ui="{
|
||||||
|
background: 'dark:bg-gray-900',
|
||||||
|
ring: 'dark:ring-gray-800',
|
||||||
|
width: 'w-auto',
|
||||||
|
item: {
|
||||||
|
padding: 'p-1',
|
||||||
|
size: 'text-xs',
|
||||||
|
active: 'dark:bg-gray-800/50'
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<UButton
|
||||||
|
:label="$route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`"
|
||||||
|
trailing-icon="i-lucide-chevron-down"
|
||||||
|
variant="outline"
|
||||||
|
size="2xs"
|
||||||
|
truncate
|
||||||
|
class="-mb-[6px] font-semibold rounded-full truncate ring-primary-500/25 dark:ring-primary-400/25 bg-primary-500/10 dark:bg-primary-400/10 hover:bg-primary-500/15 dark:hover:bg-primary-400/15 transition-colors"
|
||||||
|
/>
|
||||||
|
</UDropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #right>
|
<template #right>
|
||||||
@@ -25,10 +47,10 @@
|
|||||||
<UContentSearchButton :label="null" />
|
<UContentSearchButton :label="null" />
|
||||||
</UTooltip>
|
</UTooltip>
|
||||||
|
|
||||||
<UColorModeButton />
|
<UColorModeButton class="hidden lg:inline-flex" />
|
||||||
|
|
||||||
<UButton
|
<UButton
|
||||||
to="https://github.com/nuxt/ui"
|
to="https://github.com/nuxt/ui/tree/v2"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
icon="i-simple-icons-github"
|
icon="i-simple-icons-github"
|
||||||
aria-label="GitHub"
|
aria-label="GitHub"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ onMounted(() => {
|
|||||||
if (carbonads.value) {
|
if (carbonads.value) {
|
||||||
const script = document.createElement('script')
|
const script = document.createElement('script')
|
||||||
script.setAttribute('type', 'text/javascript')
|
script.setAttribute('type', 'text/javascript')
|
||||||
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CWYIVK3E&placement=uinuxtcom')
|
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CW7IC53I&placement=ui2nuxtcom')
|
||||||
script.setAttribute('id', '_carbonads_js')
|
script.setAttribute('id', '_carbonads_js')
|
||||||
carbonads.value.appendChild(script)
|
carbonads.value.appendChild(script)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const ui = {
|
|||||||
inactive: 'text-gray-400 dark:text-gray-500'
|
inactive: 'text-gray-400 dark:text-gray-500'
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
size: '2xs' as const
|
size: '2xs'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { sub, format, isSameDay, type Duration } from 'date-fns'
|
import { sub, format, isSameDay } from 'date-fns'
|
||||||
|
import type { Duration } from 'date-fns'
|
||||||
|
|
||||||
const ranges = [
|
const ranges = [
|
||||||
{ label: 'Last 7 days', duration: { days: 7 } },
|
{ label: 'Last 7 days', duration: { days: 7 } },
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { object, string, nonempty, type Infer } from 'superstruct'
|
import { object, string, nonempty } from 'superstruct'
|
||||||
|
import type { Infer } from 'superstruct'
|
||||||
import type { FormSubmitEvent } from '#ui/types'
|
import type { FormSubmitEvent } from '#ui/types'
|
||||||
|
|
||||||
const schema = object({
|
const schema = object({
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UForm :schema="v.safeParser(schema)" :state="state" class="space-y-4" @submit="onSubmit">
|
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||||
<UFormGroup label="Email" name="email">
|
<UFormGroup label="Email" name="email">
|
||||||
<UInput v-model="state.email" />
|
<UInput v-model="state.email" />
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { object, string, type InferType } from 'yup'
|
import { object, string } from 'yup'
|
||||||
|
import type { InferType } from 'yup'
|
||||||
import type { FormSubmitEvent } from '#ui/types'
|
import type { FormSubmitEvent } from '#ui/types'
|
||||||
|
|
||||||
const schema = object({
|
const schema = object({
|
||||||
|
|||||||
15
docs/components/content/examples/InputExampleMaxLength.vue
Normal file
15
docs/components/content/examples/InputExampleMaxLength.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<UInput
|
||||||
|
v-model="name"
|
||||||
|
:maxlength="maxLength"
|
||||||
|
>
|
||||||
|
<template #trailing>
|
||||||
|
<span class="text-xs text-gray-500 dark:text-gray-400">{{ name.length }}/{{ maxLength }}</span>
|
||||||
|
</template>
|
||||||
|
</UInput>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const name = ref('')
|
||||||
|
const maxLength = 10
|
||||||
|
</script>
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// Columns
|
// Columns
|
||||||
const columns = [{
|
const columns = [{
|
||||||
|
key: 'select',
|
||||||
|
class: 'w-2'
|
||||||
|
}, {
|
||||||
key: 'id',
|
key: 'id',
|
||||||
label: '#',
|
label: '#',
|
||||||
sortable: true
|
sortable: true
|
||||||
@@ -20,6 +23,7 @@ const columns = [{
|
|||||||
|
|
||||||
const selectedColumns = ref(columns)
|
const selectedColumns = ref(columns)
|
||||||
const columnsTable = computed(() => columns.filter(column => selectedColumns.value.includes(column)))
|
const columnsTable = computed(() => columns.filter(column => selectedColumns.value.includes(column)))
|
||||||
|
const excludeSelectColumn = computed(() => columns.filter(v => v.key !== 'select'))
|
||||||
|
|
||||||
// Selected Rows
|
// Selected Rows
|
||||||
const selectedRows = ref([])
|
const selectedRows = ref([])
|
||||||
@@ -153,7 +157,7 @@ const { data: todos, status } = await useLazyAsyncData<{
|
|||||||
</UButton>
|
</UButton>
|
||||||
</UDropdown>
|
</UDropdown>
|
||||||
|
|
||||||
<USelectMenu v-model="selectedColumns" :options="columns" multiple>
|
<USelectMenu v-model="selectedColumns" :options="excludeSelectColumn" multiple>
|
||||||
<UButton
|
<UButton
|
||||||
icon="i-heroicons-view-columns"
|
icon="i-heroicons-view-columns"
|
||||||
color="gray"
|
color="gray"
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const people = [{
|
||||||
|
id: 1,
|
||||||
|
name: 'Lindsay Walton',
|
||||||
|
title: 'Front-end Developer',
|
||||||
|
email: 'lindsay.walton@example.com',
|
||||||
|
role: 'Member'
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
name: 'Courtney Henry',
|
||||||
|
title: 'Designer',
|
||||||
|
email: 'courtney.henry@example.com',
|
||||||
|
role: 'Admin'
|
||||||
|
}, {
|
||||||
|
id: 3,
|
||||||
|
name: 'Tom Cook',
|
||||||
|
title: 'Director of Product',
|
||||||
|
email: 'tom.cook@example.com',
|
||||||
|
role: 'Member'
|
||||||
|
}, {
|
||||||
|
id: 4,
|
||||||
|
name: 'Whitney Francis',
|
||||||
|
title: 'Copywriter',
|
||||||
|
email: 'whitney.francis@example.com',
|
||||||
|
role: 'Admin'
|
||||||
|
}, {
|
||||||
|
id: 5,
|
||||||
|
name: 'Leonard Krasner',
|
||||||
|
title: 'Senior Designer',
|
||||||
|
email: 'leonard.krasner@example.com',
|
||||||
|
role: 'Owner'
|
||||||
|
}, {
|
||||||
|
id: 6,
|
||||||
|
name: 'Floyd Miles',
|
||||||
|
title: 'Principal Designer',
|
||||||
|
email: 'floyd.miles@example.com',
|
||||||
|
role: 'Member'
|
||||||
|
}]
|
||||||
|
|
||||||
|
const selected = ref([people[1]])
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
key: 'id',
|
||||||
|
label: 'ID'
|
||||||
|
}, {
|
||||||
|
key: 'name',
|
||||||
|
label: 'User name'
|
||||||
|
}, {
|
||||||
|
key: 'title',
|
||||||
|
label: 'Job position'
|
||||||
|
}, {
|
||||||
|
key: 'email',
|
||||||
|
label: 'Email'
|
||||||
|
}, {
|
||||||
|
key: 'role'
|
||||||
|
}, {
|
||||||
|
key: 'select',
|
||||||
|
class: 'w-2'
|
||||||
|
}]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UTable v-model="selected" :rows="people" :columns="columns" />
|
||||||
|
</template>
|
||||||
@@ -31,7 +31,7 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ULandingGrid ref="section" class="lg:grid-cols-10 lg:gap-8 overflow-hidden p-px">
|
<ULandingGrid ref="section" class="lg:grid-cols-10 lg:gap-8 overflow-hidden p-1">
|
||||||
<div :ref="(el) => (refs[1] = el)" class="col-span-8 flex items-center animate-top">
|
<div :ref="(el) => (refs[1] = el)" class="col-span-8 flex items-center animate-top">
|
||||||
<RangeExample />
|
<RangeExample />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Its goal is to provide everything related to UI when building a Nuxt app. This i
|
|||||||
- Keyboard shortcuts
|
- Keyboard shortcuts
|
||||||
- Bundled icons
|
- Bundled icons
|
||||||
- Fully typed
|
- Fully typed
|
||||||
- [Figma Kit](https://www.figma.com/community/file/1288455405058138934)
|
- [Figma Kit](https://www.figma.com/community/file/1436401057300493073)
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,29 @@ description: 'Learn how to install and configure Nuxt UI in your application.'
|
|||||||
|
|
||||||
### Add to a Nuxt project
|
### Add to a Nuxt project
|
||||||
|
|
||||||
1. Add `@nuxt/ui` module to your project:
|
1. Install the `@nuxt/ui` dependency in your project:
|
||||||
|
|
||||||
```bash
|
::code-group
|
||||||
npx nuxi@latest module add ui
|
|
||||||
|
```bash [pnpm]
|
||||||
|
pnpm add @nuxt/ui@2
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Add it to the `modules` section in your `nuxt.config.ts`:
|
```bash [yarn]
|
||||||
|
yarn add @nuxt/ui@2
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [npm]
|
||||||
|
npm install @nuxt/ui@2
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash [bun]
|
||||||
|
bun add @nuxt/ui@2
|
||||||
|
```
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
2. Register the `@nuxt/ui` module in your `nuxt.config.ts`:
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
@@ -29,7 +45,7 @@ That's it! You can now use all the components and composables in your Nuxt app
|
|||||||
The Nuxt Starter template is available from the `nuxi init` command.
|
The Nuxt Starter template is available from the `nuxi init` command.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx nuxi@latest init -t ui
|
npx nuxi@latest init -t ui2
|
||||||
```
|
```
|
||||||
|
|
||||||
Please check [nuxt/starter](https://github.com/nuxt/starter/tree/ui) for details.
|
Please check [nuxt/starter](https://github.com/nuxt/starter/tree/ui) for details.
|
||||||
@@ -94,7 +110,7 @@ You can read more about this in the [Theming](/getting-started/theming#dark-mode
|
|||||||
|
|
||||||
## TypeScript
|
## TypeScript
|
||||||
|
|
||||||
This module is written in TypeScript and provides typings for all the components and composables. You can look at the [source code](https://github.com/nuxt/ui/tree/dev/src/runtime/types) to see all the available types.
|
This module is written in TypeScript and provides typings for all the components and composables. You can look at the [source code](https://github.com/nuxt/ui/tree/v2/src/runtime/types) to see all the available types.
|
||||||
|
|
||||||
::callout{icon="i-heroicons-light-bulb" to="https://nuxt.com/docs/guide/concepts/typescript" target="_blank"}
|
::callout{icon="i-heroicons-light-bulb" to="https://nuxt.com/docs/guide/concepts/typescript" target="_blank"}
|
||||||
You can read more about TypeScript on the official Nuxt documentation.
|
You can read more about TypeScript on the official Nuxt documentation.
|
||||||
@@ -230,7 +246,7 @@ You can also add the following to your `.vscode/settings.json` to enable Intelli
|
|||||||
| `prefix` | `u` | Define the prefix of the imported components. |
|
| `prefix` | `u` | Define the prefix of the imported components. |
|
||||||
| `global` | `false` | Expose components globally. |
|
| `global` | `false` | Expose components globally. |
|
||||||
| `safelistColors` | `['primary']` | Force safelisting of colors to need be purged. |
|
| `safelistColors` | `['primary']` | Force safelisting of colors to need be purged. |
|
||||||
| `disableGlobalStyles` | `false` | Disable [global CSS styles](https://github.com/nuxt/ui/blob/dev/src/runtime/ui.css) injected by the module. |
|
| `disableGlobalStyles` | `false` | Disable [global CSS styles](https://github.com/nuxt/ui/blob/v2/src/runtime/ui.css) injected by the module. |
|
||||||
|
|
||||||
Configure options in your `nuxt.config.ts` as such:
|
Configure options in your `nuxt.config.ts` as such:
|
||||||
|
|
||||||
@@ -243,19 +259,21 @@ export default defineNuxtConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Edge
|
## Continuous Releases
|
||||||
|
|
||||||
To use the latest updates pushed on the [`dev`](https://github.com/nuxt/ui/tree/dev) branch, you can use `@nuxt/ui-edge`.
|
Nuxt UI uses [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) for continuous preview releases, providing developers with instant access to the latest features and bug fixes without waiting for official releases.
|
||||||
|
|
||||||
Update your `package.json` to the following:
|
Preview releases are automatically generated for every commit to the `dev` branch and pull requests targeting the `dev` branch. To use it into your project, replace the version in your `package.json` with the commit hash or pull request number.
|
||||||
|
|
||||||
```diff [package.json]
|
```diff [package.json]
|
||||||
{
|
{
|
||||||
"devDependencies": {
|
"dependencies": {
|
||||||
- "@nuxt/ui": "^2.11.0"
|
- "@nuxt/ui": "^2.21.0",
|
||||||
+ "@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
+ "@nuxt/ui": "https://pkg.pr.new/@nuxt/ui@bf1c9e7",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run `pnpm install`, `yarn install` or `npm install`.
|
::note
|
||||||
|
**pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes.
|
||||||
|
::
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Try to change the `primary` and `gray` colors by clicking on the :u-icon{name="i
|
|||||||
|
|
||||||
As this module uses Tailwind CSS under the hood, you can use any of the [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference) or your own custom colors or groups, such as `brand.primary`. By default, the `primary` color is `green` and the `gray` color is `cool`.
|
As this module uses Tailwind CSS under the hood, you can use any of the [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference) or your own custom colors or groups, such as `brand.primary`. By default, the `primary` color is `green` and the `gray` color is `cool`.
|
||||||
|
|
||||||
When [using custom colors](https://tailwindcss.com/docs/customizing-colors#using-custom-colors) or [adding additional colors](https://tailwindcss.com/docs/customizing-colors#adding-additional-colors) through the `extend` key in your `tailwind.config.ts`, you'll need to make sure to define all the shades from `50` to `950` as most of them are used in the components config defined in [`ui.config/`](https://github.com/nuxt/ui/tree/dev/src/runtime/ui.config) directory. You can [generate your colors](https://tailwindcss.com/docs/customizing-colors#generating-colors) using tools such as https://uicolors.app/ for example.
|
When [using custom colors](https://tailwindcss.com/docs/customizing-colors#using-custom-colors) or [adding additional colors](https://tailwindcss.com/docs/customizing-colors#adding-additional-colors) through the `extend` key in your `tailwind.config.ts`, you'll need to make sure to define all the shades from `50` to `950` as most of them are used in the components config defined in [`ui.config/`](https://github.com/nuxt/ui/tree/v2/src/runtime/ui.config) directory. You can [generate your colors](https://tailwindcss.com/docs/customizing-colors#generating-colors) using tools such as https://uicolors.app/ for example.
|
||||||
|
|
||||||
```ts [tailwind.config.ts]
|
```ts [tailwind.config.ts]
|
||||||
import type { Config } from 'tailwindcss'
|
import type { Config } from 'tailwindcss'
|
||||||
@@ -118,7 +118,7 @@ export default defineAppConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The available options for each component should auto-complete, and you can review the defaults for each component using your IDE's function such as `Cmd`+`Click` (these files can be found in [`src/runtime/ui.config/`](https://github.com/nuxt/ui/tree/dev/src/runtime/ui.config)).
|
The available options for each component should auto-complete, and you can review the defaults for each component using your IDE's function such as `Cmd`+`Click` (these files can be found in [`src/runtime/ui.config/`](https://github.com/nuxt/ui/tree/v2/src/runtime/ui.config)).
|
||||||
|
|
||||||
Thanks to [tailwind-merge](https://github.com/dcastil/tailwind-merge), the `app.config.ts` is smartly merged with the default config. This means you don't have to rewrite everything.
|
Thanks to [tailwind-merge](https://github.com/dcastil/tailwind-merge), the `app.config.ts` is smartly merged with the default config. This means you don't have to rewrite everything.
|
||||||
|
|
||||||
@@ -221,6 +221,52 @@ export default defineAppConfig({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Extend Tailwind Merge
|
||||||
|
|
||||||
|
Tailwind Merge is a library that allows you to efficiently merge Tailwind CSS classes. It is used by this module to merge the classes from the `ui` prop, the `class` attribute, and the default classes.
|
||||||
|
|
||||||
|
::callout{icon="i-heroicons-light-bulb" to="https://github.com/dcastil/tailwind-merge" target="_blank"}
|
||||||
|
Learn more about Tailwind Merge.
|
||||||
|
::
|
||||||
|
|
||||||
|
By default, Tailwind Merge doesn't handle custom Tailwind CSS configuration like custom colors, spacing, or other utilities you may have defined. You'll need to extend it to handle your custom configuration.
|
||||||
|
|
||||||
|
You can extend Tailwind Merge by using the `tailwindMerge` option in your `app.config.ts`:
|
||||||
|
|
||||||
|
::code-group
|
||||||
|
```ts [app.config.ts]
|
||||||
|
export default defineAppConfig({
|
||||||
|
ui: {
|
||||||
|
tailwindMerge: {
|
||||||
|
extend: {
|
||||||
|
theme: {
|
||||||
|
spacing: ['sm', 'md', 'lg', 'xl', '2xl']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts [tailwind.config.ts]
|
||||||
|
import type { Config } from 'tailwindcss'
|
||||||
|
|
||||||
|
export default <Partial<Config>>{
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
spacing: {
|
||||||
|
sm: '0.5rem',
|
||||||
|
md: '1rem',
|
||||||
|
lg: '1.5rem',
|
||||||
|
xl: '2rem',
|
||||||
|
'2xl': '2.5rem'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
## Dark mode
|
## Dark mode
|
||||||
|
|
||||||
All the components are styled with dark mode in mind.
|
All the components are styled with dark mode in mind.
|
||||||
@@ -343,6 +389,12 @@ export default defineAppConfig({
|
|||||||
loadingIcon: 'i-octicon-sync-24'
|
loadingIcon: 'i-octicon-sync-24'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
inputMenu: {
|
||||||
|
default: {
|
||||||
|
selectedIcon: 'i-octicon-check-24',
|
||||||
|
trailingIcon: 'i-octicon-chevron-down-24'
|
||||||
|
}
|
||||||
|
},
|
||||||
select: {
|
select: {
|
||||||
default: {
|
default: {
|
||||||
loadingIcon: 'i-octicon-sync-24',
|
loadingIcon: 'i-octicon-sync-24',
|
||||||
@@ -378,6 +430,9 @@ export default defineAppConfig({
|
|||||||
sortButton: {
|
sortButton: {
|
||||||
icon: 'i-octicon-arrow-switch-24'
|
icon: 'i-octicon-arrow-switch-24'
|
||||||
},
|
},
|
||||||
|
expandButton: {
|
||||||
|
icon: 'i-octicon-chevron-down-24'
|
||||||
|
},
|
||||||
loadingState: {
|
loadingState: {
|
||||||
icon: 'i-octicon-sync-24'
|
icon: 'i-octicon-sync-24'
|
||||||
},
|
},
|
||||||
@@ -411,6 +466,21 @@ export default defineAppConfig({
|
|||||||
default: {
|
default: {
|
||||||
divider: 'i-octicon-chevron-right-24'
|
divider: 'i-octicon-chevron-right-24'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
carousel: {
|
||||||
|
default: {
|
||||||
|
prevButton: {
|
||||||
|
icon: 'i-octicon-chevron-left-24'
|
||||||
|
},
|
||||||
|
nextButton: {
|
||||||
|
icon: 'i-octicon-chevron-right-24'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggle: {
|
||||||
|
default: {
|
||||||
|
loadingIcon: 'i-octicon-sync-24'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,18 +49,22 @@ defineShortcuts({
|
|||||||
Shortcuts keys are written as the literal keyboard key value. Combinations are made with `_` separator. Chained shortcuts are made with `-` separator.
|
Shortcuts keys are written as the literal keyboard key value. Combinations are made with `_` separator. Chained shortcuts are made with `-` separator.
|
||||||
|
|
||||||
Modifiers are also available:
|
Modifiers are also available:
|
||||||
- `meta`: acts as `Command` for MacOS and `Control` for others
|
| Modifier | Description |
|
||||||
- `ctrl`: acts as `Control`
|
|----------|-------------|
|
||||||
- `shift`: acts as `Shift` and is only necessary for alphabetic keys
|
| `meta` | Acts as `Command (⌘)` on macOS and `Control (Ctrl)` on Windows/Linux. |
|
||||||
|
| `ctrl` | Represents the `Control (Ctrl)` key across all operating systems. |
|
||||||
|
| `shift` | Represents the `Shift` key, only needed for alphabetic keys (e.g., `shift_e`). |
|
||||||
|
|
||||||
Examples of keys:
|
Examples of keys:
|
||||||
- `escape`: will trigger by hitting `Esc`
|
| Shortcut Key | Action |
|
||||||
- `meta_k`: will trigger by hitting `⌘` and `K` at the same time on MacOS, and `Ctrl` and `K` on Windows and Linux
|
|---------------|--------|
|
||||||
- `ctrl_k`: will trigger by hitting `Ctrl` and `K` at the same time on MacOS, Windows and Linux
|
| `escape` | Triggers when `Esc` is pressed |
|
||||||
- `shift_e`: will trigger by hitting `Shift` and `E` at the same time on MacOS, Windows and Linux
|
| `meta_k` | `⌘ + K` on Mac, `Ctrl + K` on Windows/Linux |
|
||||||
- `?`: will trigger by hitting `?` on some keyboard layouts, or for example `Shift` and `/`, which results in `?` on US Mac keyboards
|
| `ctrl_k` | Triggers `Ctrl + K` on all OS |
|
||||||
- `g-d`: will trigger by hitting `g` then `d` with a maximum delay of 800ms by default
|
| `shift_e` | Triggers `Shift + E` on all OS |
|
||||||
- `arrowleft`: will trigger by hitting `←` (also: `arrowright`, `arrowup`, `arrowdown`)
|
| `?` | Triggers `?` (Shift + `/` on US Mac keyboards) |
|
||||||
|
| `g-d` | Triggers when `g` then `d` are pressed within 800ms |
|
||||||
|
| `arrowleft` | Triggers when `←` is pressed (also: `arrowright`, `arrowup`, `arrowdown`) |
|
||||||
|
|
||||||
::callout{icon="i-heroicons-light-bulb"}
|
::callout{icon="i-heroicons-light-bulb"}
|
||||||
For a complete list of available shortcut keys, refer to the [`KeyboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) API docs. Note the `KeyboardEvent.key` has to be written in lowercase.
|
For a complete list of available shortcut keys, refer to the [`KeyboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) API docs. Note the `KeyboardEvent.key` has to be written in lowercase.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/disclosure'
|
to: 'https://headlessui.com/v1/vue/disclosure'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Accordion.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Accordion.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display an alert element to draw attention.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Alert.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Alert.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display an image that represents a resource or a group of resources
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Avatar.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Avatar.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a short text to represent a status or a category.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Badge.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Badge.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -141,6 +141,74 @@ Badge
|
|||||||
You can customize the whole [preset](#preset) by using the `ui` prop.
|
You can customize the whole [preset](#preset) by using the `ui` prop.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### Icon
|
||||||
|
|
||||||
|
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
|
||||||
|
|
||||||
|
Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position.
|
||||||
|
|
||||||
|
::component-card
|
||||||
|
---
|
||||||
|
props:
|
||||||
|
icon: 'i-heroicons-rocket-launch'
|
||||||
|
size: 'sm'
|
||||||
|
color: 'primary'
|
||||||
|
variant: 'solid'
|
||||||
|
label: Badge
|
||||||
|
trailing: false
|
||||||
|
options:
|
||||||
|
- name: variant
|
||||||
|
restriction: only
|
||||||
|
values:
|
||||||
|
- solid
|
||||||
|
excludedProps:
|
||||||
|
- icon
|
||||||
|
- label
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
|
## Slots
|
||||||
|
|
||||||
|
### `leading`
|
||||||
|
|
||||||
|
Use the `#leading` slot to set the content of the leading icon.
|
||||||
|
|
||||||
|
::component-card
|
||||||
|
---
|
||||||
|
slots:
|
||||||
|
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
|
||||||
|
baseProps:
|
||||||
|
color: 'gray'
|
||||||
|
props:
|
||||||
|
label: Badge
|
||||||
|
color: 'gray'
|
||||||
|
excludedProps:
|
||||||
|
- color
|
||||||
|
---
|
||||||
|
|
||||||
|
#leading
|
||||||
|
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs"}
|
||||||
|
::
|
||||||
|
|
||||||
|
### `trailing`
|
||||||
|
|
||||||
|
Use the `#trailing` slot to set the content of the trailing icon.
|
||||||
|
|
||||||
|
::component-card
|
||||||
|
---
|
||||||
|
slots:
|
||||||
|
trailing: <UIcon name="i-heroicons-rocket-launch" class="w-4 h-4" />
|
||||||
|
props:
|
||||||
|
label: Badge
|
||||||
|
color: 'gray'
|
||||||
|
excludedProps:
|
||||||
|
- color
|
||||||
|
---
|
||||||
|
|
||||||
|
#trailing
|
||||||
|
:u-icon{name="i-heroicons-rocket-launch" class="w-4 h-4"}
|
||||||
|
::
|
||||||
|
|
||||||
## Props
|
## Props
|
||||||
|
|
||||||
:component-props
|
:component-props
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: A list of links that indicate the current page's location within a
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Breadcrumb.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/Breadcrumb.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Create a button with icon or link capabilities.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Button.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Button.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a card for content with a header, body and footer.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Card.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/layout/Card.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display images or content in a scrollable area.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Carousel.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Carousel.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a checkbox field.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Checkbox.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Checkbox.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a chip indicator on any component.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Chip.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Chip.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/combobox'
|
to: 'https://headlessui.com/v1/vue/combobox'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/CommandPalette.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/CommandPalette.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -274,7 +274,7 @@ hiddenCode: true
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/CommandPaletteExampleThemeAlgolia.vue#L23" target="_blank"}
|
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/v2/docs/components/content/examples/CommandPaletteExampleThemeAlgolia.vue#L23" target="_blank"}
|
||||||
Take a look at the component!
|
Take a look at the component!
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -290,6 +290,6 @@ hiddenCode: true
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/CommandPaletteExampleThemeRaycast.vue#L30" target="_blank"}
|
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/v2/docs/components/content/examples/CommandPaletteExampleThemeRaycast.vue#L30" target="_blank"}
|
||||||
Take a look at the component!
|
Take a look at the component!
|
||||||
::
|
::
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: A container lets you center and constrain the width of your content
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Container.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/layout/Container.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a menu that appears on right click.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/ContextMenu.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/ContextMenu.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a separator between content.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Divider.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/layout/Divider.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: https://headlessui.com/v1/vue/menu
|
to: https://headlessui.com/v1/vue/menu
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Dropdown.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Dropdown.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a label and additional informations around a form element.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/FormGroup.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/FormGroup.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Collect and validate form data.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Form.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Form.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -14,7 +14,7 @@ It works with the [FormGroup](/components/form-group) component to display error
|
|||||||
|
|
||||||
The form component requires two props:
|
The form component requires two props:
|
||||||
- `state` - a reactive object holding the form's state.
|
- `state` - a reactive object holding the form's state.
|
||||||
- `schema` - a schema object from a validation library like [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi), [Valibot](https://github.com/fabian-hiller/valibot) or [Superstruct](https://github.com/ianstormtaylor/superstruct).
|
- `schema` - any [Standard Schema](https://standardschema.dev/) or a schema from [Yup](https://github.com/jquense/yup), [Joi](https://github.com/hapijs/joi) or [Superstruct](https://github.com/ianstormtaylor/superstruct).
|
||||||
|
|
||||||
::callout{icon="i-heroicons-light-bulb"}
|
::callout{icon="i-heroicons-light-bulb"}
|
||||||
Note that **no validation library is included** by default, so ensure you **install the one you need**.
|
Note that **no validation library is included** by default, so ensure you **install the one you need**.
|
||||||
@@ -190,7 +190,7 @@ hiddenCode: true
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/FormExampleElements.vue" target="_blank"}
|
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/v2/docs/components/content/examples/FormExampleElements.vue" target="_blank"}
|
||||||
Take a look at the component!
|
Take a look at the component!
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a list of horizontal links.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/HorizontalNavigation.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/HorizontalNavigation.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/combobox'
|
to: 'https://headlessui.com/v1/vue/combobox'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/InputMenu.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/InputMenu.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display an input field.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Input.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Input.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -142,7 +142,7 @@ props:
|
|||||||
|
|
||||||
### Loading
|
### Loading
|
||||||
|
|
||||||
Use the `loading` prop to show a loading icon and disable the Input.
|
Use the `loading` prop to show a loading icon in the Input.
|
||||||
|
|
||||||
Use the `loading-icon` prop to set a different icon or change it globally in `ui.input.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
|
Use the `loading-icon` prop to set a different icon or change it globally in `ui.input.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
|
||||||
|
|
||||||
@@ -173,6 +173,13 @@ baseProps:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### Limit
|
||||||
|
|
||||||
|
Use the `maxlength` prop to limit the length of the Input.
|
||||||
|
|
||||||
|
:component-example{component="input-example-max-length"}
|
||||||
|
|
||||||
|
|
||||||
## Slots
|
## Slots
|
||||||
|
|
||||||
### `leading`
|
### `leading`
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a keyboard key in a text block.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Kbd.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Kbd.vue
|
||||||
navigation:
|
navigation:
|
||||||
title: 'Kbd'
|
title: 'Kbd'
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Render a NuxtLink but with superpowers.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Link.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Link.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -14,6 +14,7 @@ The Link component is a wrapper around [`<NuxtLink>`](https://nuxt.com/docs/api/
|
|||||||
- `inactive-class` prop to set a class when the link is inactive, `active-class` is used when active.
|
- `inactive-class` prop to set a class when the link is inactive, `active-class` is used when active.
|
||||||
- `exact` prop to style with `active-class` when the link is active and the route is exactly the same as the current route.
|
- `exact` prop to style with `active-class` when the link is active and the route is exactly the same as the current route.
|
||||||
- `exact-query` and `exact-hash` props to style with `active-class` when the link is active and the query or hash is exactly the same as the current query or hash.
|
- `exact-query` and `exact-hash` props to style with `active-class` when the link is active and the query or hash is exactly the same as the current query or hash.
|
||||||
|
- use `exact-query="partial"` to style with `active-class` when the link is active and the query partially match the current query.
|
||||||
|
|
||||||
The incentive behind this is to provide the same API as NuxtLink back in Nuxt 2 / Vue 2. You can read more about it in the Vue Router [migration from Vue 2](https://router.vuejs.org/guide/migration/#removal-of-the-exact-prop-in-router-link) guide.
|
The incentive behind this is to provide the same API as NuxtLink back in Nuxt 2 / Vue 2. You can read more about it in the Vue Router [migration from Vue 2](https://router.vuejs.org/guide/migration/#removal-of-the-exact-prop-in-router-link) guide.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a gauge meter that fills or depletes.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Meter.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Meter.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/dialog'
|
to: 'https://headlessui.com/v1/vue/dialog'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Modal.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/Modal.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a toast notification in your app.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Notification.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/Notification.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -137,9 +137,9 @@ excludedProps:
|
|||||||
|
|
||||||
### Timeout
|
### Timeout
|
||||||
|
|
||||||
Use the `timeout` prop to configure how long the Notification will remain. The default value is `5000`, set it to `0` to disable the timeout.
|
Use the `timeout` prop to configure how long the Notification will remain. The default value is `5000`, set it to `0` to disable the timeout. The `pauseTimeoutOnHover` prop (`true` by default) controls whether hovering the notification should pause the timeout.
|
||||||
|
|
||||||
You will see a progress bar at the bottom of the Notification which will indicate the remaining time. When hovering the Notification, the progress bar will be paused.
|
You will see a progress bar at the bottom of the Notification which will indicate the remaining time. When hovering the Notification, the progress bar will be paused if `pauseTimeoutOnHover` is enabled; otherwise, it won't stop.
|
||||||
|
|
||||||
::component-card
|
::component-card
|
||||||
---
|
---
|
||||||
@@ -149,6 +149,7 @@ baseProps:
|
|||||||
description: 'This is a notification.'
|
description: 'This is a notification.'
|
||||||
props:
|
props:
|
||||||
timeout: 60000
|
timeout: 60000
|
||||||
|
pauseTimeoutOnHover: true
|
||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Add a pagination to handle pages.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Pagination.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/Pagination.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/popover'
|
to: 'https://headlessui.com/v1/vue/popover'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Popover.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/Popover.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Show a horizontal bar to indicate task progression.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Progress.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/elements/Progress.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a set of radio buttons.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/RadioGroup.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/RadioGroup.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a range field
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Range.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Range.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/listbox'
|
to: 'https://headlessui.com/v1/vue/listbox'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/SelectMenu.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/SelectMenu.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a select field.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Select.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Select.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a placeholder while content is loading.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Skeleton.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/layout/Skeleton.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/dialog'
|
to: 'https://headlessui.com/v1/vue/dialog'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Slideover.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/Slideover.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: 'Display data in a table.'
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/data/Table.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/data/Table.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -62,7 +62,7 @@ extraClass: 'overflow-hidden'
|
|||||||
padding: false
|
padding: false
|
||||||
component: 'table-example-columns-selectable'
|
component: 'table-example-columns-selectable'
|
||||||
componentProps:
|
componentProps:
|
||||||
class: 'flex-1 flex-col overflow-hidden'
|
class: 'flex-1 flex-col overflow-hidden min-h-[230px]'
|
||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -285,9 +285,68 @@ componentProps:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
||||||
|
#### Event Selectable
|
||||||
|
The `UTable` component provides two key events for handling row selection:
|
||||||
|
|
||||||
|
##### ***@select:all***
|
||||||
|
The `@select:all` event is emitted when the header checkbox in a selectable table is toggled. This event returns a boolean value indicating whether all rows are selected (true) or deselected (false).
|
||||||
|
|
||||||
|
##### ***@update:modelValue***
|
||||||
|
The `@update:modelValue` event is emitted whenever the selection state changes, including both individual row selection and bulk selection. This event returns an array containing the currently selected rows.
|
||||||
|
|
||||||
|
Here's how to implement both events:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
const selected = ref([])
|
||||||
|
|
||||||
|
const onHandleSelectAll = (isSelected: boolean) => {
|
||||||
|
console.log('All rows selected:', isSelected)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onUpdateSelection = (selectedRows: any[]) => {
|
||||||
|
console.log('Currently selected rows:', selectedRows)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UTable
|
||||||
|
v-model="selected"
|
||||||
|
:rows="people"
|
||||||
|
@select:all="onHandleSelectAll"
|
||||||
|
@update:modelValue="onUpdateSelection"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Single Select Mode
|
||||||
|
Control how the select function allows only one row to be selected at a time.
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<!-- Allow only one row to be selectable at a time -->
|
||||||
|
<UTable :single-select="true" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Checkbox Placement
|
||||||
|
You can customize the checkbox column position by using the `select` key in the `columns` configuration.
|
||||||
|
|
||||||
|
::component-example{class="grid"}
|
||||||
|
---
|
||||||
|
extraClass: 'overflow-hidden'
|
||||||
|
padding: false
|
||||||
|
component: 'table-example-dynamically-render-selectable'
|
||||||
|
componentProps:
|
||||||
|
class: 'flex-1'
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
### Contextmenu
|
### Contextmenu
|
||||||
|
|
||||||
Use the `contextmenu` listener on your Table to make the rows righ-clickable. The function will receive the original event as the first argument and the row as the second argument.
|
Use the `contextmenu` listener on your Table to make the rows right-clickable. The function will receive the original event as the first argument and the row as the second argument.
|
||||||
|
|
||||||
You can use this to open a [ContextMenu](/components/context-menu) for that row.
|
You can use this to open a [ContextMenu](/components/context-menu) for that row.
|
||||||
|
|
||||||
@@ -393,7 +452,6 @@ Controls whether multiple rows can be expanded simultaneously in the table.
|
|||||||
<!-- Or simply -->
|
<!-- Or simply -->
|
||||||
<UTable />
|
<UTable />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Disable Row Expansion
|
#### Disable Row Expansion
|
||||||
@@ -534,6 +592,82 @@ componentProps:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### `select-header`
|
||||||
|
This slot allows you to customize the checkbox appearance in the table header for selecting all rows at once while using feature [Selectable](#selectable).
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<UTable v-model="selectable">
|
||||||
|
<template #select-header="{ checked, change, indeterminate }">
|
||||||
|
<!-- Place your custom component here -->
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Props
|
||||||
|
|
||||||
|
| Prop | Type | Description |
|
||||||
|
|------|------|-------------|
|
||||||
|
| `checked` | `Boolean` | Indicates if all rows are selected |
|
||||||
|
| `change` | `Function` | Function to handle selection state changes. Must receive a boolean value (true/false) |
|
||||||
|
| `indeterminate` | `Boolean` | Indicates partial selection (when some rows are selected) |
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<UTable>
|
||||||
|
<!-- Header checkbox customization -->
|
||||||
|
<template #select-header="{ indeterminate, checked, change }">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:indeterminate="indeterminate"
|
||||||
|
:checked="checked"
|
||||||
|
@change="e => change(e.target.checked)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### `select-data`
|
||||||
|
This slot allows you to customize the checkbox appearance for each row in the table while using feature [Selectable](#selectable).
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<UTable v-model="selectable">
|
||||||
|
<template #select-data="{ checked, change }">
|
||||||
|
<!-- Place your custom component here -->
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Props
|
||||||
|
|
||||||
|
| Prop | Type | Description |
|
||||||
|
|------|------|-------------|
|
||||||
|
| `checked` | `Boolean` | Indicates if the current row is selected |
|
||||||
|
| `change` | `Function` | Function to handle selection state changes. Must receive a boolean value (true/false) |
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<UTable>
|
||||||
|
<!-- Row checkbox customization -->
|
||||||
|
<template #select-data="{ checked, change }">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:checked="checked"
|
||||||
|
@change="e => change(e.target.checked)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
### `expand-action`
|
### `expand-action`
|
||||||
|
|
||||||
The `#expand-action` slot allows you to customize the expansion control interface for expandable table rows. This feature provides a flexible way to implement custom expand/collapse functionality while maintaining access to essential row data and state.
|
The `#expand-action` slot allows you to customize the expansion control interface for expandable table rows. This feature provides a flexible way to implement custom expand/collapse functionality while maintaining access to essential row data and state.
|
||||||
@@ -635,6 +769,6 @@ hiddenCode: true
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/TableExampleAdvanced.vue" target="_blank"}
|
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/v2/docs/components/content/examples/TableExampleAdvanced.vue" target="_blank"}
|
||||||
Take a look at the component!
|
Take a look at the component!
|
||||||
::
|
::
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: A set of tab panels that are displayed one at a time.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Tabs.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/Tabs.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display a textarea field.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Textarea.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Textarea.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ links:
|
|||||||
to: 'https://headlessui.com/v1/vue/switch'
|
to: 'https://headlessui.com/v1/vue/switch'
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Toggle.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/forms/Toggle.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: Display content that appears on hover next to an element.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Tooltip.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/overlays/Tooltip.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ description: Display a list of vertical links.
|
|||||||
links:
|
links:
|
||||||
- label: GitHub
|
- label: GitHub
|
||||||
icon: i-simple-icons-github
|
icon: i-simple-icons-github
|
||||||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/VerticalNavigation.vue
|
to: https://github.com/nuxt/ui/blob/v2/src/runtime/components/navigation/VerticalNavigation.vue
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: '<span class="text-primary">Nuxt UI</span> Releases'
|
|||||||
head.title: Releases
|
head.title: Releases
|
||||||
description: Follow the latest releases and updates happening on the nuxt/ui repository.
|
description: Follow the latest releases and updates happening on the nuxt/ui repository.
|
||||||
links:
|
links:
|
||||||
- label: Get Started
|
- label: Get started
|
||||||
trailingIcon: i-heroicons-arrow-right-20-solid
|
trailingIcon: i-heroicons-arrow-right-20-solid
|
||||||
to: /getting-started
|
to: /getting-started
|
||||||
size: md
|
size: md
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
|
|
||||||
|
<Banner />
|
||||||
|
|
||||||
<Header :links="links" />
|
<Header :links="links" />
|
||||||
|
|
||||||
<UContainer>
|
<UContainer>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default defineNuxtConfig({
|
|||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
'@nuxt/ui-pro',
|
'@nuxt/ui-pro',
|
||||||
process.env.NUXT_GITHUB_TOKEN && ['github:nuxt/ui-pro/.docs#dev', { giget: { auth: process.env.NUXT_GITHUB_TOKEN } }]
|
process.env.NUXT_GITHUB_TOKEN && ['github:nuxt/ui-pro/.docs#v1', { giget: { auth: process.env.NUXT_GITHUB_TOKEN } }]
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
@@ -26,13 +26,11 @@ export default defineNuxtConfig({
|
|||||||
module,
|
module,
|
||||||
'@nuxtjs/plausible',
|
'@nuxtjs/plausible',
|
||||||
'@vueuse/nuxt',
|
'@vueuse/nuxt',
|
||||||
'nuxt-component-meta',
|
'nuxt-component-meta'
|
||||||
'nuxt-cloudflare-analytics',
|
|
||||||
'modules/content-examples-code'
|
|
||||||
],
|
],
|
||||||
|
|
||||||
site: {
|
site: {
|
||||||
url: 'https://ui.nuxt.com'
|
url: 'https://ui2.nuxt.com'
|
||||||
},
|
},
|
||||||
|
|
||||||
content: {
|
content: {
|
||||||
@@ -54,7 +52,7 @@ export default defineNuxtConfig({
|
|||||||
prefix: '/pro',
|
prefix: '/pro',
|
||||||
driver: 'github',
|
driver: 'github',
|
||||||
repo: 'nuxt/ui-pro',
|
repo: 'nuxt/ui-pro',
|
||||||
branch: 'dev',
|
branch: 'v1',
|
||||||
dir: '.docs/content/pro',
|
dir: '.docs/content/pro',
|
||||||
token: process.env.NUXT_GITHUB_TOKEN || ''
|
token: process.env.NUXT_GITHUB_TOKEN || ''
|
||||||
}
|
}
|
||||||
@@ -95,6 +93,11 @@ export default defineNuxtConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['date-fns']
|
include: ['date-fns']
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
fs: {
|
||||||
|
allow: process.env.NUXT_UI_PRO_PATH ? [resolve(process.env.NUXT_UI_PRO_PATH)] : undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -115,11 +118,6 @@ export default defineNuxtConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
cloudflareAnalytics: {
|
|
||||||
token: '1e2b0c5e9a214f0390b9b94e043d8d4c',
|
|
||||||
scriptPath: false
|
|
||||||
},
|
|
||||||
|
|
||||||
componentMeta: {
|
componentMeta: {
|
||||||
exclude: [
|
exclude: [
|
||||||
'@nuxt/content',
|
'@nuxt/content',
|
||||||
|
|||||||
@@ -3,28 +3,28 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/heroicons": "^1.2.1",
|
"@iconify-json/heroicons": "^1.2.2",
|
||||||
"@iconify-json/simple-icons": "^1.2.11",
|
"@iconify-json/lucide": "^1.2.57",
|
||||||
"@iconify-json/vscode-icons": "^1.2.2",
|
"@iconify-json/simple-icons": "^1.2.44",
|
||||||
|
"@iconify-json/vscode-icons": "^1.2.23",
|
||||||
"@nuxt/content": "^2.13.4",
|
"@nuxt/content": "^2.13.4",
|
||||||
"@nuxt/fonts": "^0.10.2",
|
"@nuxt/fonts": "^0.11.4",
|
||||||
"@nuxt/image": "^1.8.1",
|
"@nuxt/image": "^1.10.0",
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"@nuxt/ui-pro": "^1.5.0",
|
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@fdb0248",
|
||||||
"@nuxtjs/plausible": "^1.0.3",
|
"@nuxtjs/plausible": "^1.2.0",
|
||||||
"@octokit/rest": "^21.0.2",
|
"@octokit/rest": "^21.1.1",
|
||||||
"@vueuse/nuxt": "^11.2.0",
|
"@vueuse/nuxt": "^13.5.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"joi": "^17.13.3",
|
"joi": "^17.13.3",
|
||||||
"nuxt": "^3.14.159",
|
"nuxt": "^4.0.1",
|
||||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
"nuxt-component-meta": "^0.12.1",
|
||||||
"nuxt-component-meta": "^0.9.0",
|
"nuxt-og-image": "^5.1.9",
|
||||||
"nuxt-og-image": "^3.0.8",
|
"prettier": "^3.6.2",
|
||||||
"prettier": "^3.3.3",
|
"ufo": "^1.6.1",
|
||||||
"ufo": "^1.5.4",
|
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"valibot": "^0.42.1",
|
"valibot": "^1.1.0",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.6.1",
|
||||||
"zod": "^3.23.8"
|
"zod": "^4.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ defineOgImageComponent('Docs', {
|
|||||||
const communityLinks = computed(() => [{
|
const communityLinks = computed(() => [{
|
||||||
icon: 'i-heroicons-pencil-square',
|
icon: 'i-heroicons-pencil-square',
|
||||||
label: 'Edit this page',
|
label: 'Edit this page',
|
||||||
to: `https://github.com/nuxt/ui/edit/dev/docs/content/${page?.value?._file}`,
|
to: `https://github.com/nuxt/ui/edit/v2/docs/content/${page?.value?._file}`,
|
||||||
target: '_blank'
|
target: '_blank'
|
||||||
}, {
|
}, {
|
||||||
icon: 'i-heroicons-star',
|
icon: 'i-heroicons-star',
|
||||||
@@ -98,7 +98,7 @@ const communityLinks = computed(() => [{
|
|||||||
const resourcesLinks = [{
|
const resourcesLinks = [{
|
||||||
icon: 'i-simple-icons-figma',
|
icon: 'i-simple-icons-figma',
|
||||||
label: 'Figma Kit',
|
label: 'Figma Kit',
|
||||||
to: 'https://www.figma.com/community/file/1288455405058138934',
|
to: 'https://www.figma.com/community/file/1436401057300493073',
|
||||||
target: '_blank'
|
target: '_blank'
|
||||||
}, {
|
}, {
|
||||||
label: 'Playground',
|
label: 'Playground',
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #links>
|
<template #links>
|
||||||
<UButton label="Get Started" trailing-icon="i-heroicons-arrow-right-20-solid" size="lg" to="/getting-started/installation" />
|
<UButton label="Get started" size="lg" to="/getting-started/installation" />
|
||||||
|
<UButton label="Explore components" trailing-icon="i-heroicons-arrow-right-20-solid" color="gray" size="lg" to="/components/button" />
|
||||||
|
|
||||||
<UInput
|
<!-- <UInput
|
||||||
v-model="source"
|
v-model="source"
|
||||||
color="gray"
|
color="gray"
|
||||||
readonly
|
readonly
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
@click="copy(source)"
|
@click="copy(source)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</UInput>
|
</UInput> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
@@ -192,16 +193,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</ULandingHero>
|
</ULandingHero>
|
||||||
|
|
||||||
<ULandingSection v-for="(section, index) in page.pro.sections" :key="index" v-bind="section" class="!pt-0">
|
<!-- <ULandingSection v-for="(section, index) in page.pro.sections" :key="index" v-bind="section" class="!pt-0">
|
||||||
<MDC
|
<MDC
|
||||||
v-if="section.code"
|
v-if="section.code"
|
||||||
:value="section.code"
|
:value="section.code"
|
||||||
tag="pre"
|
tag="pre"
|
||||||
class="prose prose-primary dark:prose-invert max-w-none"
|
class="prose prose-primary dark:prose-invert max-w-none"
|
||||||
/>
|
/>
|
||||||
</ULandingSection>
|
</ULandingSection> -->
|
||||||
|
|
||||||
<div ref="sectionRef" :style="{ '--y': `${y}px`, '--inc': `${inc}px` }" class="_screen_xl">
|
<!-- <div ref="sectionRef" :style="{ '--y': `${y}px`, '--inc': `${inc}px` }" class="_screen_xl">
|
||||||
<ULandingSection class="sticky h-screen top-0 flex !pb-16" :ui="{ container: 'flex-1 sm:gap-y-12' }">
|
<ULandingSection class="sticky h-screen top-0 flex !pb-16" :ui="{ container: 'flex-1 sm:gap-y-12' }">
|
||||||
<template #title>
|
<template #title>
|
||||||
<Transition name="fade" mode="out-in">
|
<Transition name="fade" mode="out-in">
|
||||||
@@ -281,8 +282,6 @@
|
|||||||
<template #page-body>
|
<template #page-body>
|
||||||
<div class="-mt-8 prose prose-primary prose-sm dark:prose-invert max-w-none">
|
<div class="-mt-8 prose prose-primary prose-sm dark:prose-invert max-w-none">
|
||||||
<MDC :value="md" tag="div" />
|
<MDC :value="md" tag="div" />
|
||||||
|
|
||||||
<!-- <hr class="border-gray-800/10 dark:border-gray-200/10 !mt-5"> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -325,7 +324,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #links>
|
<template #links>
|
||||||
<UButton label="Get Started" icon="i-heroicons-rocket-launch" size="md" />
|
<UButton label="Get started" icon="i-heroicons-rocket-launch" size="md" />
|
||||||
|
|
||||||
<UInput
|
<UInput
|
||||||
model-value="npm i @nuxt/ui"
|
model-value="npm i @nuxt/ui"
|
||||||
@@ -374,9 +373,9 @@
|
|||||||
</ULandingSection>
|
</ULandingSection>
|
||||||
|
|
||||||
<div class="h-[calc(var(--inc)*42)]" />
|
<div class="h-[calc(var(--inc)*42)]" />
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<div class="_not_screen_xl">
|
<!-- <div class="_not_screen_xl">
|
||||||
<ULandingSection>
|
<ULandingSection>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span v-html="page.pro.landing?.title" />
|
<span v-html="page.pro.landing?.title" />
|
||||||
@@ -403,15 +402,15 @@
|
|||||||
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.ogg" type="video/ogg">
|
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.ogg" type="video/ogg">
|
||||||
</video>
|
</video>
|
||||||
</ULandingSection>
|
</ULandingSection>
|
||||||
</div>
|
</div> -->
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ParsedContent, NavItem } from '@nuxt/content'
|
import type { NavItem } from '@nuxt/content'
|
||||||
import { useElementBounding, useWindowScroll, useElementSize, breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
import { useElementBounding, useWindowScroll, breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||||
import type { HomeProBlock } from '~/types'
|
// import type { HomeProBlock } from '~/types'
|
||||||
|
|
||||||
const { data: page } = await useAsyncData('index', () => queryContent('/').findOne())
|
const { data: page } = await useAsyncData('index', () => queryContent('/').findOne())
|
||||||
const { data: module } = await useFetch<{
|
const { data: module } = await useFetch<{
|
||||||
@@ -423,6 +422,7 @@ const { data: module } = await useFetch<{
|
|||||||
username: string
|
username: string
|
||||||
}[]
|
}[]
|
||||||
}>('https://api.nuxt.com/modules/ui', {
|
}>('https://api.nuxt.com/modules/ui', {
|
||||||
|
key: 'stats',
|
||||||
transform: ({ stats, contributors }) => ({ stats, contributors })
|
transform: ({ stats, contributors }) => ({ stats, contributors })
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -434,321 +434,321 @@ useSeoMeta({
|
|||||||
ogTitle: page.value.title,
|
ogTitle: page.value.title,
|
||||||
description: page.value.description,
|
description: page.value.description,
|
||||||
ogDescription: page.value.description,
|
ogDescription: page.value.description,
|
||||||
ogImage: 'https://ui.nuxt.com/social-card.png',
|
ogImage: 'https://ui2.nuxt.com/social-card.png',
|
||||||
twitterImage: 'https://ui.nuxt.com/social-card.png'
|
twitterImage: 'https://ui2.nuxt.com/social-card.png'
|
||||||
})
|
})
|
||||||
|
|
||||||
const source = ref('npx nuxi@latest module add ui')
|
// const source = ref('npx nuxi@latest module add ui')
|
||||||
const sectionRef = ref()
|
const sectionRef = ref()
|
||||||
const demoRef = ref(null)
|
// const demoRef = ref(null)
|
||||||
const start = ref(0)
|
const start = ref(0)
|
||||||
|
|
||||||
const { $ui } = useNuxtApp()
|
// const { $ui } = useNuxtApp()
|
||||||
const { height } = useElementSize(demoRef)
|
// const { height } = useElementSize(demoRef)
|
||||||
const { top } = useElementBounding(sectionRef)
|
const { top } = useElementBounding(sectionRef)
|
||||||
const { y } = useWindowScroll()
|
const { y } = useWindowScroll()
|
||||||
const config = useRuntimeConfig().public
|
const config = useRuntimeConfig().public
|
||||||
const { copy, copied } = useClipboard({ source })
|
// const { copy, copied } = useClipboard({ source })
|
||||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||||
|
|
||||||
const lgAndLarger = breakpoints.greaterOrEqual('lg')
|
const lgAndLarger = breakpoints.greaterOrEqual('lg')
|
||||||
|
|
||||||
const { format } = Intl.NumberFormat('en', { notation: 'compact' })
|
const { format } = Intl.NumberFormat('en', { notation: 'compact' })
|
||||||
|
|
||||||
const steps = {
|
// const steps = {
|
||||||
header: 0,
|
// header: 0,
|
||||||
footer: 5,
|
// footer: 5,
|
||||||
landing: 10,
|
// landing: 10,
|
||||||
docs: 27
|
// docs: 27
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Computed
|
// Computed
|
||||||
|
|
||||||
const inc = computed(() => (height.value - 32 - 64 - 32 - 32) / 4)
|
// const inc = computed(() => (height.value - 32 - 64 - 32 - 32) / 4)
|
||||||
|
|
||||||
const landingBlocks = computed(() => isAfterStep(steps.landing) && isBeforeStep(steps.docs)
|
// const landingBlocks = computed(() => isAfterStep(steps.landing) && isBeforeStep(steps.docs)
|
||||||
? [{
|
// ? [{
|
||||||
class: 'inset-x-0 top-20 bottom-20 overflow-hidden',
|
// class: 'inset-x-0 top-20 bottom-20 overflow-hidden',
|
||||||
inactive: true,
|
// inactive: true,
|
||||||
children: [{
|
// children: [{
|
||||||
name: 'ULandingHero',
|
// name: 'ULandingHero',
|
||||||
to: '/pro/components/landing-hero',
|
// to: '/pro/components/landing-hero',
|
||||||
class: [
|
// class: [
|
||||||
'inset-4',
|
// 'inset-4',
|
||||||
isAfterStep(steps.landing + 2) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
// isAfterStep(steps.landing + 2) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||||
].filter(Boolean).join(' '),
|
// ].filter(Boolean).join(' '),
|
||||||
style: {
|
// style: {
|
||||||
'--step-y': `${getStepY(steps.landing + 2)}px`
|
// '--step-y': `${getStepY(steps.landing + 2)}px`
|
||||||
},
|
// },
|
||||||
inactive: isAfterStep(steps.landing + 1),
|
// inactive: isAfterStep(steps.landing + 1),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'landing-hero',
|
// slot: 'landing-hero',
|
||||||
class: 'inset-4'
|
// class: 'inset-4'
|
||||||
}]
|
// }]
|
||||||
}, isAfterStep(steps.landing + 2) && {
|
// }, isAfterStep(steps.landing + 2) && {
|
||||||
name: 'ULandingSection',
|
// name: 'ULandingSection',
|
||||||
to: '/pro/components/landing-section',
|
// to: '/pro/components/landing-section',
|
||||||
class: [
|
// class: [
|
||||||
'inset-4',
|
// 'inset-4',
|
||||||
isBeforeStep(steps.landing + 6) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]',
|
// isBeforeStep(steps.landing + 6) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]',
|
||||||
isAfterStep(steps.landing + 10) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
// isAfterStep(steps.landing + 10) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||||
].filter(Boolean).join(' '),
|
// ].filter(Boolean).join(' '),
|
||||||
style: {
|
// style: {
|
||||||
'--height': (inc.value * 4) + 'px',
|
// '--height': (inc.value * 4) + 'px',
|
||||||
'--step-y': `${getStepY(steps.landing + 10)}px`,
|
// '--step-y': `${getStepY(steps.landing + 10)}px`,
|
||||||
'--prev-step-y': `${getStepY(steps.landing + 2)}px`
|
// '--prev-step-y': `${getStepY(steps.landing + 2)}px`
|
||||||
},
|
// },
|
||||||
inactive: isAfterStep(steps.landing + 7),
|
// inactive: isAfterStep(steps.landing + 7),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'landing-section',
|
// slot: 'landing-section',
|
||||||
class: 'inset-x-4 top-16'
|
// class: 'inset-x-4 top-16'
|
||||||
}, {
|
// }, {
|
||||||
name: 'ULandingGrid',
|
// name: 'ULandingGrid',
|
||||||
to: '/pro/components/landing-grid',
|
// to: '/pro/components/landing-grid',
|
||||||
class: ['inset-x-4 bottom-4 top-48', isAfterStep(steps.landing + 8) && 'grid grid-cols-4 gap-4 p-4'].filter(Boolean).join(' '),
|
// class: ['inset-x-4 bottom-4 top-48', isAfterStep(steps.landing + 8) && 'grid grid-cols-4 gap-4 p-4'].filter(Boolean).join(' '),
|
||||||
inactive: isAfterStep(steps.landing + 8),
|
// inactive: isAfterStep(steps.landing + 8),
|
||||||
children: [isAfterStep(steps.landing + 9)
|
// children: [isAfterStep(steps.landing + 9)
|
||||||
? {
|
// ? {
|
||||||
slot: 'landing-card-1',
|
// slot: 'landing-card-1',
|
||||||
class: '!relative'
|
// class: '!relative'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: 'ULandingCard',
|
// name: 'ULandingCard',
|
||||||
to: '/pro/components/landing-card',
|
// to: '/pro/components/landing-card',
|
||||||
class: '!relative h-full',
|
// class: '!relative h-full',
|
||||||
inactive: false
|
// inactive: false
|
||||||
}, isAfterStep(steps.landing + 9)
|
// }, isAfterStep(steps.landing + 9)
|
||||||
? {
|
// ? {
|
||||||
slot: 'landing-card-2',
|
// slot: 'landing-card-2',
|
||||||
class: '!relative h-full'
|
// class: '!relative h-full'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: 'ULandingCard',
|
// name: 'ULandingCard',
|
||||||
to: '/pro/components/landing-card',
|
// to: '/pro/components/landing-card',
|
||||||
class: '!relative h-full',
|
// class: '!relative h-full',
|
||||||
inactive: false
|
// inactive: false
|
||||||
}, isAfterStep(steps.landing + 9)
|
// }, isAfterStep(steps.landing + 9)
|
||||||
? {
|
// ? {
|
||||||
slot: 'landing-card-3',
|
// slot: 'landing-card-3',
|
||||||
class: '!relative h-full'
|
// class: '!relative h-full'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: 'ULandingCard',
|
// name: 'ULandingCard',
|
||||||
to: '/pro/components/landing-card',
|
// to: '/pro/components/landing-card',
|
||||||
class: '!relative h-full',
|
// class: '!relative h-full',
|
||||||
inactive: false
|
// inactive: false
|
||||||
}, isAfterStep(steps.landing + 9)
|
// }, isAfterStep(steps.landing + 9)
|
||||||
? {
|
// ? {
|
||||||
slot: 'landing-card-4',
|
// slot: 'landing-card-4',
|
||||||
class: '!relative h-full'
|
// class: '!relative h-full'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: 'ULandingCard',
|
// name: 'ULandingCard',
|
||||||
to: '/pro/components/landing-card',
|
// to: '/pro/components/landing-card',
|
||||||
class: '!relative h-full',
|
// class: '!relative h-full',
|
||||||
inactive: false
|
// inactive: false
|
||||||
}]
|
// }]
|
||||||
}]
|
// }]
|
||||||
}, isAfterStep(steps.landing + 10) && {
|
// }, isAfterStep(steps.landing + 10) && {
|
||||||
name: 'ULandingSection',
|
// name: 'ULandingSection',
|
||||||
to: '/pro/components/landing-section',
|
// to: '/pro/components/landing-section',
|
||||||
class: [
|
// class: [
|
||||||
'inset-4',
|
// 'inset-4',
|
||||||
isBeforeStep(steps.landing + 14) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]'
|
// isBeforeStep(steps.landing + 14) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]'
|
||||||
].filter(Boolean).join(' '),
|
// ].filter(Boolean).join(' '),
|
||||||
style: {
|
// style: {
|
||||||
'--height': (inc.value * 4) + 'px',
|
// '--height': (inc.value * 4) + 'px',
|
||||||
'--step-y': `${getStepY(steps.landing + 18)}px`,
|
// '--step-y': `${getStepY(steps.landing + 18)}px`,
|
||||||
'--prev-step-y': `${getStepY(steps.landing + 10)}px`
|
// '--prev-step-y': `${getStepY(steps.landing + 10)}px`
|
||||||
},
|
// },
|
||||||
inactive: isAfterStep(steps.landing + 15),
|
// inactive: isAfterStep(steps.landing + 15),
|
||||||
children: [{
|
// children: [{
|
||||||
name: 'ULandingCTA',
|
// name: 'ULandingCTA',
|
||||||
class: 'inset-4',
|
// class: 'inset-4',
|
||||||
inactive: isAfterStep(steps.landing + 16),
|
// inactive: isAfterStep(steps.landing + 16),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'landing-cta',
|
// slot: 'landing-cta',
|
||||||
class: 'inset-0'
|
// class: 'inset-0'
|
||||||
}]
|
// }]
|
||||||
}]
|
// }]
|
||||||
}].filter(Boolean)
|
// }].filter(Boolean)
|
||||||
}]
|
// }]
|
||||||
: [])
|
// : [])
|
||||||
|
|
||||||
const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
// const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
||||||
name: 'UPage',
|
// name: 'UPage',
|
||||||
to: '/pro/components/page',
|
// to: '/pro/components/page',
|
||||||
class: 'inset-x-0 top-20 bottom-20',
|
// class: 'inset-x-0 top-20 bottom-20',
|
||||||
inactive: isAfterStep(steps.docs + 1),
|
// inactive: isAfterStep(steps.docs + 1),
|
||||||
children: [isAfterStep(steps.docs + 2)
|
// children: [isAfterStep(steps.docs + 2)
|
||||||
? {
|
// ? {
|
||||||
name: 'UAside',
|
// name: 'UAside',
|
||||||
to: '/pro/components/aside',
|
// to: '/pro/components/aside',
|
||||||
class: 'left-4 inset-y-4 w-64',
|
// class: 'left-4 inset-y-4 w-64',
|
||||||
inactive: isAfterStep(steps.docs + 3),
|
// inactive: isAfterStep(steps.docs + 3),
|
||||||
children: [isAfterStep(steps.docs + 4)
|
// children: [isAfterStep(steps.docs + 4)
|
||||||
? {
|
// ? {
|
||||||
slot: 'aside-top',
|
// slot: 'aside-top',
|
||||||
class: 'inset-x-4 top-4'
|
// class: 'inset-x-4 top-4'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#top',
|
// name: '#top',
|
||||||
class: 'inset-x-4 top-4 h-9'
|
// class: 'inset-x-4 top-4 h-9'
|
||||||
}, isAfterStep(steps.docs + 5)
|
// }, isAfterStep(steps.docs + 5)
|
||||||
? {
|
// ? {
|
||||||
name: 'UNavigationTree',
|
// name: 'UNavigationTree',
|
||||||
to: '/pro/components/navigation-tree',
|
// to: '/pro/components/navigation-tree',
|
||||||
class: ['inset-x-4 top-[4.25rem] bottom-4', isAfterStep(steps.docs + 6) && '!bg-transparent !border-0'].join(' '),
|
// class: ['inset-x-4 top-[4.25rem] bottom-4', isAfterStep(steps.docs + 6) && '!bg-transparent !border-0'].join(' '),
|
||||||
inactive: isAfterStep(steps.docs + 6),
|
// inactive: isAfterStep(steps.docs + 6),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'aside-default',
|
// slot: 'aside-default',
|
||||||
class: 'inset-0'
|
// class: 'inset-0'
|
||||||
}]
|
// }]
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#default',
|
// name: '#default',
|
||||||
class: 'inset-x-4 top-[4.25rem] bottom-4'
|
// class: 'inset-x-4 top-[4.25rem] bottom-4'
|
||||||
}]
|
// }]
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#left',
|
// name: '#left',
|
||||||
class: 'left-4 inset-y-4 w-64'
|
// class: 'left-4 inset-y-4 w-64'
|
||||||
}, isAfterStep(steps.docs + 7)
|
// }, isAfterStep(steps.docs + 7)
|
||||||
? {
|
// ? {
|
||||||
name: 'UPage',
|
// name: 'UPage',
|
||||||
to: '/pro/components/page',
|
// to: '/pro/components/page',
|
||||||
class: 'left-72 right-4 inset-y-4',
|
// class: 'left-72 right-4 inset-y-4',
|
||||||
inactive: isAfterStep(steps.docs + 8),
|
// inactive: isAfterStep(steps.docs + 8),
|
||||||
children: [...(isAfterStep(steps.docs + 9)
|
// children: [...(isAfterStep(steps.docs + 9)
|
||||||
? [{
|
// ? [{
|
||||||
name: 'UPageHeader',
|
// name: 'UPageHeader',
|
||||||
to: '/pro/components/page-header',
|
// to: '/pro/components/page-header',
|
||||||
class: 'top-4 left-4 right-72 h-32',
|
// class: 'top-4 left-4 right-72 h-32',
|
||||||
inactive: isAfterStep(steps.docs + 10),
|
// inactive: isAfterStep(steps.docs + 10),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'page-header',
|
// slot: 'page-header',
|
||||||
class: 'inset-4 justify-start'
|
// class: 'inset-4 justify-start'
|
||||||
}]
|
// }]
|
||||||
}, {
|
// }, {
|
||||||
name: 'UPageBody',
|
// name: 'UPageBody',
|
||||||
to: '/pro/components/page-body',
|
// to: '/pro/components/page-body',
|
||||||
class: 'top-40 left-4 right-72 bottom-4 overflow-y-auto',
|
// class: 'top-40 left-4 right-72 bottom-4 overflow-y-auto',
|
||||||
inactive: isAfterStep(steps.docs + 11),
|
// inactive: isAfterStep(steps.docs + 11),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'page-body',
|
// slot: 'page-body',
|
||||||
class: 'inset-x-4 top-4 justify-start'
|
// class: 'inset-x-4 top-4 justify-start'
|
||||||
}, isAfterStep(steps.docs + 12)
|
// }, isAfterStep(steps.docs + 12)
|
||||||
? {
|
// ? {
|
||||||
slot: 'content-surround',
|
// slot: 'content-surround',
|
||||||
class: 'bottom-4 inset-x-4 h-28'
|
// class: 'bottom-4 inset-x-4 h-28'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: 'UContentSurround',
|
// name: 'UContentSurround',
|
||||||
to: '/pro/components/content-surround',
|
// to: '/pro/components/content-surround',
|
||||||
class: 'bottom-4 inset-x-4 h-28',
|
// class: 'bottom-4 inset-x-4 h-28',
|
||||||
inactive: false
|
// inactive: false
|
||||||
}]
|
// }]
|
||||||
}]
|
// }]
|
||||||
: [{
|
// : [{
|
||||||
name: '#default',
|
// name: '#default',
|
||||||
class: 'left-4 right-72 inset-y-4'
|
// class: 'left-4 right-72 inset-y-4'
|
||||||
}]), isAfterStep(steps.docs + 13)
|
// }]), isAfterStep(steps.docs + 13)
|
||||||
? {
|
// ? {
|
||||||
name: 'UContentToc',
|
// name: 'UContentToc',
|
||||||
to: '/pro/components/content-toc',
|
// to: '/pro/components/content-toc',
|
||||||
class: 'right-4 inset-y-4 w-64',
|
// class: 'right-4 inset-y-4 w-64',
|
||||||
inactive: isAfterStep(steps.docs + 14),
|
// inactive: isAfterStep(steps.docs + 14),
|
||||||
children: [{
|
// children: [{
|
||||||
slot: 'content-toc',
|
// slot: 'content-toc',
|
||||||
class: 'inset-4 overflow-y-auto'
|
// class: 'inset-4 overflow-y-auto'
|
||||||
}]
|
// }]
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#right',
|
// name: '#right',
|
||||||
class: 'right-4 inset-y-4 w-64'
|
// class: 'right-4 inset-y-4 w-64'
|
||||||
}]
|
// }]
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#default',
|
// name: '#default',
|
||||||
class: 'left-72 right-4 inset-y-4'
|
// class: 'left-72 right-4 inset-y-4'
|
||||||
}]
|
// }]
|
||||||
}].filter(Boolean))
|
// }].filter(Boolean))
|
||||||
|
|
||||||
const blocks = computed(() => [isAfterStep(steps.header) && {
|
// const blocks = computed(() => [isAfterStep(steps.header) && {
|
||||||
name: 'UHeader',
|
// name: 'UHeader',
|
||||||
to: '/pro/components/header',
|
// to: '/pro/components/header',
|
||||||
class: 'h-16 inset-x-0 top-0',
|
// class: 'h-16 inset-x-0 top-0',
|
||||||
inactive: isAfterStep(steps.header + 1),
|
// inactive: isAfterStep(steps.header + 1),
|
||||||
children: [isAfterStep(steps.header + 2)
|
// children: [isAfterStep(steps.header + 2)
|
||||||
? {
|
// ? {
|
||||||
slot: 'header-left',
|
// slot: 'header-left',
|
||||||
class: 'left-4 top-4'
|
// class: 'left-4 top-4'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#left',
|
// name: '#left',
|
||||||
class: 'left-4 inset-y-4 w-64'
|
// class: 'left-4 inset-y-4 w-64'
|
||||||
}, isAfterStep(steps.header + 3)
|
// }, isAfterStep(steps.header + 3)
|
||||||
? {
|
// ? {
|
||||||
slot: 'header-center',
|
// slot: 'header-center',
|
||||||
class: 'inset-x-72 top-5'
|
// class: 'inset-x-72 top-5'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#center',
|
// name: '#center',
|
||||||
class: 'inset-x-72 inset-y-4'
|
// class: 'inset-x-72 inset-y-4'
|
||||||
}, isAfterStep(steps.header + 4)
|
// }, isAfterStep(steps.header + 4)
|
||||||
? {
|
// ? {
|
||||||
slot: 'header-right',
|
// slot: 'header-right',
|
||||||
class: 'right-4 top-4'
|
// class: 'right-4 top-4'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#right',
|
// name: '#right',
|
||||||
class: 'right-4 inset-y-4 w-64'
|
// class: 'right-4 inset-y-4 w-64'
|
||||||
}]
|
// }]
|
||||||
}, isAfterStep(steps.footer) && {
|
// }, isAfterStep(steps.footer) && {
|
||||||
name: 'UFooter',
|
// name: 'UFooter',
|
||||||
to: '/pro/components/footer',
|
// to: '/pro/components/footer',
|
||||||
class: 'h-16 inset-x-0 bottom-0',
|
// class: 'h-16 inset-x-0 bottom-0',
|
||||||
inactive: isAfterStep(steps.footer + 1),
|
// inactive: isAfterStep(steps.footer + 1),
|
||||||
children: [isAfterStep(steps.footer + 2)
|
// children: [isAfterStep(steps.footer + 2)
|
||||||
? {
|
// ? {
|
||||||
slot: 'footer-left',
|
// slot: 'footer-left',
|
||||||
class: 'left-4 bottom-5'
|
// class: 'left-4 bottom-5'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#left',
|
// name: '#left',
|
||||||
class: 'left-4 inset-y-4 w-64'
|
// class: 'left-4 inset-y-4 w-64'
|
||||||
}, isAfterStep(steps.footer + 3)
|
// }, isAfterStep(steps.footer + 3)
|
||||||
? {
|
// ? {
|
||||||
slot: 'footer-center',
|
// slot: 'footer-center',
|
||||||
class: 'inset-x-72 bottom-5'
|
// class: 'inset-x-72 bottom-5'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#center',
|
// name: '#center',
|
||||||
class: 'inset-x-72 inset-y-4'
|
// class: 'inset-x-72 inset-y-4'
|
||||||
}, isAfterStep(steps.footer + 4)
|
// }, isAfterStep(steps.footer + 4)
|
||||||
? {
|
// ? {
|
||||||
slot: 'footer-right',
|
// slot: 'footer-right',
|
||||||
class: 'right-4 bottom-4'
|
// class: 'right-4 bottom-4'
|
||||||
}
|
// }
|
||||||
: {
|
// : {
|
||||||
name: '#right',
|
// name: '#right',
|
||||||
class: 'right-4 inset-y-4 w-64'
|
// class: 'right-4 inset-y-4 w-64'
|
||||||
}]
|
// }]
|
||||||
}, ...landingBlocks.value, ...docsBlocks.value].filter(Boolean))
|
// }, ...landingBlocks.value, ...docsBlocks.value].filter(Boolean))
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
function isBeforeStep(i = 0) {
|
// function isBeforeStep(i = 0) {
|
||||||
return y.value < (start.value + (i * inc.value))
|
// return y.value < (start.value + (i * inc.value))
|
||||||
}
|
// }
|
||||||
|
|
||||||
function isAfterStep(i = 0) {
|
// function isAfterStep(i = 0) {
|
||||||
return y.value >= (start.value + (i * inc.value))
|
// return y.value >= (start.value + (i * inc.value))
|
||||||
}
|
// }
|
||||||
|
|
||||||
function getStepY(step: number) {
|
// function getStepY(step: number) {
|
||||||
return start.value + (step * inc.value)
|
// return start.value + (step * inc.value)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
|
|
||||||
@@ -760,94 +760,94 @@ onMounted(() => {
|
|||||||
|
|
||||||
// Slots Data
|
// Slots Data
|
||||||
|
|
||||||
const headerLinks = [{
|
// const headerLinks = [{
|
||||||
label: 'Documentation',
|
// label: 'Documentation',
|
||||||
active: true
|
// active: true
|
||||||
}, {
|
// }, {
|
||||||
label: 'Playground'
|
// label: 'Playground'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Roadmap'
|
// label: 'Roadmap'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Pro'
|
// label: 'Pro'
|
||||||
}]
|
// }]
|
||||||
|
|
||||||
const navigationLinks = [{
|
// const navigationLinks = [{
|
||||||
label: 'Getting Started',
|
// label: 'Getting Started',
|
||||||
children: [{
|
// children: [{
|
||||||
label: 'Introduction'
|
// label: 'Introduction'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Installation',
|
// label: 'Installation',
|
||||||
active: true
|
// active: true
|
||||||
}, {
|
// }, {
|
||||||
label: 'Theming'
|
// label: 'Theming'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Shortcuts'
|
// label: 'Shortcuts'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Examples'
|
// label: 'Examples'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Roadmap'
|
// label: 'Roadmap'
|
||||||
}]
|
// }]
|
||||||
}, {
|
// }, {
|
||||||
label: 'Elements',
|
// label: 'Elements',
|
||||||
children: [{
|
// children: [{
|
||||||
label: 'Alert'
|
// label: 'Alert'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Avatar'
|
// label: 'Avatar'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Badge'
|
// label: 'Badge'
|
||||||
}, {
|
// }, {
|
||||||
label: 'Button'
|
// label: 'Button'
|
||||||
}]
|
// }]
|
||||||
}]
|
// }]
|
||||||
|
|
||||||
const surround = [{
|
// const surround = [{
|
||||||
title: 'Introduction',
|
// title: 'Introduction',
|
||||||
description: 'Fully styled and customizable components for Nuxt.',
|
// description: 'Fully styled and customizable components for Nuxt.',
|
||||||
_path: '/'
|
// _path: '/'
|
||||||
}, {
|
// }, {
|
||||||
title: 'Theming',
|
// title: 'Theming',
|
||||||
description: 'Learn how to customize the look and feel of the components.',
|
// description: 'Learn how to customize the look and feel of the components.',
|
||||||
_path: '/'
|
// _path: '/'
|
||||||
}]
|
// }]
|
||||||
|
|
||||||
const md = `
|
// const md = `
|
||||||
## Edge
|
// ## Edge
|
||||||
|
|
||||||
To use the latest updates pushed on the [\`dev\`](https://github.com/nuxt/ui/tree/dev) branch, you can use \`@nuxt/ui-edge\`.
|
// To use the latest updates pushed on the [\`dev\`](https://github.com/nuxt/ui/tree/v2) branch, you can use \`@nuxt/ui-edge\`.
|
||||||
`
|
// `
|
||||||
|
|
||||||
const toc = [{
|
// const toc = [{
|
||||||
id: 'quick-start',
|
// id: 'quick-start',
|
||||||
depth: 2,
|
// depth: 2,
|
||||||
text: 'Quick Start'
|
// text: 'Quick Start'
|
||||||
}, {
|
// }, {
|
||||||
id: 'intellisense',
|
// id: 'intellisense',
|
||||||
depth: 2,
|
// depth: 2,
|
||||||
text: 'IntelliSense'
|
// text: 'IntelliSense'
|
||||||
}, {
|
// }, {
|
||||||
id: 'options',
|
// id: 'options',
|
||||||
depth: 2,
|
// depth: 2,
|
||||||
text: 'Options'
|
// text: 'Options'
|
||||||
}, {
|
// }, {
|
||||||
id: 'edge',
|
// id: 'edge',
|
||||||
depth: 2,
|
// depth: 2,
|
||||||
text: 'Edge'
|
// text: 'Edge'
|
||||||
}]
|
// }]
|
||||||
|
|
||||||
const communityLinks = [{
|
// const communityLinks = [{
|
||||||
icon: 'i-heroicons-pencil-square',
|
// icon: 'i-heroicons-pencil-square',
|
||||||
label: 'Edit this page'
|
// label: 'Edit this page'
|
||||||
}, {
|
// }, {
|
||||||
icon: 'i-heroicons-star',
|
// icon: 'i-heroicons-star',
|
||||||
label: 'Star on GitHub',
|
// label: 'Star on GitHub',
|
||||||
to: 'https://github.com/nuxt/ui',
|
// to: 'https://github.com/nuxt/ui',
|
||||||
target: '_blank'
|
// target: '_blank'
|
||||||
}, {
|
// }, {
|
||||||
icon: 'i-heroicons-book-open',
|
// icon: 'i-heroicons-book-open',
|
||||||
label: 'Nuxt documentation',
|
// label: 'Nuxt documentation',
|
||||||
to: 'https://nuxt.com',
|
// to: 'https://nuxt.com',
|
||||||
target: '_blank'
|
// target: '_blank'
|
||||||
}]
|
// }]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="postcss">
|
<style scoped lang="postcss">
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ if (!page.value) {
|
|||||||
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data: releases } = await useFetch('/api/releases.json')
|
const { data: releases } = await useFetch('/api/releases.json', { key: 'releases-list' })
|
||||||
const { data: pulls } = await useLazyFetch('/api/pulls.json', { default: () => [] })
|
const { data: pulls } = await useLazyFetch('/api/pulls.json', { default: () => [], key: 'pulls-list' })
|
||||||
|
|
||||||
const dates = computed(() => {
|
const dates = computed(() => {
|
||||||
const first = releases.value[releases.value.length - 1]
|
const first = releases.value[releases.value.length - 1]
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
user-agent: *
|
user-agent: *
|
||||||
disallow: /dev/*
|
|
||||||
|
|||||||
117
package.json
117
package.json
@@ -1,20 +1,29 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/ui",
|
"name": "@nuxt/ui",
|
||||||
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
||||||
"version": "2.19.2",
|
"version": "2.22.1",
|
||||||
"packageManager": "pnpm@9.12.3",
|
"packageManager": "pnpm@10.13.1",
|
||||||
"repository": "nuxt/ui",
|
"repository": {
|
||||||
"homepage": "https://ui.nuxt.com",
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/nuxt/ui.git"
|
||||||
|
},
|
||||||
|
"homepage": "https://ui2.nuxt.com",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./dist/module.mjs",
|
"types": "./dist/module.d.mts",
|
||||||
"require": "./dist/module.cjs"
|
"import": "./dist/module.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"main": "./dist/module.cjs",
|
"typesVersions": {
|
||||||
"types": "./dist/types.d.ts",
|
"*": {
|
||||||
|
".": [
|
||||||
|
"./dist/module.d.mts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"main": "./dist/module.mjs",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
@@ -32,54 +41,78 @@
|
|||||||
"test": "vitest"
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/tailwindcss": "^0.2.1",
|
"@headlessui/tailwindcss": "^0.2.2",
|
||||||
"@headlessui/vue": "^1.7.23",
|
"@headlessui/vue": "^1.7.23",
|
||||||
"@iconify-json/heroicons": "^1.2.1",
|
"@iconify-json/heroicons": "^1.2.2",
|
||||||
"@nuxt/icon": "^1.6.1",
|
"@nuxt/icon": "^1.15.0",
|
||||||
"@nuxt/kit": "^3.14.159",
|
"@nuxt/kit": "^4.0.1",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@nuxtjs/tailwindcss": "^6.12.2",
|
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
|
"@standard-schema/spec": "^1.0.0",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/forms": "^0.5.9",
|
"@tailwindcss/forms": "^0.5.10",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
"@vueuse/core": "^11.2.0",
|
"@vueuse/core": "^13.5.0",
|
||||||
"@vueuse/integrations": "^11.2.0",
|
"@vueuse/integrations": "^13.5.0",
|
||||||
"@vueuse/math": "^11.2.0",
|
"@vueuse/math": "^13.5.0",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.1.0",
|
||||||
"ohash": "^1.1.4",
|
"ohash": "^2.0.11",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^2.0.3",
|
||||||
"scule": "^1.3.0",
|
"scule": "^1.3.0",
|
||||||
"tailwind-merge": "^2.5.4",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss": "^3.4.14"
|
"tailwindcss": "^3.4.17"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^0.6.1",
|
"@nuxt/eslint-config": "^1.6.0",
|
||||||
"@nuxt/module-builder": "^0.8.4",
|
"@nuxt/module-builder": "^1.0.1",
|
||||||
"@nuxt/test-utils": "^3.14.4",
|
"@nuxt/test-utils": "^3.19.2",
|
||||||
"@release-it/conventional-changelog": "^9.0.2",
|
"@release-it/conventional-changelog": "^10.0.1",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.31.0",
|
||||||
"happy-dom": "^14.12.3",
|
"happy-dom": "^18.0.1",
|
||||||
"joi": "^17.13.3",
|
"nuxt": "^4.0.1",
|
||||||
"nuxt": "^3.14.159",
|
"release-it": "^19.0.4",
|
||||||
"release-it": "^17.10.0",
|
"typescript": "^5.8.3",
|
||||||
"superstruct": "^2.0.2",
|
"vitest": "^3.2.4",
|
||||||
"unbuild": "^2.0.0",
|
|
||||||
"valibot": "^0.42.1",
|
|
||||||
"valibot30": "npm:valibot@0.30.0",
|
|
||||||
"valibot31": "npm:valibot@0.31.0",
|
|
||||||
"vitest": "^2.1.4",
|
|
||||||
"vitest-environment-nuxt": "^1.0.1",
|
"vitest-environment-nuxt": "^1.0.1",
|
||||||
"vue-tsc": "^2.1.10",
|
"vue-tsc": "^3.0.3"
|
||||||
"yup": "^1.4.0",
|
},
|
||||||
"zod": "^3.23.8"
|
"peerDependencies": {
|
||||||
|
"joi": "^17.13.0",
|
||||||
|
"superstruct": "^2.0.0",
|
||||||
|
"valibot": "^1.0.0",
|
||||||
|
"yup": "^1.6.0",
|
||||||
|
"zod": "^3.24.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"joi": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"valibot": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"superstruct": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"yup": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"zod": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@nuxt/ui": "workspace:*",
|
"@nuxt/ui": "workspace:*",
|
||||||
"@nuxt/content": "2.13.2",
|
"@nuxt/content": "2.13.2",
|
||||||
"@nuxtjs/mdc": "0.9.0"
|
"@nuxtjs/mdc": "0.9.0",
|
||||||
|
"@vueuse/core": "^13.5.0",
|
||||||
|
"@vueuse/integrations": "^13.5.0",
|
||||||
|
"@vueuse/math": "^13.5.0",
|
||||||
|
"@vueuse/nuxt": "13.1.0",
|
||||||
|
"unimport": "4.1.1",
|
||||||
|
"chokidar": "3.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"nuxt": "^3.14.159"
|
"nuxt": "^4.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12641
pnpm-lock.yaml
generated
12641
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,10 @@
|
|||||||
packages:
|
packages:
|
||||||
- "./"
|
- ./
|
||||||
- "docs"
|
- docs
|
||||||
- "playground"
|
- playground
|
||||||
|
|
||||||
|
ignoredBuiltDependencies:
|
||||||
|
- '@parcel/watcher'
|
||||||
|
- esbuild
|
||||||
|
- sharp
|
||||||
|
- vue-demi
|
||||||
|
|||||||
@@ -5,12 +5,7 @@
|
|||||||
"lockFileMaintenance": {
|
"lockFileMaintenance": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"ignoreDeps": [
|
"baseBranches": ["v2", "v3"],
|
||||||
"happy-dom",
|
|
||||||
"valibot30",
|
|
||||||
"valibot31"
|
|
||||||
],
|
|
||||||
"baseBranches": ["dev", "v3"],
|
|
||||||
"packageRules": [{
|
"packageRules": [{
|
||||||
"matchBaseBranches": ["v3"],
|
"matchBaseBranches": ["v3"],
|
||||||
"labels": ["v3"]
|
"labels": ["v3"]
|
||||||
@@ -24,5 +19,6 @@
|
|||||||
}, {
|
}, {
|
||||||
"matchDepTypes": ["resolutions"],
|
"matchDepTypes": ["resolutions"],
|
||||||
"enabled": false
|
"enabled": false
|
||||||
}]
|
}],
|
||||||
|
"postUpdateOptions": ["pnpmDedupe"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
import { promises as fsp } from 'node:fs'
|
|
||||||
import { resolve } from 'node:path'
|
|
||||||
import { execSync } from 'node:child_process'
|
|
||||||
|
|
||||||
async function loadPackage(dir: string) {
|
|
||||||
const pkgPath = resolve(dir, 'package.json')
|
|
||||||
|
|
||||||
const data = JSON.parse(await fsp.readFile(pkgPath, 'utf-8').catch(() => '{}'))
|
|
||||||
|
|
||||||
const save = () => fsp.writeFile(pkgPath, JSON.stringify(data, null, 2) + '\n')
|
|
||||||
|
|
||||||
return {
|
|
||||||
dir,
|
|
||||||
data,
|
|
||||||
save
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const pkg = await loadPackage(process.cwd())
|
|
||||||
|
|
||||||
const commit = execSync('git rev-parse --short HEAD').toString('utf-8').trim()
|
|
||||||
|
|
||||||
const date = Math.round(Date.now() / (1000 * 60))
|
|
||||||
|
|
||||||
pkg.data.name = `${pkg.data.name}-edge`
|
|
||||||
|
|
||||||
pkg.data.version = `${pkg.data.version}-${date}.${commit}`
|
|
||||||
|
|
||||||
pkg.save()
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch((err) => {
|
|
||||||
console.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Restore all git changes
|
|
||||||
git restore -s@ -SW -- .
|
|
||||||
|
|
||||||
# Bump versions to edge
|
|
||||||
pnpm jiti ./scripts/bump-edge
|
|
||||||
|
|
||||||
# Update token
|
|
||||||
if [[ ! -z ${NODE_AUTH_TOKEN} ]] ; then
|
|
||||||
echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc
|
|
||||||
echo "registry=https://registry.npmjs.org/" >> ~/.npmrc
|
|
||||||
echo "always-auth=true" >> ~/.npmrc
|
|
||||||
npm whoami
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Release package
|
|
||||||
echo "Publishing @nuxt/ui"
|
|
||||||
npm publish -q --access public
|
|
||||||
@@ -13,4 +13,4 @@ fi
|
|||||||
|
|
||||||
# Release package
|
# Release package
|
||||||
echo "Publishing @nuxt/ui"
|
echo "Publishing @nuxt/ui"
|
||||||
npm publish -q --access public
|
npm publish --access public --no-tag
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
|
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
|
||||||
|
import type { ConfigExtension, DefaultClassGroupIds, DefaultThemeGroupIds } from 'tailwind-merge'
|
||||||
import { name, version } from '../package.json'
|
import { name, version } from '../package.json'
|
||||||
import createTemplates from './templates'
|
import createTemplates from './templates'
|
||||||
import type * as config from './runtime/ui.config'
|
import type * as config from './runtime/ui.config'
|
||||||
@@ -20,6 +21,7 @@ type UI = {
|
|||||||
gray?: string
|
gray?: string
|
||||||
colors?: string[]
|
colors?: string[]
|
||||||
strategy?: Strategy
|
strategy?: Strategy
|
||||||
|
tailwindMerge?: ConfigExtension<DefaultClassGroupIds, DefaultThemeGroupIds>
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
} & DeepPartial<typeof config, string | number | boolean>
|
} & DeepPartial<typeof config, string | number | boolean>
|
||||||
|
|
||||||
@@ -41,6 +43,11 @@ export interface ModuleOptions {
|
|||||||
*/
|
*/
|
||||||
global?: boolean
|
global?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
colorMode?: boolean
|
||||||
|
|
||||||
safelistColors?: string[]
|
safelistColors?: string[]
|
||||||
/**
|
/**
|
||||||
* Disables the global css styles added by the module.
|
* Disables the global css styles added by the module.
|
||||||
@@ -59,6 +66,7 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
},
|
},
|
||||||
defaults: {
|
defaults: {
|
||||||
prefix: 'U',
|
prefix: 'U',
|
||||||
|
colorMode: true,
|
||||||
safelistColors: ['primary'],
|
safelistColors: ['primary'],
|
||||||
disableGlobalStyles: false
|
disableGlobalStyles: false
|
||||||
},
|
},
|
||||||
@@ -81,7 +89,9 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
// Modules
|
// Modules
|
||||||
|
|
||||||
await installModule('@nuxt/icon')
|
await installModule('@nuxt/icon')
|
||||||
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
if (options.colorMode) {
|
||||||
|
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
||||||
|
}
|
||||||
await installTailwind(options, nuxt, resolve)
|
await installTailwind(options, nuxt, resolve)
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
|
|||||||
@@ -8,28 +8,27 @@
|
|||||||
</slot>
|
</slot>
|
||||||
<thead :class="ui.thead">
|
<thead :class="ui.thead">
|
||||||
<tr :class="ui.tr.base">
|
<tr :class="ui.tr.base">
|
||||||
<th v-if="modelValue" scope="col" :class="ui.checkbox.padding">
|
|
||||||
<UCheckbox
|
|
||||||
:model-value="isAllRowChecked"
|
|
||||||
:indeterminate="indeterminate"
|
|
||||||
v-bind="ui.default.checkbox"
|
|
||||||
aria-label="Select all"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th v-if="expand" scope="col" :class="ui.tr.base">
|
<th v-if="expand" scope="col" :class="ui.tr.base">
|
||||||
<span class="sr-only">Expand</span>
|
<span class="sr-only">Expand</span>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th
|
<th
|
||||||
v-for="(column, index) in columns"
|
v-for="(column, index) in columns"
|
||||||
:key="index"
|
:key="index"
|
||||||
scope="col"
|
scope="col"
|
||||||
:class="[ui.th.base, ui.th.padding, ui.th.color, ui.th.font, ui.th.size, column.class]"
|
:class="[ui.th.base, ui.th.padding, ui.th.color, ui.th.font, ui.th.size, column.key === 'select' && ui.checkbox.padding, column.class]"
|
||||||
:aria-sort="getAriaSort(column)"
|
:aria-sort="getAriaSort(column)"
|
||||||
>
|
>
|
||||||
<slot :name="`${column.key}-header`" :column="column" :sort="sort" :on-sort="onSort">
|
<slot v-if="!singleSelect && modelValue && column.key === 'select'" name="select-header" :indeterminate="indeterminate" :checked="isAllRowChecked" :change="onChange">
|
||||||
|
<UCheckbox
|
||||||
|
:model-value="isAllRowChecked"
|
||||||
|
:indeterminate="indeterminate"
|
||||||
|
v-bind="ui.default.checkbox"
|
||||||
|
aria-label="Select all"
|
||||||
|
@change="onChange"
|
||||||
|
/>
|
||||||
|
</slot>
|
||||||
|
|
||||||
|
<slot v-else :name="`${column.key}-header`" :column="column" :sort="sort" :on-sort="onSort">
|
||||||
<UButton
|
<UButton
|
||||||
v-if="column.sortable"
|
v-if="column.sortable"
|
||||||
v-bind="{ ...(ui.default.sortButton || {}), ...sortButton }"
|
v-bind="{ ...(ui.default.sortButton || {}), ...sortButton }"
|
||||||
@@ -77,16 +76,7 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-for="(row, index) in rows" :key="index">
|
<template v-for="(row, index) in rows" :key="index">
|
||||||
<tr :class="[ui.tr.base, isSelected(row) && ui.tr.selected, isExpanded(row) && ui.tr.expanded, ($attrs.onSelect || $attrs.onContextmenu) && ui.tr.active, row?.class]" @click="() => onSelect(row)" @contextmenu="(event) => onContextmenu(event, row)">
|
<tr :class="[ui.tr.base, isSelected(row) && ui.tr.selected, isExpanded(row) && ui.tr.expanded, $attrs.onSelect && ui.tr.active, row?.class]" @click="() => onSelect(row)" @contextmenu="(event) => onContextmenu(event, row)">
|
||||||
<td v-if="modelValue" :class="ui.checkbox.padding">
|
|
||||||
<UCheckbox
|
|
||||||
:model-value="isSelected(row)"
|
|
||||||
v-bind="ui.default.checkbox"
|
|
||||||
aria-label="Select row"
|
|
||||||
@change="onChangeCheckbox($event, row)"
|
|
||||||
@click.capture.stop="() => onSelect(row)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td
|
<td
|
||||||
v-if="expand"
|
v-if="expand"
|
||||||
:class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size]"
|
:class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size]"
|
||||||
@@ -102,8 +92,26 @@
|
|||||||
@click.capture.stop="toggleOpened(row)"
|
@click.capture.stop="toggleOpened(row)"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size, column?.rowClass, row[column.key]?.class]">
|
<td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size, column?.rowClass, row[column.key]?.class, column.key === 'select' && ui.checkbox.padding]">
|
||||||
<slot :name="`${column.key}-data`" :column="column" :row="row" :index="index" :get-row-data="(defaultValue) => getRowData(row, column.key, defaultValue)">
|
<!-- This is a workaround: Since the @change event doesn't bubble up naturally, we need to wrap it in another element and use @click.capture.stop to simulate event bubbling behavior -->
|
||||||
|
<span v-if="modelValue && column.key === 'select' " @click.capture.stop="() => {}">
|
||||||
|
<slot name="select-data" :checked="isSelected(row)" :change="(ev: boolean) => onChangeCheckbox(ev, row)">
|
||||||
|
<UCheckbox
|
||||||
|
:model-value="isSelected(row)"
|
||||||
|
v-bind="ui.default.checkbox"
|
||||||
|
aria-label="Select row"
|
||||||
|
@change="onChangeCheckbox($event, row)"
|
||||||
|
/>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
<slot
|
||||||
|
v-else
|
||||||
|
:name="`${column.key}-data`"
|
||||||
|
:column="column"
|
||||||
|
:row="row"
|
||||||
|
:index="index"
|
||||||
|
:get-row-data="(defaultValue) => getRowData(row, column.key, defaultValue)"
|
||||||
|
>
|
||||||
{{ getRowData(row, column.key) }}
|
{{ getRowData(row, column.key) }}
|
||||||
</slot>
|
</slot>
|
||||||
</td>
|
</td>
|
||||||
@@ -130,12 +138,13 @@ import type { PropType, AriaAttributes } from 'vue'
|
|||||||
import { upperFirst } from 'scule'
|
import { upperFirst } from 'scule'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
|
import { isEqual } from 'ohash/utils'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import UButton from '../elements/Button.vue'
|
import UButton from '../elements/Button.vue'
|
||||||
import UProgress from '../elements/Progress.vue'
|
import UProgress from '../elements/Progress.vue'
|
||||||
import UCheckbox from '../forms/Checkbox.vue'
|
import UCheckbox from '../forms/Checkbox.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, get } from '../../utils'
|
import { get, mergeConfig } from '../../utils'
|
||||||
import type { TableRow, TableColumn, Strategy, Button, ProgressColor, ProgressAnimation, DeepPartial, Expanded } from '../../types/index'
|
import type { TableRow, TableColumn, Strategy, Button, ProgressColor, ProgressAnimation, DeepPartial, Expanded } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
@@ -144,7 +153,7 @@ import { table } from '#ui/ui.config'
|
|||||||
const config = mergeConfig<typeof table>(appConfig.ui.strategy, appConfig.ui.table, table)
|
const config = mergeConfig<typeof table>(appConfig.ui.strategy, appConfig.ui.table, table)
|
||||||
|
|
||||||
function defaultComparator<T>(a: T, z: T): boolean {
|
function defaultComparator<T>(a: T, z: T): boolean {
|
||||||
return JSON.stringify(a) === JSON.stringify(z)
|
return isEqual(a, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultSort(a: any, b: any, direction: 'asc' | 'desc') {
|
function defaultSort(a: any, b: any, direction: 'asc' | 'desc') {
|
||||||
@@ -159,6 +168,14 @@ function defaultSort(a: any, b: any, direction: 'asc' | 'desc') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStringifiedSet(arr: TableRow[]) {
|
||||||
|
return new Set(arr.map(item => JSON.stringify(item)))
|
||||||
|
}
|
||||||
|
|
||||||
|
function accessor<T extends Record<string, any>>(key: string) {
|
||||||
|
return (obj: T) => get(obj, key)
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
UIcon,
|
UIcon,
|
||||||
@@ -221,7 +238,7 @@ export default defineComponent({
|
|||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
loadingState: {
|
loadingState: {
|
||||||
type: Object as PropType<{ icon: string, label: string }>,
|
type: Object as PropType<{ icon: string, label: string } | null>,
|
||||||
default: () => config.default.loadingState
|
default: () => config.default.loadingState
|
||||||
},
|
},
|
||||||
emptyState: {
|
emptyState: {
|
||||||
@@ -247,13 +264,40 @@ export default defineComponent({
|
|||||||
multipleExpand: {
|
multipleExpand: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
singleSelect: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue', 'update:sort', 'update:expand'],
|
emits: ['update:modelValue', 'update:sort', 'update:expand', 'select:all'],
|
||||||
setup(props, { emit, attrs: $attrs }) {
|
setup(props, { emit, attrs: $attrs }) {
|
||||||
const { ui, attrs } = useUI('table', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('table', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
const columns = computed(() => props.columns ?? Object.keys(props.rows[0] ?? {}).map(key => ({ key, label: upperFirst(key), sortable: false, class: undefined, sort: defaultSort }) as TableColumn))
|
const columns = computed(() => {
|
||||||
|
const defaultColumns = props.columns ?? (
|
||||||
|
Object.keys(props.rows[0]).map(key => ({
|
||||||
|
key,
|
||||||
|
label: upperFirst(key),
|
||||||
|
sortable: false,
|
||||||
|
class: undefined,
|
||||||
|
sort: defaultSort
|
||||||
|
}))
|
||||||
|
) as TableColumn[]
|
||||||
|
|
||||||
|
const hasColumnSelect = defaultColumns.find(v => v.key === 'select')
|
||||||
|
|
||||||
|
if (hasColumnSelect || !props.modelValue) {
|
||||||
|
return defaultColumns
|
||||||
|
}
|
||||||
|
|
||||||
|
return [{
|
||||||
|
key: 'select',
|
||||||
|
sortable: false,
|
||||||
|
class: undefined,
|
||||||
|
sort: defaultSort
|
||||||
|
}, ...defaultColumns]
|
||||||
|
})
|
||||||
|
|
||||||
const sort = useVModel(props, 'sort', emit, { passive: true, defaultValue: defu({}, props.sort, { column: null, direction: 'asc' }) })
|
const sort = useVModel(props, 'sort', emit, { passive: true, defaultValue: defu({}, props.sort, { column: null, direction: 'asc' }) })
|
||||||
const expand = useVModel(props, 'expand', emit, {
|
const expand = useVModel(props, 'expand', emit, {
|
||||||
@@ -292,8 +336,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const getStringifiedSet = (arr: TableRow[]) => new Set(arr.map(item => JSON.stringify(item)))
|
|
||||||
|
|
||||||
const totalRows = computed(() => props.rows.length)
|
const totalRows = computed(() => props.rows.length)
|
||||||
|
|
||||||
const countCheckedRow = computed(() => {
|
const countCheckedRow = computed(() => {
|
||||||
@@ -328,10 +370,6 @@ export default defineComponent({
|
|||||||
return props.by(a, z)
|
return props.by(a, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
function accessor<T extends Record<string, any>>(key: string) {
|
|
||||||
return (obj: T) => get(obj, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSelected(row: TableRow) {
|
function isSelected(row: TableRow) {
|
||||||
if (!props.modelValue) {
|
if (!props.modelValue) {
|
||||||
return false
|
return false
|
||||||
@@ -355,6 +393,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onSelect(row: TableRow) {
|
function onSelect(row: TableRow) {
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection && selection.toString().length > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!$attrs.onSelect) {
|
if (!$attrs.onSelect) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -393,14 +436,14 @@ export default defineComponent({
|
|||||||
} else {
|
} else {
|
||||||
selected.value = []
|
selected.value = []
|
||||||
}
|
}
|
||||||
|
emit('select:all', checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChangeCheckbox(checked: boolean, row: TableRow) {
|
function onChangeCheckbox(checked: boolean, row: TableRow) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
selected.value.push(row)
|
selected.value = props.singleSelect ? [row] : [...selected.value, row]
|
||||||
} else {
|
} else {
|
||||||
const index = selected.value.findIndex(item => compare(item, row))
|
selected.value = selected.value.filter(value => !compare(toRaw(value), toRaw(row)))
|
||||||
selected.value.splice(index, 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['open'],
|
emits: ['open', 'close'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const { ui, attrs } = useUI('accordion', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('accordion', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
@@ -142,6 +142,8 @@ export default defineComponent({
|
|||||||
|
|
||||||
if (!isOpenBefore && isOpenAfter) {
|
if (!isOpenBefore && isOpenAfter) {
|
||||||
emit('open', index)
|
emit('open', index)
|
||||||
|
} else if (isOpenBefore && !isOpenAfter) {
|
||||||
|
emit('close', index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{{ title }}
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
</p>
|
</p>
|
||||||
<div v-if="description || $slots.description" :class="twMerge(ui.description, !title && !$slots.title && 'mt-0 leading-5')">
|
<div v-if="description || $slots.description" :class="twMerge(ui.description, !title && !$slots.title && ui.descriptionOnly)">
|
||||||
<slot name="description" :description="description">
|
<slot name="description" :description="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</slot>
|
</slot>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, toRef, defineComponent } from 'vue'
|
import { computed, toRef, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import UAvatar from '../elements/Avatar.vue'
|
import UAvatar from '../elements/Avatar.vue'
|
||||||
import UButton from '../elements/Button.vue'
|
import UButton from '../elements/Button.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import type { Avatar, Button, AlertColor, AlertVariant, AlertAction, Strategy, DeepPartial } from '../../types/index'
|
import type { Avatar, Button, AlertColor, AlertVariant, AlertAction, Strategy, DeepPartial } from '../../types/index'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, twMerge } from '../../utils'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
import { alert } from '#ui/ui.config'
|
import { alert } from '#ui/ui.config'
|
||||||
|
|||||||
@@ -23,10 +23,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, computed, toRef, watch } from 'vue'
|
import { defineComponent, ref, computed, toRef, watch } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, twMerge } from '../../utils'
|
||||||
import type { AvatarSize, AvatarChipColor, AvatarChipPosition, Strategy, DeepPartial } from '../../types/index'
|
import type { AvatarSize, AvatarChipColor, AvatarChipPosition, Strategy, DeepPartial } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { h, cloneVNode, computed, toRef, defineComponent } from 'vue'
|
import { h, cloneVNode, computed, toRef, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, getSlotsChildren } from '../../utils'
|
import { getSlotsChildren, mergeConfig, twMerge } from '../../utils'
|
||||||
import type { AvatarSize, DeepPartial, Strategy } from '../../types/index'
|
import type { AvatarSize, DeepPartial, Strategy } from '../../types/index'
|
||||||
import UAvatar from './Avatar.vue'
|
import UAvatar from './Avatar.vue'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|||||||
@@ -1,15 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<span :class="badgeClass" v-bind="attrs">
|
<span :class="badgeClass" v-bind="attrs">
|
||||||
<slot>{{ label }}</slot>
|
<slot name="leading">
|
||||||
|
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
|
||||||
|
</slot>
|
||||||
|
|
||||||
|
<slot>
|
||||||
|
<span v-if="label !== undefined && label !== null">
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
|
</slot>
|
||||||
|
|
||||||
|
<slot name="trailing">
|
||||||
|
<UIcon v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass" aria-hidden="true" />
|
||||||
|
</slot>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, toRef, defineComponent } from 'vue'
|
import { computed, toRef, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
|
import UIcon from '../elements/Icon.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, twMerge } from '../../utils'
|
||||||
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
||||||
import type { BadgeColor, BadgeSize, BadgeVariant, DeepPartial, Strategy } from '../../types/index'
|
import type { BadgeColor, BadgeSize, BadgeVariant, DeepPartial, Strategy } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -19,6 +32,9 @@ import { badge } from '#ui/ui.config'
|
|||||||
const config = mergeConfig<typeof badge>(appConfig.ui.strategy, appConfig.ui.badge, badge)
|
const config = mergeConfig<typeof badge>(appConfig.ui.strategy, appConfig.ui.badge, badge)
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
UIcon
|
||||||
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
@@ -49,6 +65,26 @@ export default defineComponent({
|
|||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
leadingIcon: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
trailingIcon: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
trailing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
leading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
class: {
|
class: {
|
||||||
type: [String, Object, Array] as PropType<any>,
|
type: [String, Object, Array] as PropType<any>,
|
||||||
default: () => ''
|
default: () => ''
|
||||||
@@ -63,6 +99,14 @@ export default defineComponent({
|
|||||||
|
|
||||||
const { size, rounded } = useInjectButtonGroup({ ui, props })
|
const { size, rounded } = useInjectButtonGroup({ ui, props })
|
||||||
|
|
||||||
|
const isLeading = computed(() => {
|
||||||
|
return (props.icon && props.leading) || (props.icon && !props.trailing) || !props.trailing || props.leadingIcon
|
||||||
|
})
|
||||||
|
|
||||||
|
const isTrailing = computed(() => {
|
||||||
|
return (props.icon && props.trailing) || props.trailing || props.trailingIcon
|
||||||
|
})
|
||||||
|
|
||||||
const badgeClass = computed(() => {
|
const badgeClass = computed(() => {
|
||||||
const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
||||||
|
|
||||||
@@ -71,13 +115,42 @@ export default defineComponent({
|
|||||||
ui.value.font,
|
ui.value.font,
|
||||||
rounded.value,
|
rounded.value,
|
||||||
ui.value.size[size.value],
|
ui.value.size[size.value],
|
||||||
|
ui.value.gap[size.value],
|
||||||
variant?.replaceAll('{color}', props.color)
|
variant?.replaceAll('{color}', props.color)
|
||||||
), props.class)
|
), props.class)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const leadingIconName = computed(() => {
|
||||||
|
return props.leadingIcon || props.icon
|
||||||
|
})
|
||||||
|
|
||||||
|
const trailingIconName = computed(() => {
|
||||||
|
return props.trailingIcon || props.icon
|
||||||
|
})
|
||||||
|
|
||||||
|
const leadingIconClass = computed(() => {
|
||||||
|
return twJoin(
|
||||||
|
ui.value.icon.base,
|
||||||
|
ui.value.icon.size[size.value]
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const trailingIconClass = computed(() => {
|
||||||
|
return twJoin(
|
||||||
|
ui.value.icon.base,
|
||||||
|
ui.value.icon.size[size.value]
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attrs,
|
attrs,
|
||||||
badgeClass
|
isLeading,
|
||||||
|
isTrailing,
|
||||||
|
badgeClass,
|
||||||
|
leadingIconName,
|
||||||
|
trailingIconName,
|
||||||
|
leadingIconClass,
|
||||||
|
trailingIconClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<slot>
|
<slot>
|
||||||
<span v-if="label" :class="[truncate ? ui.truncate : '']">
|
<span v-if="label !== undefined && label !== null" :class="[truncate ? ui.truncate : '']">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</span>
|
</span>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, toRef } from 'vue'
|
import { computed, defineComponent, toRef } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import ULink from '../elements/Link.vue'
|
import ULink from '../elements/Link.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, nuxtLinkProps, getNuxtLinkProps } from '../../utils'
|
import { getNuxtLinkProps, mergeConfig, nuxtLinkProps, twMerge } from '../../utils'
|
||||||
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
||||||
import type { ButtonColor, ButtonSize, ButtonVariant, DeepPartial, Strategy } from '../../types/index'
|
import type { ButtonColor, ButtonSize, ButtonVariant, DeepPartial, Strategy } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { h, computed, toRef, defineComponent } from 'vue'
|
import { h, computed, toRef, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, getSlotsChildren } from '../../utils'
|
import { getSlotsChildren, mergeConfig, twMerge } from '../../utils'
|
||||||
import { useProvideButtonGroup } from '../../composables/useButtonGroup'
|
import { useProvideButtonGroup } from '../../composables/useButtonGroup'
|
||||||
import type { ButtonSize, DeepPartial, Strategy } from '../../types/index'
|
import type { ButtonSize, DeepPartial, Strategy } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|||||||
@@ -58,9 +58,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, toRef, computed, defineComponent } from 'vue'
|
import { ref, toRef, computed, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge } from 'tailwind-merge'
|
|
||||||
import { useScroll, useResizeObserver, useElementSize } from '@vueuse/core'
|
import { useScroll, useResizeObserver, useElementSize } from '@vueuse/core'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, twMerge } from '../../utils'
|
||||||
import UButton from '../elements/Button.vue'
|
import UButton from '../elements/Button.vue'
|
||||||
import type { Strategy, Button, DeepPartial } from '../../types/index'
|
import type { Strategy, Button, DeepPartial } from '../../types/index'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
@@ -106,7 +105,7 @@ export default defineComponent({
|
|||||||
default: () => ''
|
default: () => ''
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
type: Object as PropType<DeepPartial<typeof config & { strategy?: Strategy }>>,
|
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
||||||
default: undefined
|
default: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,13 +60,13 @@ import { defineComponent, ref, computed, watch, toRef, onMounted, resolveCompone
|
|||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { Menu as HMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem, provideUseId } from '@headlessui/vue'
|
import { Menu as HMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem, provideUseId } from '@headlessui/vue'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import UAvatar from '../elements/Avatar.vue'
|
import UAvatar from '../elements/Avatar.vue'
|
||||||
import UKbd from '../elements/Kbd.vue'
|
import UKbd from '../elements/Kbd.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { usePopper } from '../../composables/usePopper'
|
import { usePopper } from '../../composables/usePopper'
|
||||||
import { mergeConfig, getNuxtLinkProps } from '../../utils'
|
import { getNuxtLinkProps, mergeConfig, twMerge } from '../../utils'
|
||||||
import type { DeepPartial, DropdownItem, PopperOptions, Strategy } from '../../types/index'
|
import type { DeepPartial, DropdownItem, PopperOptions, Strategy } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toRef, defineComponent, computed } from 'vue'
|
import { toRef, defineComponent, computed } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, twMerge } from '../../utils'
|
||||||
import type { DeepPartial, KbdSize, Strategy } from '../../types/index'
|
import type { DeepPartial, KbdSize, Strategy } from '../../types/index'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
|
|||||||
@@ -32,8 +32,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { isEqual } from 'ohash'
|
import { isEqual, diff } from 'ohash/utils'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
import { nuxtLinkProps } from '../../utils'
|
import { nuxtLinkProps } from '../../utils'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -61,7 +62,7 @@ export default defineComponent({
|
|||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
exactQuery: {
|
exactQuery: {
|
||||||
type: Boolean,
|
type: [Boolean, String] as PropType<boolean | 'partial'>,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
exactHash: {
|
exactHash: {
|
||||||
@@ -74,9 +75,25 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
function isPartiallyEqual(item1: any, item2: any) {
|
||||||
|
const diffedKeys = diff(item1, item2).reduce((filtered, q) => {
|
||||||
|
if (q.type === 'added') {
|
||||||
|
filtered.add(q.key)
|
||||||
|
}
|
||||||
|
return filtered
|
||||||
|
}, new Set<string>())
|
||||||
|
|
||||||
|
const item1Filtered = Object.fromEntries(Object.entries(item1).filter(([key]) => !diffedKeys.has(key)))
|
||||||
|
const item2Filtered = Object.fromEntries(Object.entries(item2).filter(([key]) => !diffedKeys.has(key)))
|
||||||
|
|
||||||
|
return isEqual(item1Filtered, item2Filtered)
|
||||||
|
}
|
||||||
|
|
||||||
function resolveLinkClass(route, $route, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
|
function resolveLinkClass(route, $route, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
|
||||||
if (props.exactQuery && !isEqual(route.query, $route.query)) {
|
if (props.exactQuery === 'partial') {
|
||||||
return props.inactiveClass
|
if (!isPartiallyEqual(route.query, $route.query)) return props.inactiveClass
|
||||||
|
} else if (props.exactQuery === true) {
|
||||||
|
if (!isEqual(route.query, $route.query)) return props.inactiveClass
|
||||||
}
|
}
|
||||||
if (props.exactHash && route.hash !== $route.hash) {
|
if (props.exactHash && route.hash !== $route.hash) {
|
||||||
return props.inactiveClass
|
return props.inactiveClass
|
||||||
|
|||||||
@@ -46,10 +46,6 @@ export default defineComponent({
|
|||||||
UIcon
|
UIcon
|
||||||
},
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
slots: Object as SlotsType<{
|
|
||||||
indicator?: { percent: number, value: number }
|
|
||||||
label?: { percent: number, value: number }
|
|
||||||
}>,
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@@ -98,6 +94,10 @@ export default defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
slots: Object as SlotsType<{
|
||||||
|
indicator?: { percent: number, value: number }
|
||||||
|
label?: { percent: number, value: number }
|
||||||
|
}>,
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { ui, attrs } = useUI('meter', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('meter', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { ComputedRef, VNode, SlotsType, PropType } from 'vue'
|
|||||||
import { twJoin } from 'tailwind-merge'
|
import { twJoin } from 'tailwind-merge'
|
||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, getSlotsChildren } from '../../utils'
|
import { getSlotsChildren, mergeConfig } from '../../utils'
|
||||||
import type { DeepPartial, Strategy, MeterSize } from '../../types/index'
|
import type { DeepPartial, Strategy, MeterSize } from '../../types/index'
|
||||||
import type Meter from './Meter.vue'
|
import type Meter from './Meter.vue'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user