Skip to content

Commit

Permalink
feat(Experimental/Select): add new loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
gravitano committed Sep 6, 2023
1 parent c1eec2c commit 9c123a5
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 24 deletions.
11 changes: 11 additions & 0 deletions packages/select/src/Select.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ Error.args = {
errorMessage: 'This is an error message.',
};

export const Loading = Template.bind({});
Loading.args = {
loading: true,
};

export const Shadow: Story<typeof Select> = (args) => ({
components: {
Select,
Expand Down Expand Up @@ -117,6 +122,12 @@ Searchable.args = {
searchable: true,
};

export const SearchableLoading = Template.bind({});
SearchableLoading.args = {
searchable: true,
loading: true,
};

export const SearchableMultiple = Template.bind({});
SearchableMultiple.args = {
searchable: true,
Expand Down
59 changes: 43 additions & 16 deletions packages/select/src/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const props = withDefaults(
searchBy?: string;
selectionItemProps?: InstanceType<typeof VBadge>['$props'];
displayValue?: (item: any) => string;
iconSize?: string;
placement?: Placement;
offset?: number;
shift?: boolean | number;
Expand All @@ -65,8 +64,17 @@ const props = withDefaults(
searchPlaceholder?: string;
chips?: boolean;
icon?: string;
iconSize?: string
iconClass?: string
dropdownIcon?: string;
dropdownIconSize?: string
dropdownIconClass?: string
checkIcon?: string;
checkIconSize?: string
checkIconClass?: string
clearIcon?: string;
clearIconSize?: string
clearIconClass?: string
searchPrefixIcon?: string;
searchPrefixIconSize?: string;
searchPrefixIconClass?: string;
Expand All @@ -78,7 +86,10 @@ const props = withDefaults(
by?: string;
name?: string;
loading?: boolean;
loadingIcon?: string;
loadingText?: string;
tooltip?: InstanceType<typeof VTooltip>['$props'];
selectedText?: string;
}>(),
{
itemText: 'text',
Expand All @@ -88,23 +99,30 @@ const props = withDefaults(
clearText: 'Clear',
emptyText: 'No results.',
items: () => [],
iconSize: 'xs',
placement: 'bottom',
offset: 8,
shift: true,
flip: true,
hideError: false,
searchPlacement: 'inside',
searchPlaceholder: 'Search...',
icon: 'heroicons:chevron-down',
dropdownIcon: 'heroicons:chevron-down',
dropdownIconSize: 'sm',
icon: '',
iconSize: 'sm',
checkIcon: 'heroicons:check',
checkIconSize: 'sm',
clearIcon: 'heroicons:x-mark',
clearIconSize: 'sm',
searchPrefixIconSize: 'sm',
searchSuffixIconSize: 'sm',
selectedIconPlacement: 'left',
tooltip: () => ({
placement: 'top'
})
}),
loadingIcon: 'ri:loader-5-fill',
loadingText: 'Loading...',
selectedText: 'selected'
},
);

Expand Down Expand Up @@ -261,6 +279,7 @@ defineSlots<{
'v-select--error': error,
'v-select--searchable': searchable,
'v-select--disabled': disabled,
'v-select--loading': loading,
},
shadowClass,
`v-select--${placement}`,
Expand Down Expand Up @@ -344,12 +363,13 @@ defineSlots<{
<SelectSearchInput
v-if="searchable && searchPlacement === 'inside'"
:placement="searchPlacement"
:placeholder="searchPlaceholder || placeholder"
:disabled="disabled"
:placeholder="loading ? loadingText : searchPlaceholder || placeholder"
:disabled="disabled || loading"
:loading="loading"
:display-value="displayValue ?? defaultDisplayValue"
:prefix-icon="searchPrefixIcon"
:prefix-icon-size="searchPrefixIconSize"
:prefix-icon-class="searchPrefixIconClass"
:prefix-icon="loading ? loadingIcon : icon || searchPrefixIcon"
:prefix-icon-size="iconSize || searchPrefixIconSize"
:prefix-icon-class="iconClass || searchPrefixIconClass"
:suffix-icon="searchSuffixIcon"
:suffix-icon-size="searchSuffixIconSize"
:suffix-icon-class="searchSuffixIconClass"
Expand Down Expand Up @@ -380,17 +400,23 @@ defineSlots<{
},
]"
>
<VIcon
v-if="icon || loading"
:name="loading ? loadingIcon : icon"
:size="iconSize"
:class="['v-select__prepend-icon', iconClass]"
/>
<span v-if="multiple">
{{
modelValue && modelValue?.length > 0
? chips && searchPlacement === 'outside'
? ''
: `${modelValue?.length} selected`
: `${modelValue?.length} ${selectedText}`
: placeholder
}}
</span>
<span v-else>
{{ modelValue ? (modelValue as T)[itemText] : placeholder }}
{{ modelValue ? (modelValue as T)[itemText] : loading ? loadingText : placeholder }}
</span>
</div>
</slot>
Expand Down Expand Up @@ -424,12 +450,13 @@ defineSlots<{
<SelectSearchInput
v-if="searchable && searchPlacement === 'outside'"
:placement="searchPlacement"
:placeholder="searchPlaceholder || placeholder"
:disabled="disabled"
:placeholder="loading ? loadingText : searchPlaceholder || placeholder"
:disabled="disabled || loading"
:loading="loading"
:display-value="displayValue ?? defaultDisplayValue"
:prefix-icon="searchPrefixIcon"
:prefix-icon-size="searchPrefixIconSize"
:prefix-icon-class="searchPrefixIconClass"
:prefix-icon="loading ? loadingIcon : icon || searchPrefixIcon"
:prefix-icon-size="iconSize || searchPrefixIconSize"
:prefix-icon-class="iconClass || searchPrefixIconClass"
:suffix-icon="searchSuffixIcon"
:suffix-icon-size="searchSuffixIconSize"
:suffix-icon-class="searchSuffixIconClass"
Expand Down
22 changes: 15 additions & 7 deletions packages/select/src/SelectSearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {VDivider} from '@morpheme/divider';
import {ComboboxInput} from '@headlessui/vue';
import VIcon from '@morpheme/icon';
import { ComponentPublicInstance, ref } from 'vue';
import {ComponentPublicInstance, ref} from 'vue';
interface Props {
placement?: 'inside' | 'outside';
Expand All @@ -15,6 +15,7 @@ interface Props {
suffixIcon?: string;
suffixIconSize?: string;
suffixIconClass?: string;
loading?: boolean;
}
withDefaults(defineProps<Props>(), {
Expand All @@ -27,18 +28,18 @@ defineOptions({
inheritAttrs: false,
});
const searchInput = ref<ComponentPublicInstance<HTMLInputElement>>()
const searchInput = ref<ComponentPublicInstance<HTMLInputElement>>();
function clear() {
if (!searchInput.value) return
if (!searchInput.value) return;
searchInput.value.$el.value = ''
searchInput.value.$el.value = '';
}
function focus() {
if (!searchInput.value) return
if (!searchInput.value) return;
searchInput.value.$el.focus()
searchInput.value.$el.focus();
}
export interface ExposedProps {
Expand All @@ -58,7 +59,12 @@ defineExpose({
<div
:class="[
'v-input v-input--borderless v-input--no-ring v-select-input',
{'v-select-input-outside-wrapper': placement === 'outside'},
{
'v-select-input-outside-wrapper': placement === 'outside',
'v-input--disabled': disabled,
'v-input--loading': loading,
'v-select-input--disabled': disabled,
},
]"
>
<div class="v-input-wrapper">
Expand Down Expand Up @@ -92,3 +98,5 @@ defineExpose({
</div>
<VDivider v-if="placement === 'outside'" />
</template>


10 changes: 9 additions & 1 deletion packages/themes/src/morpheme/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,20 @@ select:-webkit-autofill:focus {
}

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

&--loading {
.v-input-prepend {
.v-icon {
animation: spin 1s linear infinite;
}
}
}

&--no-ring {
--v-input-effect-shadow-color: transparent;
}
Expand Down
13 changes: 13 additions & 0 deletions packages/themes/src/morpheme/_select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@
}
}

&--loading {
.v-select__prepend-icon {
animation: spin 1s linear infinite;
}
}

&-button {
border: 1px solid var(--v-select-border-color);
border-radius: var(--v-select-border-radius);
Expand Down Expand Up @@ -177,6 +183,9 @@
overflow: hidden;
text-overflow: ellipsis;
margin-right: 0.5rem;
display: flex;
align-items: center;
gap: var(--size-spacing-2);

&--placeholder {
color: var(--v-select-placeholder-color);
Expand Down Expand Up @@ -454,5 +463,9 @@
width: 100%;
}
}

&--disabled {
border: none;
}
}
}

0 comments on commit 9c123a5

Please sign in to comment.