Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
fix(RuiMenuSelect): adjustments to make component behave as expected (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tewshi authored Apr 5, 2024
1 parent 2922a27 commit 848fceb
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 22 deletions.
39 changes: 38 additions & 1 deletion example/src/views/MenuView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ const menuSelectPrimitive = ref<MenuSelectProps[]>([
>
Select Menus: custom activator inner content
</h4>
<div class="grid gap-6 grid-cols-4">
<div class="grid gap-6 grid-cols-2">
<div
v-for="(menu, i) in menuSelectCustom"
:key="i"
Expand All @@ -380,14 +380,21 @@ const menuSelectPrimitive = ref<MenuSelectProps[]>([
v-model="menu.value"
v-bind="objectOmit(menu, ['value'])"
:data-cy="`select-menu-custom-inner-${i}`"
:item-height="80"
full-width
float-label
clearable
label-class="h-20"
variant="outlined"
>
<template #activator.text="{ value }">
{{ value.id }} | {{ value.label }}
</template>
<template #item.text="{ option }">
<span class="my-4 block">
{{ option.label }}
</span>
</template>
</RuiMenuSelect>
</div>
</div>
Expand Down Expand Up @@ -450,6 +457,36 @@ const menuSelectPrimitive = ref<MenuSelectProps[]>([
</template>
</RuiMenuSelect>
</div>
</div><h4
class="text-h6 mt-6"
data-cy="select-menus-custom-options"
>
Select Menus: readonly
</h4>
<div class="grid gap-6 grid-cols-4">
<div
v-for="(menu, i) in menuSelectPrimitive"
:key="i"
class="py-4"
>
<RuiMenuSelect
v-model="menu.value"
v-bind="objectOmit(menu, ['value'])"
:append-width="1.5"
:data-cy="`select-menu-custom-options-${i}`"
full-width
read-only
>
<template #item.append="{ active }">
<RuiIcon
v-if="active"
class="transition"
name="check-line"
size="24"
/>
</template>
</RuiMenuSelect>
</div>
</div>
</div>
</template>
108 changes: 91 additions & 17 deletions src/components/forms/select/RuiMenuSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface Props {
textAttr?: K;
value?: T | null;
disabled?: boolean;
readOnly?: boolean;
dense?: boolean;
fullWidth?: boolean;
floatLabel?: boolean;
Expand All @@ -39,6 +40,7 @@ defineOptions({
const props = withDefaults(defineProps<Props>(), {
disabled: false,
readOnly: false,
dense: false,
floatLabel: false,
clearable: false,
Expand All @@ -55,6 +57,7 @@ const props = withDefaults(defineProps<Props>(), {
hint: undefined,
keyAttr: undefined,
textAttr: undefined,
itemHeight: undefined,
errorMessages: () => [],
successMessages: () => [],
});
Expand All @@ -67,6 +70,9 @@ const css = useCssModule();
const { dense } = toRefs(props);
const activator = ref();
const { focused } = useFocus(activator);
const isPrimitiveOptions = computed(() => !(props.options[0] instanceof Object));
const keyProp = computed(() => props.keyAttr ?? 'key');
Expand Down Expand Up @@ -112,7 +118,7 @@ const {
getIdentifier,
isActiveItem,
} = useDropdownMenu<T, K>({
itemHeight: props.itemHeight ?? props.dense ? 30 : 48,
itemHeight: props.itemHeight ?? (props.dense ? 30 : 48),
keyAttr: get(keyProp),
textAttr: get(textProp),
options: mappedOptions,
Expand All @@ -126,29 +132,37 @@ const virtualContainerProps = computed(() => ({
style: containerProps.style as any,
ref: containerProps.ref as any,
}));
function setValue(val: T) {
set(value, val);
set(focused, true);
}
</script>

<template>
<RuiMenu
v-model="isOpen"
:class="css.wrapper"
:class="[css.wrapper, { 'w-full': fullWidth }]"
v-bind="{ ...menuOptions, errorMessages, successMessages, hint, dense, fullWidth, showDetails }"
>
<template #activator="{ on, open, hasError, hasSuccess }">
<slot
name="activator"
v-bind="{ disabled, value, variant, on, open, hasError, hasSuccess }"
v-bind="{ disabled, value, variant, readOnly, on, open, hasError, hasSuccess }"
>
<div
ref="activator"
:aria-disabled="disabled"
:class="[
css.activator,
labelClass,
{
[css.disabled]: disabled,
[css.readonly]: readOnly,
[css.outlined]: variant === 'outlined',
[css.dense]: dense,
[css.float]: float,
[css['float-label']]: floatLabel,
[css.opened]: open,
[css['with-value']]: !!value,
[css['with-error']]: hasError,
Expand All @@ -157,17 +171,16 @@ const virtualContainerProps = computed(() => ({
},
]"
data-id="activator"
v-on="disabled ? {} : on"
tabindex="0"
v-on="disabled || readOnly ? {} : on"
>
<span
v-if="floatLabel || !value"
:class="[
css.label,
{
'absolute right-4': floatLabel,
'absolute': floatLabel,
'pr-2': !value && !open && floatLabel,
'left-4': floatLabel && !dense,
'left-2': floatLabel && dense,
},
]"
>
Expand Down Expand Up @@ -242,7 +255,7 @@ const virtualContainerProps = computed(() => ({
:size="dense ? 'sm' : undefined"
:value="getIdentifier(option)"
variant="list"
@input="value = option"
@input="setValue(option)"
>
<template #prepend>
<slot
Expand Down Expand Up @@ -271,15 +284,19 @@ const virtualContainerProps = computed(() => ({

<style lang="scss" module>
.wrapper {
@apply max-w-full w-full;
@apply max-w-full inline-flex flex-col;
.activator {
@apply relative inline-flex items-center max-w-full;
@apply outline-none focus:outline-none cursor-pointer min-h-12 pl-4 py-2 pr-8 rounded;
@apply m-0 bg-white hover:bg-gray-50/10 transition text-body-1;
@apply outline-none focus:outline-none cursor-pointer min-h-14 pl-4 py-2 pr-8 rounded;
@apply m-0 bg-white transition-all text-body-1 hover:border-black;
&:not(.outlined) {
@apply hover:bg-gray-100 focus-within:bg-gray-100;
}
&.dense {
@apply pl-2 py-1 min-h-8 text-sm;
@apply pl-2 py-1 min-h-10 text-sm;
~ .fieldset {
@apply px-1;
Expand All @@ -290,10 +307,15 @@ const virtualContainerProps = computed(() => ({
@apply opacity-65 text-rui-text-disabled active:text-rui-text-disabled cursor-default bg-gray-50;
}
&.readonly {
@apply opacity-80 pointer-events-none cursor-default bg-gray-50;
}
&.outlined {
@apply border border-black/[0.23] hover:border-black;
&.opened {
&.opened,
&:focus {
@apply border-rui-primary border-2;
}
Expand Down Expand Up @@ -344,9 +366,21 @@ const virtualContainerProps = computed(() => ({
}
}
&.float-label {
.label {
max-width: calc(100% - 3rem);
}
&.dense {
.label {
max-width: calc(100% - 2.5rem);
}
}
}
&.float {
&.outlined {
@apply border-t-transparent;
@apply border-t-transparent #{!important};
&.with-success {
@apply border-t-transparent #{!important};
Expand All @@ -359,9 +393,25 @@ const virtualContainerProps = computed(() => ({
.label {
@apply -translate-y-2 top-0 text-xs;
max-width: calc(100% - 3rem);
}
&.opened {
&.dense {
.label {
max-width: calc(100% - 2.5rem);
}
}
&.with-value:hover {
~ .fieldset {
@apply border-black;
}
}
&.opened,
&.opened.with-value,
&:focus,
&:focus.with-value {
~ .fieldset {
@apply border-rui-primary border-2;
}
Expand Down Expand Up @@ -407,17 +457,22 @@ const virtualContainerProps = computed(() => ({
@apply bg-transparent text-rui-text;
&:not(.outlined) {
@apply hover:bg-white/10;
@apply hover:bg-white/10 focus-within:bg-white/10;
}
&.disabled {
@apply bg-white/10;
}
&.readonly {
@apply bg-white/10;
}
&.outlined {
@apply border-white/[0.23] hover:border-white;
&.opened {
&.opened,
&:focus {
@apply border-rui-primary;
}
}
Expand All @@ -426,6 +481,25 @@ const virtualContainerProps = computed(() => ({
&.outlined {
@apply border-t-transparent;
}
&.with-value:hover {
~ .fieldset {
@apply border-white;
}
}
&.opened,
&.opened.with-value,
&:focus,
&:focus.with-value {
~ .fieldset {
@apply border-rui-primary border-2;
}
}
~ .fieldset {
@apply border border-white/[0.23];
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/tables/TablePagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ function onLast() {
v-model="currentLimit"
:options="limits"
:disabled="loading || disablePerPage"
label-class="!text-xs"
label-class="!text-xs !min-h-8"
name="limit"
key-attr="limit"
text-attr="limit"
Expand All @@ -150,7 +150,7 @@ function onLast() {
v-model="currentRange"
:options="ranges"
:disabled="loading"
label-class="!text-xs"
label-class="!text-xs !min-h-8"
name="ranges"
key-attr="page"
text-attr="text"
Expand Down
6 changes: 4 additions & 2 deletions src/composables/dropdown-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function useDropdownMenu<T, K extends keyof T>({
itemHeight = 48,
keyAttr,
options,
overscan = 1,
overscan = 5,
prependWidth,
textAttr,
value,
Expand All @@ -40,7 +40,9 @@ export function useDropdownMenu<T, K extends keyof T>({

const valueKey = computed(() => {
const selected = get(value);
return selected ? selected[keyAttr] : undefined;
if (!keyAttr || !selected)
return selected;
return selected[keyAttr];
});

const menuWidth = computed(() => {
Expand Down

0 comments on commit 848fceb

Please sign in to comment.