mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 20:48:12 +01:00
Compare commits
148 Commits
| 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 |
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
|
||||
attributes:
|
||||
value: |
|
||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before reporting a bug, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: textarea
|
||||
id: env
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before requesting a feature, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/question.yml
vendored
2
.github/ISSUE_TEMPLATE/question.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before asking a question, please make sure that you have read through our [documentation](https://ui.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
Before asking a question, please make sure that you have read through our [documentation](https://ui2.nuxt.com) and existing [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
name: ci-dev
|
||||
name: module
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- v2
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
- v2
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [20]
|
||||
node: [22]
|
||||
|
||||
env:
|
||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
@@ -37,16 +37,6 @@ jobs:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Filter changes
|
||||
uses: dorny/paths-filter@v3
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- 'src/**'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
@@ -65,8 +55,5 @@ jobs:
|
||||
- name: Test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Release Edge
|
||||
if: github.event_name == 'push' && steps.changes.outputs.src == 'true'
|
||||
run: ./scripts/release-edge.sh
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
|
||||
- name: Publish
|
||||
run: pnpx pkg-pr-new publish --compact --no-template --pnpm
|
||||
@@ -1,18 +1,18 @@
|
||||
name: ci-main
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- 'v2*'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
publish:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||
node: [20]
|
||||
node: [22]
|
||||
|
||||
env:
|
||||
NUXT_GITHUB_TOKEN: ${{ secrets.NUXT_GITHUB_TOKEN }}
|
||||
@@ -48,14 +48,7 @@ jobs:
|
||||
- name: Test
|
||||
run: pnpm run test run
|
||||
|
||||
- name: Version Check
|
||||
id: check
|
||||
uses: EndBug/version-check@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release
|
||||
if: github.event_name == 'push' && steps.check.outputs.changed == 'true'
|
||||
- name: Publish
|
||||
run: ./scripts/release.sh
|
||||
env:
|
||||
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
|
||||
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,5 +1,40 @@
|
||||
# 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
|
||||
|
||||
33
README.md
33
README.md
@@ -1,4 +1,4 @@
|
||||
[](https://ui.nuxt.com)
|
||||
[](https://ui2.nuxt.com)
|
||||
|
||||
# Nuxt UI
|
||||
|
||||
@@ -22,27 +22,32 @@ Its goal is to provide everything related to UI when building a Nuxt app. This i
|
||||
- Fully typed
|
||||
- [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
|
||||
|
||||
```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
|
||||
{
|
||||
"devDependencies": {
|
||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
||||
}
|
||||
}
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
modules: ['@nuxt/ui']
|
||||
})
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit https://ui.nuxt.com to explore the documentation.
|
||||
Visit https://ui2.nuxt.com to explore the documentation.
|
||||
|
||||
## 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:
|
||||
|
||||
- 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
|
||||
|
||||
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
|
||||
|
||||
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 -->
|
||||
[npm-version-src]: https://img.shields.io/npm/v/@nuxt/ui/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<NuxtLoadingIndicator />
|
||||
|
||||
<!-- <Banner v-if="!$route.path.startsWith('/examples')" /> -->
|
||||
<Banner v-if="!$route.path.startsWith('/examples')" />
|
||||
|
||||
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />
|
||||
|
||||
@@ -91,7 +91,7 @@ useHead({
|
||||
],
|
||||
link: [
|
||||
{ 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: {
|
||||
lang: 'en'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
const id = 'nuxt-ui-banner-3'
|
||||
const to = '/pro/pricing'
|
||||
const id = 'nuxt-ui-banner-4'
|
||||
const to = 'https://ui.nuxt.com'
|
||||
|
||||
const hideBanner = () => {
|
||||
localStorage.setItem(id, 'true')
|
||||
@@ -28,8 +28,8 @@ if (import.meta.server) {
|
||||
<NuxtLink
|
||||
v-if="to"
|
||||
:to="to"
|
||||
target="_blank"
|
||||
class="focus:outline-none"
|
||||
aria-label="20% off on all Nuxt UI Pro products for Black Friday week"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span class="absolute inset-0 " aria-hidden="true" />
|
||||
@@ -39,8 +39,8 @@ if (import.meta.server) {
|
||||
<div class="lg:flex-1 hidden lg:flex items-center" />
|
||||
|
||||
<p class="text-sm font-medium text-white dark:text-gray-900 truncate">
|
||||
<UIcon name="i-ri-discount-percent-fill" class="size-5 align-top flex-shrink-0 pointer-events-none mr-2" />
|
||||
<span class="font-bold">Black Friday Week</span>: <UBadge label="20% off" color="white" class="ring-0 font-semibold" /> on all Nuxt UI Pro products from <span class="font-semibold">Nov 25</span> to <span class="font-semibold">Dec 2</span>!
|
||||
<UIcon name="i-lucide-rocket" class="size-5 align-top flex-shrink-0 pointer-events-none mr-1.5" />
|
||||
<span class="font-bold">Nuxt UI v3</span> is officially released!
|
||||
</p>
|
||||
|
||||
<!-- <UButton
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</NuxtLink>
|
||||
|
||||
<UDropdown
|
||||
:items="[[{ label: $route.path.startsWith('/pro') ? `v${pkg.version.split('-')[0]}` : `v${config.version}`, class: 'text-primary-500 dark:text-primary-400' }, { label: 'v3.0.0-alpha.x', to: 'https://ui3.nuxt.dev' }]]"
|
||||
: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',
|
||||
@@ -50,7 +50,7 @@
|
||||
<UColorModeButton class="hidden lg:inline-flex" />
|
||||
|
||||
<UButton
|
||||
to="https://github.com/nuxt/ui/tree/dev"
|
||||
to="https://github.com/nuxt/ui/tree/v2"
|
||||
target="_blank"
|
||||
icon="i-simple-icons-github"
|
||||
aria-label="GitHub"
|
||||
|
||||
@@ -9,7 +9,7 @@ onMounted(() => {
|
||||
if (carbonads.value) {
|
||||
const script = document.createElement('script')
|
||||
script.setAttribute('type', 'text/javascript')
|
||||
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CWYIVK3E&placement=uinuxtcom')
|
||||
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CW7IC53I&placement=ui2nuxtcom')
|
||||
script.setAttribute('id', '_carbonads_js')
|
||||
carbonads.value.appendChild(script)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<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 = [
|
||||
{ label: 'Last 7 days', duration: { days: 7 } },
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<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'
|
||||
|
||||
const schema = object({
|
||||
|
||||
@@ -21,7 +21,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UForm :schema="v.safeParser(schema)" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UForm :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup label="Email" name="email">
|
||||
<UInput v-model="state.email" />
|
||||
</UFormGroup>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<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'
|
||||
|
||||
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>
|
||||
@@ -31,7 +31,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<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">
|
||||
<RangeExample />
|
||||
</div>
|
||||
|
||||
@@ -7,13 +7,29 @@ description: 'Learn how to install and configure Nuxt UI in your application.'
|
||||
|
||||
### Add to a Nuxt project
|
||||
|
||||
1. Add `@nuxt/ui` module to your project:
|
||||
1. Install the `@nuxt/ui` dependency in your project:
|
||||
|
||||
```bash
|
||||
npx nuxi@latest module add ui
|
||||
::code-group
|
||||
|
||||
```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]
|
||||
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.
|
||||
|
||||
```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.
|
||||
@@ -94,7 +110,7 @@ You can read more about this in the [Theming](/getting-started/theming#dark-mode
|
||||
|
||||
## 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"}
|
||||
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. |
|
||||
| `global` | `false` | Expose components globally. |
|
||||
| `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:
|
||||
|
||||
@@ -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]
|
||||
{
|
||||
"devDependencies": {
|
||||
- "@nuxt/ui": "^2.11.0"
|
||||
+ "@nuxt/ui": "npm:@nuxt/ui-edge@latest"
|
||||
"dependencies": {
|
||||
- "@nuxt/ui": "^2.21.0",
|
||||
+ "@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`.
|
||||
|
||||
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]
|
||||
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.
|
||||
|
||||
@@ -389,6 +389,12 @@ export default defineAppConfig({
|
||||
loadingIcon: 'i-octicon-sync-24'
|
||||
}
|
||||
},
|
||||
inputMenu: {
|
||||
default: {
|
||||
selectedIcon: 'i-octicon-check-24',
|
||||
trailingIcon: 'i-octicon-chevron-down-24'
|
||||
}
|
||||
},
|
||||
select: {
|
||||
default: {
|
||||
loadingIcon: 'i-octicon-sync-24',
|
||||
@@ -424,6 +430,9 @@ export default defineAppConfig({
|
||||
sortButton: {
|
||||
icon: 'i-octicon-arrow-switch-24'
|
||||
},
|
||||
expandButton: {
|
||||
icon: 'i-octicon-chevron-down-24'
|
||||
},
|
||||
loadingState: {
|
||||
icon: 'i-octicon-sync-24'
|
||||
},
|
||||
@@ -457,6 +466,21 @@ export default defineAppConfig({
|
||||
default: {
|
||||
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.
|
||||
|
||||
Modifiers are also available:
|
||||
- `meta`: acts as `Command` for MacOS and `Control` for others
|
||||
- `ctrl`: acts as `Control`
|
||||
- `shift`: acts as `Shift` and is only necessary for alphabetic keys
|
||||
| Modifier | Description |
|
||||
|----------|-------------|
|
||||
| `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:
|
||||
- `escape`: will trigger by hitting `Esc`
|
||||
- `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
|
||||
- `shift_e`: will trigger by hitting `Shift` and `E` at the same time on MacOS, Windows and Linux
|
||||
- `?`: will trigger by hitting `?` on some keyboard layouts, or for example `Shift` and `/`, which results in `?` on US Mac keyboards
|
||||
- `g-d`: will trigger by hitting `g` then `d` with a maximum delay of 800ms by default
|
||||
- `arrowleft`: will trigger by hitting `←` (also: `arrowright`, `arrowup`, `arrowdown`)
|
||||
| Shortcut Key | Action |
|
||||
|---------------|--------|
|
||||
| `escape` | Triggers when `Esc` is pressed |
|
||||
| `meta_k` | `⌘ + K` on Mac, `Ctrl + K` on Windows/Linux |
|
||||
| `ctrl_k` | Triggers `Ctrl + K` on all OS |
|
||||
| `shift_e` | Triggers `Shift + E` on all OS |
|
||||
| `?` | 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"}
|
||||
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'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display an alert element to draw attention.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display an image that represents a resource or a group of resources
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a short text to represent a status or a category.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: A list of links that indicate the current page's location within a
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Create a button with icon or link capabilities.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a card for content with a header, body and footer.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display images or content in a scrollable area.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a checkbox field.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a chip indicator on any component.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -7,7 +7,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/combobox'
|
||||
- label: 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
|
||||
@@ -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!
|
||||
::
|
||||
|
||||
@@ -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!
|
||||
::
|
||||
|
||||
@@ -3,7 +3,7 @@ description: A container lets you center and constrain the width of your content
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a menu that appears on right click.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a separator between content.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -6,7 +6,7 @@ links:
|
||||
to: https://headlessui.com/v1/vue/menu
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a label and additional informations around a form element.
|
||||
links:
|
||||
- label: 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:
|
||||
- label: 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
|
||||
@@ -14,7 +14,7 @@ It works with the [FormGroup](/components/form-group) component to display error
|
||||
|
||||
The form component requires two props:
|
||||
- `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"}
|
||||
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!
|
||||
::
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a list of horizontal links.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -7,7 +7,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/combobox'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display an input field.
|
||||
links:
|
||||
- label: 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
|
||||
@@ -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
|
||||
|
||||
### `leading`
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a keyboard key in a text block.
|
||||
links:
|
||||
- label: 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:
|
||||
title: 'Kbd'
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Render a NuxtLink but with superpowers.
|
||||
links:
|
||||
- label: 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
|
||||
@@ -14,7 +14,7 @@ The Link component is a wrapper around [`<NuxtLink>`](https://nuxt.com/docs/api/
|
||||
- `inactive-class` prop to set a class when the link is inactive, `active-class` is used when active.
|
||||
- `exact` prop to style with `active-class` when the link is active and the route is exactly the same as the current route.
|
||||
- `exact-query` and `exact-hash` props to style with `active-class` when the link is active and the query or hash is exactly the same as the current query or hash.
|
||||
- use `exact-query="partial"` to style with `active-class` when the link is active and the query partially match the current query.
|
||||
- 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.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a gauge meter that fills or depletes.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -6,7 +6,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/dialog'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a toast notification in your app.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Add a pagination to handle pages.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -6,7 +6,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/popover'
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Show a horizontal bar to indicate task progression.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a set of radio buttons.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a range field
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -7,7 +7,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/listbox'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a select field.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a placeholder while content is loading.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -6,7 +6,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/dialog'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: 'Display data in a table.'
|
||||
links:
|
||||
- label: 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
|
||||
@@ -311,9 +311,9 @@ const onUpdateSelection = (selectedRows: any[]) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable
|
||||
v-model="selected"
|
||||
:rows="people"
|
||||
<UTable
|
||||
v-model="selected"
|
||||
:rows="people"
|
||||
@select:all="onHandleSelectAll"
|
||||
@update:modelValue="onUpdateSelection"
|
||||
/>
|
||||
@@ -598,7 +598,7 @@ This slot allows you to customize the checkbox appearance in the table header fo
|
||||
#### Usage
|
||||
```vue
|
||||
<template>
|
||||
<UTable v-model="selectable">
|
||||
<UTable v-model="selectable">
|
||||
<template #select-header="{ checked, change, indeterminate }">
|
||||
<!-- Place your custom component here -->
|
||||
</template>
|
||||
@@ -620,7 +620,7 @@ This slot allows you to customize the checkbox appearance in the table header fo
|
||||
<UTable>
|
||||
<!-- Header checkbox customization -->
|
||||
<template #select-header="{ indeterminate, checked, change }">
|
||||
<input
|
||||
<input
|
||||
type="checkbox"
|
||||
:indeterminate="indeterminate"
|
||||
:checked="checked"
|
||||
@@ -658,7 +658,7 @@ This slot allows you to customize the checkbox appearance for each row in the ta
|
||||
<UTable>
|
||||
<!-- Row checkbox customization -->
|
||||
<template #select-data="{ checked, change }">
|
||||
<input
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="checked"
|
||||
@change="e => change(e.target.checked)"
|
||||
@@ -769,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!
|
||||
::
|
||||
|
||||
@@ -3,7 +3,7 @@ description: A set of tab panels that are displayed one at a time.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display a textarea field.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -6,7 +6,7 @@ links:
|
||||
to: 'https://headlessui.com/v1/vue/switch'
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Display content that appears on hover next to an element.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Display a list of vertical links.
|
||||
links:
|
||||
- label: 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
|
||||
|
||||
@@ -3,7 +3,7 @@ title: '<span class="text-primary">Nuxt UI</span> Releases'
|
||||
head.title: Releases
|
||||
description: Follow the latest releases and updates happening on the nuxt/ui repository.
|
||||
links:
|
||||
- label: Get Started
|
||||
- label: Get started
|
||||
trailingIcon: i-heroicons-arrow-right-20-solid
|
||||
to: /getting-started
|
||||
size: md
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<div>
|
||||
<NuxtLoadingIndicator />
|
||||
|
||||
<Banner />
|
||||
|
||||
<Header :links="links" />
|
||||
|
||||
<UContainer>
|
||||
|
||||
@@ -15,7 +15,7 @@ export default defineNuxtConfig({
|
||||
]
|
||||
: [
|
||||
'@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),
|
||||
|
||||
modules: [
|
||||
@@ -26,12 +26,11 @@ export default defineNuxtConfig({
|
||||
module,
|
||||
'@nuxtjs/plausible',
|
||||
'@vueuse/nuxt',
|
||||
'nuxt-component-meta',
|
||||
'nuxt-cloudflare-analytics'
|
||||
'nuxt-component-meta'
|
||||
],
|
||||
|
||||
site: {
|
||||
url: 'https://ui.nuxt.com'
|
||||
url: 'https://ui2.nuxt.com'
|
||||
},
|
||||
|
||||
content: {
|
||||
@@ -53,7 +52,7 @@ export default defineNuxtConfig({
|
||||
prefix: '/pro',
|
||||
driver: 'github',
|
||||
repo: 'nuxt/ui-pro',
|
||||
branch: 'dev',
|
||||
branch: 'v1',
|
||||
dir: '.docs/content/pro',
|
||||
token: process.env.NUXT_GITHUB_TOKEN || ''
|
||||
}
|
||||
@@ -94,6 +93,11 @@ export default defineNuxtConfig({
|
||||
vite: {
|
||||
optimizeDeps: {
|
||||
include: ['date-fns']
|
||||
},
|
||||
server: {
|
||||
fs: {
|
||||
allow: process.env.NUXT_UI_PRO_PATH ? [resolve(process.env.NUXT_UI_PRO_PATH)] : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -114,11 +118,6 @@ export default defineNuxtConfig({
|
||||
}
|
||||
},
|
||||
|
||||
cloudflareAnalytics: {
|
||||
token: '1e2b0c5e9a214f0390b9b94e043d8d4c',
|
||||
scriptPath: false
|
||||
},
|
||||
|
||||
componentMeta: {
|
||||
exclude: [
|
||||
'@nuxt/content',
|
||||
|
||||
@@ -4,28 +4,27 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@iconify-json/heroicons": "^1.2.2",
|
||||
"@iconify-json/lucide": "^1.2.23",
|
||||
"@iconify-json/simple-icons": "^1.2.19",
|
||||
"@iconify-json/vscode-icons": "^1.2.10",
|
||||
"@iconify-json/lucide": "^1.2.57",
|
||||
"@iconify-json/simple-icons": "^1.2.44",
|
||||
"@iconify-json/vscode-icons": "^1.2.23",
|
||||
"@nuxt/content": "^2.13.4",
|
||||
"@nuxt/fonts": "^0.10.3",
|
||||
"@nuxt/image": "^1.9.0",
|
||||
"@nuxt/fonts": "^0.11.4",
|
||||
"@nuxt/image": "^1.10.0",
|
||||
"@nuxt/ui": "latest",
|
||||
"@nuxt/ui-pro": "^1.6.0",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@fdb0248",
|
||||
"@nuxtjs/plausible": "^1.2.0",
|
||||
"@octokit/rest": "^21.1.0",
|
||||
"@vueuse/nuxt": "^12.4.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"@vueuse/nuxt": "^13.5.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"joi": "^17.13.3",
|
||||
"nuxt": "^3.15.1",
|
||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||
"nuxt-component-meta": "^0.9.0",
|
||||
"nuxt-og-image": "^4.0.2",
|
||||
"prettier": "^3.4.2",
|
||||
"ufo": "^1.5.4",
|
||||
"nuxt": "^4.0.1",
|
||||
"nuxt-component-meta": "^0.12.1",
|
||||
"nuxt-og-image": "^5.1.9",
|
||||
"prettier": "^3.6.2",
|
||||
"ufo": "^1.6.1",
|
||||
"v-calendar": "^3.1.2",
|
||||
"valibot": "^0.42.1",
|
||||
"valibot": "^1.1.0",
|
||||
"yup": "^1.6.1",
|
||||
"zod": "^3.24.1"
|
||||
"zod": "^4.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ defineOgImageComponent('Docs', {
|
||||
const communityLinks = computed(() => [{
|
||||
icon: 'i-heroicons-pencil-square',
|
||||
label: 'Edit this page',
|
||||
to: `https://github.com/nuxt/ui/edit/dev/docs/content/${page?.value?._file}`,
|
||||
to: `https://github.com/nuxt/ui/edit/v2/docs/content/${page?.value?._file}`,
|
||||
target: '_blank'
|
||||
}, {
|
||||
icon: 'i-heroicons-star',
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
</template>
|
||||
|
||||
<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"
|
||||
color="gray"
|
||||
readonly
|
||||
@@ -47,7 +48,7 @@
|
||||
@click="copy(source)"
|
||||
/>
|
||||
</template>
|
||||
</UInput>
|
||||
</UInput> -->
|
||||
</template>
|
||||
|
||||
<ClientOnly>
|
||||
@@ -192,16 +193,16 @@
|
||||
</div>
|
||||
</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
|
||||
v-if="section.code"
|
||||
:value="section.code"
|
||||
tag="pre"
|
||||
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' }">
|
||||
<template #title>
|
||||
<Transition name="fade" mode="out-in">
|
||||
@@ -281,8 +282,6 @@
|
||||
<template #page-body>
|
||||
<div class="-mt-8 prose prose-primary prose-sm dark:prose-invert max-w-none">
|
||||
<MDC :value="md" tag="div" />
|
||||
|
||||
<!-- <hr class="border-gray-800/10 dark:border-gray-200/10 !mt-5"> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -325,7 +324,7 @@
|
||||
</template>
|
||||
|
||||
<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
|
||||
model-value="npm i @nuxt/ui"
|
||||
@@ -374,9 +373,9 @@
|
||||
</ULandingSection>
|
||||
|
||||
<div class="h-[calc(var(--inc)*42)]" />
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="_not_screen_xl">
|
||||
<!-- <div class="_not_screen_xl">
|
||||
<ULandingSection>
|
||||
<template #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">
|
||||
</video>
|
||||
</ULandingSection>
|
||||
</div>
|
||||
</div> -->
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ParsedContent, NavItem } from '@nuxt/content'
|
||||
import { useElementBounding, useWindowScroll, useElementSize, breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||
import type { HomeProBlock } from '~/types'
|
||||
import type { NavItem } from '@nuxt/content'
|
||||
import { useElementBounding, useWindowScroll, breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||
// import type { HomeProBlock } from '~/types'
|
||||
|
||||
const { data: page } = await useAsyncData('index', () => queryContent('/').findOne())
|
||||
const { data: module } = await useFetch<{
|
||||
@@ -423,6 +422,7 @@ const { data: module } = await useFetch<{
|
||||
username: string
|
||||
}[]
|
||||
}>('https://api.nuxt.com/modules/ui', {
|
||||
key: 'stats',
|
||||
transform: ({ stats, contributors }) => ({ stats, contributors })
|
||||
})
|
||||
|
||||
@@ -434,321 +434,321 @@ useSeoMeta({
|
||||
ogTitle: page.value.title,
|
||||
description: page.value.description,
|
||||
ogDescription: page.value.description,
|
||||
ogImage: 'https://ui.nuxt.com/social-card.png',
|
||||
twitterImage: 'https://ui.nuxt.com/social-card.png'
|
||||
ogImage: 'https://ui2.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 demoRef = ref(null)
|
||||
// const demoRef = ref(null)
|
||||
const start = ref(0)
|
||||
|
||||
const { $ui } = useNuxtApp()
|
||||
const { height } = useElementSize(demoRef)
|
||||
// const { $ui } = useNuxtApp()
|
||||
// const { height } = useElementSize(demoRef)
|
||||
const { top } = useElementBounding(sectionRef)
|
||||
const { y } = useWindowScroll()
|
||||
const config = useRuntimeConfig().public
|
||||
const { copy, copied } = useClipboard({ source })
|
||||
// const { copy, copied } = useClipboard({ source })
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||
|
||||
const lgAndLarger = breakpoints.greaterOrEqual('lg')
|
||||
|
||||
const { format } = Intl.NumberFormat('en', { notation: 'compact' })
|
||||
|
||||
const steps = {
|
||||
header: 0,
|
||||
footer: 5,
|
||||
landing: 10,
|
||||
docs: 27
|
||||
}
|
||||
// const steps = {
|
||||
// header: 0,
|
||||
// footer: 5,
|
||||
// landing: 10,
|
||||
// docs: 27
|
||||
// }
|
||||
|
||||
// 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)
|
||||
? [{
|
||||
class: 'inset-x-0 top-20 bottom-20 overflow-hidden',
|
||||
inactive: true,
|
||||
children: [{
|
||||
name: 'ULandingHero',
|
||||
to: '/pro/components/landing-hero',
|
||||
class: [
|
||||
'inset-4',
|
||||
isAfterStep(steps.landing + 2) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||
].filter(Boolean).join(' '),
|
||||
style: {
|
||||
'--step-y': `${getStepY(steps.landing + 2)}px`
|
||||
},
|
||||
inactive: isAfterStep(steps.landing + 1),
|
||||
children: [{
|
||||
slot: 'landing-hero',
|
||||
class: 'inset-4'
|
||||
}]
|
||||
}, isAfterStep(steps.landing + 2) && {
|
||||
name: 'ULandingSection',
|
||||
to: '/pro/components/landing-section',
|
||||
class: [
|
||||
'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)]',
|
||||
isAfterStep(steps.landing + 10) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||
].filter(Boolean).join(' '),
|
||||
style: {
|
||||
'--height': (inc.value * 4) + 'px',
|
||||
'--step-y': `${getStepY(steps.landing + 10)}px`,
|
||||
'--prev-step-y': `${getStepY(steps.landing + 2)}px`
|
||||
},
|
||||
inactive: isAfterStep(steps.landing + 7),
|
||||
children: [{
|
||||
slot: 'landing-section',
|
||||
class: 'inset-x-4 top-16'
|
||||
}, {
|
||||
name: 'ULandingGrid',
|
||||
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(' '),
|
||||
inactive: isAfterStep(steps.landing + 8),
|
||||
children: [isAfterStep(steps.landing + 9)
|
||||
? {
|
||||
slot: 'landing-card-1',
|
||||
class: '!relative'
|
||||
}
|
||||
: {
|
||||
name: 'ULandingCard',
|
||||
to: '/pro/components/landing-card',
|
||||
class: '!relative h-full',
|
||||
inactive: false
|
||||
}, isAfterStep(steps.landing + 9)
|
||||
? {
|
||||
slot: 'landing-card-2',
|
||||
class: '!relative h-full'
|
||||
}
|
||||
: {
|
||||
name: 'ULandingCard',
|
||||
to: '/pro/components/landing-card',
|
||||
class: '!relative h-full',
|
||||
inactive: false
|
||||
}, isAfterStep(steps.landing + 9)
|
||||
? {
|
||||
slot: 'landing-card-3',
|
||||
class: '!relative h-full'
|
||||
}
|
||||
: {
|
||||
name: 'ULandingCard',
|
||||
to: '/pro/components/landing-card',
|
||||
class: '!relative h-full',
|
||||
inactive: false
|
||||
}, isAfterStep(steps.landing + 9)
|
||||
? {
|
||||
slot: 'landing-card-4',
|
||||
class: '!relative h-full'
|
||||
}
|
||||
: {
|
||||
name: 'ULandingCard',
|
||||
to: '/pro/components/landing-card',
|
||||
class: '!relative h-full',
|
||||
inactive: false
|
||||
}]
|
||||
}]
|
||||
}, isAfterStep(steps.landing + 10) && {
|
||||
name: 'ULandingSection',
|
||||
to: '/pro/components/landing-section',
|
||||
class: [
|
||||
'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)]'
|
||||
].filter(Boolean).join(' '),
|
||||
style: {
|
||||
'--height': (inc.value * 4) + 'px',
|
||||
'--step-y': `${getStepY(steps.landing + 18)}px`,
|
||||
'--prev-step-y': `${getStepY(steps.landing + 10)}px`
|
||||
},
|
||||
inactive: isAfterStep(steps.landing + 15),
|
||||
children: [{
|
||||
name: 'ULandingCTA',
|
||||
class: 'inset-4',
|
||||
inactive: isAfterStep(steps.landing + 16),
|
||||
children: [{
|
||||
slot: 'landing-cta',
|
||||
class: 'inset-0'
|
||||
}]
|
||||
}]
|
||||
}].filter(Boolean)
|
||||
}]
|
||||
: [])
|
||||
// const landingBlocks = computed(() => isAfterStep(steps.landing) && isBeforeStep(steps.docs)
|
||||
// ? [{
|
||||
// class: 'inset-x-0 top-20 bottom-20 overflow-hidden',
|
||||
// inactive: true,
|
||||
// children: [{
|
||||
// name: 'ULandingHero',
|
||||
// to: '/pro/components/landing-hero',
|
||||
// class: [
|
||||
// 'inset-4',
|
||||
// isAfterStep(steps.landing + 2) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||
// ].filter(Boolean).join(' '),
|
||||
// style: {
|
||||
// '--step-y': `${getStepY(steps.landing + 2)}px`
|
||||
// },
|
||||
// inactive: isAfterStep(steps.landing + 1),
|
||||
// children: [{
|
||||
// slot: 'landing-hero',
|
||||
// class: 'inset-4'
|
||||
// }]
|
||||
// }, isAfterStep(steps.landing + 2) && {
|
||||
// name: 'ULandingSection',
|
||||
// to: '/pro/components/landing-section',
|
||||
// class: [
|
||||
// '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)]',
|
||||
// isAfterStep(steps.landing + 10) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
|
||||
// ].filter(Boolean).join(' '),
|
||||
// style: {
|
||||
// '--height': (inc.value * 4) + 'px',
|
||||
// '--step-y': `${getStepY(steps.landing + 10)}px`,
|
||||
// '--prev-step-y': `${getStepY(steps.landing + 2)}px`
|
||||
// },
|
||||
// inactive: isAfterStep(steps.landing + 7),
|
||||
// children: [{
|
||||
// slot: 'landing-section',
|
||||
// class: 'inset-x-4 top-16'
|
||||
// }, {
|
||||
// name: 'ULandingGrid',
|
||||
// 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(' '),
|
||||
// inactive: isAfterStep(steps.landing + 8),
|
||||
// children: [isAfterStep(steps.landing + 9)
|
||||
// ? {
|
||||
// slot: 'landing-card-1',
|
||||
// class: '!relative'
|
||||
// }
|
||||
// : {
|
||||
// name: 'ULandingCard',
|
||||
// to: '/pro/components/landing-card',
|
||||
// class: '!relative h-full',
|
||||
// inactive: false
|
||||
// }, isAfterStep(steps.landing + 9)
|
||||
// ? {
|
||||
// slot: 'landing-card-2',
|
||||
// class: '!relative h-full'
|
||||
// }
|
||||
// : {
|
||||
// name: 'ULandingCard',
|
||||
// to: '/pro/components/landing-card',
|
||||
// class: '!relative h-full',
|
||||
// inactive: false
|
||||
// }, isAfterStep(steps.landing + 9)
|
||||
// ? {
|
||||
// slot: 'landing-card-3',
|
||||
// class: '!relative h-full'
|
||||
// }
|
||||
// : {
|
||||
// name: 'ULandingCard',
|
||||
// to: '/pro/components/landing-card',
|
||||
// class: '!relative h-full',
|
||||
// inactive: false
|
||||
// }, isAfterStep(steps.landing + 9)
|
||||
// ? {
|
||||
// slot: 'landing-card-4',
|
||||
// class: '!relative h-full'
|
||||
// }
|
||||
// : {
|
||||
// name: 'ULandingCard',
|
||||
// to: '/pro/components/landing-card',
|
||||
// class: '!relative h-full',
|
||||
// inactive: false
|
||||
// }]
|
||||
// }]
|
||||
// }, isAfterStep(steps.landing + 10) && {
|
||||
// name: 'ULandingSection',
|
||||
// to: '/pro/components/landing-section',
|
||||
// class: [
|
||||
// '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)]'
|
||||
// ].filter(Boolean).join(' '),
|
||||
// style: {
|
||||
// '--height': (inc.value * 4) + 'px',
|
||||
// '--step-y': `${getStepY(steps.landing + 18)}px`,
|
||||
// '--prev-step-y': `${getStepY(steps.landing + 10)}px`
|
||||
// },
|
||||
// inactive: isAfterStep(steps.landing + 15),
|
||||
// children: [{
|
||||
// name: 'ULandingCTA',
|
||||
// class: 'inset-4',
|
||||
// inactive: isAfterStep(steps.landing + 16),
|
||||
// children: [{
|
||||
// slot: 'landing-cta',
|
||||
// class: 'inset-0'
|
||||
// }]
|
||||
// }]
|
||||
// }].filter(Boolean)
|
||||
// }]
|
||||
// : [])
|
||||
|
||||
const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
||||
name: 'UPage',
|
||||
to: '/pro/components/page',
|
||||
class: 'inset-x-0 top-20 bottom-20',
|
||||
inactive: isAfterStep(steps.docs + 1),
|
||||
children: [isAfterStep(steps.docs + 2)
|
||||
? {
|
||||
name: 'UAside',
|
||||
to: '/pro/components/aside',
|
||||
class: 'left-4 inset-y-4 w-64',
|
||||
inactive: isAfterStep(steps.docs + 3),
|
||||
children: [isAfterStep(steps.docs + 4)
|
||||
? {
|
||||
slot: 'aside-top',
|
||||
class: 'inset-x-4 top-4'
|
||||
}
|
||||
: {
|
||||
name: '#top',
|
||||
class: 'inset-x-4 top-4 h-9'
|
||||
}, isAfterStep(steps.docs + 5)
|
||||
? {
|
||||
name: 'UNavigationTree',
|
||||
to: '/pro/components/navigation-tree',
|
||||
class: ['inset-x-4 top-[4.25rem] bottom-4', isAfterStep(steps.docs + 6) && '!bg-transparent !border-0'].join(' '),
|
||||
inactive: isAfterStep(steps.docs + 6),
|
||||
children: [{
|
||||
slot: 'aside-default',
|
||||
class: 'inset-0'
|
||||
}]
|
||||
}
|
||||
: {
|
||||
name: '#default',
|
||||
class: 'inset-x-4 top-[4.25rem] bottom-4'
|
||||
}]
|
||||
}
|
||||
: {
|
||||
name: '#left',
|
||||
class: 'left-4 inset-y-4 w-64'
|
||||
}, isAfterStep(steps.docs + 7)
|
||||
? {
|
||||
name: 'UPage',
|
||||
to: '/pro/components/page',
|
||||
class: 'left-72 right-4 inset-y-4',
|
||||
inactive: isAfterStep(steps.docs + 8),
|
||||
children: [...(isAfterStep(steps.docs + 9)
|
||||
? [{
|
||||
name: 'UPageHeader',
|
||||
to: '/pro/components/page-header',
|
||||
class: 'top-4 left-4 right-72 h-32',
|
||||
inactive: isAfterStep(steps.docs + 10),
|
||||
children: [{
|
||||
slot: 'page-header',
|
||||
class: 'inset-4 justify-start'
|
||||
}]
|
||||
}, {
|
||||
name: 'UPageBody',
|
||||
to: '/pro/components/page-body',
|
||||
class: 'top-40 left-4 right-72 bottom-4 overflow-y-auto',
|
||||
inactive: isAfterStep(steps.docs + 11),
|
||||
children: [{
|
||||
slot: 'page-body',
|
||||
class: 'inset-x-4 top-4 justify-start'
|
||||
}, isAfterStep(steps.docs + 12)
|
||||
? {
|
||||
slot: 'content-surround',
|
||||
class: 'bottom-4 inset-x-4 h-28'
|
||||
}
|
||||
: {
|
||||
name: 'UContentSurround',
|
||||
to: '/pro/components/content-surround',
|
||||
class: 'bottom-4 inset-x-4 h-28',
|
||||
inactive: false
|
||||
}]
|
||||
}]
|
||||
: [{
|
||||
name: '#default',
|
||||
class: 'left-4 right-72 inset-y-4'
|
||||
}]), isAfterStep(steps.docs + 13)
|
||||
? {
|
||||
name: 'UContentToc',
|
||||
to: '/pro/components/content-toc',
|
||||
class: 'right-4 inset-y-4 w-64',
|
||||
inactive: isAfterStep(steps.docs + 14),
|
||||
children: [{
|
||||
slot: 'content-toc',
|
||||
class: 'inset-4 overflow-y-auto'
|
||||
}]
|
||||
}
|
||||
: {
|
||||
name: '#right',
|
||||
class: 'right-4 inset-y-4 w-64'
|
||||
}]
|
||||
}
|
||||
: {
|
||||
name: '#default',
|
||||
class: 'left-72 right-4 inset-y-4'
|
||||
}]
|
||||
}].filter(Boolean))
|
||||
// const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
|
||||
// name: 'UPage',
|
||||
// to: '/pro/components/page',
|
||||
// class: 'inset-x-0 top-20 bottom-20',
|
||||
// inactive: isAfterStep(steps.docs + 1),
|
||||
// children: [isAfterStep(steps.docs + 2)
|
||||
// ? {
|
||||
// name: 'UAside',
|
||||
// to: '/pro/components/aside',
|
||||
// class: 'left-4 inset-y-4 w-64',
|
||||
// inactive: isAfterStep(steps.docs + 3),
|
||||
// children: [isAfterStep(steps.docs + 4)
|
||||
// ? {
|
||||
// slot: 'aside-top',
|
||||
// class: 'inset-x-4 top-4'
|
||||
// }
|
||||
// : {
|
||||
// name: '#top',
|
||||
// class: 'inset-x-4 top-4 h-9'
|
||||
// }, isAfterStep(steps.docs + 5)
|
||||
// ? {
|
||||
// name: 'UNavigationTree',
|
||||
// to: '/pro/components/navigation-tree',
|
||||
// class: ['inset-x-4 top-[4.25rem] bottom-4', isAfterStep(steps.docs + 6) && '!bg-transparent !border-0'].join(' '),
|
||||
// inactive: isAfterStep(steps.docs + 6),
|
||||
// children: [{
|
||||
// slot: 'aside-default',
|
||||
// class: 'inset-0'
|
||||
// }]
|
||||
// }
|
||||
// : {
|
||||
// name: '#default',
|
||||
// class: 'inset-x-4 top-[4.25rem] bottom-4'
|
||||
// }]
|
||||
// }
|
||||
// : {
|
||||
// name: '#left',
|
||||
// class: 'left-4 inset-y-4 w-64'
|
||||
// }, isAfterStep(steps.docs + 7)
|
||||
// ? {
|
||||
// name: 'UPage',
|
||||
// to: '/pro/components/page',
|
||||
// class: 'left-72 right-4 inset-y-4',
|
||||
// inactive: isAfterStep(steps.docs + 8),
|
||||
// children: [...(isAfterStep(steps.docs + 9)
|
||||
// ? [{
|
||||
// name: 'UPageHeader',
|
||||
// to: '/pro/components/page-header',
|
||||
// class: 'top-4 left-4 right-72 h-32',
|
||||
// inactive: isAfterStep(steps.docs + 10),
|
||||
// children: [{
|
||||
// slot: 'page-header',
|
||||
// class: 'inset-4 justify-start'
|
||||
// }]
|
||||
// }, {
|
||||
// name: 'UPageBody',
|
||||
// to: '/pro/components/page-body',
|
||||
// class: 'top-40 left-4 right-72 bottom-4 overflow-y-auto',
|
||||
// inactive: isAfterStep(steps.docs + 11),
|
||||
// children: [{
|
||||
// slot: 'page-body',
|
||||
// class: 'inset-x-4 top-4 justify-start'
|
||||
// }, isAfterStep(steps.docs + 12)
|
||||
// ? {
|
||||
// slot: 'content-surround',
|
||||
// class: 'bottom-4 inset-x-4 h-28'
|
||||
// }
|
||||
// : {
|
||||
// name: 'UContentSurround',
|
||||
// to: '/pro/components/content-surround',
|
||||
// class: 'bottom-4 inset-x-4 h-28',
|
||||
// inactive: false
|
||||
// }]
|
||||
// }]
|
||||
// : [{
|
||||
// name: '#default',
|
||||
// class: 'left-4 right-72 inset-y-4'
|
||||
// }]), isAfterStep(steps.docs + 13)
|
||||
// ? {
|
||||
// name: 'UContentToc',
|
||||
// to: '/pro/components/content-toc',
|
||||
// class: 'right-4 inset-y-4 w-64',
|
||||
// inactive: isAfterStep(steps.docs + 14),
|
||||
// children: [{
|
||||
// slot: 'content-toc',
|
||||
// class: 'inset-4 overflow-y-auto'
|
||||
// }]
|
||||
// }
|
||||
// : {
|
||||
// name: '#right',
|
||||
// class: 'right-4 inset-y-4 w-64'
|
||||
// }]
|
||||
// }
|
||||
// : {
|
||||
// name: '#default',
|
||||
// class: 'left-72 right-4 inset-y-4'
|
||||
// }]
|
||||
// }].filter(Boolean))
|
||||
|
||||
const blocks = computed(() => [isAfterStep(steps.header) && {
|
||||
name: 'UHeader',
|
||||
to: '/pro/components/header',
|
||||
class: 'h-16 inset-x-0 top-0',
|
||||
inactive: isAfterStep(steps.header + 1),
|
||||
children: [isAfterStep(steps.header + 2)
|
||||
? {
|
||||
slot: 'header-left',
|
||||
class: 'left-4 top-4'
|
||||
}
|
||||
: {
|
||||
name: '#left',
|
||||
class: 'left-4 inset-y-4 w-64'
|
||||
}, isAfterStep(steps.header + 3)
|
||||
? {
|
||||
slot: 'header-center',
|
||||
class: 'inset-x-72 top-5'
|
||||
}
|
||||
: {
|
||||
name: '#center',
|
||||
class: 'inset-x-72 inset-y-4'
|
||||
}, isAfterStep(steps.header + 4)
|
||||
? {
|
||||
slot: 'header-right',
|
||||
class: 'right-4 top-4'
|
||||
}
|
||||
: {
|
||||
name: '#right',
|
||||
class: 'right-4 inset-y-4 w-64'
|
||||
}]
|
||||
}, isAfterStep(steps.footer) && {
|
||||
name: 'UFooter',
|
||||
to: '/pro/components/footer',
|
||||
class: 'h-16 inset-x-0 bottom-0',
|
||||
inactive: isAfterStep(steps.footer + 1),
|
||||
children: [isAfterStep(steps.footer + 2)
|
||||
? {
|
||||
slot: 'footer-left',
|
||||
class: 'left-4 bottom-5'
|
||||
}
|
||||
: {
|
||||
name: '#left',
|
||||
class: 'left-4 inset-y-4 w-64'
|
||||
}, isAfterStep(steps.footer + 3)
|
||||
? {
|
||||
slot: 'footer-center',
|
||||
class: 'inset-x-72 bottom-5'
|
||||
}
|
||||
: {
|
||||
name: '#center',
|
||||
class: 'inset-x-72 inset-y-4'
|
||||
}, isAfterStep(steps.footer + 4)
|
||||
? {
|
||||
slot: 'footer-right',
|
||||
class: 'right-4 bottom-4'
|
||||
}
|
||||
: {
|
||||
name: '#right',
|
||||
class: 'right-4 inset-y-4 w-64'
|
||||
}]
|
||||
}, ...landingBlocks.value, ...docsBlocks.value].filter(Boolean))
|
||||
// const blocks = computed(() => [isAfterStep(steps.header) && {
|
||||
// name: 'UHeader',
|
||||
// to: '/pro/components/header',
|
||||
// class: 'h-16 inset-x-0 top-0',
|
||||
// inactive: isAfterStep(steps.header + 1),
|
||||
// children: [isAfterStep(steps.header + 2)
|
||||
// ? {
|
||||
// slot: 'header-left',
|
||||
// class: 'left-4 top-4'
|
||||
// }
|
||||
// : {
|
||||
// name: '#left',
|
||||
// class: 'left-4 inset-y-4 w-64'
|
||||
// }, isAfterStep(steps.header + 3)
|
||||
// ? {
|
||||
// slot: 'header-center',
|
||||
// class: 'inset-x-72 top-5'
|
||||
// }
|
||||
// : {
|
||||
// name: '#center',
|
||||
// class: 'inset-x-72 inset-y-4'
|
||||
// }, isAfterStep(steps.header + 4)
|
||||
// ? {
|
||||
// slot: 'header-right',
|
||||
// class: 'right-4 top-4'
|
||||
// }
|
||||
// : {
|
||||
// name: '#right',
|
||||
// class: 'right-4 inset-y-4 w-64'
|
||||
// }]
|
||||
// }, isAfterStep(steps.footer) && {
|
||||
// name: 'UFooter',
|
||||
// to: '/pro/components/footer',
|
||||
// class: 'h-16 inset-x-0 bottom-0',
|
||||
// inactive: isAfterStep(steps.footer + 1),
|
||||
// children: [isAfterStep(steps.footer + 2)
|
||||
// ? {
|
||||
// slot: 'footer-left',
|
||||
// class: 'left-4 bottom-5'
|
||||
// }
|
||||
// : {
|
||||
// name: '#left',
|
||||
// class: 'left-4 inset-y-4 w-64'
|
||||
// }, isAfterStep(steps.footer + 3)
|
||||
// ? {
|
||||
// slot: 'footer-center',
|
||||
// class: 'inset-x-72 bottom-5'
|
||||
// }
|
||||
// : {
|
||||
// name: '#center',
|
||||
// class: 'inset-x-72 inset-y-4'
|
||||
// }, isAfterStep(steps.footer + 4)
|
||||
// ? {
|
||||
// slot: 'footer-right',
|
||||
// class: 'right-4 bottom-4'
|
||||
// }
|
||||
// : {
|
||||
// name: '#right',
|
||||
// class: 'right-4 inset-y-4 w-64'
|
||||
// }]
|
||||
// }, ...landingBlocks.value, ...docsBlocks.value].filter(Boolean))
|
||||
|
||||
// Methods
|
||||
|
||||
function isBeforeStep(i = 0) {
|
||||
return y.value < (start.value + (i * inc.value))
|
||||
}
|
||||
// function isBeforeStep(i = 0) {
|
||||
// return y.value < (start.value + (i * inc.value))
|
||||
// }
|
||||
|
||||
function isAfterStep(i = 0) {
|
||||
return y.value >= (start.value + (i * inc.value))
|
||||
}
|
||||
// function isAfterStep(i = 0) {
|
||||
// return y.value >= (start.value + (i * inc.value))
|
||||
// }
|
||||
|
||||
function getStepY(step: number) {
|
||||
return start.value + (step * inc.value)
|
||||
}
|
||||
// function getStepY(step: number) {
|
||||
// return start.value + (step * inc.value)
|
||||
// }
|
||||
|
||||
// Hooks
|
||||
|
||||
@@ -760,94 +760,94 @@ onMounted(() => {
|
||||
|
||||
// Slots Data
|
||||
|
||||
const headerLinks = [{
|
||||
label: 'Documentation',
|
||||
active: true
|
||||
}, {
|
||||
label: 'Playground'
|
||||
}, {
|
||||
label: 'Roadmap'
|
||||
}, {
|
||||
label: 'Pro'
|
||||
}]
|
||||
// const headerLinks = [{
|
||||
// label: 'Documentation',
|
||||
// active: true
|
||||
// }, {
|
||||
// label: 'Playground'
|
||||
// }, {
|
||||
// label: 'Roadmap'
|
||||
// }, {
|
||||
// label: 'Pro'
|
||||
// }]
|
||||
|
||||
const navigationLinks = [{
|
||||
label: 'Getting Started',
|
||||
children: [{
|
||||
label: 'Introduction'
|
||||
}, {
|
||||
label: 'Installation',
|
||||
active: true
|
||||
}, {
|
||||
label: 'Theming'
|
||||
}, {
|
||||
label: 'Shortcuts'
|
||||
}, {
|
||||
label: 'Examples'
|
||||
}, {
|
||||
label: 'Roadmap'
|
||||
}]
|
||||
}, {
|
||||
label: 'Elements',
|
||||
children: [{
|
||||
label: 'Alert'
|
||||
}, {
|
||||
label: 'Avatar'
|
||||
}, {
|
||||
label: 'Badge'
|
||||
}, {
|
||||
label: 'Button'
|
||||
}]
|
||||
}]
|
||||
// const navigationLinks = [{
|
||||
// label: 'Getting Started',
|
||||
// children: [{
|
||||
// label: 'Introduction'
|
||||
// }, {
|
||||
// label: 'Installation',
|
||||
// active: true
|
||||
// }, {
|
||||
// label: 'Theming'
|
||||
// }, {
|
||||
// label: 'Shortcuts'
|
||||
// }, {
|
||||
// label: 'Examples'
|
||||
// }, {
|
||||
// label: 'Roadmap'
|
||||
// }]
|
||||
// }, {
|
||||
// label: 'Elements',
|
||||
// children: [{
|
||||
// label: 'Alert'
|
||||
// }, {
|
||||
// label: 'Avatar'
|
||||
// }, {
|
||||
// label: 'Badge'
|
||||
// }, {
|
||||
// label: 'Button'
|
||||
// }]
|
||||
// }]
|
||||
|
||||
const surround = [{
|
||||
title: 'Introduction',
|
||||
description: 'Fully styled and customizable components for Nuxt.',
|
||||
_path: '/'
|
||||
}, {
|
||||
title: 'Theming',
|
||||
description: 'Learn how to customize the look and feel of the components.',
|
||||
_path: '/'
|
||||
}]
|
||||
// const surround = [{
|
||||
// title: 'Introduction',
|
||||
// description: 'Fully styled and customizable components for Nuxt.',
|
||||
// _path: '/'
|
||||
// }, {
|
||||
// title: 'Theming',
|
||||
// description: 'Learn how to customize the look and feel of the components.',
|
||||
// _path: '/'
|
||||
// }]
|
||||
|
||||
const md = `
|
||||
## Edge
|
||||
// const md = `
|
||||
// ## 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 = [{
|
||||
id: 'quick-start',
|
||||
depth: 2,
|
||||
text: 'Quick Start'
|
||||
}, {
|
||||
id: 'intellisense',
|
||||
depth: 2,
|
||||
text: 'IntelliSense'
|
||||
}, {
|
||||
id: 'options',
|
||||
depth: 2,
|
||||
text: 'Options'
|
||||
}, {
|
||||
id: 'edge',
|
||||
depth: 2,
|
||||
text: 'Edge'
|
||||
}]
|
||||
// const toc = [{
|
||||
// id: 'quick-start',
|
||||
// depth: 2,
|
||||
// text: 'Quick Start'
|
||||
// }, {
|
||||
// id: 'intellisense',
|
||||
// depth: 2,
|
||||
// text: 'IntelliSense'
|
||||
// }, {
|
||||
// id: 'options',
|
||||
// depth: 2,
|
||||
// text: 'Options'
|
||||
// }, {
|
||||
// id: 'edge',
|
||||
// depth: 2,
|
||||
// text: 'Edge'
|
||||
// }]
|
||||
|
||||
const communityLinks = [{
|
||||
icon: 'i-heroicons-pencil-square',
|
||||
label: 'Edit this page'
|
||||
}, {
|
||||
icon: 'i-heroicons-star',
|
||||
label: 'Star on GitHub',
|
||||
to: 'https://github.com/nuxt/ui',
|
||||
target: '_blank'
|
||||
}, {
|
||||
icon: 'i-heroicons-book-open',
|
||||
label: 'Nuxt documentation',
|
||||
to: 'https://nuxt.com',
|
||||
target: '_blank'
|
||||
}]
|
||||
// const communityLinks = [{
|
||||
// icon: 'i-heroicons-pencil-square',
|
||||
// label: 'Edit this page'
|
||||
// }, {
|
||||
// icon: 'i-heroicons-star',
|
||||
// label: 'Star on GitHub',
|
||||
// to: 'https://github.com/nuxt/ui',
|
||||
// target: '_blank'
|
||||
// }, {
|
||||
// icon: 'i-heroicons-book-open',
|
||||
// label: 'Nuxt documentation',
|
||||
// to: 'https://nuxt.com',
|
||||
// target: '_blank'
|
||||
// }]
|
||||
</script>
|
||||
|
||||
<style scoped lang="postcss">
|
||||
|
||||
@@ -41,8 +41,8 @@ if (!page.value) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
||||
}
|
||||
|
||||
const { data: releases } = await useFetch('/api/releases.json')
|
||||
const { data: pulls } = await useLazyFetch('/api/pulls.json', { default: () => [] })
|
||||
const { data: releases } = await useFetch('/api/releases.json', { key: 'releases-list' })
|
||||
const { data: pulls } = await useLazyFetch('/api/pulls.json', { default: () => [], key: 'pulls-list' })
|
||||
|
||||
const dates = computed(() => {
|
||||
const first = releases.value[releases.value.length - 1]
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
user-agent: *
|
||||
disallow: /dev/*
|
||||
user-agent: *
|
||||
108
package.json
108
package.json
@@ -1,20 +1,29 @@
|
||||
{
|
||||
"name": "@nuxt/ui",
|
||||
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
||||
"version": "2.21.0",
|
||||
"packageManager": "pnpm@9.15.3",
|
||||
"repository": "nuxt/ui",
|
||||
"homepage": "https://ui.nuxt.com",
|
||||
"version": "2.22.1",
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nuxt/ui.git"
|
||||
},
|
||||
"homepage": "https://ui2.nuxt.com",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/module.mjs",
|
||||
"require": "./dist/module.cjs"
|
||||
"types": "./dist/module.d.mts",
|
||||
"import": "./dist/module.mjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/module.cjs",
|
||||
"types": "./dist/types.d.ts",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
".": [
|
||||
"./dist/module.d.mts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"main": "./dist/module.mjs",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@@ -32,57 +41,78 @@
|
||||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/tailwindcss": "^0.2.1",
|
||||
"@headlessui/tailwindcss": "^0.2.2",
|
||||
"@headlessui/vue": "^1.7.23",
|
||||
"@iconify-json/heroicons": "^1.2.2",
|
||||
"@nuxt/icon": "^1.10.3",
|
||||
"@nuxt/kit": "^3.15.1",
|
||||
"@nuxt/icon": "^1.15.0",
|
||||
"@nuxt/kit": "^4.0.1",
|
||||
"@nuxtjs/color-mode": "^3.5.2",
|
||||
"@nuxtjs/tailwindcss": "^6.13.1",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@vueuse/core": "^12.4.0",
|
||||
"@vueuse/integrations": "^12.4.0",
|
||||
"@vueuse/math": "^12.4.0",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"@vueuse/integrations": "^13.5.0",
|
||||
"@vueuse/math": "^13.5.0",
|
||||
"defu": "^6.1.4",
|
||||
"fuse.js": "^7.0.0",
|
||||
"ohash": "^1.1.4",
|
||||
"pathe": "^2.0.1",
|
||||
"fuse.js": "^7.1.0",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"scule": "^1.3.0",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tailwindcss": "^3.4.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint-config": "^0.7.5",
|
||||
"@nuxt/module-builder": "^0.8.4",
|
||||
"@nuxt/test-utils": "^3.15.4",
|
||||
"@release-it/conventional-changelog": "^10.0.0",
|
||||
"@nuxt/eslint-config": "^1.6.0",
|
||||
"@nuxt/module-builder": "^1.0.1",
|
||||
"@nuxt/test-utils": "^3.19.2",
|
||||
"@release-it/conventional-changelog": "^10.0.1",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"eslint": "^9.18.0",
|
||||
"happy-dom": "^14.12.3",
|
||||
"joi": "^17.13.3",
|
||||
"nuxt": "^3.15.1",
|
||||
"release-it": "^18.1.1",
|
||||
"superstruct": "^2.0.2",
|
||||
"typescript": "^5.6.3",
|
||||
"valibot": "^0.42.1",
|
||||
"valibot30": "npm:valibot@0.30.0",
|
||||
"valibot31": "npm:valibot@0.31.0",
|
||||
"vitest": "^2.1.8",
|
||||
"eslint": "^9.31.0",
|
||||
"happy-dom": "^18.0.1",
|
||||
"nuxt": "^4.0.1",
|
||||
"release-it": "^19.0.4",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.2.4",
|
||||
"vitest-environment-nuxt": "^1.0.1",
|
||||
"vue-tsc": "^2.1.10",
|
||||
"yup": "^1.6.1",
|
||||
"zod": "^3.24.1"
|
||||
"vue-tsc": "^3.0.3"
|
||||
},
|
||||
"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": {
|
||||
"@nuxt/ui": "workspace:*",
|
||||
"@nuxt/content": "2.13.2",
|
||||
"@nuxtjs/mdc": "0.9.0",
|
||||
"chokidar": "3.6.0",
|
||||
"vue-tsc": "2.1.10",
|
||||
"typescript": "5.6.3"
|
||||
"@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": {
|
||||
"@nuxt/ui": "latest",
|
||||
"nuxt": "^3.15.1"
|
||||
"nuxt": "^4.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
11373
pnpm-lock.yaml
generated
11373
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,10 @@
|
||||
packages:
|
||||
- "./"
|
||||
- "docs"
|
||||
- "playground"
|
||||
- ./
|
||||
- docs
|
||||
- playground
|
||||
|
||||
ignoredBuiltDependencies:
|
||||
- '@parcel/watcher'
|
||||
- esbuild
|
||||
- sharp
|
||||
- vue-demi
|
||||
|
||||
@@ -5,12 +5,7 @@
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true
|
||||
},
|
||||
"ignoreDeps": [
|
||||
"happy-dom",
|
||||
"valibot30",
|
||||
"valibot31"
|
||||
],
|
||||
"baseBranches": ["dev", "v3"],
|
||||
"baseBranches": ["v2", "v3"],
|
||||
"packageRules": [{
|
||||
"matchBaseBranches": ["v3"],
|
||||
"labels": ["v3"]
|
||||
@@ -24,5 +19,6 @@
|
||||
}, {
|
||||
"matchDepTypes": ["resolutions"],
|
||||
"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
|
||||
echo "Publishing @nuxt/ui"
|
||||
npm publish -q --access public
|
||||
npm publish --access public --no-tag
|
||||
|
||||
@@ -43,6 +43,11 @@ export interface ModuleOptions {
|
||||
*/
|
||||
global?: boolean
|
||||
|
||||
/**
|
||||
* @default true
|
||||
*/
|
||||
colorMode?: boolean
|
||||
|
||||
safelistColors?: string[]
|
||||
/**
|
||||
* Disables the global css styles added by the module.
|
||||
@@ -61,6 +66,7 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
},
|
||||
defaults: {
|
||||
prefix: 'U',
|
||||
colorMode: true,
|
||||
safelistColors: ['primary'],
|
||||
disableGlobalStyles: false
|
||||
},
|
||||
@@ -83,7 +89,9 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
// Modules
|
||||
|
||||
await installModule('@nuxt/icon')
|
||||
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
||||
if (options.colorMode) {
|
||||
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
||||
}
|
||||
await installTailwind(options, nuxt, resolve)
|
||||
|
||||
// Plugins
|
||||
|
||||
@@ -93,18 +93,19 @@
|
||||
/>
|
||||
</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, column.key === 'select' && ui.checkbox.padding]">
|
||||
<slot v-if="modelValue && column.key === 'select' " 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>
|
||||
|
||||
<!-- 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
|
||||
:key="retriggerSlot"
|
||||
:name="`${column.key}-data`"
|
||||
:column="column"
|
||||
:row="row"
|
||||
@@ -132,12 +133,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, ref, toRaw, toRef, watch } from 'vue'
|
||||
import { computed, defineComponent, toRaw, toRef } from 'vue'
|
||||
import type { PropType, AriaAttributes } from 'vue'
|
||||
import { upperFirst } from 'scule'
|
||||
import { defu } from 'defu'
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import { isEqual } from 'ohash'
|
||||
import { isEqual } from 'ohash/utils'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
import UButton from '../elements/Button.vue'
|
||||
import UProgress from '../elements/Progress.vue'
|
||||
@@ -307,8 +308,6 @@ export default defineComponent({
|
||||
})
|
||||
})
|
||||
|
||||
const retriggerSlot = ref(null)
|
||||
|
||||
const savedSort = { column: sort.value.column, direction: null }
|
||||
|
||||
const rows = computed(() => {
|
||||
@@ -483,12 +482,6 @@ export default defineComponent({
|
||||
return undefined
|
||||
}
|
||||
|
||||
watch(rows, () => {
|
||||
retriggerSlot.value = new Date()
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
ui,
|
||||
@@ -515,8 +508,7 @@ export default defineComponent({
|
||||
getRowData,
|
||||
toggleOpened,
|
||||
getAriaSort,
|
||||
isExpanded,
|
||||
retriggerSlot
|
||||
isExpanded
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{{ title }}
|
||||
</slot>
|
||||
</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">
|
||||
{{ description }}
|
||||
</slot>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</slot>
|
||||
|
||||
<slot>
|
||||
<span v-if="label">
|
||||
<span v-if="label !== undefined && label !== null">
|
||||
{{ label }}
|
||||
</span>
|
||||
</slot>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</slot>
|
||||
|
||||
<slot>
|
||||
<span v-if="label" :class="[truncate ? ui.truncate : '']">
|
||||
<span v-if="label !== undefined && label !== null" :class="[truncate ? ui.truncate : '']">
|
||||
{{ label }}
|
||||
</span>
|
||||
</slot>
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { isEqual, diff } from 'ohash'
|
||||
import { type PropType, defineComponent } from 'vue'
|
||||
import { isEqual, diff } from 'ohash/utils'
|
||||
import { defineComponent } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { nuxtLinkProps } from '../../utils'
|
||||
|
||||
export default defineComponent({
|
||||
@@ -74,14 +75,18 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
function isPartiallyEqual(item1, item2) {
|
||||
function isPartiallyEqual(item1: any, item2: any) {
|
||||
const diffedKeys = diff(item1, item2).reduce((filtered, q) => {
|
||||
if (q.type === 'added') {
|
||||
filtered.push(q.key)
|
||||
filtered.add(q.key)
|
||||
}
|
||||
return filtered
|
||||
}, [])
|
||||
return isEqual(item1, item2, { excludeKeys: key => diffedKeys.includes(key) })
|
||||
}, 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 }) {
|
||||
|
||||
@@ -46,10 +46,6 @@ export default defineComponent({
|
||||
UIcon
|
||||
},
|
||||
inheritAttrs: false,
|
||||
slots: Object as SlotsType<{
|
||||
indicator?: { percent: number, value: number }
|
||||
label?: { percent: number, value: number }
|
||||
}>,
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
@@ -98,6 +94,10 @@ export default defineComponent({
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
slots: Object as SlotsType<{
|
||||
indicator?: { percent: number, value: number }
|
||||
label?: { percent: number, value: number }
|
||||
}>,
|
||||
setup(props) {
|
||||
const { ui, attrs } = useUI('meter', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { provide, ref, type PropType, defineComponent, onUnmounted, onMounted, readonly } from 'vue'
|
||||
import { provide, ref, defineComponent, onUnmounted, onMounted, readonly } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { useEventBus } from '@vueuse/core'
|
||||
import type { ZodSchema } from 'zod'
|
||||
import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi'
|
||||
import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup'
|
||||
import type { BaseSchema as ValibotSchema30, BaseSchemaAsync as ValibotSchemaAsync30 } from 'valibot30'
|
||||
import type { GenericSchema as ValibotSchema31, GenericSchemaAsync as ValibotSchemaAsync31, SafeParser as ValibotSafeParser31, SafeParserAsync as ValibotSafeParserAsync31 } from 'valibot31'
|
||||
import type { GenericSchema as ValibotSchema, GenericSchemaAsync as ValibotSchemaAsync, SafeParser as ValibotSafeParser, SafeParserAsync as ValibotSafeParserAsync } from 'valibot'
|
||||
import type { StandardSchemaV1 } from '@standard-schema/spec'
|
||||
import type { Struct } from 'superstruct'
|
||||
import type { FormError, FormEvent, FormEventType, FormSubmitEvent, FormErrorEvent, Form, ValidateReturnSchema } from '../../types/form'
|
||||
import { useId } from '#imports'
|
||||
@@ -25,14 +23,10 @@ class FormException extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
type Schema = PropType<ZodSchema>
|
||||
type Schema = PropType<StandardSchemaV1>
|
||||
| PropType<YupObjectSchema<any>>
|
||||
| PropType<Struct<any, any>>
|
||||
| PropType<JoiSchema>
|
||||
| PropType<ValibotSchema30 | ValibotSchemaAsync30>
|
||||
| PropType<ValibotSchema31 | ValibotSchemaAsync31>
|
||||
| PropType<ValibotSafeParser31<any, any> | ValibotSafeParserAsync31<any, any>>
|
||||
| PropType<ValibotSchema | ValibotSchemaAsync>
|
||||
| PropType<ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>> | PropType<Struct<any, any>>
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -212,26 +206,18 @@ function isJoiError(error: any): error is JoiError {
|
||||
return error.isJoi === true
|
||||
}
|
||||
|
||||
function isValibotSchema(schema: any): schema is ValibotSchema30 | ValibotSchemaAsync30 | ValibotSchema31 | ValibotSchemaAsync31 | ValibotSafeParser31<any, any> | ValibotSafeParserAsync31<any, any> | ValibotSchema | ValibotSchemaAsync | ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any> {
|
||||
return '_parse' in schema || '_run' in schema || (typeof schema === 'function' && 'schema' in schema)
|
||||
export function isStandardSchema(schema: any): schema is StandardSchemaV1 {
|
||||
return '~standard' in schema
|
||||
}
|
||||
|
||||
function isZodSchema(schema: any): schema is ZodSchema {
|
||||
return schema.parse !== undefined
|
||||
}
|
||||
|
||||
async function validateValibotSchema(
|
||||
export async function validateStandardSchema(
|
||||
state: any,
|
||||
schema: ValibotSchema30 | ValibotSchemaAsync30 | ValibotSchema31 | ValibotSchemaAsync31 | ValibotSafeParser31<any, any> | ValibotSafeParserAsync31<any, any> | ValibotSchema | ValibotSchemaAsync | ValibotSafeParser<any, any> | ValibotSafeParserAsync<any, any>
|
||||
schema: StandardSchemaV1
|
||||
): Promise<ValidateReturnSchema<typeof state>> {
|
||||
const result = await ('_parse' in schema ? schema._parse(state) : '_run' in schema ? schema._run({ typed: false, value: state }, {}) : schema(state))
|
||||
const result = await schema['~standard'].validate(state)
|
||||
|
||||
if (!result.issues || result.issues.length === 0) {
|
||||
const output = ('output' in result
|
||||
? result.output
|
||||
: 'value' in result
|
||||
? result.value
|
||||
: null)
|
||||
const output = ('value' in result ? result.value : null)
|
||||
return {
|
||||
errors: null,
|
||||
result: output
|
||||
@@ -239,7 +225,7 @@ async function validateValibotSchema(
|
||||
}
|
||||
|
||||
const errors = result.issues.map(issue => ({
|
||||
path: issue.path?.map(item => item.key).join('.') || '',
|
||||
path: issue.path?.map(item => typeof item === 'object' ? item.key : item).join('.') || '',
|
||||
message: issue.message
|
||||
}))
|
||||
|
||||
@@ -276,28 +262,6 @@ async function validateJoiSchema(
|
||||
}
|
||||
}
|
||||
|
||||
async function validateZodSchema(
|
||||
state: any,
|
||||
schema: ZodSchema
|
||||
): Promise<ValidateReturnSchema<typeof state>> {
|
||||
const result = await schema.safeParseAsync(state)
|
||||
if (result.success === false) {
|
||||
const errors = result.error.issues.map(issue => ({
|
||||
path: issue.path.join('.'),
|
||||
message: issue.message
|
||||
}))
|
||||
|
||||
return {
|
||||
errors,
|
||||
result: null
|
||||
}
|
||||
}
|
||||
return {
|
||||
result: result.data,
|
||||
errors: null
|
||||
}
|
||||
}
|
||||
|
||||
async function validateSuperstructSchema(state: any, schema: Struct<any, any>): Promise<ValidateReturnSchema<typeof state>> {
|
||||
const [err, result] = schema.validate(state)
|
||||
if (err) {
|
||||
@@ -346,12 +310,10 @@ async function validateYupSchema(
|
||||
}
|
||||
|
||||
function parseSchema(state: any, schema: Schema): Promise<ValidateReturnSchema<typeof state>> {
|
||||
if (isZodSchema(schema)) {
|
||||
return validateZodSchema(state, schema)
|
||||
if (isStandardSchema(schema)) {
|
||||
return validateStandardSchema(state, schema)
|
||||
} else if (isJoiSchema(schema)) {
|
||||
return validateJoiSchema(state, schema)
|
||||
} else if (isValibotSchema(schema)) {
|
||||
return validateValibotSchema(state, schema)
|
||||
} else if (isYupSchema(schema)) {
|
||||
return validateYupSchema(state, schema)
|
||||
} else if (isSuperStructSchema(schema)) {
|
||||
|
||||
@@ -104,7 +104,7 @@ import {
|
||||
import { computedAsync, useDebounceFn } from '@vueuse/core'
|
||||
import { defu } from 'defu'
|
||||
import { twJoin } from 'tailwind-merge'
|
||||
import { isEqual } from 'ohash'
|
||||
import { isEqual } from 'ohash/utils'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
import UAvatar from '../elements/Avatar.vue'
|
||||
import { useUI } from '../../composables/useUI'
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
:value="modelValue"
|
||||
:required="required"
|
||||
:class="uiMenu.required"
|
||||
:form="inputTargetForm"
|
||||
tabindex="-1"
|
||||
aria-hidden="true"
|
||||
>
|
||||
@@ -140,7 +141,7 @@ import {
|
||||
import { computedAsync, useDebounceFn } from '@vueuse/core'
|
||||
import { defu } from 'defu'
|
||||
import { twJoin } from 'tailwind-merge'
|
||||
import { isEqual } from 'ohash'
|
||||
import { isEqual } from 'ohash/utils'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
import UAvatar from '../elements/Avatar.vue'
|
||||
import { useUI } from '../../composables/useUI'
|
||||
@@ -314,6 +315,10 @@ export default defineComponent({
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
inputTargetForm: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
popper: {
|
||||
type: Object as PropType<PopperOptions>,
|
||||
default: () => ({})
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{{ title }}
|
||||
</slot>
|
||||
</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">
|
||||
{{ description }}
|
||||
</slot>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ref, type Ref, onMounted, onUnmounted } from 'vue'
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
export const useCarouselScroll = (el: Ref<HTMLElement>) => {
|
||||
const x = ref<number>(0)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { inject, ref, computed } from 'vue'
|
||||
import { type UseEventBusReturn, useDebounceFn } from '@vueuse/core'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import type { UseEventBusReturn } from '@vueuse/core'
|
||||
import type { FormEvent, FormEventType, InjectedFormGroupValue } from '../types/form'
|
||||
|
||||
type InputProps = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createSharedComposable, useActiveElement } from '@vueuse/core'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import type {} from '@vueuse/shared'
|
||||
|
||||
export const _useShortcuts = () => {
|
||||
const macOS = computed(() => import.meta.client && navigator && navigator.userAgent && navigator.userAgent.match(/Macintosh;/))
|
||||
|
||||
24
src/runtime/types/component.d.ts
vendored
24
src/runtime/types/component.d.ts
vendored
@@ -1,14 +1,14 @@
|
||||
export type ComponentProps<T> =
|
||||
T extends new () => { $props: infer P } ? NonNullable<P> :
|
||||
T extends (props: infer P, ...args: any) => any ? P :
|
||||
{}
|
||||
export type ComponentProps<T>
|
||||
= T extends new () => { $props: infer P } ? NonNullable<P>
|
||||
: T extends (props: infer P, ...args: any) => any ? P
|
||||
: {}
|
||||
|
||||
export type ComponentSlots<T> =
|
||||
T extends new () => { $slots: infer S } ? NonNullable<S> :
|
||||
T extends (props: any, ctx: { slots: infer S, attrs: any, emit: any }, ...args: any) => any ? NonNullable<S> :
|
||||
{}
|
||||
export type ComponentSlots<T>
|
||||
= T extends new () => { $slots: infer S } ? NonNullable<S>
|
||||
: T extends (props: any, ctx: { slots: infer S, attrs: any, emit: any }, ...args: any) => any ? NonNullable<S>
|
||||
: {}
|
||||
|
||||
export type ComponentEmit<T> =
|
||||
T extends new () => { $emit: infer E } ? NonNullable<E> :
|
||||
T extends (props: any, ctx: { slots: any, attrs: any, emit: infer E }, ...args: any) => any ? NonNullable<E> :
|
||||
{}
|
||||
export type ComponentEmit<T>
|
||||
= T extends new () => { $emit: infer E } ? NonNullable<E>
|
||||
: T extends (props: any, ctx: { slots: any, attrs: any, emit: infer E }, ...args: any) => any ? NonNullable<E>
|
||||
: {}
|
||||
|
||||
4
src/runtime/types/utils.d.ts
vendored
4
src/runtime/types/utils.d.ts
vendored
@@ -18,8 +18,8 @@ export type NestedKeyOf<ObjectType extends Record<string, any>> = {
|
||||
: Key
|
||||
}[keyof ObjectType]
|
||||
|
||||
type DeepKey<T, Keys extends string[]> =
|
||||
Keys extends [infer First, ...infer Rest]
|
||||
type DeepKey<T, Keys extends string[]>
|
||||
= Keys extends [infer First, ...infer Rest]
|
||||
? First extends keyof T
|
||||
? Rest extends string[]
|
||||
? DeepKey<T[First], Rest>
|
||||
|
||||
@@ -5,6 +5,7 @@ export default {
|
||||
inner: 'w-0 flex-1',
|
||||
title: 'text-sm font-medium',
|
||||
description: 'mt-1 text-sm leading-4 opacity-90',
|
||||
descriptionOnly: 'mt-0 leading-5',
|
||||
actions: 'flex items-center gap-2 mt-3 flex-shrink-0',
|
||||
shadow: '',
|
||||
rounded: 'rounded-lg',
|
||||
|
||||
@@ -6,6 +6,7 @@ export default {
|
||||
inner: 'w-0 flex-1',
|
||||
title: 'text-sm font-medium text-gray-900 dark:text-white',
|
||||
description: 'mt-1 text-sm leading-4 text-gray-500 dark:text-gray-400',
|
||||
descriptionOnly: 'mt-0 leading-5',
|
||||
actions: 'flex items-center gap-2 mt-3 flex-shrink-0',
|
||||
background: 'bg-white dark:bg-gray-900',
|
||||
shadow: 'shadow-lg',
|
||||
|
||||
@@ -127,9 +127,11 @@ export const getNuxtLinkProps = (props) => {
|
||||
}
|
||||
|
||||
export const getULinkProps = (props) => {
|
||||
const keys = [...Object.keys(nuxtLinkProps), ...Object.keys(uLinkProps), 'ariaLabel', 'title']
|
||||
const keys = Object.keys(props)
|
||||
const ariaKeys = keys.filter(key => key.startsWith('aria-'))
|
||||
const dataKeys = keys.filter(key => key.startsWith('data-'))
|
||||
|
||||
return keys.reduce((acc, key) => {
|
||||
return [...Object.keys(nuxtLinkProps), ...Object.keys(uLinkProps), ...ariaKeys, ...dataKeys].reduce((acc, key) => {
|
||||
if (props[key] !== undefined) {
|
||||
acc[key] = props[key]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user