improve dropdown
This commit is contained in:
parent
f73ad56c0e
commit
b1aad32beb
2 changed files with 20 additions and 12 deletions
|
@ -1,6 +1,5 @@
|
||||||
.box {
|
.box {
|
||||||
display: contents;
|
display: contents;
|
||||||
inline-size: max-content;
|
|
||||||
|
|
||||||
&:has(> :popover-open) > .button {
|
&:has(> :popover-open) > .button {
|
||||||
background-color: var(--surface-500);
|
background-color: var(--surface-500);
|
||||||
|
@ -15,7 +14,9 @@
|
||||||
grid-template-columns: inherit;
|
grid-template-columns: inherit;
|
||||||
place-items: center start;
|
place-items: center start;
|
||||||
|
|
||||||
inline-size: max-content;
|
/* Make sure the height of the button does not collapse when it is empty */
|
||||||
|
block-size: 1em;
|
||||||
|
box-sizing: content-box;
|
||||||
|
|
||||||
padding: var(--padding-m);
|
padding: var(--padding-m);
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
@ -44,13 +45,14 @@
|
||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
display: none;
|
display: none;
|
||||||
|
position: relative;
|
||||||
grid-template-columns: inherit;
|
grid-template-columns: inherit;
|
||||||
|
|
||||||
inset-inline-start: anchor(start);
|
inset-inline-start: anchor(start);
|
||||||
inset-block-start: anchor(end);
|
inset-block-start: anchor(end);
|
||||||
position-try-fallbacks: flip-inline;
|
position-try-fallbacks: flip-block, flip-inline;
|
||||||
|
|
||||||
inline-size: anchor-size(self-inline);
|
/* inline-size: anchor-size(self-inline); */
|
||||||
background-color: var(--surface-500);
|
background-color: var(--surface-500);
|
||||||
padding: var(--padding-m);
|
padding: var(--padding-m);
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { createMemo, createSignal, For, JSX, Setter, createEffect, Show } from "solid-js";
|
import { createMemo, createSignal, For, JSX, Setter, createEffect, Show } from "solid-js";
|
||||||
import css from './index.module.css';
|
|
||||||
import { FaSolidAngleDown } from "solid-icons/fa";
|
import { FaSolidAngleDown } from "solid-icons/fa";
|
||||||
|
import css from './index.module.css';
|
||||||
|
|
||||||
interface DropdownProps<T, K extends string> {
|
interface DropdownProps<T, K extends string> {
|
||||||
id: string;
|
id: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
value: K;
|
value?: K;
|
||||||
setValue?: Setter<K>;
|
setValue?: Setter<K | undefined>;
|
||||||
values: Record<K, T>;
|
values: Record<K, T>;
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
showCaret?: boolean;
|
showCaret?: boolean;
|
||||||
|
@ -16,7 +16,7 @@ interface DropdownProps<T, K extends string> {
|
||||||
|
|
||||||
export function Dropdown<T, K extends string>(props: DropdownProps<T, K>) {
|
export function Dropdown<T, K extends string>(props: DropdownProps<T, K>) {
|
||||||
const [dialog, setDialog] = createSignal<HTMLDialogElement>();
|
const [dialog, setDialog] = createSignal<HTMLDialogElement>();
|
||||||
const [value, setValue] = createSignal<K>(props.value);
|
const [key, setKey] = createSignal<K | undefined>(props.value);
|
||||||
const [open, setOpen] = createSignal<boolean>(props.open ?? false);
|
const [open, setOpen] = createSignal<boolean>(props.open ?? false);
|
||||||
const [query, setQuery] = createSignal<string>('');
|
const [query, setQuery] = createSignal<string>('');
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export function Dropdown<T, K extends string>(props: DropdownProps<T, K>) {
|
||||||
const showCaret = createMemo(() => props.showCaret ?? true);
|
const showCaret = createMemo(() => props.showCaret ?? true);
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
props.setValue?.(() => value());
|
props.setValue?.(() => key());
|
||||||
});
|
});
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
|
@ -44,7 +44,13 @@ export function Dropdown<T, K extends string>(props: DropdownProps<T, K>) {
|
||||||
|
|
||||||
return <section class={`${css.box} ${props.class}`}>
|
return <section class={`${css.box} ${props.class}`}>
|
||||||
<button id={`${props.id}_button`} popoverTarget={`${props.id}_dialog`} class={css.button}>
|
<button id={`${props.id}_button`} popoverTarget={`${props.id}_dialog`} class={css.button}>
|
||||||
{props.children(value(), props.values[value()])}
|
<Show when={key()}>{
|
||||||
|
key => {
|
||||||
|
const value = createMemo(() => props.values[key()]);
|
||||||
|
|
||||||
|
return <>{props.children(key(), value())}</>;
|
||||||
|
}
|
||||||
|
}</Show>
|
||||||
|
|
||||||
<Show when={showCaret()}>
|
<Show when={showCaret()}>
|
||||||
<FaSolidAngleDown class={css.caret} />
|
<FaSolidAngleDown class={css.caret} />
|
||||||
|
@ -61,10 +67,10 @@ export function Dropdown<T, K extends string>(props: DropdownProps<T, K>) {
|
||||||
<main>
|
<main>
|
||||||
<For each={values()}>{
|
<For each={values()}>{
|
||||||
([k, v]) => {
|
([k, v]) => {
|
||||||
const selected = createMemo(() => value() === k);
|
const selected = createMemo(() => key() === k);
|
||||||
|
|
||||||
return <span class={`${css.option} ${selected() ? css.selected : ''}`} onpointerdown={() => {
|
return <span class={`${css.option} ${selected() ? css.selected : ''}`} onpointerdown={() => {
|
||||||
setValue(() => k);
|
setKey(() => k);
|
||||||
dialog()?.hidePopover();
|
dialog()?.hidePopover();
|
||||||
}}>{props.children(k, v)}</span>;
|
}}>{props.children(k, v)}</span>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue