Skip to content

Commit

Permalink
feat(Experimental/Select): extract select search into SFC `SelectSear…
Browse files Browse the repository at this point in the history
…chInput`
  • Loading branch information
gravitano committed Aug 3, 2023
1 parent 8f02650 commit cc06c98
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 20 deletions.
14 changes: 14 additions & 0 deletions packages/select/src/Select.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export default {
control: 'select',
options: themeColors,
},
searchPlacement: {
control: 'select',
options: ['inside', 'outside'],
},
},
args: {
items,
Expand Down Expand Up @@ -120,6 +124,16 @@ SearchableOutsidePlacement.args = {
chips: true,
};

export const SearchableInputIcons = Template.bind({});
SearchableInputIcons.args = {
searchable: true,
placeholder: 'Choose',
label: 'Searchable With Icons',
chips: true,
searchPrefixIcon: 'ic:round-search',
searchSuffixIcon: 'heroicons:plus',
};

export const Empty = Template.bind({});
Empty.args = {
items: [],
Expand Down
51 changes: 33 additions & 18 deletions packages/select/src/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
ListboxOption,
ListboxLabel,
Combobox,
ComboboxInput,
ComboboxOptions,
ComboboxOption,
ComboboxButton,
Expand All @@ -18,7 +17,7 @@ import {computed, ref, watch} from 'vue';
import VBadge from '@morpheme/badge';
import {Float} from '@headlessui-float/vue';
import type {Placement} from '@floating-ui/vue';
import VDivider from '@morpheme/divider';
import SelectSearchInput from './SelectSearchInput.vue';
type T = Record<string, any>;
type ModelValue = T | T[] | undefined;
Expand Down Expand Up @@ -68,6 +67,12 @@ const props = withDefaults(
icon?: string;
checkIcon?: string;
clearIcon?: string;
searchPrefixIcon?: string;
searchPrefixIconSize?: string;
searchPrefixIconClass?: string;
searchSuffixIcon?: string;
searchSuffixIconSize?: string;
searchSuffixIconClass?: string;
}>(),
{
itemText: 'text',
Expand All @@ -88,6 +93,8 @@ const props = withDefaults(
icon: 'heroicons:chevron-down',
checkIcon: 'heroicons:check',
clearIcon: 'heroicons:x-mark',
searchPrefixIconSize: 'sm',
searchSuffixIconSize: 'sm',
},
);
Expand Down Expand Up @@ -286,12 +293,18 @@ defineSlots<{
</div>
</slot>

<ComboboxInput
<SelectSearchInput
v-if="searchable && searchPlacement === 'inside'"
class="v-select-input"
:display-value="displayValue ?? defaultDisplayValue"
:placement="searchPlacement"
:placeholder="searchPlaceholder || placeholder"
:disabled="disabled"
:display-value="displayValue ?? defaultDisplayValue"
:prefix-icon="searchPrefixIcon"
:prefix-icon-size="searchPrefixIconSize"
:prefix-icon-class="searchPrefixIconClass"
:suffix-icon="searchSuffixIcon"
:suffix-icon-size="searchSuffixIconSize"
:suffix-icon-class="searchSuffixIconClass"
@change="query = $event.target.value"
@keydown.enter="query = ''"
/>
Expand Down Expand Up @@ -358,20 +371,22 @@ defineSlots<{
:is="searchable ? ComboboxOptions : ListboxOptions"
class="v-select-options"
>
<div
<SelectSearchInput
v-if="searchable && searchPlacement === 'outside'"
class="v-select-input-outside-wrapper"
>
<ComboboxInput
class="v-select-input"
:display-value="displayValue ?? defaultDisplayValue"
:placeholder="searchPlaceholder || placeholder"
:disabled="disabled"
@change="query = $event.target.value"
@keydown.enter="query = ''"
/>
<VDivider />
</div>
:placement="searchPlacement"
:placeholder="searchPlaceholder || placeholder"
:disabled="disabled"
:display-value="displayValue ?? defaultDisplayValue"
:prefix-icon="searchPrefixIcon"
:prefix-icon-size="searchPrefixIconSize"
:prefix-icon-class="searchPrefixIconClass"
:suffix-icon="searchSuffixIcon"
:suffix-icon-size="searchSuffixIconSize"
:suffix-icon-class="searchSuffixIconClass"
@change="query = $event.target.value"
@keydown.enter="query = ''"
/>

<slot
name="empty"
v-bind="{
Expand Down
66 changes: 66 additions & 0 deletions packages/select/src/SelectSearchInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup lang="ts">
import {VDivider} from '@morpheme/divider';
import {ComboboxInput} from '@headlessui/vue';
import VIcon from '@morpheme/icon';
interface Props {
placement?: 'inside' | 'outside';
placeholder?: string;
disabled?: boolean;
displayValue?: (item: Record<string, any>) => string;
prefixIcon?: string;
prefixIconSize?: string;
prefixIconClass?: string;
suffixIcon?: string;
suffixIconSize?: string;
suffixIconClass?: string;
}
withDefaults(defineProps<Props>(), {
placement: 'inside',
prefixIconSize: 'sm',
suffixIconSize: 'sm',
});
defineOptions({
inheritAttrs: false,
});
</script>

<template>
<div
:class="[
'v-input v-input--borderless v-input--no-ring v-select-input',
{'v-select-input-outside-wrapper': placement === 'outside'},
]"
>
<div class="v-input-wrapper">
<div class="v-input-prepend">
<VIcon
v-if="prefixIcon"
:name="prefixIcon"
:size="prefixIconSize"
:class="prefixIconClass"
/>
</div>

<ComboboxInput
class="v-select-input v-input-control"
:display-value="displayValue"
:placeholder="placeholder"
:disabled="disabled"
v-bind="$attrs"
/>

<div class="v-input-append">
<VIcon
v-if="suffixIcon"
:name="suffixIcon"
:size="suffixIconSize"
:class="suffixIconClass"
/>
</div>
</div>
</div>
<VDivider v-if="placement === 'outside'" />
</template>
1 change: 1 addition & 0 deletions packages/select/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export {default} from './VSelect.vue';
export {default as VSelect} from './VSelect.vue';
export {default as Select} from './Select.vue';
export {default as SelectField} from './SelectField.vue';
export {default as SelectSearchInput} from './SelectSearchInput.vue';
// alias
export {default as SelectInput} from './SelectField.vue';
6 changes: 5 additions & 1 deletion packages/themes/src/morpheme/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

// shadow
--v-input-shadow: var(--effect-shadow-xs);
--v-input-wrapper-shadow-color: rgba(16, 24, 40, 0.05);

// autofill
--v-autofill-color: var(--color-gray-700);
Expand Down Expand Up @@ -87,6 +88,9 @@ select:-webkit-autofill:focus {

&--borderless {
--v-input-border-color: transparent;
--v-input-effect-border-color: transparent;
--v-input-effect-shadow-color: transparent;
--v-input-wrapper-shadow-color: transparent;
}

&--no-ring {
Expand Down Expand Up @@ -245,7 +249,7 @@ select:-webkit-autofill:focus {
&-wrapper {
&:focus-within {
border: 1px solid var(--v-input-effect-border-color);
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05),
box-shadow: 0px 1px 2px var(--v-input-wrapper-shadow-color),
0px 0px 0px 4px var(--v-input-effect-shadow-color);
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/themes/src/morpheme/_select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -431,14 +431,16 @@
flex-grow: 1;
border: none;
border-radius: var(--v-select-border-radius);
max-width: calc(100% - 20px);
max-width: calc(100% - 12px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: auto !important;

&:focus {
outline: none;
box-shadow: none;
border: none;
}

&-outside-wrapper {
Expand Down

0 comments on commit cc06c98

Please sign in to comment.