Virtual list in dropdowns
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
"@litegraph-ts/nodes-math": "workspace:*",
|
"@litegraph-ts/nodes-math": "workspace:*",
|
||||||
"@litegraph-ts/nodes-strings": "workspace:*",
|
"@litegraph-ts/nodes-strings": "workspace:*",
|
||||||
"@litegraph-ts/tsconfig": "workspace:*",
|
"@litegraph-ts/tsconfig": "workspace:*",
|
||||||
|
"@sveltejs/svelte-virtual-list": "^3.0.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
||||||
"@tsconfig/svelte": "^4.0.1",
|
"@tsconfig/svelte": "^4.0.1",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
|
|||||||
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@@ -64,6 +64,9 @@ importers:
|
|||||||
'@litegraph-ts/tsconfig':
|
'@litegraph-ts/tsconfig':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:litegraph/packages/tsconfig
|
version: link:litegraph/packages/tsconfig
|
||||||
|
'@sveltejs/svelte-virtual-list':
|
||||||
|
specifier: ^3.0.1
|
||||||
|
version: 3.0.1
|
||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1(svelte@3.58.0)(vite@4.3.1)
|
version: 2.1.1(svelte@3.58.0)(vite@4.3.1)
|
||||||
@@ -2225,6 +2228,10 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@sveltejs/svelte-virtual-list@3.0.1:
|
||||||
|
resolution: {integrity: sha512-aF9TptS7NKKS7/TqpsxQBSDJ9Q0XBYzBehCeIC5DzdMEgrJZpIYao9LRLnyyo6SVodpapm2B7FE/Lj+FSA5/SQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@sveltejs/vite-plugin-svelte@2.1.1(svelte@3.58.0):
|
/@sveltejs/vite-plugin-svelte@2.1.1(svelte@3.58.0):
|
||||||
resolution: {integrity: sha512-7YeBDt4us0FiIMNsVXxyaP4Hwyn2/v9x3oqStkHU3ZdIc5O22pGwUwH33wUqYo+7Itdmo8zxJ45Qvfm3H7UUjQ==}
|
resolution: {integrity: sha512-7YeBDt4us0FiIMNsVXxyaP4Hwyn2/v9x3oqStkHU3ZdIc5O22pGwUwH33wUqYo+7Itdmo8zxJ45Qvfm3H7UUjQ==}
|
||||||
engines: {node: ^14.18.0 || >= 16}
|
engines: {node: ^14.18.0 || >= 16}
|
||||||
|
|||||||
@@ -764,6 +764,16 @@ export default class ComfyApp {
|
|||||||
async refreshComboInNodes(flashUI: boolean = false) {
|
async refreshComboInNodes(flashUI: boolean = false) {
|
||||||
const defs = await this.api.getNodeDefs();
|
const defs = await this.api.getNodeDefs();
|
||||||
|
|
||||||
|
for (let nodeNum in this.lGraph._nodes) {
|
||||||
|
const node = this.lGraph._nodes[nodeNum];
|
||||||
|
if (node.type === "ui/combo") {
|
||||||
|
(node as nodes.ComfyComboNode).valuesForCombo = null;
|
||||||
|
(node as nodes.ComfyComboNode).comboRefreshed.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let seen = new Set()
|
||||||
|
|
||||||
for (let nodeNum in this.lGraph._nodes) {
|
for (let nodeNum in this.lGraph._nodes) {
|
||||||
const node = this.lGraph._nodes[nodeNum];
|
const node = this.lGraph._nodes[nodeNum];
|
||||||
|
|
||||||
@@ -775,13 +785,18 @@ export default class ComfyApp {
|
|||||||
const comfyInput = input as IComfyInputSlot;
|
const comfyInput = input as IComfyInputSlot;
|
||||||
|
|
||||||
if (comfyInput.defaultWidgetNode == nodes.ComfyComboNode && def["input"]["required"][comfyInput.name] !== undefined) {
|
if (comfyInput.defaultWidgetNode == nodes.ComfyComboNode && def["input"]["required"][comfyInput.name] !== undefined) {
|
||||||
comfyInput.config.values = def["input"]["required"][comfyInput.name][0];
|
const rawValues = def["input"]["required"][comfyInput.name][0];
|
||||||
|
|
||||||
|
comfyInput.config.values = rawValues;
|
||||||
const inputNode = node.getInputNode(index)
|
const inputNode = node.getInputNode(index)
|
||||||
|
|
||||||
if (inputNode && "doAutoConfig" in inputNode && comfyInput.widgetNodeType === inputNode.type) {
|
if (inputNode && "doAutoConfig" in inputNode && comfyInput.widgetNodeType === inputNode.type && !seen.has(inputNode.id)) {
|
||||||
console.debug("[ComfyApp] Reconfiguring combo widget", inputNode.type, comfyInput.config.values)
|
seen.add(inputNode.id)
|
||||||
|
console.warn("[ComfyApp] Reconfiguring combo widget", inputNode.type, comfyInput.config.values.length)
|
||||||
const comfyComboNode = inputNode as nodes.ComfyComboNode;
|
const comfyComboNode = inputNode as nodes.ComfyComboNode;
|
||||||
comfyComboNode.doAutoConfig(comfyInput, { includeProperties: new Set(["values"]), setWidgetTitle: false })
|
comfyComboNode.doAutoConfig(comfyInput, { includeProperties: new Set(["values"]), setWidgetTitle: false })
|
||||||
|
|
||||||
|
comfyComboNode.formatValues(rawValues)
|
||||||
if (!comfyInput.config.values.includes(get(comfyComboNode.value))) {
|
if (!comfyInput.config.values.includes(get(comfyComboNode.value))) {
|
||||||
comfyComboNode.setValue(comfyInput.config.defaultValue || comfyInput.config.values[0])
|
comfyComboNode.setValue(comfyInput.config.defaultValue || comfyInput.config.values[0])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@
|
|||||||
on:input={(e) => updateAttribute(spec, target, e.detail)}
|
on:input={(e) => updateAttribute(spec, target, e.detail)}
|
||||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||||
label={spec.name}
|
label={spec.name}
|
||||||
max_lines={1}
|
max_lines={spec.multiline ? 5 : 1}
|
||||||
/>
|
/>
|
||||||
{:else if spec.type === "boolean"}
|
{:else if spec.type === "boolean"}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -307,7 +307,7 @@
|
|||||||
on:input={(e) => updateProperty(spec, e.detail)}
|
on:input={(e) => updateProperty(spec, e.detail)}
|
||||||
label={spec.name}
|
label={spec.name}
|
||||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||||
max_lines={1}
|
max_lines={spec.multiline ? 5 : 1}
|
||||||
/>
|
/>
|
||||||
{:else if spec.type === "boolean"}
|
{:else if spec.type === "boolean"}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -345,7 +345,7 @@
|
|||||||
on:input={(e) => updateVar(spec, e.detail)}
|
on:input={(e) => updateVar(spec, e.detail)}
|
||||||
label={spec.name}
|
label={spec.name}
|
||||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||||
max_lines={1}
|
max_lines={spec.multiline ? 5 : 1}
|
||||||
/>
|
/>
|
||||||
{:else if spec.type === "boolean"}
|
{:else if spec.type === "boolean"}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
on:input={(e) => updateWorkflowAttribute(spec, e.detail)}
|
on:input={(e) => updateWorkflowAttribute(spec, e.detail)}
|
||||||
label={spec.name}
|
label={spec.name}
|
||||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||||
max_lines={1}
|
max_lines={spec.multiline ? 5 : 1}
|
||||||
/>
|
/>
|
||||||
{:else if spec.type === "boolean"}
|
{:else if spec.type === "boolean"}
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onValueUpdated(value: any) {
|
private onValueUpdated(value: any) {
|
||||||
console.debug("[Widget] valueUpdated", this, value)
|
// console.debug("[Widget] valueUpdated", this, value)
|
||||||
this.displayWidget.value = this.formatValue(value)
|
this.displayWidget.value = this.formatValue(value)
|
||||||
|
|
||||||
if (this.outputIndex !== null && this.outputs.length >= this.outputIndex) {
|
if (this.outputIndex !== null && this.outputs.length >= this.outputIndex) {
|
||||||
@@ -151,7 +151,7 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
|
|||||||
if (!this.delayChangedEvent)
|
if (!this.delayChangedEvent)
|
||||||
this.triggerChangeEvent(get(this.value))
|
this.triggerChangeEvent(get(this.value))
|
||||||
else {
|
else {
|
||||||
console.debug("[Widget] queueChangeEvent", this, value)
|
// console.debug("[Widget] queueChangeEvent", this, value)
|
||||||
this._aboutToChange = 2; // wait 1.5-2 frames, in case we're already in the middle of executing the graph
|
this._aboutToChange = 2; // wait 1.5-2 frames, in case we're already in the middle of executing the graph
|
||||||
this._aboutToChangeValue = get(this.value);
|
this._aboutToChangeValue = get(this.value);
|
||||||
}
|
}
|
||||||
@@ -402,13 +402,17 @@ LiteGraph.registerNodeType({
|
|||||||
|
|
||||||
export interface ComfyComboProperties extends ComfyWidgetProperties {
|
export interface ComfyComboProperties extends ComfyWidgetProperties {
|
||||||
values: string[]
|
values: string[]
|
||||||
|
|
||||||
|
/* JS Function body that takes a parameter named "value" as a parameter and returns the label for each combo entry */
|
||||||
|
convertValueToLabelCode: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ComfyComboNode extends ComfyWidgetNode<string> {
|
export class ComfyComboNode extends ComfyWidgetNode<string> {
|
||||||
override properties: ComfyComboProperties = {
|
override properties: ComfyComboProperties = {
|
||||||
tags: [],
|
tags: [],
|
||||||
defaultValue: "A",
|
defaultValue: "A",
|
||||||
values: ["A", "B", "C", "D"]
|
values: ["A", "B", "C", "D"],
|
||||||
|
convertValueToLabelCode: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
static slotLayout: SlotLayout = {
|
static slotLayout: SlotLayout = {
|
||||||
@@ -428,11 +432,52 @@ export class ComfyComboNode extends ComfyWidgetNode<string> {
|
|||||||
|
|
||||||
comboRefreshed: Writable<boolean>;
|
comboRefreshed: Writable<boolean>;
|
||||||
|
|
||||||
|
valuesForCombo: any[] | null = null;
|
||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
super(name, "A")
|
super(name, "A")
|
||||||
this.comboRefreshed = writable(false)
|
this.comboRefreshed = writable(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override onPropertyChanged(property: any, value: any) {
|
||||||
|
if (property === "values" || property === "convertValueToLabelCode") {
|
||||||
|
this.formatValues(this.properties.values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formatValues(values: string[]) {
|
||||||
|
if (values == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.properties.values = values;
|
||||||
|
|
||||||
|
let formatter: any;
|
||||||
|
if (this.properties.convertValueToLabelCode)
|
||||||
|
formatter = new Function("value", this.properties.convertValueToLabelCode) as (v: string) => string;
|
||||||
|
else
|
||||||
|
formatter = (value) => `${value}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.valuesForCombo = this.properties.values.map(value => {
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
label: formatter(value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error("Failed formatting!", err)
|
||||||
|
this.valuesForCombo = this.properties.values.map(value => {
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
label: `${value}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.comboRefreshed.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
onConnectOutput(
|
onConnectOutput(
|
||||||
outputIndex: number,
|
outputIndex: number,
|
||||||
inputType: INodeInputSlot["type"],
|
inputType: INodeInputSlot["type"],
|
||||||
@@ -476,6 +521,12 @@ export class ComfyComboNode extends ComfyWidgetNode<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override onSerialize(o: SerializedLGraphNode) {
|
||||||
|
super.onSerialize(o);
|
||||||
|
// TODO fix saving combo nodes with huge values lists
|
||||||
|
o.properties.values = []
|
||||||
|
}
|
||||||
|
|
||||||
override stripUserState(o: SerializedLGraphNode) {
|
override stripUserState(o: SerializedLGraphNode) {
|
||||||
super.stripUserState(o);
|
super.stripUserState(o);
|
||||||
o.properties.values = []
|
o.properties.values = []
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ export type AttributesSpec = {
|
|||||||
*/
|
*/
|
||||||
max?: number,
|
max?: number,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If `type` is "string", display as a textarea.
|
||||||
|
*/
|
||||||
|
multiline?: boolean,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Valid `LGraphNode.type`s this property applies to if it's located in a node.
|
* Valid `LGraphNode.type`s this property applies to if it's located in a node.
|
||||||
* These are like "ui/button", "ui/slider".
|
* These are like "ui/button", "ui/slider".
|
||||||
@@ -386,6 +391,17 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
|
|||||||
defaultValue: "large"
|
defaultValue: "large"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Combo
|
||||||
|
{
|
||||||
|
name: "convertValueToLabelCode",
|
||||||
|
type: "string",
|
||||||
|
location: "nodeProps",
|
||||||
|
editable: true,
|
||||||
|
multiline: true,
|
||||||
|
validNodeTypes: ["ui/combo"],
|
||||||
|
defaultValue: ""
|
||||||
|
},
|
||||||
|
|
||||||
// Gallery
|
// Gallery
|
||||||
{
|
{
|
||||||
name: "variant",
|
name: "variant",
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BlockTitle } from "@gradio/atoms";
|
import { BlockTitle } from "@gradio/atoms";
|
||||||
import Select from 'svelte-select';
|
import Select from 'svelte-select';
|
||||||
|
import VirtualList from '@sveltejs/svelte-virtual-list';
|
||||||
|
import ListItem from "./ListItem.svelte"
|
||||||
import type { ComfyComboNode } from "$lib/nodes/index";
|
import type { ComfyComboNode } from "$lib/nodes/index";
|
||||||
import { type WidgetLayout } from "$lib/stores/layoutState";
|
import { type WidgetLayout } from "$lib/stores/layoutState";
|
||||||
import { get, type Writable } from "svelte/store";
|
import { get, writable, type Writable } from "svelte/store";
|
||||||
import { isDisabled } from "./utils"
|
import { isDisabled } from "./utils"
|
||||||
export let widget: WidgetLayout | null = null;
|
export let widget: WidgetLayout | null = null;
|
||||||
export let isMobile: boolean = false;
|
export let isMobile: boolean = false;
|
||||||
@@ -12,22 +14,21 @@
|
|||||||
let propsChanged: Writable<number> | null = null;
|
let propsChanged: Writable<number> | null = null;
|
||||||
let comboRefreshed: Writable<boolean> | null = null;
|
let comboRefreshed: Writable<boolean> | null = null;
|
||||||
let wasComboRefreshed: boolean = false;
|
let wasComboRefreshed: boolean = false;
|
||||||
let option: any
|
|
||||||
|
|
||||||
export let debug: boolean = false;
|
export let debug: boolean = false;
|
||||||
let input: HTMLInputElement | null = null
|
let input: HTMLInputElement | null = null
|
||||||
|
|
||||||
$: widget && setNodeValue(widget);
|
$: widget && setNodeValue(widget);
|
||||||
|
|
||||||
$: if (nodeValue !== null && (!$propsChanged || $propsChanged)) {
|
$: if (nodeValue !== null) {
|
||||||
if (node.properties.values.indexOf(option.value) === -1) {
|
// if (option == null || node.properties.values.indexOf(option.value) === -1) {
|
||||||
setOption($nodeValue)
|
// setOption($nodeValue)
|
||||||
$nodeValue = option
|
// $nodeValue = option
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
$nodeValue = option
|
// $nodeValue = option
|
||||||
setOption($nodeValue)
|
// setOption($nodeValue)
|
||||||
}
|
// }
|
||||||
setNodeValue(widget)
|
setNodeValue(widget)
|
||||||
node.properties = node.properties
|
node.properties = node.properties
|
||||||
}
|
}
|
||||||
@@ -40,18 +41,10 @@
|
|||||||
comboRefreshed = node.comboRefreshed;
|
comboRefreshed = node.comboRefreshed;
|
||||||
if ($comboRefreshed)
|
if ($comboRefreshed)
|
||||||
flashOnRefreshed();
|
flashOnRefreshed();
|
||||||
setOption($nodeValue) // don't react on option
|
// setOption($nodeValue) // don't react on option
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOption(value: any) {
|
|
||||||
option = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$: if (nodeValue && option && option.value) {
|
|
||||||
$nodeValue = option.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$: $comboRefreshed && flashOnRefreshed();
|
$: $comboRefreshed && flashOnRefreshed();
|
||||||
|
|
||||||
function flashOnRefreshed() {
|
function flashOnRefreshed() {
|
||||||
@@ -76,39 +69,81 @@
|
|||||||
input.blur();
|
input.blur();
|
||||||
navigator.vibrate(20)
|
navigator.vibrate(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let start = 0;
|
||||||
|
let end = 0;
|
||||||
|
let listOpen: boolean = false
|
||||||
|
|
||||||
|
function selectItem(item: any) {
|
||||||
|
$nodeValue = item.value;
|
||||||
|
listOpen = false;
|
||||||
|
document.activeElement?.blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
let option: any = null;
|
||||||
|
let rebuild = writable(0);
|
||||||
|
let virtualList = null;
|
||||||
|
|
||||||
|
function onFilter() {
|
||||||
|
// $rebuild += 1
|
||||||
|
if (virtualList) {
|
||||||
|
// force refresh virtual list
|
||||||
|
const viewport = virtualList.querySelector("svelte-virtual-list-viewport")
|
||||||
|
viewport.scrollTo(0, 1)
|
||||||
|
viewport.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("no")
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper comfy-combo" class:updated={$comboRefreshed}>
|
<div class="wrapper comfy-combo" class:updated={$comboRefreshed}>
|
||||||
{#key $propsChanged}
|
{#key $comboRefreshed}
|
||||||
{#key $comboRefreshed}
|
{#if node !== null && nodeValue !== null}
|
||||||
{#if node !== null && nodeValue !== null}
|
{#if node.valuesForCombo == null}
|
||||||
|
<span>Loading...</span>
|
||||||
|
{:else}
|
||||||
|
<span>Count {node.valuesForCombo.length}</span>
|
||||||
<label>
|
<label>
|
||||||
{#if widget.attrs.title !== ""}
|
{#if widget.attrs.title !== ""}
|
||||||
<BlockTitle show_label={true}>{widget.attrs.title}</BlockTitle>
|
<BlockTitle show_label={true}>{widget.attrs.title}</BlockTitle>
|
||||||
{/if}
|
{/if}
|
||||||
<Select
|
<Select
|
||||||
bind:value={option}
|
value={$nodeValue}
|
||||||
items={node.properties.values}
|
bind:justValue={option}
|
||||||
disabled={isDisabled(widget) || node.properties.values.length === 0}
|
bind:listOpen
|
||||||
|
items={node.valuesForCombo}
|
||||||
|
disabled={isDisabled(widget)}
|
||||||
clearable={false}
|
clearable={false}
|
||||||
showChevron={true}
|
showChevron={true}
|
||||||
|
listAutoWidth={true}
|
||||||
inputAttributes={{ autocomplete: 'off' }}
|
inputAttributes={{ autocomplete: 'off' }}
|
||||||
bind:input
|
bind:input
|
||||||
on:change
|
on:change
|
||||||
on:focus={onFocus}
|
on:focus={onFocus}
|
||||||
on:select={onSelect}
|
on:select={onSelect}
|
||||||
on:filter
|
on:filter={onFilter}
|
||||||
on:blur
|
on:blur
|
||||||
/>
|
>
|
||||||
{#if debug}
|
<div slot="list" class="list" let:filteredItems>
|
||||||
<div>Value: {option?.value}</div>
|
{#key $rebuild}
|
||||||
<div>Items: {node.properties.values}</div>
|
<div class="container" bind:this={virtualList}>
|
||||||
<div>NodeValue: {$nodeValue}</div>
|
<VirtualList items={filteredItems} bind:start bind:end let:item>
|
||||||
<div>LinkValue: {getLinkValue()}</div>
|
<div class="item"
|
||||||
{/if}
|
class:selected={option === item.value}
|
||||||
|
on:click={() => selectItem(item)}>
|
||||||
|
{item.label}
|
||||||
|
</div>
|
||||||
|
</VirtualList>
|
||||||
|
<p class="details">showing items {start}-{end}</p>
|
||||||
|
</div>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
{/if}
|
{/if}
|
||||||
{/key}
|
{/if}
|
||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -116,6 +151,12 @@
|
|||||||
.wrapper {
|
.wrapper {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
:global(.selected-item) {
|
||||||
|
// no idea how to get the select box to shrink in the flexbox otherwise...
|
||||||
|
position: absolute !important;
|
||||||
|
width: -webkit-fill-available !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes -global-light-up {
|
@keyframes -global-light-up {
|
||||||
@@ -142,5 +183,43 @@
|
|||||||
|
|
||||||
:global(.svelte-select-list) {
|
:global(.svelte-select-list) {
|
||||||
z-index: var(--layer-top) !important;
|
z-index: var(--layer-top) !important;
|
||||||
|
overflow-y: initial !important;
|
||||||
|
width: auto !important; // seems floating-ui overrides listAutoWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
border-top: 1px solid #333;
|
||||||
|
border-bottom: 1px solid #333;
|
||||||
|
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
height: 30rem;
|
||||||
|
width: 30rem;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: 16px;
|
||||||
|
&.selected {
|
||||||
|
color: white;
|
||||||
|
background: var(--color-yellow-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
background: white;
|
||||||
|
border: 1px solid grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(svelte-virtual-list-row) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(svelte-virtual-list-row:hover) {
|
||||||
|
color: white;
|
||||||
|
background: var(--color-blue-500);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user