mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-16 04:58:12 +01:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c75c0152ce | ||
|
|
993bb89e02 | ||
|
|
9f01145bc6 | ||
|
|
c1d9e0ecd4 | ||
|
|
f610c96a0b | ||
|
|
8b546600db | ||
|
|
f08471ccda | ||
|
|
d19d7077e4 | ||
|
|
07a4d13c0f | ||
|
|
9e90d1768b | ||
|
|
91e5002050 | ||
|
|
eb68d0d453 | ||
|
|
2bdb5d2b42 | ||
|
|
b62cd7905d | ||
|
|
58faa1053b | ||
|
|
e909884d03 | ||
|
|
5e84fd0570 | ||
|
|
98c0f567fc | ||
|
|
379d20fc3c | ||
|
|
c12f94653e | ||
|
|
2392b4aa40 | ||
|
|
36055ba978 | ||
|
|
73541f2d4f | ||
|
|
03030ab1db | ||
|
|
c98d6e31c0 | ||
|
|
49b73aa024 |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,5 +1,38 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.15.2](https://github.com/nuxt/ui/compare/v2.15.1...v2.15.2) (2024-04-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Accordion:** add `unmount` prop to allow lazy mounting for heavy components ([#1590](https://github.com/nuxt/ui/issues/1590)) ([91e5002](https://github.com/nuxt/ui/commit/91e50020507ac66992dfb52b3e0ad1a1ae5614b5))
|
||||||
|
* **Table:** add `checkbox` ui config ([#1409](https://github.com/nuxt/ui/issues/1409)) ([8b54660](https://github.com/nuxt/ui/commit/8b546600dbfbff187d9c5be1b35ea1772e94f83f))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Breadcrumb:** missing `min-w-0` on wrapper to truncate ([9f01145](https://github.com/nuxt/ui/commit/9f01145bc674378371ff34d7110f3235b57d2459)), closes [#1650](https://github.com/nuxt/ui/issues/1650)
|
||||||
|
* **Carousel:** next and prev buttons disabled ([#1619](https://github.com/nuxt/ui/issues/1619)) ([e909884](https://github.com/nuxt/ui/commit/e909884d0327bfd7b4d5551382123f8998beff6a))
|
||||||
|
* **Popover/Dropdown:** prevent unintended closure on touchstart in mobile devices ([#1609](https://github.com/nuxt/ui/issues/1609)) ([2392b4a](https://github.com/nuxt/ui/commit/2392b4aa405430fc22766f130448a7cc5ced9a3a))
|
||||||
|
* **Slideover:** remove dynamic component when closing ([#1615](https://github.com/nuxt/ui/issues/1615)) ([58faa10](https://github.com/nuxt/ui/commit/58faa1053b9be3f627c3fcff1bcaa14850bb9e7f))
|
||||||
|
* **Slideover:** wait for transition to complete to reset state ([#1624](https://github.com/nuxt/ui/issues/1624)) ([07a4d13](https://github.com/nuxt/ui/commit/07a4d13c0fcb05c87fb42e02a3a2d6c5c52ccf09))
|
||||||
|
|
||||||
|
## [2.15.1](https://github.com/nuxt/ui/compare/v2.15.0...v2.15.1) (2024-04-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Avatar:** add `as` prop to use `NuxtImg` underneath ([49b73aa](https://github.com/nuxt/ui/commit/49b73aa024be14a9aa150a2804f4dcb18542fa49)), closes [#1577](https://github.com/nuxt/ui/issues/1577)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Checkbox:** `[@change](https://github.com/change)` event value ([#1580](https://github.com/nuxt/ui/issues/1580)) ([c98d6e3](https://github.com/nuxt/ui/commit/c98d6e31c0e3f46b97957d5cf3de7f9da1f70c58))
|
||||||
|
* **Divider:** add `w-full` only on horizontal wrapper ([#1565](https://github.com/nuxt/ui/issues/1565)) ([bd8b737](https://github.com/nuxt/ui/commit/bd8b737642280e6a83b67f9a27dd7a823a77e963))
|
||||||
|
* **Dropdown:** missing `mouseenter` event on container ([7288953](https://github.com/nuxt/ui/commit/72889535e7e9763e7ebf59498f22c39bf09d6477))
|
||||||
|
* **Input/SelectMenu:** handle `file` type and `change` events ([#1570](https://github.com/nuxt/ui/issues/1570)) ([878f707](https://github.com/nuxt/ui/commit/878f7078a28c5e70a662682d1293db466d518c7d))
|
||||||
|
* **Popover:** missing `mouseenter` event on container ([8517897](https://github.com/nuxt/ui/commit/8517897c34adaa9e3624f867b43106deb59fcbe8)), closes [#1564](https://github.com/nuxt/ui/issues/1564)
|
||||||
|
|
||||||
## [2.15.0](https://github.com/nuxt/ui/compare/v2.14.2...v2.15.0) (2024-03-26)
|
## [2.15.0](https://github.com/nuxt/ui/compare/v2.14.2...v2.15.0) (2024-03-26)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,7 @@ Read more on [ui.nuxt.com](https://ui.nuxt.com)
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# npm
|
npx nuxi@latest module add ui
|
||||||
npm install @nuxt/ui
|
|
||||||
# yarn
|
|
||||||
yarn add @nuxt/ui
|
|
||||||
# pnpm
|
|
||||||
pnpm add @nuxt/ui
|
|
||||||
# bun
|
|
||||||
bun add @nuxt/ui
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, register the module in your `nuxt.config.ts`:
|
Then, register the module in your `nuxt.config.ts`:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const links = computed(() => {
|
|||||||
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
||||||
}, {
|
}, {
|
||||||
label: 'Pricing',
|
label: 'Pricing',
|
||||||
icon: 'i-heroicons-credit-card',
|
icon: 'i-heroicons-ticket',
|
||||||
to: '/pro/pricing'
|
to: '/pro/pricing'
|
||||||
}, {
|
}, {
|
||||||
label: 'Templates',
|
label: 'Templates',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="[&>div>pre]:!rounded-t-none [&>div>pre]:!mt-0">
|
<div class="[&>div>pre]:!rounded-t-none [&>div>pre]:!mt-0">
|
||||||
<div
|
<div
|
||||||
|
v-if="hasPreview"
|
||||||
class="flex border border-gray-200 dark:border-gray-700 relative rounded-t-md"
|
class="flex border border-gray-200 dark:border-gray-700 relative rounded-t-md"
|
||||||
:class="[{ 'p-4': padding, 'rounded-b-md': !hasCode, 'border-b-0': hasCode, 'not-prose': !prose }, backgroundClass, extraClass]"
|
:class="[{ 'p-4': padding, 'rounded-b-md': !hasCode, 'border-b-0': hasCode, 'not-prose': !prose }, backgroundClass, extraClass]"
|
||||||
>
|
>
|
||||||
@@ -37,6 +38,10 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
hiddenPreview: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
hiddenCode: {
|
hiddenCode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@@ -79,6 +84,7 @@ const data = await fetchContentExampleCode(camelName)
|
|||||||
const highlighter = useShikiHighlighter()
|
const highlighter = useShikiHighlighter()
|
||||||
|
|
||||||
const hasCode = computed(() => !props.hiddenCode && (data?.code || instance.slots.code))
|
const hasCode = computed(() => !props.hiddenCode && (data?.code || instance.slots.code))
|
||||||
|
const hasPreview = computed(() => !props.hiddenPreview && (props.component || instance.slots.default))
|
||||||
|
|
||||||
const { data: ast } = await useAsyncData(`content-example-${camelName}-ast`, () => transformContent('content:_markdown.md', `\`\`\`vue\n${data?.code ?? ''}\n\`\`\``, {
|
const { data: ast } = await useAsyncData(`content-example-${camelName}-ast`, () => transformContent('content:_markdown.md', `\`\`\`vue\n${data?.code ?? ''}\n\`\`\``, {
|
||||||
markdown: {
|
markdown: {
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ const items = [{
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<code>$ npm i @nuxt/ui</code>
|
<code>$ npx nuxi@latest module add ui</code>
|
||||||
<code>$ yarn add @nuxt/ui</code>
|
|
||||||
<code>$ pnpm add @nuxt/ui</code>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UAccordion>
|
</UAccordion>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const links = [{
|
|||||||
<template>
|
<template>
|
||||||
<UBreadcrumb :links="links">
|
<UBreadcrumb :links="links">
|
||||||
<template #default="{ link, isActive, index }">
|
<template #default="{ link, isActive, index }">
|
||||||
<UBadge :color="isActive ? 'primary' : 'gray'" class="rounded-full">
|
<UBadge :color="isActive ? 'primary' : 'gray'" class="rounded-full truncate">
|
||||||
{{ index + 1 }}. {{ link.label }}
|
{{ index + 1 }}. {{ link.label }}
|
||||||
</UBadge>
|
</UBadge>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,13 +5,24 @@ defineProps({
|
|||||||
default: 0
|
default: 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
|
||||||
|
function onSuccess () {
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UModal>
|
<UModal>
|
||||||
<UCard>
|
<UCard>
|
||||||
<p>This modal was opened programmatically !</p>
|
<div class="space-y-2">
|
||||||
<p>Count: {{ count }}</p>
|
<p>This modal was opened programmatically !</p>
|
||||||
|
<p>Count: {{ count }}</p>
|
||||||
|
<UButton @click="onSuccess">
|
||||||
|
Click to emit a success event
|
||||||
|
</UButton>
|
||||||
|
</div>
|
||||||
</UCard>
|
</UCard>
|
||||||
</UModal>
|
</UModal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ModalExampleComponent } from '#components'
|
import { ModalExampleComponent } from '#components'
|
||||||
|
|
||||||
|
const toast = useToast()
|
||||||
const modal = useModal()
|
const modal = useModal()
|
||||||
const count = ref(0)
|
const count = ref(0)
|
||||||
|
|
||||||
function openModal () {
|
function openModal () {
|
||||||
count.value += 1
|
count.value += 1
|
||||||
modal.open(ModalExampleComponent, {
|
modal.open(ModalExampleComponent, {
|
||||||
count: count.value
|
count: count.value,
|
||||||
|
onSuccess () {
|
||||||
|
toast.add({
|
||||||
|
title: 'Success !',
|
||||||
|
id: 'modal-success'
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ const { data: todos, pending } = await useLazyAsyncData<{
|
|||||||
sort-desc-icon="i-heroicons-arrow-down"
|
sort-desc-icon="i-heroicons-arrow-down"
|
||||||
sort-mode="manual"
|
sort-mode="manual"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
:ui="{ td: { base: 'max-w-[0] truncate' } }"
|
:ui="{ td: { base: 'max-w-[0] truncate' }, default: { checkbox: { color: 'gray' } } }"
|
||||||
@select="select"
|
@select="select"
|
||||||
>
|
>
|
||||||
<template #completed-data="{ row }">
|
<template #completed-data="{ row }">
|
||||||
|
|||||||
@@ -5,29 +5,15 @@ description: 'Learn how to install and configure Nuxt UI in your application.'
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
1. Install `@nuxt/ui` dependency to your project:
|
### Add to a Nuxt project
|
||||||
|
|
||||||
::code-group
|
1. Add `@nuxt/ui` module to your project:
|
||||||
|
|
||||||
```bash [pnpm]
|
```bash
|
||||||
pnpm add @nuxt/ui
|
npx nuxi@latest module add ui
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash [yarn]
|
2. Add it to the `modules` section in your `nuxt.config.ts`:
|
||||||
yarn add @nuxt/ui
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [npm]
|
|
||||||
npm install @nuxt/ui
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash [bun]
|
|
||||||
bun add @nuxt/ui
|
|
||||||
```
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
2. Add it to your `modules` section in your `nuxt.config`:
|
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
@@ -37,6 +23,19 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
That's it! You can now use all the components and composables in your Nuxt app ✨
|
That's it! You can now use all the components and composables in your Nuxt app ✨
|
||||||
|
|
||||||
|
### Use Nuxt starter
|
||||||
|
|
||||||
|
[Nuxt Starter](https://nuxt.new/) template makes it easy to get started with Nuxt UI.
|
||||||
|
The Nuxt Starter template is available from the `nuxi init` command.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx nuxi@latest init -t ui
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Please check [nuxt/starter](https://github.com/nuxt/starter/tree/ui) for details.
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
Nuxt UI will automatically install the [@nuxtjs/tailwindcss](https://tailwindcss.nuxtjs.org/), [@nuxtjs/color-mode](https://color-mode.nuxtjs.org/) and [nuxt-icon](https://github.com/nuxt-modules/icon) modules for you.
|
Nuxt UI will automatically install the [@nuxtjs/tailwindcss](https://tailwindcss.nuxtjs.org/), [@nuxtjs/color-mode](https://color-mode.nuxtjs.org/) and [nuxt-icon](https://github.com/nuxt-modules/icon) modules for you.
|
||||||
|
|||||||
@@ -77,7 +77,13 @@ First of all, add the `Modals` component to your app, preferably inside `app.vue
|
|||||||
|
|
||||||
Then, you can use the `useModal` composable to control your modals within your app.
|
Then, you can use the `useModal` composable to control your modals within your app.
|
||||||
|
|
||||||
:component-example{component="modal-example-composable"}
|
<!-- For prerendering -->
|
||||||
|
:component-example{component="modal-example-component" hiddenCode hiddenPreview }
|
||||||
|
|
||||||
|
::code-group{class="[&>div:last-child>div:first-child]:!rounded-t-none"}
|
||||||
|
:component-example{component="modal-example-composable" label="app.vue" }
|
||||||
|
:component-example{component="modal-example-component" hiddenPreview label="modal.vue" }
|
||||||
|
::
|
||||||
|
|
||||||
Additionally, you can close the modal within the modal component by calling `modal.close()`.
|
Additionally, you can close the modal within the modal component by calling `modal.close()`.
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const links = computed(() => {
|
|||||||
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
|
||||||
}, {
|
}, {
|
||||||
label: 'Pricing',
|
label: 'Pricing',
|
||||||
icon: 'i-heroicons-credit-card',
|
icon: 'i-heroicons-ticket',
|
||||||
to: '/pro/pricing'
|
to: '/pro/pricing'
|
||||||
}, {
|
}, {
|
||||||
label: 'Templates',
|
label: 'Templates',
|
||||||
|
|||||||
@@ -74,16 +74,6 @@ export default defineNuxtConfig({
|
|||||||
image: {
|
image: {
|
||||||
provider: 'ipx'
|
provider: 'ipx'
|
||||||
},
|
},
|
||||||
fontMetrics: {
|
|
||||||
fonts: ['DM Sans']
|
|
||||||
},
|
|
||||||
googleFonts: {
|
|
||||||
display: 'swap',
|
|
||||||
download: true,
|
|
||||||
families: {
|
|
||||||
'DM+Sans': [400, 500, 600, 700]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nitro: {
|
nitro: {
|
||||||
prerender: {
|
prerender: {
|
||||||
routes: [
|
routes: [
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/heroicons": "^1.1.20",
|
"@iconify-json/heroicons": "^1.1.20",
|
||||||
"@iconify-json/simple-icons": "^1.1.97",
|
"@iconify-json/simple-icons": "^1.1.99",
|
||||||
"@nuxt/content": "^2.12.1",
|
"@nuxt/content": "^2.12.1",
|
||||||
"@nuxt/eslint-config": "^0.2.0",
|
"@nuxt/eslint-config": "^0.3.6",
|
||||||
"@nuxt/fonts": "^0.5.1",
|
"@nuxt/fonts": "^0.6.1",
|
||||||
"@nuxt/image": "^1.4.0",
|
"@nuxt/image": "^1.5.0",
|
||||||
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@1.1.0-28524317.f36a434",
|
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@1.1.0-28546155.4b9828b",
|
||||||
"@nuxtjs/plausible": "^0.2.4",
|
"@nuxtjs/plausible": "^1.0.0",
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.1.0",
|
||||||
"@vueuse/nuxt": "^10.9.0",
|
"@vueuse/nuxt": "^10.9.0",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"joi": "^17.12.2",
|
"joi": "^17.12.3",
|
||||||
"nuxt": "^3.11.1",
|
"nuxt": "^3.11.2",
|
||||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||||
"nuxt-component-meta": "^0.6.3",
|
"nuxt-component-meta": "^0.6.3",
|
||||||
"nuxt-og-image": "^2.2.4",
|
"nuxt-og-image": "^2.2.4",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"typescript": "^5.4.3",
|
"typescript": "^5.4.5",
|
||||||
"ufo": "^1.5.3",
|
"ufo": "^1.5.3",
|
||||||
"v-calendar": "^3.1.2",
|
"v-calendar": "^3.1.2",
|
||||||
"valibot": "^0.30.0",
|
"valibot": "^0.30.0",
|
||||||
|
|||||||
@@ -31,10 +31,11 @@
|
|||||||
readonly
|
readonly
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
icon="i-heroicons-command-line"
|
icon="i-heroicons-command-line"
|
||||||
input-class="select-none"
|
class="w-72"
|
||||||
|
input-class="focus:ring-1 focus:ring-gray-300 dark:focus:ring-gray-700"
|
||||||
aria-label="Install @nuxt/ui"
|
aria-label="Install @nuxt/ui"
|
||||||
size="lg"
|
size="lg"
|
||||||
:ui="{ base: 'disabled:cursor-default', icon: { trailing: { pointer: '' } } }"
|
:ui="{ icon: { trailing: { pointer: '' } } }"
|
||||||
>
|
>
|
||||||
<template #trailing>
|
<template #trailing>
|
||||||
<UButton
|
<UButton
|
||||||
@@ -435,7 +436,7 @@ useSeoMeta({
|
|||||||
twitterImage: 'https://ui.nuxt.com/social-card.png'
|
twitterImage: 'https://ui.nuxt.com/social-card.png'
|
||||||
})
|
})
|
||||||
|
|
||||||
const source = ref('npm i @nuxt/ui')
|
const source = ref('npx nuxi@latest module add ui')
|
||||||
const sectionRef = ref()
|
const sectionRef = ref()
|
||||||
const demoRef = ref()
|
const demoRef = ref()
|
||||||
const start = ref(0)
|
const start = ref(0)
|
||||||
|
|||||||
32
package.json
32
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nuxt/ui",
|
"name": "@nuxt/ui",
|
||||||
"version": "2.15.0",
|
"version": "2.15.2",
|
||||||
"repository": "nuxt/ui",
|
"repository": "nuxt/ui",
|
||||||
"homepage": "https://ui.nuxt.com",
|
"homepage": "https://ui.nuxt.com",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -37,14 +37,14 @@
|
|||||||
"@headlessui/tailwindcss": "^0.2.0",
|
"@headlessui/tailwindcss": "^0.2.0",
|
||||||
"@headlessui/vue": "^1.7.19",
|
"@headlessui/vue": "^1.7.19",
|
||||||
"@iconify-json/heroicons": "^1.1.20",
|
"@iconify-json/heroicons": "^1.1.20",
|
||||||
"@nuxt/kit": "^3.11.1",
|
"@nuxt/kit": "^3.11.2",
|
||||||
"@nuxtjs/color-mode": "^3.3.3",
|
"@nuxtjs/color-mode": "^3.4.0",
|
||||||
"@nuxtjs/tailwindcss": "^6.11.4",
|
"@nuxtjs/tailwindcss": "^6.11.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.12",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"@vueuse/integrations": "^10.9.0",
|
"@vueuse/integrations": "^10.9.0",
|
||||||
"@vueuse/math": "^10.9.0",
|
"@vueuse/math": "^10.9.0",
|
||||||
@@ -55,32 +55,32 @@
|
|||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"scule": "^1.3.0",
|
"scule": "^1.3.0",
|
||||||
"tailwind-merge": "^2.2.2",
|
"tailwind-merge": "^2.2.2",
|
||||||
"tailwindcss": "^3.4.1"
|
"tailwindcss": "^3.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^0.2.0",
|
"@nuxt/eslint-config": "^0.3.6",
|
||||||
"@nuxt/module-builder": "^0.5.5",
|
"@nuxt/module-builder": "^0.5.5",
|
||||||
"@nuxt/test-utils": "^3.12.0",
|
"@nuxt/test-utils": "^3.12.0",
|
||||||
"@release-it/conventional-changelog": "^8.0.1",
|
"@release-it/conventional-changelog": "^8.0.1",
|
||||||
"@vue/test-utils": "^2.4.5",
|
"@vue/test-utils": "^2.4.5",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"happy-dom": "^14.3.6",
|
"happy-dom": "^14.7.1",
|
||||||
"joi": "^17.12.2",
|
"joi": "^17.12.3",
|
||||||
"nuxt": "^3.11.1",
|
"nuxt": "^3.11.2",
|
||||||
"release-it": "^17.1.1",
|
"release-it": "^17.2.0",
|
||||||
"typescript": "^5.4.3",
|
"typescript": "^5.4.5",
|
||||||
"unbuild": "^2.0.0",
|
"unbuild": "^2.0.0",
|
||||||
"valibot": "^0.30.0",
|
"valibot": "^0.30.0",
|
||||||
"vitest": "^1.4.0",
|
"vitest": "^1.5.0",
|
||||||
"vitest-environment-nuxt": "^1.0.0",
|
"vitest-environment-nuxt": "^1.0.0",
|
||||||
"vue-tsc": "^2.0.7",
|
"vue-tsc": "^2.0.13",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@nuxt/kit": "^3.11.1",
|
"@nuxt/kit": "^3.11.2",
|
||||||
"@nuxt/schema": "3.11.1",
|
"@nuxt/schema": "3.11.2",
|
||||||
"tailwindcss": "3.4.1",
|
"tailwindcss": "^3.4.3",
|
||||||
"@headlessui/vue": "1.7.19",
|
"@headlessui/vue": "1.7.19",
|
||||||
"vue": "3.4.21"
|
"vue": "3.4.21"
|
||||||
}
|
}
|
||||||
|
|||||||
2682
pnpm-lock.yaml
generated
2682
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
<thead :class="ui.thead">
|
<thead :class="ui.thead">
|
||||||
<tr :class="ui.tr.base">
|
<tr :class="ui.tr.base">
|
||||||
<th v-if="modelValue" scope="col" :class="ui.checkbox.padding">
|
<th v-if="modelValue" scope="col" :class="ui.checkbox.padding">
|
||||||
<UCheckbox :model-value="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" aria-label="Select all" @change="onChange" />
|
<UCheckbox :model-value="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" v-bind="ui.default.checkbox" aria-label="Select all" @change="onChange" />
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th v-for="(column, index) in columns" :key="index" scope="col" :class="[ui.th.base, ui.th.padding, ui.th.color, ui.th.font, ui.th.size, column.class]">
|
<th v-for="(column, index) in columns" :key="index" scope="col" :class="[ui.th.base, ui.th.padding, ui.th.color, ui.th.font, ui.th.size, column.class]">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<tr v-for="(row, index) in rows" :key="index" :class="[ui.tr.base, isSelected(row) && ui.tr.selected, $attrs.onSelect && ui.tr.active, row?.class]" @click="() => onSelect(row)">
|
<tr v-for="(row, index) in rows" :key="index" :class="[ui.tr.base, isSelected(row) && ui.tr.selected, $attrs.onSelect && ui.tr.active, row?.class]" @click="() => onSelect(row)">
|
||||||
<td v-if="modelValue" :class="ui.checkbox.padding">
|
<td v-if="modelValue" :class="ui.checkbox.padding">
|
||||||
<UCheckbox v-model="selected" :value="row" aria-label="Select row" @click.stop />
|
<UCheckbox v-model="selected" :value="row" v-bind="ui.default.checkbox" aria-label="Select row" @click.stop />
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size, row[column.key]?.class]">
|
<td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size, row[column.key]?.class]">
|
||||||
@@ -280,8 +280,8 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange (event: any) {
|
function onChange (checked: boolean) {
|
||||||
if (event.target.checked) {
|
if (checked) {
|
||||||
selectAllRows()
|
selectAllRows()
|
||||||
} else {
|
} else {
|
||||||
selected.value = []
|
selected.value = []
|
||||||
|
|||||||
@@ -39,13 +39,27 @@
|
|||||||
@before-leave="onBeforeLeave"
|
@before-leave="onBeforeLeave"
|
||||||
@leave="onLeave"
|
@leave="onLeave"
|
||||||
>
|
>
|
||||||
<div v-show="open">
|
<HDisclosurePanel
|
||||||
<HDisclosurePanel :class="[ui.item.base, ui.item.size, ui.item.color, ui.item.padding]" static>
|
v-if="unmount"
|
||||||
<slot :name="item.slot || 'item'" :item="item" :index="index" :open="open" :close="close">
|
:class="[ui.item.base, ui.item.size, ui.item.color, ui.item.padding]"
|
||||||
{{ item.content }}
|
unmount
|
||||||
</slot>
|
>
|
||||||
</HDisclosurePanel>
|
<slot :name="item.slot || 'item'" :item="item" :index="index" :open="open" :close="close">
|
||||||
</div>
|
{{ item.content }}
|
||||||
|
</slot>
|
||||||
|
</HDisclosurePanel>
|
||||||
|
<template v-else>
|
||||||
|
<div v-show="open">
|
||||||
|
<HDisclosurePanel
|
||||||
|
:class="[ui.item.base, ui.item.size, ui.item.color, ui.item.padding]"
|
||||||
|
static
|
||||||
|
>
|
||||||
|
<slot :name="item.slot || 'item'" :item="item" :index="index" :open="open" :close="close">
|
||||||
|
{{ item.content }}
|
||||||
|
</slot>
|
||||||
|
</HDisclosurePanel>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</Transition>
|
</Transition>
|
||||||
</HDisclosure>
|
</HDisclosure>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,6 +105,10 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
default: () => config.default.openIcon
|
default: () => config.default.openIcon
|
||||||
},
|
},
|
||||||
|
unmount: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
closeIcon: {
|
closeIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: () => config.default.closeIcon
|
default: () => config.default.closeIcon
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<span :class="wrapperClass">
|
<span :class="wrapperClass">
|
||||||
<img
|
<component
|
||||||
|
:is="as"
|
||||||
v-if="url && !error"
|
v-if="url && !error"
|
||||||
:class="imgClass"
|
:class="imgClass"
|
||||||
:alt="alt"
|
:alt="alt"
|
||||||
:src="url"
|
:src="url"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
@error="onError"
|
@error="onError"
|
||||||
>
|
/>
|
||||||
<span v-else-if="text" :class="ui.text">{{ text }}</span>
|
<span v-else-if="text" :class="ui.text">{{ text }}</span>
|
||||||
<UIcon v-else-if="icon" :name="icon" :class="iconClass" />
|
<UIcon v-else-if="icon" :name="icon" :class="iconClass" />
|
||||||
<span v-else-if="placeholder" :class="ui.placeholder">{{ placeholder }}</span>
|
<span v-else-if="placeholder" :class="ui.placeholder">{{ placeholder }}</span>
|
||||||
@@ -39,6 +40,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
|
as: {
|
||||||
|
type: [String, Object],
|
||||||
|
default: 'img'
|
||||||
|
},
|
||||||
src: {
|
src: {
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: null
|
default: null
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, toRef, toRefs, computed, defineComponent } from 'vue'
|
import { ref, toRef, computed, defineComponent } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { mergeConfig } from '../../utils'
|
import { mergeConfig } from '../../utils'
|
||||||
@@ -112,10 +112,9 @@ export default defineComponent({
|
|||||||
const carouselRef = ref<HTMLElement>()
|
const carouselRef = ref<HTMLElement>()
|
||||||
const itemWidth = ref(0)
|
const itemWidth = ref(0)
|
||||||
|
|
||||||
const { x, arrivedState } = useScroll(carouselRef, { behavior: 'smooth' })
|
const { x } = useScroll(carouselRef, { behavior: 'smooth' })
|
||||||
const { width: carouselWidth } = useElementSize(carouselRef)
|
|
||||||
|
|
||||||
const { left: isFirst, right: isLast } = toRefs(arrivedState)
|
const { width: carouselWidth } = useElementSize(carouselRef)
|
||||||
|
|
||||||
useCarouselScroll(carouselRef)
|
useCarouselScroll(carouselRef)
|
||||||
|
|
||||||
@@ -125,7 +124,13 @@ export default defineComponent({
|
|||||||
itemWidth.value = entry?.target?.firstElementChild?.clientWidth || 0
|
itemWidth.value = entry?.target?.firstElementChild?.clientWidth || 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentPage = computed(() => Math.round(x.value / itemWidth.value) + 1)
|
const currentPage = computed(() => {
|
||||||
|
if (!itemWidth.value) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(x.value / itemWidth.value) + 1
|
||||||
|
})
|
||||||
|
|
||||||
const pages = computed(() => {
|
const pages = computed(() => {
|
||||||
if (!itemWidth.value) {
|
if (!itemWidth.value) {
|
||||||
@@ -135,6 +140,9 @@ export default defineComponent({
|
|||||||
return props.items.length - Math.round(carouselWidth.value / itemWidth.value) + 1
|
return props.items.length - Math.round(carouselWidth.value / itemWidth.value) + 1
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isFirst = computed(() => currentPage.value <= 1)
|
||||||
|
const isLast = computed(() => currentPage.value === pages.value)
|
||||||
|
|
||||||
function onClickNext () {
|
function onClickNext () {
|
||||||
x.value += itemWidth.value
|
x.value += itemWidth.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,8 +182,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function onTouchStart () {
|
function onTouchStart (event: TouchEvent) {
|
||||||
if (!menuApi.value) {
|
if (!event.cancelable || !menuApi.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const onChange = (event: Event) => {
|
const onChange = (event: Event) => {
|
||||||
emit('change', (event.target as HTMLInputElement).value)
|
emit('change', (event.target as HTMLInputElement).checked)
|
||||||
emitFormChange()
|
emitFormChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<TransitionRoot :appear="appear" :show="isOpen" as="template">
|
<TransitionRoot :appear="appear" :show="isOpen" as="template" @after-leave="onAfterLeave">
|
||||||
<HDialog :class="ui.wrapper" v-bind="attrs" @close="close">
|
<HDialog :class="ui.wrapper" v-bind="attrs" @close="close">
|
||||||
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
||||||
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
||||||
@@ -82,7 +82,7 @@ export default defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue', 'close', 'close-prevented'],
|
emits: ['update:modelValue', 'close', 'close-prevented', 'after-leave'],
|
||||||
setup (props, { emit }) {
|
setup (props, { emit }) {
|
||||||
const { ui, attrs } = useUI('modal', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('modal', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
@@ -117,6 +117,10 @@ export default defineComponent({
|
|||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onAfterLeave = () => {
|
||||||
|
emit('after-leave')
|
||||||
|
}
|
||||||
|
|
||||||
provideUseId(() => useId())
|
provideUseId(() => useId())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -125,6 +129,7 @@ export default defineComponent({
|
|||||||
attrs,
|
attrs,
|
||||||
isOpen,
|
isOpen,
|
||||||
transitionClass,
|
transitionClass,
|
||||||
|
onAfterLeave,
|
||||||
close
|
close
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<component :is="modalState.component" v-if="modalState" v-bind="modalState.props" v-model="isOpen" />
|
<component
|
||||||
|
:is="modalState.component"
|
||||||
|
v-if="modalState"
|
||||||
|
v-bind="modalState.props"
|
||||||
|
v-model="isOpen"
|
||||||
|
@after-leave="reset"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -8,5 +14,5 @@ import { useModal, modalInjectionKey } from '../../composables/useModal'
|
|||||||
|
|
||||||
const modalState = inject(modalInjectionKey)
|
const modalState = inject(modalInjectionKey)
|
||||||
|
|
||||||
const { isOpen } = useModal()
|
const { isOpen, reset } = useModal()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -154,8 +154,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function onTouchStart () {
|
function onTouchStart (event: TouchEvent) {
|
||||||
if (!popoverApi.value) {
|
if (!event.cancelable || !popoverApi.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<TransitionRoot as="template" :appear="appear" :show="isOpen">
|
<TransitionRoot as="template" :appear="appear" :show="isOpen" @after-leave="onAfterLeave">
|
||||||
<HDialog :class="[ui.wrapper, { 'justify-end': side === 'right' }]" v-bind="attrs" @close="close">
|
<HDialog :class="[ui.wrapper, { 'justify-end': side === 'right' }]" v-bind="attrs" @close="close">
|
||||||
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
<TransitionChild v-if="overlay" as="template" :appear="appear" v-bind="ui.overlay.transition">
|
||||||
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
<div :class="[ui.overlay.base, ui.overlay.background]" />
|
||||||
@@ -71,7 +71,7 @@ export default defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue', 'close', 'close-prevented'],
|
emits: ['update:modelValue', 'close', 'close-prevented', 'after-leave'],
|
||||||
setup (props, { emit }) {
|
setup (props, { emit }) {
|
||||||
const { ui, attrs } = useUI('slideover', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('slideover', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
@@ -109,6 +109,10 @@ export default defineComponent({
|
|||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onAfterLeave = () => {
|
||||||
|
emit('after-leave')
|
||||||
|
}
|
||||||
|
|
||||||
provideUseId(() => useId())
|
provideUseId(() => useId())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -117,6 +121,7 @@ export default defineComponent({
|
|||||||
attrs,
|
attrs,
|
||||||
isOpen,
|
isOpen,
|
||||||
transitionClass,
|
transitionClass,
|
||||||
|
onAfterLeave,
|
||||||
close
|
close
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
v-if="slideoverState"
|
v-if="slideoverState"
|
||||||
v-bind="slideoverState.props"
|
v-bind="slideoverState.props"
|
||||||
v-model="isOpen"
|
v-model="isOpen"
|
||||||
|
@after-leave="reset"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -13,5 +14,5 @@ import { useSlideover, slidOverInjectionKey } from '../../composables/useSlideov
|
|||||||
|
|
||||||
const slideoverState = inject(slidOverInjectionKey)
|
const slideoverState = inject(slidOverInjectionKey)
|
||||||
|
|
||||||
const { isOpen } = useSlideover()
|
const { isOpen, reset } = useSlideover()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -12,15 +12,25 @@ function _useModal () {
|
|||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
|
|
||||||
function open<T extends Component> (component: T, props?: Modal & ComponentProps<T>) {
|
function open<T extends Component> (component: T, props?: Modal & ComponentProps<T>) {
|
||||||
|
if (!modalState) {
|
||||||
|
throw new Error('useModal() is called without provider')
|
||||||
|
}
|
||||||
|
|
||||||
modalState.value = {
|
modalState.value = {
|
||||||
component,
|
component,
|
||||||
props: props ?? {}
|
props: props ?? {}
|
||||||
}
|
}
|
||||||
|
|
||||||
isOpen.value = true
|
isOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function close () {
|
async function close () {
|
||||||
|
if (!modalState) return
|
||||||
|
|
||||||
isOpen.value = false
|
isOpen.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset () {
|
||||||
modalState.value = {
|
modalState.value = {
|
||||||
component: 'div',
|
component: 'div',
|
||||||
props: {}
|
props: {}
|
||||||
@@ -31,6 +41,8 @@ function _useModal () {
|
|||||||
* Allows updating the modal props
|
* Allows updating the modal props
|
||||||
*/
|
*/
|
||||||
function patch <T extends Component = {}> (props: Partial<Modal & ComponentProps<T>>) {
|
function patch <T extends Component = {}> (props: Partial<Modal & ComponentProps<T>>) {
|
||||||
|
if (!modalState) return
|
||||||
|
|
||||||
modalState.value = {
|
modalState.value = {
|
||||||
...modalState.value,
|
...modalState.value,
|
||||||
props: {
|
props: {
|
||||||
@@ -41,10 +53,11 @@ function _useModal () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isOpen,
|
|
||||||
open,
|
open,
|
||||||
close,
|
close,
|
||||||
patch
|
reset,
|
||||||
|
patch,
|
||||||
|
isOpen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,55 +1,64 @@
|
|||||||
import { ref, inject } from 'vue'
|
import { ref, inject } from 'vue'
|
||||||
import { createSharedComposable } from '@vueuse/core'
|
|
||||||
import type { ShallowRef, Component, InjectionKey } from 'vue'
|
import type { ShallowRef, Component, InjectionKey } from 'vue'
|
||||||
|
import { createSharedComposable } from '@vueuse/core'
|
||||||
import type { ComponentProps } from '../types/component'
|
import type { ComponentProps } from '../types/component'
|
||||||
import type { Slideover, SlideoverState } from '../types/slideover'
|
import type { Slideover, SlideoverState } from '../types/slideover'
|
||||||
|
|
||||||
export const slidOverInjectionKey: InjectionKey<ShallowRef<SlideoverState>> =
|
export const slidOverInjectionKey: InjectionKey<ShallowRef<SlideoverState>> = Symbol('nuxt-ui.slideover')
|
||||||
Symbol('nuxt-ui.slideover')
|
|
||||||
|
|
||||||
function _useSlideover () {
|
function _useSlideover () {
|
||||||
const slideoverState = inject(slidOverInjectionKey)
|
const slideoverState = inject(slidOverInjectionKey)
|
||||||
const isOpen = ref(false)
|
|
||||||
|
|
||||||
function open<T extends Component> (component: T, props?: Slideover & ComponentProps<T>) {
|
const isOpen = ref(false)
|
||||||
if (!slideoverState) {
|
|
||||||
throw new Error('useSlideover() is called without provider')
|
|
||||||
}
|
|
||||||
|
|
||||||
slideoverState.value = {
|
function open<T extends Component> (component: T, props?: Slideover & ComponentProps<T>) {
|
||||||
component,
|
if (!slideoverState) {
|
||||||
props: props ?? {}
|
throw new Error('useSlideover() is called without provider')
|
||||||
}
|
|
||||||
|
|
||||||
isOpen.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function close () {
|
slideoverState.value = {
|
||||||
if (!slideoverState) return
|
component,
|
||||||
|
props: props ?? {}
|
||||||
isOpen.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
isOpen.value = true
|
||||||
* Allows updating the slideover props
|
}
|
||||||
*/
|
|
||||||
function patch<T extends Component = {}> (props: Partial<Slideover & ComponentProps<T>>) {
|
|
||||||
if (!slideoverState) return
|
|
||||||
|
|
||||||
slideoverState.value = {
|
async function close () {
|
||||||
...slideoverState.value,
|
if (!slideoverState) return
|
||||||
props: {
|
|
||||||
...slideoverState.value.props,
|
isOpen.value = false
|
||||||
...props
|
}
|
||||||
}
|
|
||||||
}
|
function reset () {
|
||||||
|
slideoverState.value = {
|
||||||
|
component: 'div',
|
||||||
|
props: {}
|
||||||
}
|
}
|
||||||
return {
|
}
|
||||||
open,
|
|
||||||
close,
|
/**
|
||||||
patch,
|
* Allows updating the slideover props
|
||||||
isOpen
|
*/
|
||||||
|
function patch<T extends Component = {}> (props: Partial<Slideover & ComponentProps<T>>) {
|
||||||
|
if (!slideoverState) return
|
||||||
|
|
||||||
|
slideoverState.value = {
|
||||||
|
...slideoverState.value,
|
||||||
|
props: {
|
||||||
|
...slideoverState.value.props,
|
||||||
|
...props
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
reset,
|
||||||
|
patch,
|
||||||
|
isOpen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSlideover = createSharedComposable(_useSlideover)
|
export const useSlideover = createSharedComposable(_useSlideover)
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ export default {
|
|||||||
variant: 'ghost' as const,
|
variant: 'ghost' as const,
|
||||||
class: '-m-1.5'
|
class: '-m-1.5'
|
||||||
},
|
},
|
||||||
|
checkbox: {
|
||||||
|
color: 'primary' as const
|
||||||
|
},
|
||||||
progress: {
|
progress: {
|
||||||
color: 'primary' as const,
|
color: 'primary' as const,
|
||||||
animation: 'carousel' as const
|
animation: 'carousel' as const
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
wrapper: 'relative',
|
wrapper: 'relative min-w-0',
|
||||||
ol: 'flex items-center gap-x-1.5',
|
ol: 'flex items-center gap-x-1.5',
|
||||||
li: 'flex items-center gap-x-1.5 text-gray-500 dark:text-gray-400 text-sm leading-6 min-w-0',
|
li: 'flex items-center gap-x-1.5 text-gray-500 dark:text-gray-400 text-sm leading-6 min-w-0',
|
||||||
base: 'flex items-center gap-x-1.5 group font-semibold min-w-0',
|
base: 'flex items-center gap-x-1.5 group font-semibold min-w-0',
|
||||||
|
|||||||
Reference in New Issue
Block a user