Skip to content

Commit

Permalink
feat: allow hiding create prompt + fix multiple selection with objects
Browse files Browse the repository at this point in the history
close #111
close #110
  • Loading branch information
stafyniaksacha committed Feb 25, 2024
1 parent becb63f commit 21cadd8
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 42 deletions.
83 changes: 70 additions & 13 deletions .playground/pages/tests/form/autocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ const persons = ref<Person[]>([
},
])
const personValue = ref<Person>()
const personSelection = ref<Person[]>([persons.value[1]])
const personSelectionProp = ref<number[]>([2])
const hobbyValue = ref<Hobby>()
const hobbyValue = ref<Hobby | null>(null)
const hobbies = ref<Hobby[]>([
{
id: 1,
Expand Down Expand Up @@ -114,6 +116,7 @@ const fields = reactive({
tenth: '',
eleventh: '',
twelfth: '',
thirteenth: '',
})
const value = ref<string[]>(['Nuxt', 'Vue.js'])
Expand All @@ -126,14 +129,6 @@ const frameworks = ref([
'Angular',
'Alpine.js',
])
const people = ref([
'Clarissa Perez',
'Aaron Splatter',
'Mike Miller',
'Benedict Kessler',
'Maya Rosselini',
])
</script>

<template>
Expand Down Expand Up @@ -517,7 +512,7 @@ const people = ref([
</NuiPreview>

<NuiPreview
title="Multiple"
title="Multiple: Scalar"
description="Autocomplete component multiple selection"
>
<div class="max-w-sm">
Expand All @@ -533,6 +528,49 @@ const people = ref([
</div>
</NuiPreview>

<NuiPreview
title="Multiple: Objects"
description="Autocomplete component multiple object selection"
>
<div class="max-w-sm">
<BaseAutocomplete
v-model="personSelection"
:items="persons"
:display-value="(item: Person) => item?.name"
:filter-items="filterItems"
rounded="md"
icon="lucide:list-filter"
placeholder="Search..."
label="Assignee"
multiple
/>
</div>
</NuiPreview>

<NuiPreview
title="Multiple: Objects /w prop modifier"
description="Autocomplete component multiple object selection"
>
<div class="max-w-sm">
<BaseAutocomplete
v-model.prop="personSelectionProp"
:items="persons"
:filter-items="filterItems"
rounded="md"
icon="lucide:list-filter"
placeholder="Search..."
label="Assignee"
multiple
:properties="{
value: 'id',
label: 'name',
sublabel: 'text',
media: 'media',
}"
/>
</div>
</NuiPreview>

<NuiPreview
title="Label: float"
description="Autocomplete component label float"
Expand Down Expand Up @@ -671,13 +709,14 @@ const people = ref([
<BaseAutocomplete
v-model="hobbyValue"
:items="hobbies"
:display-value="(item: Hobby) => item.name"
:display-value="(item: Hobby) => item?.name"
:filter-items="filterItems"
icon="ph:buildings"
rounded="md"
placeholder="Select a hobby"
label="Company"
clearable
:clear-value="null"
:properties="{
value: 'id',
label: 'name',
Expand All @@ -694,9 +733,9 @@ const people = ref([
>
<div class="max-w-sm">
<BaseAutocomplete
v-model="value"
v-model="personValue"
:items="persons"
:display-value="(item: Person) => item.name"
:display-value="(item: Person) => item?.name"
:filter-items="filterItems"
icon="ph:users-three"
rounded="md"
Expand All @@ -712,6 +751,24 @@ const people = ref([
/>
</div>
</NuiPreview>

<NuiPreview title="Allow create" description="Allow to create new items">
<div class="grid gap-6 md:max-w-3xl md:grid-cols-3">
<BaseAutocomplete
v-model="fields.thirteenth"
:items="frameworks"
label="With prompt (default)"
allow-create
/>
<BaseAutocomplete
v-model="fields.thirteenth"
:items="frameworks"
label="Hidden prompt"
allow-create
hide-create-prompt
/>
</div>
</NuiPreview>
</NuiPreviewContainer>
</div>
</template>
63 changes: 61 additions & 2 deletions .playground/pages/tests/form/listbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const people = [
// the v-model should be an array
const multipleValues = ref([])
const multipleProps = ref([])
</script>

<template>
Expand Down Expand Up @@ -688,8 +689,8 @@ const multipleValues = ref([])
</NuiPreview>

<NuiPreview
title="Multiple"
description="Listbox component multiple selection"
title="Multiple: Objects"
description="Listbox component multiple selection with object values"
>
<div class="flex flex-wrap items-end gap-3 max-w-3xl">
<div class="flex-1">
Expand Down Expand Up @@ -744,6 +745,64 @@ const multipleValues = ref([])
</div>
</div>
</NuiPreview>

<NuiPreview
title="Multiple: Objects /w prop modifier"
description="Listbox component multiple selection"
>
<div class="flex flex-wrap items-end gap-3 max-w-3xl">
<div class="flex-1">
<BaseListbox
v-model.prop="multipleProps"
size="sm"
rounded="md"
label="Hobbies"
:items="people"
:properties="{
value: 'id',
label: 'name',
sublabel: 'text',
media: 'media',
}"
multiple
/>
</div>

<div class="flex-1">
<BaseListbox
v-model.prop="multipleProps"
size="md"
rounded="md"
label="Hobbies"
:items="people"
:properties="{
value: 'id',
label: 'name',
sublabel: 'text',
media: 'media',
}"
multiple
/>
</div>

<div class="flex-1">
<BaseListbox
v-model.prop="multipleProps"
size="lg"
rounded="md"
label="Hobbies"
:items="people"
:properties="{
value: 'id',
label: 'name',
sublabel: 'text',
media: 'media',
}"
multiple
/>
</div>
</div>
</NuiPreview>
</NuiPreviewContainer>
</div>
</template>
2 changes: 1 addition & 1 deletion .playground/pages/tests/tests/input-models.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ autocomplete1: {{ autocomplete1 }}({{ typeof autocomplete1 }})</pre
<div class="col-span-2">
<BaseAutocomplete
v-model="autocomplete2"
:display-value="(item) => item.name"
:display-value="(item) => item?.name"
clearable
:items="[
{
Expand Down
30 changes: 23 additions & 7 deletions components/form/BaseAutocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,17 @@ const props = withDefaults(
*/
error?: string | string[]
}
/**
* Allow custom entries by the user
*/
allowCreate?: boolean
/**
* Hide the create custom prompt (just set the model to the value entered)
*/
hideCreatePrompt?: boolean
/**
* Whether the component is in a loading state.
*/
Expand Down Expand Up @@ -251,6 +257,7 @@ const props = withDefaults(
filterItems: undefined,
classes: () => ({}),
allowCreate: false,
hideCreatePrompt: false,
fixed: false,
placement: 'bottom-start',
properties: undefined,
Expand Down Expand Up @@ -321,7 +328,7 @@ defineSlots<{
const [modelValue, modelModifiers] = defineModel<T | T[], 'prop'>({
set(value) {
if (modelModifiers.prop && props.properties?.value) {
if (!props.multiple && modelModifiers.prop && props.properties?.value) {
const attr = props.properties.value
return items.value.find(
Expand Down Expand Up @@ -491,7 +498,7 @@ watch(
)
function clear() {
modelValue.value = props.clearValue ?? []
modelValue.value = props.clearValue ?? (props.multiple ? [] : null)
}
const iconResolved = computed(() => {
Expand Down Expand Up @@ -707,7 +714,7 @@ const internal = ref<any>(modelValue)
as="div"
:class="{
'nui-autocomplete-results':
filteredItems.length > 0 || !allowCreate,
filteredItems.length > 0 || !hideCreatePrompt,
}"
>
<!-- Placeholder -->
Expand Down Expand Up @@ -756,6 +763,9 @@ const internal = ref<any>(modelValue)
v-if="allowCreate && queryCreate"
:value="queryCreate"
v-slot="{ active, selected }"
:class="
hideCreatePrompt ? 'hidden' : 'nui-autocomplete-results-item'
"
as="div"
>
<slot
Expand All @@ -769,9 +779,15 @@ const internal = ref<any>(modelValue)
selected,
}"
>
<span class="nui-autocomplete-results-item">
Create {{ query }}
</span>
<BaseAutocompleteItem
:rounded="rounded"
:item="{
label: `Create '${query}'`,
value: query,
}"
:active="active"
:selected="selected"
/>
</slot>
</ComboboxOption>
<ComboboxOption
Expand Down Expand Up @@ -799,7 +815,7 @@ const internal = ref<any>(modelValue)
}"
>
<BaseAutocompleteItem
:rounded="props.rounded ? props.rounded : rounded"
:rounded="rounded"
:item="
properties
? item
Expand Down
Loading

0 comments on commit 21cadd8

Please sign in to comment.