Skip to content

Commit

Permalink
fix(components): hydration attribute mismatch with vue 3.4 (#1199)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamincanac committed Feb 6, 2024
1 parent 4a5f7b0 commit 10db144
Show file tree
Hide file tree
Showing 19 changed files with 227 additions and 253 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"dependencies": {
"@egoist/tailwindcss-icons": "^1.7.4",
"@headlessui/tailwindcss": "^0.2.0",
"@headlessui/vue": "1.7.16",
"@headlessui/vue": "^1.7.18",
"@iconify-json/heroicons": "^1.1.19",
"@nuxt/kit": "^3.10.0",
"@nuxtjs/color-mode": "^3.3.2",
Expand Down Expand Up @@ -80,6 +80,7 @@
"@nuxt/kit": "3.10.0",
"@nuxt/schema": "3.10.0",
"tailwindcss": "3.4.1",
"vue": "3.3.13"
"@headlessui/vue": "1.7.18",
"vue": "3.4.15"
}
}
349 changes: 158 additions & 191 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default defineNuxtModule<ModuleOptions>({
version,
configKey: 'ui',
compatibility: {
nuxt: '^3.0.0-rc.8'
nuxt: '^3.10.0'
}
},
defaults: {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/data/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<thead :class="ui.thead">
<tr :class="ui.tr.base">
<th v-if="modelValue" scope="col" :class="ui.checkbox.padding">
<UCheckbox :checked="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" aria-label="Select all" @change="onChange" />
<UCheckbox :model-value="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" aria-label="Select all" @change="onChange" />
</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]">
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/components/elements/Accordion.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div :class="ui.wrapper">
<HDisclosure v-for="(item, index) in items" v-slot="{ open, close }" :key="index" :default-open="defaultOpen || item.defaultOpen">
<HDisclosure v-for="(item, index) in items" v-slot="{ open, close }" :key="index" as="div" :default-open="defaultOpen || item.defaultOpen">
<HDisclosureButton
:ref="() => buttonRefs[index] = { open, close }"
as="template"
Expand Down Expand Up @@ -47,7 +47,7 @@
<script lang="ts">
import { ref, computed, toRef, defineComponent } 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, provideUseId } from '@headlessui/vue'
import UIcon from '../elements/Icon.vue'
import UButton from '../elements/Button.vue'
import { useUI } from '../../composables/useUI'
Expand All @@ -56,6 +56,7 @@ import type { AccordionItem, Strategy } from '../../types'
// @ts-expect-error
import appConfig from '#build/app.config'
import { accordion, button } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof accordion>(appConfig.ui.strategy, appConfig.ui.accordion, accordion)
Expand Down Expand Up @@ -146,6 +147,8 @@ export default defineComponent({
el.addEventListener('transitionend', done, { once: true })
}
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/components/elements/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<script lang="ts">
import { defineComponent, ref, computed, watch, toRef, onMounted, resolveComponent } 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, provideUseId } from '@headlessui/vue'
import { defu } from 'defu'
import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
Expand All @@ -70,6 +70,7 @@ import type { DropdownItem, PopperOptions, Strategy } from '../../types'
// @ts-expect-error
import appConfig from '#build/app.config'
import { dropdown } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof dropdown>(appConfig.ui.strategy, appConfig.ui.dropdown, dropdown)
Expand Down Expand Up @@ -251,6 +252,8 @@ export default defineComponent({
const NuxtLink = resolveComponent('NuxtLink')
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
7 changes: 1 addition & 6 deletions src/runtime/components/forms/Checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
:required="required"
:value="value"
:disabled="disabled"
:checked="checked"
:indeterminate="indeterminate"
type="checkbox"
:class="inputClass"
Expand Down Expand Up @@ -66,13 +65,9 @@ export default defineComponent({
type: Boolean,
default: false
},
checked: {
type: Boolean,
default: false
},
indeterminate: {
type: Boolean,
default: false
default: undefined
},
help: {
type: String,
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/forms/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
</template>

<script lang="ts">
import { useId } from '#app'
import { provide, ref, type PropType, defineComponent, onUnmounted, onMounted } from 'vue'
import { useEventBus } from '@vueuse/core'
import type { ZodSchema } from 'zod'
import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi'
import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup'
import type { ObjectSchemaAsync as ValibotObjectSchema } from 'valibot'
import type { FormError, FormEvent, FormEventType, FormSubmitEvent, FormErrorEvent, Form } from '../../types/form'
import { useId } from '#imports'
class FormException extends Error {
constructor (message: string) {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/forms/FormGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
</template>

<script lang="ts">
import { useId } from '#app'
import { computed, defineComponent, provide, inject, ref, toRef } from 'vue'
import type { Ref, PropType } from 'vue'
import { useUI } from '../../composables/useUI'
Expand All @@ -47,6 +46,7 @@ import type { FormError, InjectedFormGroupValue, FormGroupSize, Strategy } from
// @ts-expect-error
import appConfig from '#build/app.config'
import { formGroup } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof formGroup>(appConfig.ui.strategy, appConfig.ui.formGroup, formGroup)
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/components/forms/InputMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ import {
ComboboxButton as HComboboxButton,
ComboboxOptions as HComboboxOptions,
ComboboxOption as HComboboxOption,
ComboboxInput as HComboboxInput
ComboboxInput as HComboboxInput,
provideUseId
} from '@headlessui/vue'
import { computedAsync, useDebounceFn } from '@vueuse/core'
import { defu } from 'defu'
Expand All @@ -114,6 +115,7 @@ import type { InputSize, InputColor, InputVariant, PopperOptions, Strategy } fro
// @ts-expect-error
import appConfig from '#build/app.config'
import { input, inputMenu } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof input>(appConfig.ui.strategy, appConfig.ui.input, input)
Expand Down Expand Up @@ -275,7 +277,6 @@ export default defineComponent({
emits: ['update:modelValue', 'update:query', 'open', 'close', 'change'],
setup (props, { emit, slots }) {
const { ui, attrs } = useUI('input', toRef(props, 'ui'), config, toRef(props, 'class'))
const { ui: uiMenu } = useUI('inputMenu', toRef(props, 'uiMenu'), configMenu)
const popper = computed<PopperOptions>(() => defu({}, props.popper, uiMenu.value.popper as PopperOptions))
Expand Down Expand Up @@ -428,6 +429,8 @@ export default defineComponent({
query.value = event.target.value
}
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Radio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@
</template>

<script lang="ts">
import { useId } from '#app'
import { computed, defineComponent, inject, toRef } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig } from '../../utils'
import type { Strategy } from '../../types'
// @ts-expect-error
import appConfig from '#build/app.config'
import { radio } from '#ui/ui.config'
import colors from '#ui-colors'
import { useFormGroup } from '../../composables/useFormGroup'
import { useId } from '#imports'
const config = mergeConfig<typeof radio>(appConfig.ui.strategy, appConfig.ui.radio, radio)
Expand Down
41 changes: 14 additions & 27 deletions src/runtime/components/forms/SelectMenu.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<template>
<component
:is="searchable ? 'HCombobox' : 'HListbox'"
<HCombobox
v-slot="{ open }"
:by="by"
:name="name"
Expand All @@ -20,13 +19,7 @@
aria-hidden="true"
>

<component
:is="searchable ? 'HComboboxButton' : 'HListboxButton'"
ref="trigger"
as="div"
role="button"
:class="uiMenu.trigger"
>
<HComboboxButton ref="trigger" as="div" role="button" :class="uiMenu.trigger">
<slot :open="open" :disabled="disabled" :loading="loading">
<button :id="inputId" :class="selectClass" :disabled="disabled" type="button" v-bind="attrs">
<span v-if="(isLeading && leadingIconName) || $slots.leading" :class="leadingWrapperIconClass">
Expand All @@ -47,14 +40,14 @@
</span>
</button>
</slot>
</component>
</HComboboxButton>

<div v-if="open" ref="container" :class="[uiMenu.container, uiMenu.width]">
<Transition appear v-bind="uiMenu.transition">
<div>
<div v-if="popper.arrow" data-popper-arrow :class="Object.values(uiMenu.arrow)" />

<component :is="searchable ? 'HComboboxOptions' : 'HListboxOptions'" static :class="[uiMenu.base, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]">
<HComboboxOptions static :class="[uiMenu.base, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]">
<HComboboxInput
v-if="searchable"
:display-value="() => query"
Expand All @@ -65,8 +58,7 @@
:class="uiMenu.input"
@change="onChange"
/>
<component
:is="searchable ? 'HComboboxOption' : 'HListboxOption'"
<HComboboxOption
v-for="(option, index) in filteredOptions"
v-slot="{ active, selected, disabled: optionDisabled }"
:key="index"
Expand Down Expand Up @@ -94,17 +86,17 @@
<UIcon :name="selectedIcon" :class="uiMenu.option.selectedIcon.base" aria-hidden="true" />
</span>
</li>
</component>
</HComboboxOption>

<component :is="searchable ? 'HComboboxOption' : 'HListboxOption'" v-if="creatable && createOption" v-slot="{ active, selected }" :value="createOption" as="template">
<HComboboxOption v-if="creatable && createOption" v-slot="{ active, selected }" :value="createOption" as="template">
<li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive]">
<div :class="uiMenu.option.container">
<slot name="option-create" :option="createOption" :active="active" :selected="selected">
<span :class="uiMenu.option.create">Create "{{ createOption[optionAttribute] }}"</span>
</slot>
</div>
</li>
</component>
</HComboboxOption>
<p v-else-if="searchable && query && !filteredOptions.length" :class="uiMenu.option.empty">
<slot name="option-empty" :query="query">
No results for "{{ query }}".
Expand All @@ -115,11 +107,11 @@
No options.
</slot>
</p>
</component>
</HComboboxOptions>
</div>
</Transition>
</div>
</component>
</HCombobox>
</template>

<script lang="ts">
Expand All @@ -131,10 +123,7 @@ import {
ComboboxOptions as HComboboxOptions,
ComboboxOption as HComboboxOption,
ComboboxInput as HComboboxInput,
Listbox as HListbox,
ListboxButton as HListboxButton,
ListboxOptions as HListboxOptions,
ListboxOption as HListboxOption
provideUseId
} from '@headlessui/vue'
import { computedAsync, useDebounceFn } from '@vueuse/core'
import { defu } from 'defu'
Expand All @@ -150,6 +139,7 @@ import type { SelectSize, SelectColor, SelectVariant, PopperOptions, Strategy }
// @ts-expect-error
import appConfig from '#build/app.config'
import { select, selectMenu } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof select>(appConfig.ui.strategy, appConfig.ui.select, select)
Expand All @@ -162,10 +152,6 @@ export default defineComponent({
HComboboxOptions,
HComboboxOption,
HComboboxInput,
HListbox,
HListboxButton,
HListboxOptions,
HListboxOption,
UIcon,
UAvatar
},
Expand Down Expand Up @@ -331,7 +317,6 @@ export default defineComponent({
emits: ['update:modelValue', 'update:query', 'open', 'close', 'change'],
setup (props, { emit, slots }) {
const { ui, attrs } = useUI('select', toRef(props, 'ui'), config, toRef(props, 'class'))
const { ui: uiMenu } = useUI('selectMenu', toRef(props, 'uiMenu'), configMenu)
const popper = computed<PopperOptions>(() => defu({}, props.popper, uiMenu.value.popper as PopperOptions))
Expand Down Expand Up @@ -512,6 +497,8 @@ export default defineComponent({
query.value = event.target.value
}
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/components/forms/Toggle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { Switch as HSwitch } from '@headlessui/vue'
import { Switch as HSwitch, provideUseId } from '@headlessui/vue'
import { twMerge, twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
Expand All @@ -32,6 +32,7 @@ import type { ToggleSize, Strategy } from '../../types'
import appConfig from '#build/app.config'
import { toggle } from '#ui/ui.config'
import colors from '#ui-colors'
import { useId } from '#imports'
const config = mergeConfig<typeof toggle>(appConfig.ui.strategy, appConfig.ui.toggle, toggle)
Expand Down Expand Up @@ -137,6 +138,8 @@ export default defineComponent({
)
})
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
5 changes: 4 additions & 1 deletion src/runtime/components/navigation/CommandPalette.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

<script lang="ts">
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, provideUseId } from '@headlessui/vue'
import type { ComputedRef, PropType, ComponentPublicInstance } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import { useFuse } from '@vueuse/integrations/useFuse'
Expand All @@ -79,6 +79,7 @@ import type { Group, Command, Button, Strategy } from '../../types'
// @ts-expect-error
import appConfig from '#build/app.config'
import { commandPalette } from '#ui/ui.config'
import { useId } from '#imports'
const config = mergeConfig<typeof commandPalette>(appConfig.ui.strategy, appConfig.ui.commandPalette, commandPalette)
Expand Down Expand Up @@ -366,6 +367,8 @@ export default defineComponent({
results
})
provideUseId(() => useId())
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
Expand Down
Loading

0 comments on commit 10db144

Please sign in to comment.