UI/select: make z-index adjustable

This commit is contained in:
Johannes Kirschbauer
2025-08-08 20:59:55 +02:00
parent 6cbe221f44
commit c13741602c
2 changed files with 76 additions and 68 deletions

View File

@@ -1,88 +1,88 @@
.trigger { .trigger {
@apply bg-def-1 flex flex-grow justify-between items-center gap-2 h-7 px-2 py-1; @apply bg-def-1 flex flex-grow justify-between items-center gap-2 h-7 px-2 py-1;
@apply rounded-[4px]; @apply rounded-[4px];
&[data-expanded] { &[data-expanded] {
@apply outline-def-2 outline-1 outline; @apply outline-def-2 outline-1 outline;
z-index: 40; z-index: var(--z-index + 5);
}
&[data-highlighted] {
@apply outline outline-1 outline-inv-2;
}
&[data-loading] {
@apply cursor-wait;
}
&:hover {
@apply bg-def-2;
& .icon {
@apply bg-def-1 text-fg-def-1;
} }
}
&[data-highlighted] { &:active {
@apply outline outline-1 outline-inv-2 @apply bg-def-4;
& .icon {
@apply bg-inv-4 text-fg-inv-1;
} }
}
&[data-loading] { &:focus-visible {
@apply cursor-wait; @apply outline-def-2 outline-1 outline;
} }
&:hover {
@apply bg-def-2;
& .icon {
@apply bg-def-1 text-fg-def-1;
}
}
&:active {
@apply bg-def-4;
& .icon {
@apply bg-inv-4 text-fg-inv-1;
}
}
&:focus-visible {
@apply outline-def-2 outline-1 outline;
}
} }
.icon { .icon {
@apply bg-def-2 rounded-sm; @apply bg-def-2 rounded-sm;
@apply flex items-center justify-center h-[14px] w-[14px] p-[2px]; @apply flex items-center justify-center h-[14px] w-[14px] p-[2px];
&[data-disabled] { &[data-disabled] {
@apply cursor-not-allowed; @apply cursor-not-allowed;
} }
&[data-loading] { &[data-loading] {
@apply bg-inherit; @apply bg-inherit;
} }
} }
.options_content { .options_content {
@apply bg-def-1 px-1 py-3 rounded-[4px] -mt-8 pt-10 -mx-1; z-index: var(--z-index);
@apply outline-def-2 outline-1 outline;
transform-origin: var(--kb-popper-content-transform-origin); @apply bg-def-1 px-1 py-3 rounded-[4px] -mt-8 pt-10 -mx-1;
&[data-expanded] { @apply outline-def-2 outline-1 outline;
animation: overlayShow 250ms ease-out;
transform-origin: var(--kb-popper-content-transform-origin);
&[data-expanded] {
animation: overlayShow 250ms ease-out;
}
/* Option elements (typically <li>) */
& [role="option"] {
@apply px-2 py-4 rounded-sm flex items-center gap-1 flex-shrink-0;
&[data-highlighted],
&:focus-visible {
@apply outline outline-1 outline-inv-2;
} }
/* Option elements (typically <li>) */ &:hover {
& [role="option"] { @apply bg-def-2;
@apply px-1 py-2 rounded-sm flex items-center gap-1 flex-shrink-0 ;
&[data-highlighted],
&:focus-visible {
@apply outline outline-1 outline-inv-2
}
&:hover {
@apply bg-def-2;
}
&:active {
@apply bg-def-4;
}
} }
& [role="listbox"] { &:active {
&:focus-visible { @apply bg-def-4;
@apply outline-none;
}
} }
}
& [role="listbox"] {
&:focus-visible {
@apply outline-none;
}
}
} }
@keyframes overlayShow { @keyframes overlayShow {
from { from {
opacity: 0; opacity: 0;

View File

@@ -1,4 +1,4 @@
import { Select as KSelect } from "@kobalte/core/select"; import { Select as KSelect, SelectPortalProps } from "@kobalte/core/select";
import Icon from "../Icon/Icon"; import Icon from "../Icon/Icon";
import { Orienter } from "../Form/Orienter"; import { Orienter } from "../Form/Orienter";
import { Label, LabelProps } from "../Form/Label"; import { Label, LabelProps } from "../Form/Label";
@@ -28,6 +28,8 @@ export type SelectProps = {
// Custom props // Custom props
orientation?: "horizontal" | "vertical"; orientation?: "horizontal" | "vertical";
label?: Omit<LabelProps, "labelComponent" | "descriptionComponent">; label?: Omit<LabelProps, "labelComponent" | "descriptionComponent">;
portalProps?: Partial<SelectPortalProps>;
zIndex?: number;
} & ( } & (
| { | {
// Sync options // Sync options
@@ -48,6 +50,8 @@ export const Select = (props: SelectProps) => {
["placeholder", "ref", "onInput", "onChange", "onBlur"], ["placeholder", "ref", "onInput", "onChange", "onBlur"],
); );
const zIndex = () => props.zIndex ?? 40;
const [getValue, setValue] = createSignal<Option>(); const [getValue, setValue] = createSignal<Option>();
const [resolvedOptions, setResolvedOptions] = createSignal<Option[]>([]); const [resolvedOptions, setResolvedOptions] = createSignal<Option[]>([]);
@@ -78,6 +82,7 @@ export const Select = (props: SelectProps) => {
return ( return (
<KSelect <KSelect
{...root} {...root}
fitViewport={true}
options={options()} options={options()}
sameWidth={true} sameWidth={true}
gutter={0} gutter={0}
@@ -164,8 +169,11 @@ export const Select = (props: SelectProps) => {
</KSelect.Icon> </KSelect.Icon>
</KSelect.Trigger> </KSelect.Trigger>
</Orienter> </Orienter>
<KSelect.Portal> <KSelect.Portal {...props.portalProps}>
<KSelect.Content class={styles.options_content}> <KSelect.Content
class={styles.options_content}
style={{ "--z-index": zIndex() }}
>
<KSelect.Listbox /> <KSelect.Listbox />
</KSelect.Content> </KSelect.Content>
</KSelect.Portal> </KSelect.Portal>