Skip to content

Commit

Permalink
MINOR: Feature/search in select (#315)
Browse files Browse the repository at this point in the history
* add search bar into BIMDataSelect component

* add documentation for search bar into BIMDataSelect

* delete unused component

* delete template tag into BIMDataSelect file

* fix search bar width

* compute this.searchText.toLowerCase()

* add reset search methods

* add reset search documentation

* refactoring
  • Loading branch information
LrxGaelle authored Oct 10, 2023
1 parent 856faf0 commit a6974ad
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 107 deletions.
26 changes: 13 additions & 13 deletions src/BIMDataComponents/BIMDataSelect/BIMDataSelect.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
<template>
<component
:is="selectorComponent"
v-bind="$props"
:modelValue="modelValue"
@update:modelValue="$emit('update:modelValue', $event)"
/>
</template>

<script>
import { h } from "vue";
// Components
import BIMDataSelectMulti from "./BIMDataSelectMulti.vue";
import BIMDataSelectSingle from "./BIMDataSelectSingle.vue";
Expand Down Expand Up @@ -60,10 +52,18 @@ export default {
},
},
emits: ["update:modelValue"],
computed: {
selectorComponent() {
return this.multi ? "BIMDataSelectMulti" : "BIMDataSelectSingle";
},
setup(props, { emit, slots }) {
return () =>
h(
props.multi ? BIMDataSelectMulti : BIMDataSelectSingle,
{
...props,
"onUpdate:modelValue": event => emit("update:modelValue", event),
},
{
empty: () => slots.empty?.(),
},
);
},
};
</script>
94 changes: 70 additions & 24 deletions src/BIMDataComponents/BIMDataSelect/BIMDataSelectMulti.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
'not-empty': modelValue.length > 0,
}"
:style="{ width }"
v-clickaway="() => (isOpen = false)"
v-clickaway="away"
>
<div class="bimdata-select__content">
<div class="bimdata-select__content__value" @click="toggle">
Expand All @@ -21,29 +21,43 @@
</div>

<transition name="slide-fade-down">
<ul v-show="!disabled && isOpen" class="bimdata-select__option-list">
<li
class="bimdata-select__option-list__entry"
v-for="(option, index) of options"
:key="index"
:class="{
selected: isSelected(option),
disabled: isDisabled(option),
'option-group': isOptionGroup(option),
}"
@click="onOptionClick(option)"
>
<template v-if="isOptionGroup(option)">
{{ optionLabel(option) }}
</template>
<BIMDataCheckbox
v-else
:modelValue="isSelected(option)"
:disabled="isDisabled(option)"
:text="optionLabel(option)"
></BIMDataCheckbox>
</li>
</ul>
<div v-show="!disabled && isOpen" class="bimdata-select__option-list">
<BIMDataSearch
v-if="search"
width="calc(100% - 12px)"
color="primary"
radius
:placeholder="searchPlaceholder"
v-model="searchText"
class="m-6"
/>
<div v-if="filteredOptions.length === 0" class="p-x-6 p-b-6">
<slot name="empty"></slot>
</div>
<ul class="bimdata-list m-b-6">
<li
class="bimdata-select__option-list__entry"
v-for="(option, index) of filteredOptions"
:key="index"
:class="{
selected: isSelected(option),
disabled: isDisabled(option),
'option-group': isOptionGroup(option),
}"
@click="onOptionClick(option)"
>
<template v-if="isOptionGroup(option)">
{{ optionLabel(option) }}
</template>
<BIMDataCheckbox
v-else
:modelValue="isSelected(option)"
:disabled="isDisabled(option)"
:text="optionLabel(option)"
></BIMDataCheckbox>
</li>
</ul>
</div>
</transition>
</div>
</template>
Expand Down Expand Up @@ -94,17 +108,40 @@ export default {
type: Boolean,
default: false,
},
search: {
type: Boolean,
default: false,
},
searchPlaceholder: {
type: String,
default: "Search",
},
isResetSearch: {
type: Boolean,
default: false,
},
},
emits: ["update:modelValue"],
data() {
return {
isOpen: false,
searchText: "",
};
},
computed: {
displayedValue() {
return this.modelValue.map(this.optionLabel).join(", ");
},
filteredOptions() {
if (this.searchText === "") {
return this.options;
} else {
const lowerCaseSearchText = this.searchText.toLowerCase();
return this.options.filter(option =>
option.toLowerCase().includes(lowerCaseSearchText),
);
}
},
},
methods: {
toggle() {
Expand Down Expand Up @@ -154,6 +191,15 @@ export default {
}
this.$emit("update:modelValue", options);
},
resetSearch() {
if (this.isResetSearch) {
this.searchText = "";
}
},
away() {
this.isOpen = false;
this.resetSearch();
},
},
};
</script>
Expand Down
94 changes: 71 additions & 23 deletions src/BIMDataComponents/BIMDataSelect/BIMDataSelectSingle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
'not-empty': modelValue !== undefined && modelValue !== null,
}"
:style="{ width }"
v-clickaway="() => (isOpen = false)"
v-clickaway="away"
>
<div class="bimdata-select__content">
<div class="bimdata-select__content__value" @click="toggle">
Expand All @@ -21,28 +21,42 @@
</div>

