Lib: Replace the <Dropdown> popup with a native select element + bind the value

This commit is contained in:
2025-02-06 19:48:22 +01:00
parent c8ce8118cb
commit 0b64425284
6 changed files with 60 additions and 150 deletions

View File

@ -92,7 +92,7 @@
{#await data.teams then teams}
<Dropdown
name="team"
input_variable={team_select_value}
bind:value={team_select_value}
options={team_dropdown_options(teams)}
{labelwidth}
{disabled}

View File

@ -49,6 +49,9 @@
const racedate: string | undefined = $derived(
race ? format(new Date(race.racedate), dateformat) : undefined,
);
let step_value: string = $state(race?.step.toString() ?? "");
let pxx_value: string = $state(race?.pxx.toString() ?? "");
</script>
{#await data.graphics then graphics}
@ -86,7 +89,7 @@
</Input>
<Input
name="step"
value={race?.step ?? ""}
bind:value={step_value}
autocomplete="off"
type="number"
min={1}
@ -99,7 +102,7 @@
</Input>
<Input
name="pxx"
value={race?.pxx ?? ""}
bind:value={pxx_value}
autocomplete="off"
type="number"
min={1}

View File

@ -39,22 +39,9 @@
racepick = meta.racepick;
}
// This is executed on mount of the element specifying the "action"
const register_pxx_preview_handler: Action = (node: HTMLElement) => {
node.addEventListener("DropdownChange", update_pxx_preview);
};
// This event handler is registered to the Dropdown's <input> element through the action above.
const update_pxx_preview = async (event: Event) => {
const target: HTMLInputElement = event.target as HTMLInputElement;
const src: string =
get_by_value<Driver>(await data.drivers, "code", target.value)?.headshot_url || "";
const img = document.getElementById("headshot_preview") as HTMLImageElement;
// Can be null if lazyimg not loaded
if (img) img.src = src;
};
// Await promises
let drivers: Driver[] | undefined = $state(undefined);
data.drivers.then((d: Driver[]) => (drivers = d));
const required: boolean = $derived(!racepick);
const disabled: boolean = $derived(!data.admin);
@ -86,6 +73,14 @@
let pxx_select_value: string = $state(racepick?.pxx ?? "");
let dnf_select_value: string = $state(racepick?.dnf ?? "");
// Update preview
$effect(() => {
if (!drivers) return;
const src: string = get_by_value(drivers, "id", pxx_select_value)?.headshot_url ?? "";
const img: HTMLImageElement = document.getElementById("headshot_preview") as HTMLImageElement;
if (img) img.src = src;
});
</script>
{#await Promise.all([data.graphics, data.drivers]) then [graphics, drivers]}
@ -118,8 +113,7 @@
{#await active_drivers_and_substitutes then pxx_drivers}
<Dropdown
name="pxx"
input_variable={pxx_select_value}
action={register_pxx_preview_handler}
bind:value={pxx_select_value}
options={driver_dropdown_options(pxx_drivers)}
{labelwidth}
{disabled}
@ -127,13 +121,11 @@
>
P{data.currentrace?.pxx ?? "XX"}
</Dropdown>
{/await}
<!-- DNF select -->
{#await active_drivers_and_substitutes then pxx_drivers}
<!-- DNF select -->
<Dropdown
name="dnf"
input_variable={dnf_select_value}
bind:value={dnf_select_value}
options={driver_dropdown_options(pxx_drivers)}
{labelwidth}
{disabled}

View File

@ -30,6 +30,11 @@
result = meta.result;
}
let races: Race[] | undefined = $state(undefined);
data.races.then((r: Race[]) => {
races = r;
});
const required: boolean = $derived(!result);
const disabled: boolean = $derived(!data.admin);
const labelwidth: string = "70px";
@ -38,10 +43,18 @@
// TODO: Currentrace needs to be updated once a race is selected
// This way it doesn't update the placeholder (or the chips)...
const currentrace: Promise<Race | undefined> = $derived.by(async () =>
get_by_value(await data.races, "id", race_select_value),
// const currentrace: Promise<Race | undefined> = $derived.by(async () =>
// get_by_value(await data.races, "id", race_select_value),
// );
let currentrace: Race | undefined = $derived(
races ? (get_by_value(races, "id", race_select_value) ?? undefined) : undefined,
);
$effect(() => {
console.log("Updated currentrace", currentrace);
});
let pxxs_input: string = $state("");
let pxxs_chips: string[] = $state([]);
@ -179,7 +192,7 @@
{#await data.races then races}
<Dropdown
name="race"
input_variable={race_select_value}
bind:value={race_select_value}
options={race_dropdown_options(races)}
{labelwidth}
{disabled}

View File

@ -26,21 +26,9 @@
substitution = meta.substitution;
}
// This is executed on mount of the element specifying the "action"
const register_substitute_preview_handler: Action = (node: HTMLElement) =>
node.addEventListener("DropdownChange", update_substitute_preview);
// This event handler is registered to the Dropdown's <input> element through the action above.
const update_substitute_preview = async (event: Event) => {
const target: HTMLInputElement = event.target as HTMLInputElement;
const src: string =
get_by_value<Driver>(await data.drivers, "code", target.value)?.headshot_url ?? "";
const img = document.getElementById("headshot_preview") as HTMLImageElement;
// Can be null if lazyimage hasn't loaded
if (img) img.src = src;
};
// Await promises
let drivers: Driver[] | undefined = $state(undefined);
data.drivers.then((d: Driver[]) => (drivers = d));
const active_drivers = (drivers: Driver[]): Driver[] =>
drivers.filter((driver: Driver) => driver.active);
@ -54,6 +42,14 @@
let substitute_select_value: string = $state(substitution?.substitute ?? "");
let driver_select_value: string = $state(substitution?.for ?? "");
let race_select_value: string = $state(substitution?.race ?? "");
// Update preview
$effect(() => {
if (!drivers) return;
const src: string = get_by_value(drivers, "id", substitute_select_value)?.headshot_url ?? "";
const img: HTMLImageElement = document.getElementById("headshot_preview") as HTMLImageElement;
if (img) img.src = src;
});
</script>
{#await Promise.all([data.graphics, data.drivers]) then [graphics, drivers]}
@ -82,8 +78,7 @@
<!-- Substitute select -->
<Dropdown
name="substitute"
input_variable={substitute_select_value}
action={register_substitute_preview_handler}
bind:value={substitute_select_value}
options={driver_dropdown_options(inactive_drivers(drivers))}
{labelwidth}
{disabled}
@ -95,7 +90,7 @@
<!-- Driver select -->
<Dropdown
name="for"
input_variable={driver_select_value}
bind:value={driver_select_value}
options={driver_dropdown_options(active_drivers(drivers))}
{labelwidth}
{disabled}
@ -108,7 +103,7 @@
{#await data.races then races}
<Dropdown
name="race"
input_variable={race_select_value}
bind:value={race_select_value}
options={race_dropdown_options(races)}
{labelwidth}
{disabled}