From 4e8e42091b39e025c6a407b73724b32dad5d10ea Mon Sep 17 00:00:00 2001 From: romanhrynevych Date: Fri, 30 Aug 2024 18:35:50 +0300 Subject: [PATCH 1/5] feat(combobox): add `clearSearchTermOnSelect` param to `ComboboxRoot` --- packages/radix-vue/src/Combobox/ComboboxRoot.vue | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/radix-vue/src/Combobox/ComboboxRoot.vue b/packages/radix-vue/src/Combobox/ComboboxRoot.vue index 237aaea29..9a959ef16 100644 --- a/packages/radix-vue/src/Combobox/ComboboxRoot.vue +++ b/packages/radix-vue/src/Combobox/ComboboxRoot.vue @@ -75,6 +75,11 @@ export interface ComboboxRootProps extends PrimitiveProps { * @defaultValue `true` */ resetSearchTermOnBlur?: boolean + /** + * Whether to clear the searchTerm when the Combobox value is selected + * @defaultValue `true` + */ + clearSearchTermOnSelect?: boolean } @@ -89,6 +94,7 @@ import isEqual from 'fast-deep-equal' const props = withDefaults(defineProps>(), { open: undefined, resetSearchTermOnBlur: true, + clearSearchTermOnSelect: true, }) const emit = defineEmits>() @@ -212,6 +218,9 @@ const stringifiedModelValue = computed(() => JSON.stringify(modelValue.value)) // nextTick() are required in the following watchers as we are waiting for DOM element to be mounted first the only apply following logic watch(stringifiedModelValue, async () => { + if (!props.clearSearchTermOnSelect) + return + await nextTick() await nextTick() resetSearchTerm() From 06f9395471af4f4647a4c50b45a81ee00b57b99e Mon Sep 17 00:00:00 2001 From: romanhrynevych Date: Fri, 30 Aug 2024 18:40:46 +0300 Subject: [PATCH 2/5] docs(combobox): add `clearSearchTermOnSelect` parameter in `ComboboxRoot` markdown --- docs/content/meta/ComboboxRoot.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/content/meta/ComboboxRoot.md b/docs/content/meta/ComboboxRoot.md index bdf6bb490..fc21ca724 100644 --- a/docs/content/meta/ComboboxRoot.md +++ b/docs/content/meta/ComboboxRoot.md @@ -81,6 +81,13 @@ 'required': false, 'default': 'true' }, + { + 'name': 'clearSearchTermOnSelect', + 'description': '

Whether to clear the searchTerm when the Combobox value is selected

\n', + 'type': 'boolean', + 'required': false, + 'default': 'true' + }, { 'name': 'searchTerm', 'description': '

The controlled search term of the Combobox. Can be binded-with with v-model:searchTerm.

