mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-20 15:01:46 +01:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66c78c899c | ||
|
|
05e90aa1d1 | ||
|
|
d28bb0efa8 | ||
|
|
d67c7482ac | ||
|
|
b8db18513d | ||
|
|
a3b33ac917 | ||
|
|
0f25f8563e | ||
|
|
81126b299a | ||
|
|
4ce8348a43 | ||
|
|
0776455a71 | ||
|
|
1a937919a2 | ||
|
|
b9fe74bca5 | ||
|
|
e116f931b2 | ||
|
|
393b992aeb | ||
|
|
c187d367ff | ||
|
|
d43fb835d8 | ||
|
|
033fcfacd8 | ||
|
|
e0977b2933 | ||
|
|
4405d3239f | ||
|
|
a3a7201396 | ||
|
|
29029ca8ae | ||
|
|
2862741e5f | ||
|
|
e4fd20888b | ||
|
|
5c759c326d | ||
|
|
4c9c8d343a | ||
|
|
28b736a703 | ||
|
|
02d72df527 | ||
|
|
a44bfc8511 | ||
|
|
b0df864379 | ||
|
|
969b02d936 | ||
|
|
d3e19dc65a | ||
|
|
cefa597664 | ||
|
|
bad8a69a36 |
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
### 🔗 Linked issue
|
### 🔗 Linked issue
|
||||||
|
|
||||||
<!-- Please ensure there is an open issue and mention its number as: Fixes #123 -->
|
<!-- If it resolves an open issue, please link the issue here. For example "Resolves #123" -->
|
||||||
|
|
||||||
### ❓ Type of change
|
### ❓ Type of change
|
||||||
|
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
<!-- Describe your changes in detail -->
|
<!-- Describe your changes in detail -->
|
||||||
<!-- Why is this change required? What problem does it solve? -->
|
<!-- Why is this change required? What problem does it solve? -->
|
||||||
<!-- If it resolves an open issue, please link to the issue here. For example "Resolves #1337" -->
|
|
||||||
|
|
||||||
### 📝 Checklist
|
### 📝 Checklist
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/ci-dev.yml
vendored
2
.github/workflows/ci-dev.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Setup pnpm cache
|
name: Setup pnpm cache
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||||
|
|||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
name: Setup pnpm cache
|
name: Setup pnpm cache
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||||
|
|||||||
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,5 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.12.2](https://github.com/nuxt/ui/compare/v2.12.1...v2.12.2) (2024-01-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **link:** improve nuxt link `rel` type ([05e90aa](https://github.com/nuxt/ui/commit/05e90aa1d13ab1772189d33278f482405ff88975))
|
||||||
|
|
||||||
|
## [2.12.1](https://github.com/nuxt/ui/compare/v2.12.0...v2.12.1) (2024-01-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Button:** inherit nuxt link props without breaking `nuxt-component-meta` ([d3e19dc](https://github.com/nuxt/ui/commit/d3e19dc65a530201c3adc7738e95e5a09b0a9274)), closes [#578](https://github.com/nuxt/ui/issues/578)
|
||||||
|
* **Button:** pass-through nuxt link props to `ULink` ([a44bfc8](https://github.com/nuxt/ui/commit/a44bfc85114bed15ed25bb8c79d7ed52adc8d43c))
|
||||||
|
* **InputMenu:** take `option-attribute` into account to display label ([1a93791](https://github.com/nuxt/ui/commit/1a937919a26546cfd7edb3f6a11ef790d401999d))
|
||||||
|
* **Link:** prevent `type` bind on `<a>` ([b0df864](https://github.com/nuxt/ui/commit/b0df86437902696b594e5e7042601506a8bf4436))
|
||||||
|
* **SelectMenu:** take `option-attribute` into account to display label ([b9fe74b](https://github.com/nuxt/ui/commit/b9fe74bca5f48555e76c16237c2acc868f69e243)), closes [#1151](https://github.com/nuxt/ui/issues/1151)
|
||||||
|
* **Tooltip:** typo in kbd component ([4405d32](https://github.com/nuxt/ui/commit/4405d3239f7e19d399659347f079555318b3231b))
|
||||||
|
|
||||||
## [2.12.0](https://github.com/nuxt/ui/compare/v2.11.1...v2.12.0) (2024-01-09)
|
## [2.12.0](https://github.com/nuxt/ui/compare/v2.11.1...v2.12.0) (2024-01-09)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { NavItem } from '@nuxt/content/dist/runtime/types'
|
import type { NavItem } from '@nuxt/content/dist/runtime/types'
|
||||||
import type { Link } from '#ui-pro/types'
|
import type { HeaderLink } from '#ui-pro/types'
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
links: Link[]
|
links: HeaderLink[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ const propsToSelect = computed(() => Object.keys(componentProps).map((key) => {
|
|||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
const code = computed(() => {
|
const code = computed(() => {
|
||||||
let code = `\`\`\`html
|
let code = `\`\`\`html
|
||||||
|
<template>
|
||||||
<${name}`
|
<${name}`
|
||||||
for (const [key, value] of Object.entries(fullProps.value)) {
|
for (const [key, value] of Object.entries(fullProps.value)) {
|
||||||
if (value === 'undefined' || value === null) {
|
if (value === 'undefined' || value === null) {
|
||||||
@@ -246,7 +247,7 @@ const code = computed(() => {
|
|||||||
} else {
|
} else {
|
||||||
code += ' />'
|
code += ' />'
|
||||||
}
|
}
|
||||||
code += `
|
code += `\n</template>
|
||||||
\`\`\`
|
\`\`\`
|
||||||
`
|
`
|
||||||
return code
|
return code
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const form = reactive({ email: 'mail@example.com', password: 'password' })
|
|||||||
<UButton label="Login" color="gray" block />
|
<UButton label="Login" color="gray" block />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UDivider label="OR" color="gray" orientation="vertical" />
|
<UDivider label="OR" orientation="vertical" />
|
||||||
|
|
||||||
<div class="space-y-4 flex flex-col justify-center">
|
<div class="space-y-4 flex flex-col justify-center">
|
||||||
<UButton color="black" label="Login with GitHub" icon="i-simple-icons-github" block />
|
<UButton color="black" label="Login with GitHub" icon="i-simple-icons-github" block />
|
||||||
@@ -37,7 +37,7 @@ const form = reactive({ email: 'mail@example.com', password: 'password' })
|
|||||||
|
|
||||||
<UButton label="Login" color="gray" block />
|
<UButton label="Login" color="gray" block />
|
||||||
|
|
||||||
<UDivider label="OR" color="gray" />
|
<UDivider label="OR" />
|
||||||
|
|
||||||
<UButton color="black" label="Login with GitHub" icon="i-simple-icons-github" block />
|
<UButton color="black" label="Login with GitHub" icon="i-simple-icons-github" block />
|
||||||
<UButton color="black" label="Login with Google" icon="i-simple-icons-google" block />
|
<UButton color="black" label="Login with Google" icon="i-simple-icons-google" block />
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ const people = [{
|
|||||||
name: 'Tom Cook'
|
name: 'Tom Cook'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
const selected = ref(people[0].name)
|
const selected = ref(people[0].id)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UInputMenu
|
<UInputMenu
|
||||||
v-model="selected"
|
v-model="selected"
|
||||||
:options="people"
|
:options="people"
|
||||||
value-attribute="name"
|
value-attribute="id"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const people = [{
|
|||||||
name: 'Tom Cook'
|
name: 'Tom Cook'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
const selected = ref(people[0].name)
|
const selected = ref(people[0].id)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -21,7 +21,7 @@ const selected = ref(people[0].name)
|
|||||||
v-model="selected"
|
v-model="selected"
|
||||||
:options="people"
|
:options="people"
|
||||||
placeholder="Select people"
|
placeholder="Select people"
|
||||||
value-attribute="name"
|
value-attribute="id"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</UAvatarGroup>
|
</UAvatarGroup>
|
||||||
|
|
||||||
<UButton label="Button" icon="i-heroicons-pencil-square" />
|
<UButton label="Button" loading />
|
||||||
|
|
||||||
<UBadge label="Badge" />
|
<UBadge label="Badge" />
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Nuxt UI will automatically install the [@nuxtjs/tailwindcss](https://tailwindcss
|
|||||||
You should remove them from your `modules` and `dependencies` if you've previously installed them.
|
You should remove them from your `modules` and `dependencies` if you've previously installed them.
|
||||||
::
|
::
|
||||||
|
|
||||||
### `@nuxtjs/tailwindcs`
|
### `@nuxtjs/tailwindcss`
|
||||||
|
|
||||||
This module is pre-configured and will automatically load the following plugins:
|
This module is pre-configured and will automatically load the following plugins:
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ props:
|
|||||||
variant: 'soft'
|
variant: 'soft'
|
||||||
size: 'sm'
|
size: 'sm'
|
||||||
options:
|
options:
|
||||||
|
- name: color
|
||||||
|
restriction: included
|
||||||
|
values:
|
||||||
|
- gray
|
||||||
|
- white
|
||||||
|
- black
|
||||||
- name: variant
|
- name: variant
|
||||||
restriction: included
|
restriction: included
|
||||||
values:
|
values:
|
||||||
|
|||||||
@@ -32,3 +32,7 @@ Link
|
|||||||
It also renders an `<a>` tag when a `to` prop is provided, otherwise it defaults to rendering a `<button>` tag. The default behavior can be customized using the `as` prop.
|
It also renders an `<a>` tag when a `to` prop is provided, otherwise it defaults to rendering a `<button>` tag. The default behavior can be customized using the `as` prop.
|
||||||
|
|
||||||
It is used underneath by the [Button](/elements/button), [Dropdown](/elements/dropdown) and [VerticalNavigation](/navigation/vertical-navigation) components.
|
It is used underneath by the [Button](/elements/button), [Dropdown](/elements/dropdown) and [VerticalNavigation](/navigation/vertical-navigation) components.
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
:component-props
|
||||||
|
|||||||
@@ -6,26 +6,26 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/heroicons": "^1.1.19",
|
"@iconify-json/heroicons": "^1.1.19",
|
||||||
"@iconify-json/simple-icons": "^1.1.87",
|
"@iconify-json/simple-icons": "^1.1.88",
|
||||||
"@nuxt/content": "^2.10.0",
|
"@nuxt/content": "^2.10.0",
|
||||||
"@nuxt/devtools": "^1.0.6",
|
"@nuxt/devtools": "^1.0.8",
|
||||||
"@nuxt/eslint-config": "^0.2.0",
|
"@nuxt/eslint-config": "^0.2.0",
|
||||||
"@nuxt/image": "^1.1.0",
|
"@nuxt/image": "^1.3.0",
|
||||||
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@0.6.1-28413612.408e456",
|
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@0.7.0-28425529.a466815",
|
||||||
"@nuxthq/studio": "^1.0.6",
|
"@nuxthq/studio": "^1.0.8",
|
||||||
"@nuxtjs/fontaine": "^0.4.1",
|
"@nuxtjs/fontaine": "^0.4.1",
|
||||||
"@nuxtjs/google-fonts": "^3.1.3",
|
"@nuxtjs/google-fonts": "^3.1.3",
|
||||||
"@nuxtjs/plausible": "^0.2.4",
|
"@nuxtjs/plausible": "^0.2.4",
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
"@vueuse/nuxt": "^10.7.1",
|
"@vueuse/nuxt": "^10.7.2",
|
||||||
"date-fns": "^3.1.0",
|
"date-fns": "^3.2.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"joi": "^17.11.0",
|
"joi": "^17.11.1",
|
||||||
"nuxt": "^3.9.1",
|
"nuxt": "^3.9.3",
|
||||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||||
"nuxt-component-meta": "^0.6.0",
|
"nuxt-component-meta": "^0.6.2",
|
||||||
"nuxt-og-image": "^2.2.4",
|
"nuxt-og-image": "^2.2.4",
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.2.4",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"ufo": "^1.3.2",
|
"ufo": "^1.3.2",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
|
|||||||
34
package.json
34
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/ui",
|
"name": "@nuxt/ui",
|
||||||
"version": "2.12.0",
|
"version": "2.12.2",
|
||||||
"repository": "nuxt/ui",
|
"repository": "nuxt/ui",
|
||||||
"homepage": "https://ui.nuxt.com",
|
"homepage": "https://ui.nuxt.com",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -34,52 +34,52 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@egoist/tailwindcss-icons": "^1.7.2",
|
"@egoist/tailwindcss-icons": "^1.7.2",
|
||||||
"@headlessui/tailwindcss": "^0.2.0",
|
"@headlessui/tailwindcss": "^0.2.0",
|
||||||
"@headlessui/vue": "^1.7.16",
|
"@headlessui/vue": "1.7.16",
|
||||||
"@iconify-json/heroicons": "^1.1.19",
|
"@iconify-json/heroicons": "^1.1.19",
|
||||||
"@nuxt/kit": "^3.9.1",
|
"@nuxt/kit": "^3.9.3",
|
||||||
"@nuxtjs/color-mode": "^3.3.2",
|
"@nuxtjs/color-mode": "^3.3.2",
|
||||||
"@nuxtjs/tailwindcss": "^6.10.3",
|
"@nuxtjs/tailwindcss": "^6.10.4",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/forms": "^0.5.7",
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"@tailwindcss/typography": "^0.5.10",
|
"@tailwindcss/typography": "^0.5.10",
|
||||||
"@vueuse/core": "^10.7.1",
|
"@vueuse/core": "^10.7.2",
|
||||||
"@vueuse/integrations": "^10.7.1",
|
"@vueuse/integrations": "^10.7.2",
|
||||||
"@vueuse/math": "^10.7.1",
|
"@vueuse/math": "^10.7.2",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"nuxt-icon": "^0.6.8",
|
"nuxt-icon": "^0.6.8",
|
||||||
"ohash": "^1.1.3",
|
"ohash": "^1.1.3",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.2",
|
||||||
"scule": "^1.1.1",
|
"scule": "^1.2.0",
|
||||||
"tailwind-merge": "^2.2.0",
|
"tailwind-merge": "^2.2.0",
|
||||||
"tailwindcss": "^3.4.1"
|
"tailwindcss": "^3.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^0.2.0",
|
"@nuxt/eslint-config": "^0.2.0",
|
||||||
"@nuxt/module-builder": "^0.5.5",
|
"@nuxt/module-builder": "^0.5.5",
|
||||||
"@nuxt/test-utils": "^3.9.0",
|
"@nuxt/test-utils": "^3.10.0",
|
||||||
"@release-it/conventional-changelog": "^8.0.1",
|
"@release-it/conventional-changelog": "^8.0.1",
|
||||||
"@vue/test-utils": "^2.4.3",
|
"@vue/test-utils": "^2.4.3",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"happy-dom": "^12.10.3",
|
"happy-dom": "^12.10.3",
|
||||||
"joi": "^17.11.0",
|
"joi": "^17.11.1",
|
||||||
"nuxt": "^3.9.1",
|
"nuxt": "^3.9.3",
|
||||||
"release-it": "^17.0.1",
|
"release-it": "^17.0.1",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"unbuild": "^2.0.0",
|
"unbuild": "^2.0.0",
|
||||||
"valibot": "^0.25.0",
|
"valibot": "^0.25.0",
|
||||||
"vitest": "^1.1.3",
|
"vitest": "^1.2.1",
|
||||||
"vitest-environment-nuxt": "^1.0.0",
|
"vitest-environment-nuxt": "^1.0.0",
|
||||||
"vue-tsc": "^1.8.27",
|
"vue-tsc": "^1.8.27",
|
||||||
"yup": "^1.3.3",
|
"yup": "^1.3.3",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@nuxt/kit": "3.9.1",
|
"@nuxt/kit": "3.9.3",
|
||||||
"@nuxt/schema": "3.9.1",
|
"@nuxt/schema": "3.9.3",
|
||||||
"vue": "3.3.13",
|
"tailwindcss": "3.4.1",
|
||||||
"tailwindcss": "3.4.1"
|
"vue": "3.3.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1555
pnpm-lock.yaml
generated
1555
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<ULink :type="type" :disabled="disabled || loading" :class="buttonClass" v-bind="attrs">
|
<ULink :type="type" :disabled="disabled || loading" :class="buttonClass" v-bind="{ ...linkProps, ...attrs }">
|
||||||
<slot name="leading" :disabled="disabled" :loading="loading">
|
<slot name="leading" :disabled="disabled" :loading="loading">
|
||||||
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
|
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
|
||||||
</slot>
|
</slot>
|
||||||
@@ -23,7 +23,7 @@ import { twMerge, twJoin } from 'tailwind-merge'
|
|||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import ULink from '../elements/Link.vue'
|
import ULink from '../elements/Link.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig, nuxtLinkProps, getNuxtLinkProps } from '../../utils'
|
||||||
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
|
||||||
import type { ButtonColor, ButtonSize, ButtonVariant, Strategy } from '../../types'
|
import type { ButtonColor, ButtonSize, ButtonVariant, Strategy } from '../../types'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -39,6 +39,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
|
...nuxtLinkProps,
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'button'
|
default: 'button'
|
||||||
@@ -190,6 +191,8 @@ export default defineComponent({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const linkProps = computed(() => getNuxtLinkProps(props))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
ui,
|
ui,
|
||||||
@@ -201,7 +204,8 @@ export default defineComponent({
|
|||||||
leadingIconName,
|
leadingIconName,
|
||||||
trailingIconName,
|
trailingIconName,
|
||||||
leadingIconClass,
|
leadingIconClass,
|
||||||
trailingIconClass
|
trailingIconClass,
|
||||||
|
linkProps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<HMenuItems :class="[ui.base, ui.divide, ui.ring, ui.rounded, ui.shadow, ui.background, ui.height]" static>
|
<HMenuItems :class="[ui.base, ui.divide, ui.ring, ui.rounded, ui.shadow, ui.background, ui.height]" static>
|
||||||
<div v-for="(subItems, index) of items" :key="index" :class="ui.padding">
|
<div v-for="(subItems, index) of items" :key="index" :class="ui.padding">
|
||||||
<NuxtLink v-for="(item, subIndex) of subItems" :key="subIndex" v-slot="{ href, target, rel, navigate, isExternal }" v-bind="omit(item, ['label', 'labelClass', 'slot', 'icon', 'iconClass', 'avatar', 'shortcuts', 'disabled', 'class', 'click'])" custom>
|
<NuxtLink v-for="(item, subIndex) of subItems" :key="subIndex" v-slot="{ href, target, rel, navigate, isExternal }" v-bind="getNuxtLinkProps(item)" custom>
|
||||||
<HMenuItem v-slot="{ active, disabled: itemDisabled, close }" :disabled="item.disabled">
|
<HMenuItem v-slot="{ active, disabled: itemDisabled, close }" :disabled="item.disabled">
|
||||||
<component
|
<component
|
||||||
:is="!!href ? 'a' : 'button'"
|
:is="!!href ? 'a' : 'button'"
|
||||||
@@ -65,7 +65,7 @@ import UAvatar from '../elements/Avatar.vue'
|
|||||||
import UKbd from '../elements/Kbd.vue'
|
import UKbd from '../elements/Kbd.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { usePopper } from '../../composables/usePopper'
|
import { usePopper } from '../../composables/usePopper'
|
||||||
import { mergeConfig, omit } from '../../utils'
|
import { mergeConfig, getNuxtLinkProps } from '../../utils'
|
||||||
import type { DropdownItem, PopperOptions, Strategy } from '../../types'
|
import type { DropdownItem, PopperOptions, Strategy } from '../../types'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
@@ -263,7 +263,7 @@ export default defineComponent({
|
|||||||
onMouseOver,
|
onMouseOver,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
onClick,
|
onClick,
|
||||||
omit,
|
getNuxtLinkProps,
|
||||||
twMerge,
|
twMerge,
|
||||||
twJoin,
|
twJoin,
|
||||||
NuxtLink
|
NuxtLink
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<component
|
<component
|
||||||
:is="as"
|
:is="as"
|
||||||
v-if="!to"
|
v-if="!to"
|
||||||
|
:type="type"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:class="active ? activeClass : inactiveClass"
|
:class="active ? activeClass : inactiveClass"
|
||||||
@@ -32,16 +33,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { isEqual } from 'ohash'
|
import { isEqual } from 'ohash'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { NuxtLink } from '#components'
|
import { nuxtLinkProps } from '../../utils'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
...NuxtLink.props,
|
...nuxtLinkProps,
|
||||||
as: {
|
as: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'button'
|
default: 'button'
|
||||||
},
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'button'
|
||||||
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: null
|
default: null
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
:class="inputClass"
|
:class="inputClass"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
:display-value="() => query ? query : ['string', 'number'].includes(typeof modelValue) ? modelValue : modelValue[optionAttribute]"
|
:display-value="() => query ? query : label"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -293,6 +293,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const label = computed(() => {
|
||||||
|
if (props.valueAttribute) {
|
||||||
|
const option = props.options.find(option => option[props.valueAttribute] === props.modelValue)
|
||||||
|
return option ? option[props.optionAttribute] : null
|
||||||
|
} else {
|
||||||
|
return ['string', 'number'].includes(typeof props.modelValue) ? props.modelValue : props.modelValue[props.optionAttribute]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const inputClass = computed(() => {
|
const inputClass = computed(() => {
|
||||||
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
||||||
|
|
||||||
@@ -423,6 +432,7 @@ export default defineComponent({
|
|||||||
popper,
|
popper,
|
||||||
trigger,
|
trigger,
|
||||||
container,
|
container,
|
||||||
|
label,
|
||||||
isLeading,
|
isLeading,
|
||||||
isTrailing,
|
isTrailing,
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
|
|||||||
@@ -36,8 +36,7 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<span v-if="multiple && Array.isArray(modelValue) && modelValue.length" :class="uiMenu.label">{{ modelValue.length }} selected</span>
|
<span v-if="label" :class="uiMenu.label">{{ label }}</span>
|
||||||
<span v-else-if="!multiple && modelValue" :class="uiMenu.label">{{ ['string', 'number'].includes(typeof modelValue) ? modelValue : modelValue[optionAttribute] }}</span>
|
|
||||||
<span v-else :class="uiMenu.label">{{ placeholder || ' ' }}</span>
|
<span v-else :class="uiMenu.label">{{ placeholder || ' ' }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
@@ -355,6 +354,23 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const label = computed(() => {
|
||||||
|
if (props.multiple) {
|
||||||
|
if (Array.isArray(props.modelValue) && props.modelValue.length) {
|
||||||
|
return `${props.modelValue.length} selected`
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (props.valueAttribute) {
|
||||||
|
const option = props.options.find(option => option[props.valueAttribute] === props.modelValue)
|
||||||
|
return option ? option[props.optionAttribute] : null
|
||||||
|
} else {
|
||||||
|
return ['string', 'number'].includes(typeof props.modelValue) ? props.modelValue : props.modelValue[props.optionAttribute]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const selectClass = computed(() => {
|
const selectClass = computed(() => {
|
||||||
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
||||||
|
|
||||||
@@ -509,6 +525,7 @@ export default defineComponent({
|
|||||||
popper,
|
popper,
|
||||||
trigger,
|
trigger,
|
||||||
container,
|
container,
|
||||||
|
label,
|
||||||
isLeading,
|
isLeading,
|
||||||
isTrailing,
|
isTrailing,
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
|
|||||||
@@ -74,27 +74,25 @@ export default defineComponent({
|
|||||||
setup (props) {
|
setup (props) {
|
||||||
const { ui, attrs } = useUI('divider', toRef(props, 'ui'), config)
|
const { ui, attrs } = useUI('divider', toRef(props, 'ui'), config)
|
||||||
|
|
||||||
const isHorizontal = computed(() => props.orientation === 'horizontal' )
|
|
||||||
|
|
||||||
const wrapperClass = computed(() => {
|
const wrapperClass = computed(() => {
|
||||||
return twMerge(twJoin(
|
return twMerge(twJoin(
|
||||||
ui.value.wrapper.base,
|
ui.value.wrapper.base,
|
||||||
isHorizontal.value ? ui.value.wrapper.horizontal : ui.value.wrapper.vertical
|
ui.value.wrapper[props.orientation]
|
||||||
), props.class)
|
), props.class)
|
||||||
})
|
})
|
||||||
|
|
||||||
const containerClass = computed(() => {
|
const containerClass = computed(() => {
|
||||||
return twJoin(
|
return twJoin(
|
||||||
ui.value.container.base,
|
ui.value.container.base,
|
||||||
isHorizontal.value ? ui.value.container.horizontal : ui.value.container.vertical
|
ui.value.container[props.orientation]
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const borderClass = computed(() => {
|
const borderClass = computed(() => {
|
||||||
return twJoin(
|
return twJoin(
|
||||||
ui.value.border.base,
|
ui.value.border.base,
|
||||||
isHorizontal.value ? ui.value.border.horizontal : ui.value.border.vertical,
|
ui.value.border[props.orientation],
|
||||||
isHorizontal.value ? ui.value.border.size.horizontal : ui.value.border.size.vertical,
|
ui.value.border.size[props.orientation],
|
||||||
ui.value.border.type[props.type]
|
ui.value.border.type[props.type]
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<ULink
|
<ULink
|
||||||
as="span"
|
as="span"
|
||||||
:class="[ui.base, index === links.length - 1 ? ui.active : !!link.to ? ui.inactive : '']"
|
:class="[ui.base, index === links.length - 1 ? ui.active : !!link.to ? ui.inactive : '']"
|
||||||
v-bind="omit(link, ['label', 'labelClass', 'icon', 'iconClass'])"
|
v-bind="getULinkProps(link)"
|
||||||
:aria-current="index === links.length - 1 ? 'page' : undefined"
|
:aria-current="index === links.length - 1 ? 'page' : undefined"
|
||||||
>
|
>
|
||||||
<slot name="icon" :link="link" :index="index" :is-active="index === links.length - 1">
|
<slot name="icon" :link="link" :index="index" :is-active="index === links.length - 1">
|
||||||
@@ -39,7 +39,7 @@ import { twMerge, twJoin } from 'tailwind-merge'
|
|||||||
import UIcon from '../elements/Icon.vue'
|
import UIcon from '../elements/Icon.vue'
|
||||||
import ULink from '../elements/Link.vue'
|
import ULink from '../elements/Link.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, omit } from '../../utils'
|
import { mergeConfig, getULinkProps } from '../../utils'
|
||||||
import type { BreadcrumbLink, Strategy } from '../../types'
|
import type { BreadcrumbLink, Strategy } from '../../types'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
@@ -78,7 +78,7 @@ export default defineComponent({
|
|||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
ui,
|
ui,
|
||||||
attrs,
|
attrs,
|
||||||
omit,
|
getULinkProps,
|
||||||
twMerge,
|
twMerge,
|
||||||
twJoin
|
twJoin
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav :class="ui.wrapper" v-bind="attrs">
|
<nav :class="ui.wrapper" v-bind="attrs">
|
||||||
<ul v-for="(section, sectionIndex) of linkSections" :key="`linkSection${sectionIndex}`">
|
<ul v-for="(section, sectionIndex) of sections" :key="`section${sectionIndex}`">
|
||||||
<li v-for="(link, index) of section" :key="`linkSection${sectionIndex}-${index}`">
|
<li v-for="(link, index) of section" :key="`section${sectionIndex}-${index}`">
|
||||||
<ULink
|
<ULink
|
||||||
v-slot="{ isActive }"
|
v-slot="{ isActive }"
|
||||||
v-bind="omit(link, ['label', 'labelClass', 'icon', 'iconClass', 'avatar', 'badge', 'click'])"
|
v-bind="getULinkProps(link)"
|
||||||
:class="[ui.base, ui.padding, ui.width, ui.ring, ui.rounded, ui.font, ui.size]"
|
:class="[ui.base, ui.padding, ui.width, ui.ring, ui.rounded, ui.font, ui.size]"
|
||||||
:active-class="ui.active"
|
:active-class="ui.active"
|
||||||
:inactive-class="ui.inactive"
|
:inactive-class="ui.inactive"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</ULink>
|
</ULink>
|
||||||
</li>
|
</li>
|
||||||
<UDivider v-if="sectionIndex < linkSections.length - 1" :ui="ui.divider" />
|
<UDivider v-if="sectionIndex < sections.length - 1" :ui="ui.divider" />
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
@@ -54,7 +54,7 @@ import UAvatar from '../elements/Avatar.vue'
|
|||||||
import ULink from '../elements/Link.vue'
|
import ULink from '../elements/Link.vue'
|
||||||
import UDivider from '../layout/Divider.vue'
|
import UDivider from '../layout/Divider.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, omit } from '../../utils'
|
import { mergeConfig, getULinkProps } from '../../utils'
|
||||||
import type { VerticalNavigationLink, Strategy } from '../../types'
|
import type { VerticalNavigationLink, Strategy } from '../../types'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
@@ -87,16 +87,14 @@ export default defineComponent({
|
|||||||
setup (props) {
|
setup (props) {
|
||||||
const { ui, attrs } = useUI('verticalNavigation', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('verticalNavigation', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
const linkSections = computed(() => {
|
const sections = computed(() => (Array.isArray(props.links[0]) ? props.links : [props.links]) as VerticalNavigationLink[][])
|
||||||
return (Array.isArray(props.links[0]) ? props.links : [props.links]) as VerticalNavigationLink[][]
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
ui,
|
ui,
|
||||||
attrs,
|
attrs,
|
||||||
omit,
|
sections,
|
||||||
linkSections,
|
getULinkProps,
|
||||||
twMerge,
|
twMerge,
|
||||||
twJoin
|
twJoin
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<UKbd v-for="shortcut of shortcuts" :key="shortcut" size="xs">
|
<UKbd v-for="shortcut of shortcuts" :key="shortcut" size="xs">
|
||||||
{{ shortcut }}
|
{{ shortcut }}
|
||||||
</Ukbd>
|
</UKbd>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
4
src/runtime/types/chip.d.ts
vendored
4
src/runtime/types/chip.d.ts
vendored
@@ -6,6 +6,10 @@ export type ChipColor = 'gray' | typeof colors[number]
|
|||||||
export type ChipPosition = keyof typeof chip.position
|
export type ChipPosition = keyof typeof chip.position
|
||||||
|
|
||||||
export interface Chip {
|
export interface Chip {
|
||||||
|
size?: ChipSize
|
||||||
color?: ChipColor
|
color?: ChipColor
|
||||||
position?: ChipPosition
|
position?: ChipPosition
|
||||||
|
text?: string
|
||||||
|
inset?: boolean
|
||||||
|
show?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/runtime/types/index.d.ts
vendored
1
src/runtime/types/index.d.ts
vendored
@@ -22,5 +22,6 @@ export * from './select'
|
|||||||
export * from './tabs'
|
export * from './tabs'
|
||||||
export * from './textarea'
|
export * from './textarea'
|
||||||
export * from './toggle'
|
export * from './toggle'
|
||||||
|
export * from './tooltip'
|
||||||
export * from './vertical-navigation'
|
export * from './vertical-navigation'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
|
|||||||
3
src/runtime/types/link.d.ts
vendored
3
src/runtime/types/link.d.ts
vendored
@@ -1,6 +1,9 @@
|
|||||||
import type { NuxtLinkProps } from '#app'
|
import type { NuxtLinkProps } from '#app'
|
||||||
|
|
||||||
export interface Link extends NuxtLinkProps {
|
export interface Link extends NuxtLinkProps {
|
||||||
|
as?: string
|
||||||
|
type?: string
|
||||||
|
disabled?: boolean
|
||||||
active?: boolean
|
active?: boolean
|
||||||
exact?: boolean
|
exact?: boolean
|
||||||
exactQuery?: boolean
|
exactQuery?: boolean
|
||||||
|
|||||||
7
src/runtime/types/tooltip.d.ts
vendored
Normal file
7
src/runtime/types/tooltip.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export interface Tooltip {
|
||||||
|
text?: string
|
||||||
|
prevent?: boolean
|
||||||
|
shortcuts?: string[]
|
||||||
|
openDelay?: number
|
||||||
|
closeDelay?: number
|
||||||
|
}
|
||||||
@@ -74,3 +74,4 @@ export function looseToNumber (val: any): any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export * from './lodash'
|
export * from './lodash'
|
||||||
|
export * from './link'
|
||||||
|
|||||||
119
src/runtime/utils/link.ts
Normal file
119
src/runtime/utils/link.ts
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import type { PropType } from 'vue'
|
||||||
|
import type { RouteLocationRaw } from 'vue-router'
|
||||||
|
|
||||||
|
export const nuxtLinkProps = {
|
||||||
|
to: {
|
||||||
|
type: [String, Object] as PropType<RouteLocationRaw>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
href: {
|
||||||
|
type: [String, Object] as PropType<RouteLocationRaw>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
// Attributes
|
||||||
|
target: {
|
||||||
|
type: String as PropType<'_blank' | '_parent' | '_self' | '_top' | (string & {}) | null>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
rel: {
|
||||||
|
type: String as PropType<string | null>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
noRel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
// Prefetching
|
||||||
|
prefetch: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
noPrefetch: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
// Styling
|
||||||
|
activeClass: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
exactActiveClass: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
prefetchedClass: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
// Vue Router's `<RouterLink>` additional props
|
||||||
|
replace: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
ariaCurrentValue: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
// Edge cases handling
|
||||||
|
external: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
}
|
||||||
|
} as const
|
||||||
|
|
||||||
|
const uLinkProps = {
|
||||||
|
as: {
|
||||||
|
type: String,
|
||||||
|
default: 'button'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'button'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
exact: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
exactQuery: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
exactHash: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
inactiveClass: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
}
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export const getNuxtLinkProps = (props) => {
|
||||||
|
const keys = Object.keys(nuxtLinkProps)
|
||||||
|
|
||||||
|
return keys.reduce((acc, key) => {
|
||||||
|
if (props[key] !== undefined) {
|
||||||
|
acc[key] = props[key]
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getULinkProps = (props) => {
|
||||||
|
const keys = [...Object.keys(nuxtLinkProps), ...Object.keys(uLinkProps)]
|
||||||
|
|
||||||
|
return keys.reduce((acc, key) => {
|
||||||
|
if (props[key] !== undefined) {
|
||||||
|
acc[key] = props[key]
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
// @vitest-environment nuxt
|
|
||||||
import { describe, it, expect } from 'vitest'
|
import { describe, it, expect } from 'vitest'
|
||||||
import Button from '../../src/runtime/components/elements/Button.vue'
|
import { UButton } from '#components'
|
||||||
import type { TypeOf } from 'zod'
|
import type { TypeOf } from 'zod'
|
||||||
import ComponentRender from '../component-render'
|
import ComponentRender from '../component-render'
|
||||||
|
|
||||||
type ButtonOptions = TypeOf<typeof Button.props>
|
|
||||||
|
|
||||||
describe('Button', () => {
|
describe('Button', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[ 'basic case', { } ],
|
[ 'basic case', { } ],
|
||||||
@@ -14,12 +11,12 @@ describe('Button', () => {
|
|||||||
[ 'rounded full', { props: { ui: { rounded: 'rounded-full' } } } ],
|
[ 'rounded full', { props: { ui: { rounded: 'rounded-full' } } } ],
|
||||||
[ '<UButton icon="i-heroicons-pencil-square" size="sm" color="primary" square variant="solid" />' ]
|
[ '<UButton icon="i-heroicons-pencil-square" size="sm" color="primary" square variant="solid" />' ]
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
])('renders %s correctly', async (nameOrHtml: string, options: ButtonOptions) => {
|
])('renders %s correctly', async (nameOrHtml: string, options: TypeOf<typeof Button.props>) => {
|
||||||
if (options !== undefined) {
|
if (options !== undefined) {
|
||||||
options.slots = options.slots || { default: () => 'label' }
|
options.slots = options.slots || { default: () => 'label' }
|
||||||
options.slots.default = options.slots.default || (() => 'label')
|
options.slots.default = options.slots.default || (() => 'label')
|
||||||
}
|
}
|
||||||
const html = await ComponentRender(nameOrHtml, options, Button)
|
const html = await ComponentRender(nameOrHtml, options, UButton)
|
||||||
expect(html).toMatchSnapshot()
|
expect(html).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user