gradio
104 строки · 2.6 Кб
1<script lang="ts">
2import type { Gradio } from "@gradio/utils";
3import { Block, BlockTitle } from "@gradio/atoms";
4import { StatusTracker } from "@gradio/statustracker";
5import type { LoadingStatus } from "@gradio/statustracker";
6
7export let label = "Dropdown";
8export let elem_id = "";
9export let elem_classes: string[] = [];
10export let visible = true;
11export let value: string | number;
12export let value_is_output = false;
13export let choices: [string, string | number][];
14export let show_label: boolean;
15export let scale: number | null = null;
16export let min_width: number | undefined = undefined;
17export let loading_status: LoadingStatus;
18export let gradio: Gradio<{
19change: string;
20input: never;
21}>;
22export let interactive: boolean;
23
24const container = true;
25let display_value: string;
26let candidate: [string, string | number][];
27
28function handle_change(): void {
29gradio.dispatch("change");
30if (!value_is_output) {
31gradio.dispatch("input");
32}
33}
34
35$: if (display_value) {
36candidate = choices.filter((choice) => choice[0] === display_value);
37value = candidate.length ? candidate[0][1] : "";
38}
39
40// When the value changes, dispatch the change event via handle_change()
41// See the docs for an explanation: https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive
42$: value, handle_change();
43</script>
44
45<Block
46{visible}
47{elem_id}
48{elem_classes}
49padding={container}
50allow_overflow={false}
51{scale}
52{min_width}
53>
54{#if loading_status}
55<StatusTracker
56autoscroll={gradio.autoscroll}
57i18n={gradio.i18n}
58{...loading_status}
59/>
60{/if}
61
62<label class:container>
63<BlockTitle {show_label} info={undefined}>{label}</BlockTitle>
64<select disabled={!interactive} bind:value={display_value}>
65{#each choices as choice}
66<option>{choice[0]}</option>
67{/each}
68</select>
69</label>
70</Block>
71
72<style>
73select {
74--ring-color: transparent;
75display: block;
76position: relative;
77outline: none !important;
78box-shadow:
790 0 0 var(--shadow-spread) var(--ring-color),
80var(--shadow-inset);
81border: var(--input-border-width) solid var(--border-color-primary);
82border-radius: var(--radius-lg);
83background-color: var(--input-background-base);
84padding: var(--size-2-5);
85width: 100%;
86color: var(--color-text-body);
87font-size: var(--scale-00);
88line-height: var(--line-sm);
89}
90
91select:focus {
92--ring-color: var(--color-focus-ring);
93border-color: var(--input-border-color-focus);
94}
95
96select::placeholder {
97color: var(--color-text-placeholder);
98}
99
100select[disabled] {
101cursor: not-allowed;
102box-shadow: none;
103}
104</style>
105