Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/light-toes-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@soramitsu-ui/ui': minor
---

**feat**(`SSelect`,`SDropdown`): add loading state (`loading` prop)
5 changes: 5 additions & 0 deletions .changeset/silver-countries-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@soramitsu-ui/ui': minor
---

**feat**(`SSelect`,`SDropdown`): add prop to select options type (`optionType` prop)
5 changes: 5 additions & 0 deletions .changeset/stupid-experts-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@soramitsu-ui/ui': patch
---

**fix**(`SSelect`): add ellipsis on select text overflow
25 changes: 21 additions & 4 deletions packages/ui/etc/api/ui.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,21 +537,25 @@ shortcuts: DatePickerOptions;
export const SDropdown: DefineComponent<__VLS_TypePropsToRuntimeProps_10<{
modelValue?: any;
options?: SelectOption<any>[] | SelectOptionGroup<any>[] | undefined;
optionType?: SelectOptionType | undefined;
disabled?: boolean | undefined;
multiple?: boolean | undefined;
label?: string | undefined;
size?: SelectSize | undefined;
inline?: boolean | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
}>, {}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps_10<{
modelValue?: any;
options?: SelectOption<any>[] | SelectOptionGroup<any>[] | undefined;
optionType?: SelectOptionType | undefined;
disabled?: boolean | undefined;
multiple?: boolean | undefined;
label?: string | undefined;
size?: SelectSize | undefined;
inline?: boolean | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
}>>>, {}>;

// @public (undocumented)
Expand All @@ -567,6 +571,8 @@ export interface SelectApi<T> extends UnwrapRef<UseSelectModelReturn<T>> {
readonly isMenuOpened: boolean;
// (undocumented)
readonly label: string | null;
// (undocumented)
readonly loading: boolean;
menuToggle: (value?: boolean) => void;
// (undocumented)
readonly multiple: boolean;
Expand Down Expand Up @@ -607,8 +613,9 @@ export interface SelectOptionGroup<T = any> {

// @public (undocumented)
export const SelectOptionType: {
readonly RadioOrCheckbox: "rad-or-check";
readonly Check: "check";
readonly Radio: "radio";
readonly Checkbox: "checkbox";
readonly Default: "default";
};

// @public (undocumented)
Expand Down Expand Up @@ -1061,19 +1068,23 @@ radioSelector: string;
export const SSelect: DefineComponent<__VLS_TypePropsToRuntimeProps_9<{
modelValue?: any;
options?: SelectOption<any>[] | SelectOptionGroup<any>[] | undefined;
optionType?: SelectOptionType | undefined;
disabled?: boolean | undefined;
multiple?: boolean | undefined;
label?: string | undefined;
size?: SelectSize | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
}>, {}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps_9<{
modelValue?: any;
options?: SelectOption<any>[] | SelectOptionGroup<any>[] | undefined;
optionType?: SelectOptionType | undefined;
disabled?: boolean | undefined;
multiple?: boolean | undefined;
label?: string | undefined;
size?: SelectSize | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
}>>>, {}>;

// Warning: (ae-forgotten-export) The symbol "__VLS_WithDefaults" needs to be exported by the entry point lib.d.ts
Expand All @@ -1090,6 +1101,7 @@ label?: string | null | undefined;
mandatory?: boolean | undefined;
syncMenuAndInputWidths?: boolean | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
sameWidthPopper?: boolean | undefined;
}>, {
size: "md";
Expand All @@ -1100,6 +1112,8 @@ disabled: boolean;
syncMenuAndInputWidths: boolean;
noAutoClose: boolean;
label: null;
loading: boolean;
sameWidthPopper: boolean;
}>, {}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
"update:modelValue": (value: any) => void;
}, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<__VLS_WithDefaults_9<__VLS_TypePropsToRuntimeProps_11<{
Expand All @@ -1112,6 +1126,7 @@ label?: string | null | undefined;
mandatory?: boolean | undefined;
syncMenuAndInputWidths?: boolean | undefined;
noAutoClose?: boolean | undefined;
loading?: boolean | undefined;
sameWidthPopper?: boolean | undefined;
}>, {
size: "md";
Expand All @@ -1122,17 +1137,21 @@ disabled: boolean;
syncMenuAndInputWidths: boolean;
noAutoClose: boolean;
label: null;
loading: boolean;
sameWidthPopper: boolean;
}>>> & {
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
}, {
modelValue: any;
multiple: boolean;
size: SelectSize;
disabled: boolean;
loading: boolean;
options: SelectOption[] | SelectOptionGroup[];
label: string | null;
noAutoClose: boolean;
syncMenuAndInputWidths: boolean;
sameWidthPopper: boolean;
}>;

