fix(module): retain props reactivity through useUI (#745)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Aditio Pangestu
2023-09-28 19:06:57 +07:00
committed by GitHub
parent 874447cb41
commit 109ec52d50
36 changed files with 237 additions and 99 deletions

View File

@@ -10,7 +10,7 @@
"@nuxt/content": "^2.8.4", "@nuxt/content": "^2.8.4",
"@nuxt/devtools": "^0.8.3", "@nuxt/devtools": "^0.8.3",
"@nuxt/eslint-config": "^0.2.0", "@nuxt/eslint-config": "^0.2.0",
"@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@0.0.1-28255017.af7c0a2", "@nuxt/ui-pro": "npm:@nuxt/ui-pro-edge@0.0.1-28264972.7d9d1f6",
"@nuxthq/studio": "^0.14.1", "@nuxthq/studio": "^0.14.1",
"@nuxtjs/fontaine": "^0.4.1", "@nuxtjs/fontaine": "^0.4.1",
"@nuxtjs/google-fonts": "^3.0.2", "@nuxtjs/google-fonts": "^3.0.2",

16
pnpm-lock.yaml generated
View File

@@ -137,8 +137,8 @@ importers:
specifier: ^0.2.0 specifier: ^0.2.0
version: 0.2.0(eslint@8.49.0) version: 0.2.0(eslint@8.49.0)
'@nuxt/ui-pro': '@nuxt/ui-pro':
specifier: npm:@nuxt/ui-pro-edge@0.0.1-28255017.af7c0a2 specifier: npm:@nuxt/ui-pro-edge@0.0.1-28264972.7d9d1f6
version: /@nuxt/ui-pro-edge@0.0.1-28255017.af7c0a2(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2) version: /@nuxt/ui-pro-edge@0.0.1-28264972.7d9d1f6(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2)
'@nuxthq/studio': '@nuxthq/studio':
specifier: ^0.14.1 specifier: ^0.14.1
version: 0.14.1(rollup@3.28.1) version: 0.14.1(rollup@3.28.1)
@@ -1032,7 +1032,6 @@ packages:
tailwindcss: ^3.0 tailwindcss: ^3.0
dependencies: dependencies:
tailwindcss: 3.3.3 tailwindcss: 3.3.3
dev: false
/@headlessui/vue@1.7.16(vue@3.3.4): /@headlessui/vue@1.7.16(vue@3.3.4):
resolution: {integrity: sha512-nKT+nf/q6x198SsyK54mSszaQl/z+QxtASmgMEJtpxSX2Q0OPJX0upS/9daDyiECpeAsvjkoOrm2O/6PyBQ+Qg==} resolution: {integrity: sha512-nKT+nf/q6x198SsyK54mSszaQl/z+QxtASmgMEJtpxSX2Q0OPJX0upS/9daDyiECpeAsvjkoOrm2O/6PyBQ+Qg==}
@@ -1702,11 +1701,12 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@nuxt/ui-edge@2.8.1-28262323.b306138(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2): /@nuxt/ui-edge@2.8.1-28264933.874447c(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2):
resolution: {integrity: sha512-piljLwguAK9NH45HuKYBif2g4J5sIBI3cqSndygIxmIN84j4ZQ8lSdE3rIutoIj7YzwEdInV3Vj7RLexGMLIBA==} resolution: {integrity: sha512-+8HtwrCFGQ7Cz6MYdjvsR2fhdlawZI73OZ1J74ZFRm3KdbECsN1fY6Cy/R33kw7arZJRm5SREjkSxd37zlr3og==}
engines: {node: '>=v16.20.2'} engines: {node: '>=v16.20.2'}
dependencies: dependencies:
'@egoist/tailwindcss-icons': 1.1.0(tailwindcss@3.3.3) '@egoist/tailwindcss-icons': 1.1.0(tailwindcss@3.3.3)
'@headlessui/tailwindcss': 0.2.0(tailwindcss@3.3.3)
'@headlessui/vue': 1.7.16(vue@3.3.4) '@headlessui/vue': 1.7.16(vue@3.3.4)
'@iconify-json/heroicons': 1.1.12 '@iconify-json/heroicons': 1.1.12
'@nuxt/kit': 3.7.4(rollup@3.28.1) '@nuxt/kit': 3.7.4(rollup@3.28.1)
@@ -1747,10 +1747,10 @@ packages:
- webpack - webpack
dev: true dev: true
/@nuxt/ui-pro-edge@0.0.1-28255017.af7c0a2(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2): /@nuxt/ui-pro-edge@0.0.1-28264972.7d9d1f6(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2):
resolution: {integrity: sha512-ULHT1oKXQJRqkduLePBO2livZ/hXJIxzUtEWjuMdXqHRcTBWvr8aShoJ4u6lHcpgr6URt6VxbhhlLixdlyb2WA==} resolution: {integrity: sha512-blx7a70AKStd/z75JOvpuG5mhNT467dfXoZdJU8huBU9uhUyBsw5mw199yga+aO/p20UUJvgo4VntMlmjjr18A==}
dependencies: dependencies:
'@nuxt/ui': /@nuxt/ui-edge@2.8.1-28262323.b306138(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2) '@nuxt/ui': /@nuxt/ui-edge@2.8.1-28264933.874447c(rollup@3.28.1)(vue@3.3.4)(webpack@5.88.2)
'@vueuse/core': 10.4.1(vue@3.3.4) '@vueuse/core': 10.4.1(vue@3.3.4)
ofetch: 1.3.3 ofetch: 1.3.3
pathe: 1.1.1 pathe: 1.1.1

View File

@@ -67,7 +67,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, defineComponent, toRaw } from 'vue' import { ref, computed, defineComponent, toRaw, toRef } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { upperFirst } from 'scule' import { upperFirst } from 'scule'
import { defu } from 'defu' import { defu } from 'defu'
@@ -143,6 +143,10 @@ export default defineComponent({
type: Object as PropType<{ icon: string, label: string }>, type: Object as PropType<{ icon: string, label: string }>,
default: () => config.default.emptyState default: () => config.default.emptyState
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -150,7 +154,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
setup (props, { emit, attrs: $attrs }) { setup (props, { emit, attrs: $attrs }) {
const { ui, attrs } = useUI('table', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('table', toRef(props, 'ui'), config, toRef(props, 'class'))
const columns = computed(() => props.columns ?? Object.keys(omit(props.rows[0] ?? {}, ['click'])).map((key) => ({ key, label: upperFirst(key), sortable: false }))) const columns = computed(() => props.columns ?? Object.keys(omit(props.rows[0] ?? {}, ['click'])).map((key) => ({ key, label: upperFirst(key), sortable: false })))

View File

@@ -40,7 +40,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, defineComponent } from 'vue' import { ref, computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { Disclosure as HDisclosure, DisclosureButton as HDisclosureButton, DisclosurePanel as HDisclosurePanel } from '@headlessui/vue' import { Disclosure as HDisclosure, DisclosureButton as HDisclosureButton, DisclosurePanel as HDisclosurePanel } from '@headlessui/vue'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -88,13 +88,17 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: false default: false
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('accordion', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('accordion', toRef(props, 'ui'), config, toRef(props, 'class'))
const uiButton = computed<Partial<typeof configButton>>(() => configButton) const uiButton = computed<Partial<typeof configButton>>(() => configButton)

View File

@@ -32,7 +32,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -97,6 +97,10 @@ export default defineComponent({
].includes(value) ].includes(value)
} }
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -104,7 +108,7 @@ export default defineComponent({
}, },
emits: ['close'], emits: ['close'],
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('alert', props.ui, config) const { ui, attrs } = useUI('alert', toRef(props, 'ui'), config)
const alertClass = computed(() => { const alertClass = computed(() => {
const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant] const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant]
@@ -115,7 +119,7 @@ export default defineComponent({
ui.value.shadow, ui.value.shadow,
ui.value.padding, ui.value.padding,
variant?.replaceAll('{color}', props.color) variant?.replaceAll('{color}', props.color)
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -20,7 +20,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, computed, watch } from 'vue' import { defineComponent, ref, computed, toRef, watch } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -84,13 +84,17 @@ export default defineComponent({
type: String, type: String,
default: '' default: ''
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('avatar', props.ui, config) const { ui, attrs } = useUI('avatar', toRef(props, 'ui'), config)
const url = computed(() => { const url = computed(() => {
if (typeof props.src === 'boolean') { if (typeof props.src === 'boolean') {
@@ -109,7 +113,7 @@ export default defineComponent({
(error.value || !url.value) && ui.value.background, (error.value || !url.value) && ui.value.background,
ui.value.rounded, ui.value.rounded,
ui.value.size[props.size] ui.value.size[props.size]
), attrsClass) ), props.class)
}) })
const imgClass = computed(() => { const imgClass = computed(() => {

View File

@@ -1,4 +1,4 @@
import { h, cloneVNode, computed, defineComponent } from 'vue' import { h, cloneVNode, computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UAvatar from './Avatar.vue' import UAvatar from './Avatar.vue'
@@ -27,13 +27,17 @@ export default defineComponent({
type: Number, type: Number,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof avatarGroupConfig & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof avatarGroupConfig & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props, { slots }) { setup (props, { slots }) {
const { ui, attrs } = useUI('avatarGroup', props.ui, avatarGroupConfig, { mergeWrapper: true }) const { ui, attrs } = useUI('avatarGroup', toRef(props, 'ui'), avatarGroupConfig, toRef(props, 'class'))
const children = computed(() => getSlotsChildren(slots)) const children = computed(() => getSlotsChildren(slots))

View File

@@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -49,13 +49,17 @@ export default defineComponent({
type: [String, Number], type: [String, Number],
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('badge', props.ui, config) const { ui, attrs } = useUI('badge', toRef(props, 'ui'), config)
const badgeClass = computed(() => { const badgeClass = computed(() => {
const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant] const variant = ui.value.color?.[props.color as string]?.[props.variant as string] || ui.value.variant[props.variant]
@@ -66,7 +70,7 @@ export default defineComponent({
ui.value.rounded, ui.value.rounded,
ui.value.size[props.size], ui.value.size[props.size],
variant?.replaceAll('{color}', props.color) variant?.replaceAll('{color}', props.color)
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -17,7 +17,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, defineComponent, toRef } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -118,13 +118,17 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: false default: false
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props, { slots }) { setup (props, { slots }) {
const { ui, attrs, attrsClass } = useUI('button', props.ui, config) const { ui, attrs } = useUI('button', toRef(props, 'ui'), config)
const isLeading = computed(() => { const isLeading = computed(() => {
return (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing) || props.leadingIcon return (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing) || props.leadingIcon
@@ -148,7 +152,7 @@ export default defineComponent({
props.padded && ui.value[isSquare.value ? 'square' : 'padding'][props.size], props.padded && ui.value[isSquare.value ? 'square' : 'padding'][props.size],
variant?.replaceAll('{color}', props.color), variant?.replaceAll('{color}', props.color),
props.block ? 'w-full flex justify-center items-center' : 'inline-flex items-center' props.block ? 'w-full flex justify-center items-center' : 'inline-flex items-center'
), attrsClass) ), props.class)
}) })
const leadingIconName = computed(() => { const leadingIconName = computed(() => {

View File

@@ -1,4 +1,4 @@
import { h, cloneVNode, computed, defineComponent } from 'vue' import { h, cloneVNode, computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -28,13 +28,17 @@ export default defineComponent({
return ['horizontal', 'vertical'].includes(value) return ['horizontal', 'vertical'].includes(value)
} }
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof buttonGroupConfig & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof buttonGroupConfig & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props, { slots }) { setup (props, { slots }) {
const { ui, attrs, attrsClass } = useUI('buttonGroup', props.ui, buttonGroupConfig) const { ui, attrs } = useUI('buttonGroup', toRef(props, 'ui'), buttonGroupConfig)
const children = computed(() => getSlotsChildren(slots)) const children = computed(() => getSlotsChildren(slots))
@@ -80,7 +84,7 @@ export default defineComponent({
ui.value.wrapper[props.orientation], ui.value.wrapper[props.orientation],
ui.value.rounded, ui.value.rounded,
ui.value.shadow ui.value.shadow
), attrsClass) ), props.class)
}) })
return () => h('div', { class: wrapperClass.value, ...attrs.value }, clones.value) return () => h('div', { class: wrapperClass.value, ...attrs.value }, clones.value)

View File

@@ -45,7 +45,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, computed, onMounted } from 'vue' import { defineComponent, ref, computed, toRef, onMounted } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { Menu as HMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem } from '@headlessui/vue' import { Menu as HMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem } from '@headlessui/vue'
import { defu } from 'defu' import { defu } from 'defu'
@@ -101,13 +101,17 @@ export default defineComponent({
type: Number, type: Number,
default: 0 default: 0
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('dropdown', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('dropdown', toRef(props, 'ui'), config, toRef(props, 'class'))
const popper = computed<PopperOptions>(() => defu(props.mode === 'hover' ? { offsetDistance: 0 } : {}, props.popper, ui.value.popper as PopperOptions)) const popper = computed<PopperOptions>(() => defu(props.mode === 'hover' ? { offsetDistance: 0 } : {}, props.popper, ui.value.popper as PopperOptions))

View File

@@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, computed } from 'vue' import { toRef, defineComponent, computed } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -31,13 +31,17 @@ export default defineComponent({
return Object.keys(config.size).includes(value) return Object.keys(config.size).includes(value)
} }
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('kbd', props.ui, config) const { ui, attrs } = useUI('kbd', toRef(props, 'ui'), config)
const kbdClass = computed(() => { const kbdClass = computed(() => {
return twMerge(twJoin( return twMerge(twJoin(
@@ -48,7 +52,7 @@ export default defineComponent({
ui.value.font, ui.value.font,
ui.value.background, ui.value.background,
ui.value.ring ui.value.ring
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -30,7 +30,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -100,6 +100,10 @@ export default defineComponent({
type: String, type: String,
default: '' default: ''
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -107,7 +111,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'change'], emits: ['update:modelValue', 'change'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('checkbox', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('checkbox', toRef(props, 'ui'), config, toRef(props, 'class'))
const { emitFormChange, color, name, inputId } = useFormGroup(props) const { emitFormChange, color, name, inputId } = useFormGroup(props)

View File

@@ -20,7 +20,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, provide, inject, ref } from 'vue' import { computed, defineComponent, provide, inject, ref, toRef } from 'vue'
import type { Ref, PropType } from 'vue' import type { Ref, PropType } from 'vue'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils' import { mergeConfig } from '../../utils'
@@ -70,13 +70,17 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('formGroup', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('formGroup', toRef(props, 'ui'), config, toRef(props, 'class'))
const formErrors = inject<Ref<FormError[]> | null>('form-errors', null) const formErrors = inject<Ref<FormError[]> | null>('form-errors', null)

View File

@@ -32,7 +32,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, onMounted, defineComponent } from 'vue' import { ref, computed, toRef, onMounted, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -145,6 +145,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -152,7 +156,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'blur'], emits: ['update:modelValue', 'blur'],
setup (props, { emit, slots }) { setup (props, { emit, slots }) {
const { ui, attrs } = useUI('input', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('input', toRef(props, 'ui'), config, toRef(props, 'class'))
const { emitFormBlur, emitFormInput, size, color, inputId, name } = useFormGroup(props, config) const { emitFormBlur, emitFormInput, size, color, inputId, name } = useFormGroup(props, config)

View File

@@ -27,7 +27,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -89,6 +89,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -96,7 +100,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('radio', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('radio', toRef(props, 'ui'), config, toRef(props, 'class'))
const { emitFormChange, color, name, inputId } = useFormGroup(props) const { emitFormChange, color, name, inputId } = useFormGroup(props)

View File

@@ -20,7 +20,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -83,6 +83,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -90,7 +94,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'change'], emits: ['update:modelValue', 'change'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs, attrsClass } = useUI('range', props.ui, config) const { ui, attrs } = useUI('range', toRef(props, 'ui'), config)
const { emitFormChange, inputId, color, size, name } = useFormGroup(props, config) const { emitFormChange, inputId, color, size, name } = useFormGroup(props, config)
@@ -112,7 +116,7 @@ export default defineComponent({
return twMerge(twJoin( return twMerge(twJoin(
ui.value.wrapper, ui.value.wrapper,
ui.value.size[size.value] ui.value.size[size.value]
), attrsClass) ), props.class)
}) })
const inputClass = computed(() => { const inputClass = computed(() => {

View File

@@ -54,7 +54,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType, ComputedRef } from 'vue' import type { PropType, ComputedRef } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -171,6 +171,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -178,7 +182,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'change'], emits: ['update:modelValue', 'change'],
setup (props, { emit, slots }) { setup (props, { emit, slots }) {
const { ui, attrs } = useUI('select', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('select', toRef(props, 'ui'), config, toRef(props, 'class'))
const { emitFormChange, inputId, color, size, name } = useFormGroup(props, config) const { emitFormChange, inputId, color, size, name } = useFormGroup(props, config)

View File

@@ -116,7 +116,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, watch, defineComponent } from 'vue' import { ref, computed, toRef, watch, defineComponent } from 'vue'
import type { PropType, ComponentPublicInstance } from 'vue' import type { PropType, ComponentPublicInstance } from 'vue'
import { import {
Combobox as HCombobox, Combobox as HCombobox,
@@ -296,6 +296,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -307,9 +311,9 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'open', 'close', 'change'], emits: ['update:modelValue', 'open', 'close', 'change'],
setup (props, { emit, slots }) { setup (props, { emit, slots }) {
const { ui, attrs } = useUI('select', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('select', toRef(props, 'ui'), config, toRef(props, 'class'))
const { ui: uiMenu } = useUI('selectMenu', props.uiMenu, configMenu) const { ui: uiMenu } = useUI('selectMenu', toRef(props, 'uiMenu'), configMenu)
const popper = computed<PopperOptions>(() => defu({}, props.popper, uiMenu.value.popper as PopperOptions)) const popper = computed<PopperOptions>(() => defu({}, props.popper, uiMenu.value.popper as PopperOptions))

View File

@@ -19,7 +19,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, watch, onMounted, nextTick, defineComponent } from 'vue' import { ref, computed, toRef, watch, onMounted, nextTick, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -108,6 +108,10 @@ export default defineComponent({
type: String, type: String,
default: null default: null
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -115,7 +119,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'blur'], emits: ['update:modelValue', 'blur'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('textarea', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('textarea', toRef(props, 'ui'), config, toRef(props, 'class'))
const { emitFormBlur, emitFormInput, inputId, color, size, name } = useFormGroup(props, config) const { emitFormBlur, emitFormInput, inputId, color, size, name } = useFormGroup(props, config)

View File

@@ -19,7 +19,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { Switch as HSwitch } from '@headlessui/vue' import { Switch as HSwitch } from '@headlessui/vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
@@ -73,6 +73,10 @@ export default defineComponent({
return appConfig.ui.colors.includes(value) return appConfig.ui.colors.includes(value)
} }
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -80,7 +84,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs, attrsClass } = useUI('toggle', props.ui, config) const { ui, attrs } = useUI('toggle', toRef(props, 'ui'), config)
const { emitFormChange, color, inputId, name } = useFormGroup(props) const { emitFormChange, color, inputId, name } = useFormGroup(props)
@@ -100,7 +104,7 @@ export default defineComponent({
ui.value.rounded, ui.value.rounded,
ui.value.ring.replaceAll('{color}', color.value), ui.value.ring.replaceAll('{color}', color.value),
(active.value ? ui.value.active : ui.value.inactive).replaceAll('{color}', color.value) (active.value ? ui.value.active : ui.value.inactive).replaceAll('{color}', color.value)
), attrsClass) ), props.class)
}) })
const onIconClass = computed(() => { const onIconClass = computed(() => {

View File

@@ -17,7 +17,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -36,13 +36,17 @@ export default defineComponent({
type: String, type: String,
default: 'div' default: 'div'
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('card', props.ui, config) const { ui, attrs } = useUI('card', toRef(props, 'ui'), config)
const cardClass = computed(() => { const cardClass = computed(() => {
return twMerge(twJoin( return twMerge(twJoin(
@@ -52,7 +56,7 @@ export default defineComponent({
ui.value.ring, ui.value.ring,
ui.value.shadow, ui.value.shadow,
ui.value.background ui.value.background
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -24,20 +24,24 @@ export default defineComponent({
type: String, type: String,
default: 'div' default: 'div'
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('container', props.ui, config) const { ui, attrs } = useUI('container', toRef(props, 'ui'), config)
const containerClass = computed(() => { const containerClass = computed(() => {
return twMerge(twJoin( return twMerge(twJoin(
ui.value.base, ui.value.base,
ui.value.padding, ui.value.padding,
ui.value.constrained ui.value.constrained
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -3,7 +3,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -18,20 +18,24 @@ const config = mergeConfig<typeof skeleton>(appConfig.ui.strategy, appConfig.ui.
export default defineComponent({ export default defineComponent({
inheritAttrs: false, inheritAttrs: false,
props: { props: {
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('skeleton', props.ui, config) const { ui, attrs } = useUI('skeleton', toRef(props, 'ui'), config)
const skeletonClass = computed(() => { const skeletonClass = computed(() => {
return twMerge(twJoin( return twMerge(twJoin(
ui.value.base, ui.value.base,
ui.value.background, ui.value.background,
ui.value.rounded ui.value.rounded
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -62,7 +62,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, watch, onMounted, defineComponent } from 'vue' import { ref, computed, watch, toRef, onMounted, defineComponent } from 'vue'
import { Combobox as HCombobox, ComboboxInput as HComboboxInput, ComboboxOptions as HComboboxOptions } from '@headlessui/vue' import { Combobox as HCombobox, ComboboxInput as HComboboxInput, ComboboxOptions as HComboboxOptions } from '@headlessui/vue'
import type { ComputedRef, PropType, ComponentPublicInstance } from 'vue' import type { ComputedRef, PropType, ComponentPublicInstance } from 'vue'
import { useDebounceFn } from '@vueuse/core' import { useDebounceFn } from '@vueuse/core'
@@ -169,6 +169,10 @@ export default defineComponent({
type: Object as PropType<UseFuseOptions<Command>>, type: Object as PropType<UseFuseOptions<Command>>,
default: () => ({}) default: () => ({})
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -176,7 +180,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'close'], emits: ['update:modelValue', 'close'],
setup (props, { emit, expose }) { setup (props, { emit, expose }) {
const { ui, attrs } = useUI('commandPalette', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('commandPalette', toRef(props, 'ui'), config, toRef(props, 'class'))
const query = ref('') const query = ref('')
const comboboxInput = ref<ComponentPublicInstance<HTMLInputElement>>() const comboboxInput = ref<ComponentPublicInstance<HTMLInputElement>>()

View File

@@ -40,7 +40,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import UButton from '../elements/Button.vue' import UButton from '../elements/Button.vue'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -106,6 +106,10 @@ export default defineComponent({
type: String, type: String,
default: '…' default: '…'
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -113,7 +117,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('pagination', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('pagination', toRef(props, 'ui'), config, toRef(props, 'class'))
const currentPage = computed({ const currentPage = computed({
get () { get () {

View File

@@ -49,7 +49,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, watch, onMounted, defineComponent } from 'vue' import { toRef, ref, watch, onMounted, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { TabGroup as HTabGroup, TabList as HTabList, Tab as HTab, TabPanels as HTabPanels, TabPanel as HTabPanel } from '@headlessui/vue' import { TabGroup as HTabGroup, TabList as HTabList, Tab as HTab, TabPanels as HTabPanels, TabPanel as HTabPanel } from '@headlessui/vue'
import { useResizeObserver } from '@vueuse/core' import { useResizeObserver } from '@vueuse/core'
@@ -89,6 +89,10 @@ export default defineComponent({
type: Array as PropType<TabItem[]>, type: Array as PropType<TabItem[]>,
default: () => [] default: () => []
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -96,7 +100,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'change'], emits: ['update:modelValue', 'change'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('tabs', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('tabs', toRef(props, 'ui'), config, toRef(props, 'class'))
const listRef = ref<HTMLElement>() const listRef = ref<HTMLElement>()
const itemRefs = ref<HTMLElement[]>([]) const itemRefs = ref<HTMLElement[]>([])

View File

@@ -38,7 +38,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue' import UAvatar from '../elements/Avatar.vue'
@@ -64,13 +64,17 @@ export default defineComponent({
type: Array as PropType<VerticalNavigationLink[]>, type: Array as PropType<VerticalNavigationLink[]>,
default: () => [] default: () => []
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('verticalNavigation', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('verticalNavigation', toRef(props, 'ui'), config, toRef(props, 'class'))
return { return {
// eslint-disable-next-line vue/no-dupe-keys // eslint-disable-next-line vue/no-dupe-keys

View File

@@ -40,6 +40,10 @@ export default defineComponent({
type: Object as PropType<PopperOptions>, type: Object as PropType<PopperOptions>,
default: () => ({}) default: () => ({})
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -47,7 +51,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'close'], emits: ['update:modelValue', 'close'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs, attrsClass } = useUI('contextMenu', props.ui, config) const { ui, attrs } = useUI('contextMenu', toRef(props, 'ui'), config)
const popper = computed<PopperOptions>(() => defu({}, props.popper, ui.value.popper as PopperOptions)) const popper = computed<PopperOptions>(() => defu({}, props.popper, ui.value.popper as PopperOptions))
@@ -68,7 +72,7 @@ export default defineComponent({
return twMerge(twJoin( return twMerge(twJoin(
ui.value.container, ui.value.container,
ui.value.width ui.value.width
), attrsClass) ), props.class)
}) })
onClickOutside(container, () => { onClickOutside(container, () => {

View File

@@ -30,7 +30,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { Dialog as HDialog, DialogPanel as HDialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue' import { Dialog as HDialog, DialogPanel as HDialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -75,6 +75,10 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: false default: false
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -82,7 +86,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'close'], emits: ['update:modelValue', 'close'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('modal', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('modal', toRef(props, 'ui'), config, toRef(props, 'class'))
const isOpen = computed({ const isOpen = computed({
get () { get () {

View File

@@ -39,7 +39,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ref, computed, onMounted, onUnmounted, watchEffect, defineComponent } from 'vue' import { ref, computed, toRef, onMounted, onUnmounted, watchEffect, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
@@ -106,6 +106,10 @@ export default defineComponent({
return ['gray', ...appConfig.ui.colors].includes(value) return ['gray', ...appConfig.ui.colors].includes(value)
} }
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -113,7 +117,7 @@ export default defineComponent({
}, },
emits: ['close'], emits: ['close'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs, attrsClass } = useUI('notification', props.ui, config) const { ui, attrs } = useUI('notification', toRef(props, 'ui'), config)
let timer: any = null let timer: any = null
const remaining = ref(props.timeout) const remaining = ref(props.timeout)
@@ -124,7 +128,7 @@ export default defineComponent({
ui.value.background, ui.value.background,
ui.value.rounded, ui.value.rounded,
ui.value.shadow ui.value.shadow
), attrsClass) ), props.class)
}) })
const progressClass = computed(() => { const progressClass = computed(() => {

View File

@@ -18,7 +18,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge' import { twMerge, twJoin } from 'tailwind-merge'
import UNotification from './Notification.vue' import UNotification from './Notification.vue'
@@ -39,13 +39,17 @@ export default defineComponent({
}, },
inheritAttrs: false, inheritAttrs: false,
props: { props: {
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs, attrsClass } = useUI('notifications', props.ui, config) const { ui, attrs } = useUI('notifications', toRef(props, 'ui'), config)
const toast = useToast() const toast = useToast()
const notifications = useState<Notification[]>('notifications', () => []) const notifications = useState<Notification[]>('notifications', () => [])
@@ -55,7 +59,7 @@ export default defineComponent({
ui.value.wrapper, ui.value.wrapper,
ui.value.position, ui.value.position,
ui.value.width ui.value.width
), attrsClass) ), props.class)
}) })
return { return {

View File

@@ -26,7 +26,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, ref, onMounted, defineComponent } from 'vue' import { computed, ref, toRef, onMounted, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { defu } from 'defu' import { defu } from 'defu'
import { Popover as HPopover, PopoverButton as HPopoverButton, PopoverPanel as HPopoverPanel } from '@headlessui/vue' import { Popover as HPopover, PopoverButton as HPopoverButton, PopoverPanel as HPopoverPanel } from '@headlessui/vue'
@@ -69,13 +69,17 @@ export default defineComponent({
type: Object as PropType<PopperOptions>, type: Object as PropType<PopperOptions>,
default: () => ({}) default: () => ({})
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('popover', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('popover', toRef(props, 'ui'), config, toRef(props, 'class'))
const popper = computed<PopperOptions>(() => defu(props.mode === 'hover' ? { offsetDistance: 0 } : {}, props.popper, ui.value.popper as PopperOptions)) const popper = computed<PopperOptions>(() => defu(props.mode === 'hover' ? { offsetDistance: 0 } : {}, props.popper, ui.value.popper as PopperOptions))

View File

@@ -15,7 +15,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from 'vue' import { computed, toRef, defineComponent } from 'vue'
import type { WritableComputedRef, PropType } from 'vue' import type { WritableComputedRef, PropType } from 'vue'
import { Dialog as HDialog, DialogPanel as HDialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue' import { Dialog as HDialog, DialogPanel as HDialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
@@ -61,6 +61,10 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: false default: false
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
@@ -68,7 +72,7 @@ export default defineComponent({
}, },
emits: ['update:modelValue', 'close'], emits: ['update:modelValue', 'close'],
setup (props, { emit }) { setup (props, { emit }) {
const { ui, attrs } = useUI('slideover', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('slideover', toRef(props, 'ui'), config, toRef(props, 'class'))
const isOpen: WritableComputedRef<boolean> = computed({ const isOpen: WritableComputedRef<boolean> = computed({
get () { get () {

View File

@@ -24,7 +24,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, ref, defineComponent } from 'vue' import { computed, ref, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { defu } from 'defu' import { defu } from 'defu'
import UKbd from '../elements/Kbd.vue' import UKbd from '../elements/Kbd.vue'
@@ -68,13 +68,17 @@ export default defineComponent({
type: Object as PropType<PopperOptions>, type: Object as PropType<PopperOptions>,
default: () => ({}) default: () => ({})
}, },
class: {
type: [String, Object, Array] as PropType<any>,
default: undefined
},
ui: { ui: {
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>, type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
default: undefined default: undefined
} }
}, },
setup (props) { setup (props) {
const { ui, attrs } = useUI('tooltip', props.ui, config, { mergeWrapper: true }) const { ui, attrs } = useUI('tooltip', toRef(props, 'ui'), config, toRef(props, 'class'))
const popper = computed<PopperOptions>(() => defu({}, props.popper, ui.value.popper as PopperOptions)) const popper = computed<PopperOptions>(() => defu({}, props.popper, ui.value.popper as PopperOptions))

View File

@@ -1,24 +1,30 @@
import { computed, toValue, useAttrs } from 'vue' import { computed, toValue, useAttrs } from 'vue'
import type { Ref } from 'vue'
import { useAppConfig } from '#imports' import { useAppConfig } from '#imports'
import { mergeConfig, omit, get } from '../utils' import { mergeConfig, omit, get } from '../utils'
import { Strategy } from '../types' import { Strategy } from '../types'
export const useUI = <T>(key, $ui: Partial<T & { strategy: Strategy }>, $config?: T, { mergeWrapper = false }: { mergeWrapper?: boolean } = {}) => { export const useUI = <T>(key, $ui: Ref<Partial<T & { strategy: Strategy }> | undefined>, $config?: Ref<T> | T, $wrapperClass?: Ref<string>) => {
const $attrs = useAttrs() const $attrs = useAttrs()
const appConfig = useAppConfig() const appConfig = useAppConfig()
const ui = computed(() => mergeConfig<T>( const ui = computed(() => {
$ui?.strategy || (appConfig.ui?.strategy as Strategy), const _ui = toValue($ui)
mergeWrapper ? { wrapper: $attrs?.class } : {}, const _config = toValue($config)
$ui || {}, const _wrapperClass = toValue($wrapperClass)
process.dev ? get(appConfig.ui, key, {}) : {}, return mergeConfig<T>(
toValue($config || {}) _ui?.strategy || (appConfig.ui?.strategy as Strategy),
)) _wrapperClass ? { wrapper: _wrapperClass } : {},
_ui || {},
process.dev ? get(appConfig.ui, key, {}) : {},
_config || {}
)
})
const attrs = computed(() => omit($attrs, ['class'])) const attrs = computed(() => omit($attrs, ['class']))
return { return {
ui, ui,
attrs, attrs
attrsClass: mergeWrapper ? undefined : $attrs?.class as string
} }
} }