Skip to content

Fix useModelMigration in async components #6608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: stable8
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/NcActionCheckbox/NcActionCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('checked', 'update:checked')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'checked', 'update:checked')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcActionInput/NcActionInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcActionRadio/NcActionRadio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@ export default {
'change',
],

setup(props) {
setup(props, {emit}) {
if (typeof props.modelValue === 'boolean') {
Vue.util.warn('[NcActionRadio] Boolean type of `modelValue` is deprecated and will be removed in next versions')
}

const model = useModelMigration('checked', 'update:checked')
const model = useModelMigration(props, emit, 'checked', 'update:checked')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcActionTextEditable/NcActionTextEditable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ export default {
'submit',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
isRtl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('checked', 'update:checked')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'checked', 'update:checked')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcColorPicker/NcColorPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ export default {
'input',
],

setup() {
const model = useModelMigration('value', 'update:value', true)
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value', true)
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcDateTimePicker/NcDateTimePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ export default {
'update:timezone-id',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
timezoneDialogHeaderId: `timezone-dialog-header-${GenRandomId()}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('value', 'input')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'input')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcInputField/NcInputField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ export default {
'trailing-button-click',
],

setup() {
const model = useModelMigration('value', 'update:value', true)
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value', true)
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcPasswordField/NcPasswordField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,9 @@ export default {
'smart-picker-submit',
],

setup() {
setup(props, {emit}) {
const uid = GenRandomId(5)
const model = useModelMigration('value', 'update:value', true)
const model = useModelMigration(props, emit, 'value', 'update:value', true)
return {
model,
// Constants
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcSelect/NcSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -990,12 +990,12 @@ export default {
'update:model-value',
],

setup() {
setup(props, {emit}) {
const clickableArea = Number.parseInt(window.getComputedStyle(document.body).getPropertyValue('--default-clickable-area'))
const gridBaseLine = Number.parseInt(window.getComputedStyle(document.body).getPropertyValue('--default-grid-baseline'))
const avatarSize = clickableArea - 2 * gridBaseLine

const model = useModelMigration('value', 'input')
const model = useModelMigration(props, emit, 'value', 'input')

return {
avatarSize,
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcSelectTags/NcSelectTags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ export default {
' ',
],

setup() {
const model = useModelMigration('value', 'input')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'input')
const noop = () => {}
return {
model,
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcSettingsInputText/NcSettingsInputText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ export default {
'change',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ export default {
'update:model-value',
'error',
],
setup() {
const model = useModelMigration('value', 'input')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'input')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcTextArea/NcTextArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('value', 'update:value', true)
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value', true)
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcTextField/NcTextField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ export default {
'update:model-value',
],

setup() {
const model = useModelMigration('value', 'update:value')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'update:value')
return {
model,
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/NcTimezonePicker/NcTimezonePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ export default {
/** Same as update:modelValue for Vue 2 compatibility */
'update:model-value',
],
setup() {
const model = useModelMigration('value', 'input')
setup(props, {emit}) {
const model = useModelMigration(props, emit, 'value', 'input')
return {
model,
}
Expand Down
33 changes: 18 additions & 15 deletions src/composables/useModelMigration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,40 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import Vue, { getCurrentInstance, computed } from 'vue'
import Vue, { computed } from 'vue'
import type { WritableComputedRef } from 'vue'
import type { EmitFn } from 'vue/types/v3-setup-context'
import type { DefaultProps } from 'vue/types/options'

/**
* Create model proxy to new v9 model (modelValue + update:modelValue) with a fallback to old model
* @param {string} oldModelName - Name of model prop in nextcloud-vue v8
* @param {string} oldModelEvent - Event name of model event in nextcloud-vue v8
* @param {boolean} required - If the prop is required
* @return {import('vue').WritableComputedRef} - model proxy
* @param props - Original props from setup()
* @param emit - Original emit from setup()
* @param oldModelName - Name of model prop in nextcloud-vue v8
* @param oldModelEvent - Event name of model event in nextcloud-vue v8
* @param required - If the prop is required
* @return model proxy
*/
export function useModelMigration(oldModelName, oldModelEvent, required = false) {
const vm = getCurrentInstance()!.proxy

if (required && vm.$props[oldModelName] === undefined && vm.$props.modelValue === undefined) {
export function useModelMigration(props: DefaultProps, emit: EmitFn, oldModelName: string, oldModelEvent: string, required: boolean = false): WritableComputedRef<any> {
if (required && props[oldModelName] === undefined && props.modelValue === undefined) {
Vue.util.warn(`Missing required prop: "modelValue" or old "${oldModelName}"`)
}

const model = computed({
get() {
if (vm.$props[oldModelName] !== undefined) {
return vm.$props[oldModelName]
if (props[oldModelName] !== undefined) {
return props[oldModelName]
}
return vm.$props.modelValue
return props.modelValue
},

set(value) {
// New nextcloud-vue v9 event
vm.$emit('update:modelValue', value)
emit('update:modelValue', value)
// Vue 2 fallback for kebab-case event names in templates (recommended by Vue 3 style guide)
vm.$emit('update:model-value', value)
emit('update:model-value', value)
// Old nextcloud-vue v8 event
vm.$emit(oldModelEvent, value)
emit(oldModelEvent, value)
},
})

Expand Down