\n', From b15966caaa34bef3bb2f3fd9d41cb5a902331ca3 Mon Sep 17 00:00:00 2001 From: romanhrynevych Date: Fri, 30 Aug 2024 18:44:30 +0300 Subject: [PATCH 3/5] chore(lint): run lint:fix --- packages/plugins/src/namespaced/generate.ts | 6 +++--- packages/radix-vue/src/Menu/MenuRoot.vue | 2 -- packages/radix-vue/src/Splitter/SplitterGroup.vue | 6 +++--- packages/radix-vue/src/shared/createContext.ts | 4 ++-- packages/radix-vue/src/shared/useSingleOrMultipleValue.ts | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/plugins/src/namespaced/generate.ts b/packages/plugins/src/namespaced/generate.ts index b5467f09a..4599682df 100644 --- a/packages/plugins/src/namespaced/generate.ts +++ b/packages/plugins/src/namespaced/generate.ts @@ -21,10 +21,10 @@ const namespaced = filteredComponent.map((curr: keyof typeof components) => { } else { return `export const ${key} = {\n${ - Object.keys(tmp).map((k) => { return ` ${k}: ${tmp[k]},\n` }).join('') + Object.keys(tmp).map((k) => { return ` ${k}: ${tmp[k]},\n` }).join('') }} as {\n${Object.keys(tmp).map((k) => { - return ` ${k}: typeof ${tmp[k]}\n` - }).join('')}}` + return ` ${k}: typeof ${tmp[k]}\n` + }).join('')}}` } }) diff --git a/packages/radix-vue/src/Menu/MenuRoot.vue b/packages/radix-vue/src/Menu/MenuRoot.vue index 7feea2aa8..c08427968 100644 --- a/packages/radix-vue/src/Menu/MenuRoot.vue +++ b/packages/radix-vue/src/Menu/MenuRoot.vue @@ -50,9 +50,7 @@ export const [injectMenuRootContext, provideMenuRootContext] import { ref, toRefs, - watchEffect, } from 'vue' -import { isClient } from '@vueuse/shared' import { useVModel } from '@vueuse/core' import { PopperRoot } from '@/Popper' diff --git a/packages/radix-vue/src/Splitter/SplitterGroup.vue b/packages/radix-vue/src/Splitter/SplitterGroup.vue index 34c46086a..92be7094a 100644 --- a/packages/radix-vue/src/Splitter/SplitterGroup.vue +++ b/packages/radix-vue/src/Splitter/SplitterGroup.vue @@ -522,7 +522,7 @@ function collapsePanel(panelData: PanelData) { assert( panelSize != null, - `Panel size not found for panel "${panelData.id}"`, + `Panel size not found for panel "${panelData.id}"`, ) if (panelSize !== collapsedSize) { @@ -625,7 +625,7 @@ function getPanelSize(panelData: PanelData) { assert( panelSize != null, - `Panel size not found for panel "${panelData.id}"`, + `Panel size not found for panel "${panelData.id}"`, ) return panelSize @@ -654,7 +654,7 @@ function isPanelExpanded(panelData: PanelData) { assert( panelSize != null, - `Panel size not found for panel "${panelData.id}"`, + `Panel size not found for panel "${panelData.id}"`, ) return !collapsible || panelSize > collapsedSize diff --git a/packages/radix-vue/src/shared/createContext.ts b/packages/radix-vue/src/shared/createContext.ts index 18977efe4..cf69d29a5 100644 --- a/packages/radix-vue/src/shared/createContext.ts +++ b/packages/radix-vue/src/shared/createContext.ts @@ -40,8 +40,8 @@ export function createContext( `Injection \`${injectionKey.toString()}\` not found. Component must be used within ${ Array.isArray(providerComponentName) ? `one of the following components: ${providerComponentName.join( - ', ', - )}` + ', ', + )}` : `\`${providerComponentName}\`` }`, ) diff --git a/packages/radix-vue/src/shared/useSingleOrMultipleValue.ts b/packages/radix-vue/src/shared/useSingleOrMultipleValue.ts index 9283d3252..b77e1fcba 100644 --- a/packages/radix-vue/src/shared/useSingleOrMultipleValue.ts +++ b/packages/radix-vue/src/shared/useSingleOrMultipleValue.ts @@ -21,7 +21,7 @@ function validateProps({ type, defaultValue, modelValue }: SingleOrMultipleProps if (modelValue !== undefined && defaultValue !== undefined && typeof modelValue !== typeof defaultValue) { throw new Error( - `Invalid prop \`value\` of value \`${modelValue}\` supplied, should be the same type as the \`defaultValue\` prop, which is \`${defaultValue}\`. The \`value\` prop must be: + `Invalid prop \`value\` of value \`${modelValue}\` supplied, should be the same type as the \`defaultValue\` prop, which is \`${defaultValue}\`. The \`value\` prop must be: ${type === 'single' ? '- a string' : type === 'multiple' ? '- an array of strings' : '- a string\n- an array of strings'} - \`undefined\``, ) From c2733af888f4686bc8ec87829b4e26cc3637d4d8 Mon Sep 17 00:00:00 2001 From: romanhrynevych Date: Sat, 31 Aug 2024 10:31:43 +0300 Subject: [PATCH 4/5] fix(combobox): rename `clear` to `reset` on select --- docs/content/meta/ComboboxRoot.md | 4 ++-- packages/radix-vue/src/Combobox/ComboboxRoot.vue | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/content/meta/ComboboxRoot.md b/docs/content/meta/ComboboxRoot.md index fc21ca724..44d343170 100644 --- a/docs/content/meta/ComboboxRoot.md +++ b/docs/content/meta/ComboboxRoot.md @@ -82,8 +82,8 @@ 'default': 'true' }, { - 'name': 'clearSearchTermOnSelect', - 'description': '