// Warning: (ae-forgotten-export) The symbol "__VLS_WithDefaults" needs to be exported by the entry point lib.d.ts
Expand Down Expand Up @@ -1164,13 +1183,11 @@ export const SSelectInput: DefineComponent< {}, {}, {}, {}, {}, ComponentOpti
// @public (undocumented)
export const SSelectOption: DefineComponent<__VLS_TypePropsToRuntimeProps_13<{
type: SelectOptionType;
multiple?: boolean | undefined;
selected?: boolean | undefined;
}>, {}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
toggle: () => void;
}, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps_13<{
type: SelectOptionType;
multiple?: boolean | undefined;
selected?: boolean | undefined;
}>>> & {
onToggle?: (() => any) | undefined;
Expand Down
4 changes: 3 additions & 1 deletion packages/ui/src/components/Select/SDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import SSelectDropdown from './SSelectDropdown.vue'
const props = defineProps<{
modelValue?: any
options?: SelectOption[] | SelectOptionGroup[]
optionType?: SelectOptionType
disabled?: boolean
multiple?: boolean
label?: string
size?: SelectSize
inline?: boolean
noAutoClose?: boolean
loading?: boolean
}>()

const buttonType = computed(() => (props.inline ? SelectButtonType.Inline : SelectButtonType.Default))
Expand Down Expand Up @@ -43,7 +45,7 @@ function isThereLabelSlot() {
</template>

<template #dropdown>
<SSelectDropdown :item-type="SelectOptionType.Check" />
<SSelectDropdown :item-type="optionType ?? SelectOptionType.Default" />
</template>
</SSelectBase>
</template>
8 changes: 6 additions & 2 deletions packages/ui/src/components/Select/SSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ import SSelectBase from './SSelectBase.vue'
import SSelectInput from './SSelectInput.vue'
import SSelectDropdown from './SSelectDropdown.vue'

defineProps<{
const props = defineProps<{
modelValue?: any
options?: SelectOption[] | SelectOptionGroup[]
optionType?: SelectOptionType
disabled?: boolean
multiple?: boolean
label?: string
size?: SelectSize
noAutoClose?: boolean
loading?: boolean
}>()

const defaultOptionType = computed(() => (props.multiple ? SelectOptionType.Checkbox : SelectOptionType.Radio))
</script>

<template>
Expand All @@ -34,7 +38,7 @@ defineProps<{
</template>

<template #dropdown>
<SSelectDropdown :item-type="SelectOptionType.RadioOrCheckbox" />
<SSelectDropdown :item-type="optionType ?? defaultOptionType" />
</template>
</SSelectBase>
</template>
10 changes: 9 additions & 1 deletion packages/ui/src/components/Select/SSelectBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const props = withDefaults(
*/
noAutoClose?: boolean

/**
* Enables loading state.
*/
loading?: boolean

/**
* Makes popper same width as trigger.
*/
Expand All @@ -56,13 +61,15 @@ const props = withDefaults(
syncMenuAndInputWidths: false,
noAutoClose: false,
label: null,
loading: false,
sameWidthPopper: false,
},
)

const emit = defineEmits<(event: 'update:modelValue', value: any) => void>()

const model = useVModel(props, 'modelValue', emit)
const { multiple, disabled, options, size, label, noAutoClose } = toRefs(props)
const { multiple, disabled, loading, options, size, label, noAutoClose } = toRefs(props)

const modeling = useSelectModel({
model,
Expand All @@ -82,6 +89,7 @@ const api: SelectApi<any> = reactive({
multiple,
options,
disabled,
loading,
label,
isMenuOpened: showPopper,
menuToggle: togglePopper,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Select/SSelectButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const slots = useSlots()
typography(),
{
's-select-btn_empty': !api.isSomethingSelected,
's-select-btn_disabled': api.disabled,
's-select-btn_disabled': api.disabled || api.loading,
},
]"
@click="toggle"
Expand Down
84 changes: 51 additions & 33 deletions packages/ui/src/components/Select/SSelectDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SelectOptionGroup, SelectOptionType, SelectSize } from './types'
import SSelectOption from './SSelectOption.vue'
import { ComputedRef } from 'vue'
import { isSelectOptions } from '@/components/Select/utils'
import SSpinner from '@/components/Spinner/SSpinner.vue'

defineProps<{
itemType: SelectOptionType
Expand Down Expand Up @@ -47,40 +48,49 @@ const ACTION_FONT = {
class="s-select-dropdown"
:class="`s-select-dropdown_size_${api.size}`"
>
<template
v-for="(optionGroup, i) in optionGroups"
:key="i"
<div
v-if="api.loading"
class="s-select-dropdown__loading flex items-center justify-center"
>
<div
v-if="isActionButtonShown(!!optionGroup.selectAllBtn) || optionGroup.header"
class="s-select-dropdown__header flex items-center justify-between"
<SSpinner />
</div>

<template v-else>
<template
v-for="(optionGroup, i) in optionGroups"
:key="i"
>
<div
v-if="optionGroup.header"
:class="HEADER_FONT[api.size]"
v-if="isActionButtonShown(!!optionGroup.selectAllBtn) || optionGroup.header"
class="s-select-dropdown__header flex items-center justify-between"
>
{{ optionGroup.header }}
<div
v-if="optionGroup.header"
:class="HEADER_FONT[api.size]"
>
{{ optionGroup.header }}
</div>
<button
v-if="isActionButtonShown(!!optionGroup.selectAllBtn)"
class="s-select-dropdown__action cursor-pointer ml-auto"
:class="ACTION_FONT[api.size]"
@click="api.toggleGroupSelection(optionGroup)"
>
{{ api.isGroupSelected(optionGroup) ? 'Deselect all' : 'Select all' }}
</button>
</div>
<button
v-if="isActionButtonShown(!!optionGroup.selectAllBtn)"
class="s-select-dropdown__action cursor-pointer ml-auto"
:class="ACTION_FONT[api.size]"
@click="api.toggleGroupSelection(optionGroup)"
<SSelectOption
v-for="(opt, j) in optionGroup.items"
:key="j"
:class="fontClass"
:type="itemType"
:multiple="api.multiple"
:selected="api.isValueSelected(opt.value)"
@toggle="api.toggleSelection(opt.value)"
>
{{ api.isGroupSelected(optionGroup) ? 'Deselect all' : 'Select all' }}
</button>
</div>
<SSelectOption
v-for="(opt, j) in optionGroup.items"
:key="j"
:class="fontClass"
:type="itemType"
:multiple="api.multiple"
:selected="api.isValueSelected(opt.value)"
@toggle="api.toggleSelection(opt.value)"
>
{{ opt.label }}
</SSelectOption>
{{ opt.label }}
</SSelectOption>
</template>
</template>
</div>
</template>
Expand All @@ -102,17 +112,25 @@ const ACTION_FONT = {
color: theme.token-as-var('sys.color.status.info');
}

@mixin select-dropdown-size($name, $header-height, $px) {
@mixin select-dropdown-size($name, $header-height, $px, $loading-height, $spinner-size) {
&_size_#{$name} &__header {
height: $header-height;
padding-right: $px;
padding-left: $px;
}

&_size_#{$name} &__loading {
height: $loading-height;

// spinner styles
font-size: $spinner-size;
color: theme.token-as-var('sys.color.content-tertiary');
}
}

@include select-dropdown-size('xl', $header-height: 56px, $px: 16px);
@include select-dropdown-size('lg', $header-height: 40px, $px: 16px);
@include select-dropdown-size('md', $header-height: 32px, $px: 10px);
@include select-dropdown-size('sm', $header-height: 24px, $px: 8px);
@include select-dropdown-size('xl', $header-height: 56px, $px: 16px, $loading-height: 170px, $spinner-size: 40px);
@include select-dropdown-size('lg', $header-height: 40px, $px: 16px, $loading-height: 150px, $spinner-size: 40px);
@include select-dropdown-size('md', $header-height: 32px, $px: 10px, $loading-height: 120px, $spinner-size: 24px);
@include select-dropdown-size('sm', $header-height: 24px, $px: 8px, $loading-height: 100px, $spinner-size: 24px);
}
</style>
8 changes: 4 additions & 4 deletions packages/ui/src/components/Select/SSelectInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const FSelection = () =>
? h(
'span',
{
class: typographySelection(),
class: ['overflow-hidden', 'overflow-ellipsis', typographySelection()],
},
selectionsJoined.value,
)
Expand All @@ -54,20 +54,20 @@ const FSelection = () =>
`s-select-input_size_${api.size}`,
{
's-select-input_empty': !api.isSomethingSelected,
's-select-input_disabled': api.disabled,
's-select-input_disabled': api.disabled || api.loading,
},
]"
@click="api.menuToggle()"
>
<template v-if="isColumnLayout">
<div class="flex flex-col flex-1">
<div class="flex flex-col flex-1 truncate">
<FLabel />
<FSelection />
</div>
</template>

<template v-else>
<div class="flex items-center flex-1">
<div class="flex items-center flex-1 truncate">
<FLabel /> <FSelection />
</div>
</template>
Expand Down
Loading