Lib: Remove LazyDropdown
It was identical to "Dropdown" after removing the non-lazy "Image" component
This commit is contained in:
@ -1,148 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { ListBox, ListBoxItem, popup, type PopupSettings } from "@skeletonlabs/skeleton";
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
import type { Action } from "svelte/action";
|
|
||||||
import type { HTMLInputAttributes } from "svelte/elements";
|
|
||||||
import { v4 as uuid } from "uuid";
|
|
||||||
import { type LazyDropdownOption, LazyImage } from "$lib/components";
|
|
||||||
|
|
||||||
interface LazyDropdownProps extends HTMLInputAttributes {
|
|
||||||
children: Snippet;
|
|
||||||
|
|
||||||
/** Placeholder for the empty input element */
|
|
||||||
placeholder?: string;
|
|
||||||
|
|
||||||
/** Form name of the input element, to reference input data after form submission */
|
|
||||||
name?: string;
|
|
||||||
|
|
||||||
/** Manually set the label width, to align multiple inputs vertically. Supply value in CSS units. */
|
|
||||||
labelwidth?: string;
|
|
||||||
|
|
||||||
/** The variable to bind to the input element. Has to be a [$state] so its value can be updated with the input element's contents. */
|
|
||||||
input_variable: string;
|
|
||||||
|
|
||||||
/** Any action to bind to the input element */
|
|
||||||
action?: Action;
|
|
||||||
|
|
||||||
/** The ID of the popup to trigger. UUID by default. */
|
|
||||||
popup_id?: string;
|
|
||||||
|
|
||||||
/** The [PopupSettings] object for the popup to trigger. */
|
|
||||||
popup_settings?: PopupSettings;
|
|
||||||
|
|
||||||
/** The options this autocomplete component allows to choose from.
|
|
||||||
* Example: [[{ label: "Aston", value: "0" }, { label: "VCARB", value: "1" }]].
|
|
||||||
*/
|
|
||||||
options: LazyDropdownOption[];
|
|
||||||
}
|
|
||||||
|
|
||||||
let {
|
|
||||||
children,
|
|
||||||
placeholder = "",
|
|
||||||
name = "",
|
|
||||||
labelwidth = "auto",
|
|
||||||
input_variable,
|
|
||||||
action = undefined,
|
|
||||||
popup_id = uuid(),
|
|
||||||
popup_settings = {
|
|
||||||
event: "click",
|
|
||||||
target: popup_id,
|
|
||||||
placement: "bottom",
|
|
||||||
closeQuery: ".listbox-item",
|
|
||||||
},
|
|
||||||
options,
|
|
||||||
...restProps
|
|
||||||
}: LazyDropdownProps = $props();
|
|
||||||
|
|
||||||
/** Find the "label" of an option by its "value" */
|
|
||||||
const get_label = (value: string): string | undefined => {
|
|
||||||
return options.find((o) => o.value === value)?.label;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use an action to fill the "input" variable
|
|
||||||
// required to dispatch the custom event using $effect
|
|
||||||
let input: HTMLInputElement | undefined = undefined;
|
|
||||||
const obtain_input: Action = (node: HTMLElement) => {
|
|
||||||
input = node as HTMLInputElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This will run everyting "input_variable" changes.
|
|
||||||
// The event is fired when the input's value is updated via JavaScript.
|
|
||||||
$effect(() => {
|
|
||||||
// Just list this so SvelteKit picks it up as dependency
|
|
||||||
input_variable;
|
|
||||||
|
|
||||||
if (input) input.dispatchEvent(new CustomEvent("DropdownChange"));
|
|
||||||
});
|
|
||||||
|
|
||||||
let load: boolean = $state(false);
|
|
||||||
|
|
||||||
const lazy_click_handler = () => {
|
|
||||||
load = true;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="input-group input-group-divider grid-cols-[auto_1fr_auto]">
|
|
||||||
<div
|
|
||||||
class="input-group-shim select-none text-nowrap text-neutral-900"
|
|
||||||
style="width: {labelwidth};"
|
|
||||||
>
|
|
||||||
{@render children()}
|
|
||||||
</div>
|
|
||||||
<!-- TODO: How to assign use: conditionally? I don't wan't to repeat the entire input... -->
|
|
||||||
{#if action}
|
|
||||||
<input
|
|
||||||
use:popup={popup_settings}
|
|
||||||
type="button"
|
|
||||||
autocomplete="off"
|
|
||||||
style="height: 42px; text-align: start; text-indent: 12px; border-top-left-radius: 0; border-bottom-left-radius: 0;"
|
|
||||||
use:obtain_input
|
|
||||||
use:action
|
|
||||||
onmousedown={lazy_click_handler}
|
|
||||||
onkeypress={(event: Event) => event.preventDefault()}
|
|
||||||
value={get_label(input_variable) ?? placeholder}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
<input
|
|
||||||
use:popup={popup_settings}
|
|
||||||
type="button"
|
|
||||||
autocomplete="off"
|
|
||||||
style="height: 42px; text-align: start; text-indent: 12px; border-top-left-radius: 0; border-bottom-left-radius: 0;"
|
|
||||||
use:obtain_input
|
|
||||||
onmousedown={lazy_click_handler}
|
|
||||||
onkeypress={(event: Event) => event.preventDefault()}
|
|
||||||
value={get_label(input_variable) ?? placeholder}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
data-popup={popup_id}
|
|
||||||
class="card z-10 w-auto overflow-y-scroll p-2 shadow"
|
|
||||||
style="max-height: 350px;"
|
|
||||||
>
|
|
||||||
{#if load}
|
|
||||||
<ListBox>
|
|
||||||
{#each options as option}
|
|
||||||
<ListBoxItem bind:group={input_variable} {name} value={option.value}>
|
|
||||||
<div class="flex flex-nowrap">
|
|
||||||
{#if option.icon_url}
|
|
||||||
<LazyImage
|
|
||||||
src={option.icon_url}
|
|
||||||
alt=""
|
|
||||||
imgwidth={option.icon_width ?? 1}
|
|
||||||
imgheight={option.icon_height ?? 1}
|
|
||||||
class="rounded"
|
|
||||||
imgstyle="height: 24px;"
|
|
||||||
containerstyle="height: 24px;"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
<span class="ml-2">{option.label}</span>
|
|
||||||
</div>
|
|
||||||
</ListBoxItem>
|
|
||||||
{/each}
|
|
||||||
</ListBox>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { type DropdownOption } from "$lib/components";
|
|
||||||
|
|
||||||
export interface LazyDropdownOption extends DropdownOption {
|
|
||||||
/** The label displayed in the list of options. */
|
|
||||||
label: string;
|
|
||||||
|
|
||||||
/** The value assigned to the dropdown value variable */
|
|
||||||
value: string;
|
|
||||||
|
|
||||||
/** An optional icon displayed left to the label */
|
|
||||||
icon_url?: string;
|
|
||||||
|
|
||||||
/** The aspect ratio width of the optional icon */
|
|
||||||
icon_width?: number;
|
|
||||||
|
|
||||||
/** The aspect ratio height of the optional icon */
|
|
||||||
icon_height?: number;
|
|
||||||
}
|
|
||||||
@ -5,7 +5,6 @@ import Table from "./Table.svelte";
|
|||||||
import Button from "./form/Button.svelte";
|
import Button from "./form/Button.svelte";
|
||||||
import Dropdown from "./form/Dropdown.svelte";
|
import Dropdown from "./form/Dropdown.svelte";
|
||||||
import Input from "./form/Input.svelte";
|
import Input from "./form/Input.svelte";
|
||||||
import LazyDropdown from "./form/LazyDropdown.svelte";
|
|
||||||
import Search from "./form/Search.svelte";
|
import Search from "./form/Search.svelte";
|
||||||
|
|
||||||
import Card from "./cards/Card.svelte";
|
import Card from "./cards/Card.svelte";
|
||||||
@ -16,7 +15,6 @@ import SubstitutionCard from "./cards/SubstitutionCard.svelte";
|
|||||||
import TeamCard from "./cards/TeamCard.svelte";
|
import TeamCard from "./cards/TeamCard.svelte";
|
||||||
|
|
||||||
import type { DropdownOption } from "./form/Dropdown";
|
import type { DropdownOption } from "./form/Dropdown";
|
||||||
import type { LazyDropdownOption } from "./form/LazyDropdown";
|
|
||||||
import type { TableColumn } from "./Table";
|
import type { TableColumn } from "./Table";
|
||||||
|
|
||||||
import MenuDrawerIcon from "./svg/MenuDrawerIcon.svelte";
|
import MenuDrawerIcon from "./svg/MenuDrawerIcon.svelte";
|
||||||
@ -33,7 +31,6 @@ export {
|
|||||||
Button,
|
Button,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Input,
|
Input,
|
||||||
LazyDropdown,
|
|
||||||
Search,
|
Search,
|
||||||
|
|
||||||
// Cards
|
// Cards
|
||||||
@ -46,7 +43,6 @@ export {
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
type DropdownOption,
|
type DropdownOption,
|
||||||
type LazyDropdownOption,
|
|
||||||
type TableColumn,
|
type TableColumn,
|
||||||
|
|
||||||
// SVG
|
// SVG
|
||||||
|
|||||||
@ -9,15 +9,13 @@
|
|||||||
type ModalStore,
|
type ModalStore,
|
||||||
} from "@skeletonlabs/skeleton";
|
} from "@skeletonlabs/skeleton";
|
||||||
|
|
||||||
import { Button, Table, type LazyDropdownOption, type TableColumn } from "$lib/components";
|
import { Button, Table, type DropdownOption, type TableColumn } from "$lib/components";
|
||||||
import { get_by_value } from "$lib/database";
|
import { get_by_value } from "$lib/database";
|
||||||
import {
|
import {
|
||||||
DRIVER_HEADSHOT_HEIGHT,
|
DRIVER_HEADSHOT_HEIGHT,
|
||||||
DRIVER_HEADSHOT_WIDTH,
|
DRIVER_HEADSHOT_WIDTH,
|
||||||
RACE_PICTOGRAM_HEIGHT,
|
RACE_PICTOGRAM_HEIGHT,
|
||||||
RACE_PICTOGRAM_WIDTH,
|
RACE_PICTOGRAM_WIDTH,
|
||||||
TEAM_BANNER_HEIGHT,
|
|
||||||
TEAM_BANNER_WIDTH,
|
|
||||||
TEAM_LOGO_HEIGHT,
|
TEAM_LOGO_HEIGHT,
|
||||||
TEAM_LOGO_WIDTH,
|
TEAM_LOGO_WIDTH,
|
||||||
} from "$lib/config";
|
} from "$lib/config";
|
||||||
@ -57,7 +55,7 @@
|
|||||||
update_substitution_race_select_values["create"] = "";
|
update_substitution_race_select_values["create"] = "";
|
||||||
|
|
||||||
// All options to create a <Dropdown> component for the teams
|
// All options to create a <Dropdown> component for the teams
|
||||||
const team_dropdown_options: LazyDropdownOption[] = [];
|
const team_dropdown_options: DropdownOption[] = [];
|
||||||
data.teams.forEach((team: Team) => {
|
data.teams.forEach((team: Team) => {
|
||||||
team_dropdown_options.push({
|
team_dropdown_options.push({
|
||||||
label: team.name,
|
label: team.name,
|
||||||
@ -69,7 +67,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// All options to create a <Dropdown> component for the drivers
|
// All options to create a <Dropdown> component for the drivers
|
||||||
const driver_dropdown_options: LazyDropdownOption[] = [];
|
const driver_dropdown_options: DropdownOption[] = [];
|
||||||
data.drivers.then((drivers: Driver[]) =>
|
data.drivers.then((drivers: Driver[]) =>
|
||||||
drivers.forEach((driver: Driver) => {
|
drivers.forEach((driver: Driver) => {
|
||||||
driver_dropdown_options.push({
|
driver_dropdown_options.push({
|
||||||
@ -83,7 +81,7 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
// All options to create a <Dropdown> component for the races
|
// All options to create a <Dropdown> component for the races
|
||||||
const race_dropdown_options: LazyDropdownOption[] = [];
|
const race_dropdown_options: DropdownOption[] = [];
|
||||||
data.races.then((races: Race[]) =>
|
data.races.then((races: Race[]) =>
|
||||||
races.forEach((race: Race) => {
|
races.forEach((race: Race) => {
|
||||||
race_dropdown_options.push({
|
race_dropdown_options.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user