Whether to clear the searchTerm when the Combobox value is selected

\n', + 'name': 'resetSearchTermOnSelect', + 'description': '

Whether to reset the searchTerm when the Combobox value is selected

\n', 'type': 'boolean', 'required': false, 'default': 'true' diff --git a/packages/radix-vue/src/Combobox/ComboboxRoot.vue b/packages/radix-vue/src/Combobox/ComboboxRoot.vue index 9a959ef16..f74ff109d 100644 --- a/packages/radix-vue/src/Combobox/ComboboxRoot.vue +++ b/packages/radix-vue/src/Combobox/ComboboxRoot.vue @@ -76,10 +76,10 @@ export interface ComboboxRootProps extends PrimitiveProps { */ resetSearchTermOnBlur?: boolean /** - * Whether to clear the searchTerm when the Combobox value is selected + * Whether to reset the searchTerm when the Combobox value is selected * @defaultValue `true` */ - clearSearchTermOnSelect?: boolean + resetSearchTermOnSelect?: boolean } @@ -94,7 +94,7 @@ import isEqual from 'fast-deep-equal' const props = withDefaults(defineProps>(), { open: undefined, resetSearchTermOnBlur: true, - clearSearchTermOnSelect: true, + resetSearchTermOnSelect: true, }) const emit = defineEmits>() @@ -218,7 +218,7 @@ const stringifiedModelValue = computed(() => JSON.stringify(modelValue.value)) // nextTick() are required in the following watchers as we are waiting for DOM element to be mounted first the only apply following logic watch(stringifiedModelValue, async () => { - if (!props.clearSearchTermOnSelect) + if (!props.resetSearchTermOnSelect) return await nextTick() From e8b4606eb03a1a2487e9f77a362b6bbd7bf45a11 Mon Sep 17 00:00:00 2001 From: romanhrynevych Date: Tue, 3 Sep 2024 21:02:02 +0300 Subject: [PATCH 5/5] fix(combobox): update resetSearchTerm to accept mode parameter for enhanced behavior --- packages/radix-vue/src/Combobox/ComboboxRoot.vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/radix-vue/src/Combobox/ComboboxRoot.vue b/packages/radix-vue/src/Combobox/ComboboxRoot.vue index f74ff109d..62ec2407f 100644 --- a/packages/radix-vue/src/Combobox/ComboboxRoot.vue +++ b/packages/radix-vue/src/Combobox/ComboboxRoot.vue @@ -149,7 +149,7 @@ async function onOpenChange(val: boolean) { else { isUserInputted.value = false if (props.resetSearchTermOnBlur) - resetSearchTerm() + resetSearchTerm('blur') } } @@ -195,16 +195,19 @@ const filteredOptions = computed(() => { return options.value }) -function resetSearchTerm() { +function resetSearchTerm(mode?: 'blur' | 'select') { + // clear when blur or when select and resetSearchTermOnSelect is true + const condition = mode === 'blur' || (mode === 'select' && props.resetSearchTermOnSelect) + if (!multiple.value && modelValue.value && !Array.isArray(modelValue.value)) { if (props.displayValue) searchTerm.value = props.displayValue(modelValue.value) else if (typeof modelValue.value !== 'object') searchTerm.value = modelValue.value.toString() - else + else if (condition) searchTerm.value = '' } - else { + else if (condition) { searchTerm.value = '' } } @@ -218,12 +221,9 @@ const stringifiedModelValue = computed(() => JSON.stringify(modelValue.value)) // nextTick() are required in the following watchers as we are waiting for DOM element to be mounted first the only apply following logic watch(stringifiedModelValue, async () => { - if (!props.resetSearchTermOnSelect) - return - await nextTick() await nextTick() - resetSearchTerm() + resetSearchTerm('select') }, { // If searchTerm is provided with value during initialization, we don't reset it immediately immediate: !props.searchTerm,