<transition name="slide-fade-down">
<ul v-show="!disabled && isOpen" class="bimdata-select__option-list">
<li
v-if="nullValue"
class="bimdata-select__option-list__entry"
@click="onNullValueClick()"
>
{{ nullLabel || "None" }}
</li>
<li
class="bimdata-select__option-list__entry"
v-for="(option, index) of options"
:key="index"
:class="{
selected: isSelected(option),
disabled: isDisabled(option),
'option-group': isOptionGroup(option),
}"
@click="onOptionClick(option)"
>
{{ optionLabel(option) }}
</li>
</ul>
<div v-show="!disabled && isOpen" class="bimdata-select__option-list">
<BIMDataSearch
v-if="search"
width="calc(100% - 12px)"
color="primary"
radius
:placeholder="searchPlaceholder"
v-model="searchText"
class="m-6"
/>
<div v-if="filteredOptions.length === 0" class="p-x-6 p-b-6">
<slot name="empty"></slot>
</div>
<ul class="bimdata-list m-y-6">
<li
v-if="nullValue"
class="bimdata-select__option-list__entry"
@click="onNullValueClick()"
>
{{ nullLabel || "None" }}
</li>
<li
class="bimdata-select__option-list__entry"
v-for="(option, index) of filteredOptions"
:key="index"
:class="{
selected: isSelected(option),
disabled: isDisabled(option),
'option-group': isOptionGroup(option),
}"
@click="onOptionClick(option)"
>
{{ optionLabel(option) }}
</li>
</ul>
</div>
</transition>
</div>
</template>
Expand Down Expand Up @@ -95,17 +109,40 @@ export default {
type: Boolean,
default: false,
},
search: {
type: Boolean,
default: false,
},
searchPlaceholder: {
type: String,
default: "Search",
},
isResetSearch: {
type: Boolean,
default: false,
},
},
emits: ["update:modelValue"],
data() {
return {
isOpen: false,
searchText: "",
};
},
computed: {
displayedValue() {
return this.optionLabel(this.modelValue);
},
filteredOptions() {
if (this.searchText === "") {
return this.options;
} else {
const lowerCaseSearchText = this.searchText.toLowerCase();
return this.options.filter(option =>
option.toLowerCase().includes(lowerCaseSearchText),
);
}
},
},
methods: {
toggle() {
Expand Down Expand Up @@ -142,16 +179,27 @@ export default {
isOptionGroup(option) {
return this.optionKey && option && option.optionGroup;
},
resetSearch() {
if (this.isResetSearch) {
this.searchText = "";
}
},
onOptionClick(option) {
if (this.optionKey && (option.disabled || option.optionGroup)) {
return;
}
this.$emit("update:modelValue", option);
this.resetSearch();
this.isOpen = false;
},
onNullValueClick() {
this.$emit("update:modelValue", null);
this.resetSearch();
this.isOpen = false;
},
away() {
this.isOpen = false;
this.resetSearch();
},
},
};
Expand Down
1 change: 0 additions & 1 deletion src/BIMDataComponents/BIMDataSelect/_BIMDataSelect.scss
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
top: -3px;
width: 100%;
max-height: 220px;
padding: calc(var(--spacing-unit) / 2) 0;
overflow: auto;
box-shadow: var(--box-shadow);
background-color: var(--color-white);
Expand Down
Loading

0 comments on commit a6974ad

Please sign in to comment.