Skip to content

Commit

Permalink
feat: add slot before label (#241)
Browse files Browse the repository at this point in the history
* feat: add slot before label

* feat: add slot before label

* feat: add slot before label

* feat: add slot before label

* chore: revised selected item display
  • Loading branch information
reeves999999 authored Dec 7, 2023
1 parent 8347ef5 commit 74fc469
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
64 changes: 51 additions & 13 deletions src/components/Listbox/Listbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
v-slot="{ open }"
class="concrete__listbox"
>
{{ selectedValue }}
<div :class="['relative', disabledClass]">
<div class="inline-flex w-full">
<div class="relative z-0 inline-flex w-full" :class="inputColorClass">
<div
class="relative z-0 inline-flex w-full items-center"
:class="inputColorClass"
>
<CInputAffix v-if="prefix" type="prefix">{{ prefix }}</CInputAffix>
<slot name="prefix" class="z-10" />
<ListboxButton
Expand All @@ -36,13 +40,18 @@
inputColorClass,
mergedSizeClass,
cursorClass,
open && 'ring-1 border-indigo-light'
]"
class="!flex items-center"
>
<slot name="buttonPrefix" />
<span
class="block-truncate"
:class="selectedLabel || 'text-gray-400'"
>{{ selectedLabel || placeholder }}</span
>
{{ selectedLabel || placeholder }}
</span>

<span
class="
absolute
Expand All @@ -67,13 +76,23 @@
</div>

<transition
enter-from-class="opacity-0 -mt-4"
enter-from-class="opacity-0 mt-0 mb-0"
leave-to-class="opacity-0"
name="listbox"
>
<ListboxOptions
class="transition-all mt-1 duration-200 absolute z-30 w-full bg-white shadow-lg outline-none overflow-y-auto"
:class="[optionsSizeClass, maxOptionsHeightClass]"
class="
transition-all
duration-100
absolute
z-30
w-full
bg-white
shadow-lg
outline-none
overflow-y-auto
"
:class="[optionsSizeClass, maxOptionsHeightClass, getOptionsClass()]"
>
<ListboxOption
as="template"
Expand All @@ -85,17 +104,24 @@
>
<li
:class="[
option.disabled ? 'text-opacity-50' : 'cursor-pointer hover:bg-gray-50',
'select-none relative py-2 pl-3 pr-8 text-black',
option.disabled
? 'text-opacity-50'
: 'cursor-pointer',
'select-none relative py-2 px-3 text-black',
active && 'bg-steel-light'
]"
>
<div class="truncate" :class="selected ? 'font-semibold' : 'font-normal'">
<div
class="truncate flex items-center"
:class="selected ? 'font-semibold' : 'font-normal'"
>
<slot
v-if="$slots.optionPrefix"
name="optionPrefix"
:option="option"
/>
{{ option.label }}
</div>

<span v-if="selected" class="absolute inset-y-0 right-0 flex items-center pr-4">
<CheckIcon class="h-5 w-5" aria-hidden="true" />
</span>
</li>
</ListboxOption>
</ListboxOptions>
Expand Down Expand Up @@ -128,7 +154,7 @@ import {
useStackedValue,
useInputValue,
useRegisterInput,
useInputIdToOptions
useInputIdToOptions,
} from '../../composables/forms.js';
import { useEventHandler } from '../../composables/events.js';
import CFormElement from '../FormElement/FormElement.vue';
Expand Down Expand Up @@ -264,5 +290,17 @@ const iconColorClass = computed(() => {
}[props.color];
});
function getOptionsClass() {
const el = buttonRef.value?.el;
if (!el) return;
const screenHeight = window.innerHeight;
const elPostionOnScreen = el.getBoundingClientRect().top;
const isOptionsBelowInput = elPostionOnScreen > screenHeight / 2;
return isOptionsBelowInput ? 'bottom-full mb-1' : 'top-full mt-1';
}
useRegisterInput(props, buttonRef);
</script>
2 changes: 1 addition & 1 deletion src/composables/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const colorClassMap = {
};

const layoutClasses = 'block truncate z-20 w-full border text-left'
const focusClasses = 'focus:outline-none focus:ring-1 focus:border-indigo-light focus:ring-indigo-light';
const focusClasses = 'focus:outline-none focus:ring-1 focus:border-indigo-light ring-indigo-light';
export const inputStaticClasses = [layoutClasses, focusClasses].join(' ' +
'');

Expand Down

0 comments on commit 74fc469

Please sign in to comment.