[#4674] updated select field ui

This commit is contained in:
Gani Georgiev
2025-03-20 13:46:40 +02:00
parent 9f1946057f
commit d61ec398a2
34 changed files with 286 additions and 129 deletions
@@ -0,0 +1,151 @@
<script>
import CommonHelper from "@/utils/CommonHelper";
import Toggler from "@/components/base/Toggler.svelte";
import Draggable from "@/components/base/Draggable.svelte";
export let id = null;
export let items = [];
export let disabled = false;
export let emptyPlaceholder = "Add choices...";
export let newPlaceholder = "e.g. optionA";
let newInput;
let newInputVal = "";
$: formattedValue = items.join(" • ");
function remove(item) {
items = items || [];
CommonHelper.removeByValue(items, item);
if (!items.length) {
newInput?.focus();
}
}
function add(item) {
const val = item.trim();
if (!val.length) {
return;
}
items = items || [];
CommonHelper.pushUnique(items, val);
// reset input
newInputVal = "";
}
</script>
<div>
<input
{id}
readonly
type="text"
class="formatted-value-input"
{disabled}
placeholder={emptyPlaceholder}
value={formattedValue}
title={formattedValue}
/>
{#if !disabled}
<Toggler
class="dropdown dropdown-block options-dropdown dropdown-left m-t-0 p-0"
on:hide={() => (newInputVal = "")}
>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="block"
on:dragover|stopPropagation
on:dragleave|stopPropagation
on:dragend|stopPropagation
on:dragstart|stopPropagation
on:drop|stopPropagation
>
{#each items as item, i (item)}
<Draggable bind:list={items} index={i} group={"options_" + id}>
<div class="dropdown-item plain">
<span class="txt">{item}</span>
<div class="flex-fill"></div>
<button
type="button"
class="btn btn-circle btn-transparent btn-hint btn-xs"
title="Remove item"
on:click|stopPropagation={() => remove(item)}
>
<i class="ri-close-line" aria-hidden="true"></i>
</button>
</div>
</Draggable>
{/each}
<div class="new-item-form">
<div class="form-field form-field-sm m-0">
<div class="input-group">
<!-- svelte-ignore a11y-autofocus -->
<input
bind:this={newInput}
autofocus
type="text"
class="new-item-input"
placeholder={newPlaceholder}
bind:value={newInputVal}
on:keydown={(e) => {
if (e.code === "Enter") {
e.preventDefault();
add(e.target.value);
}
}}
/>
<div class="form-field-addon suffix">
<button
type="button"
class="btn btn-transparent btn-xs btn-circle new-item-btn"
title="Add new item"
class:btn-disabled={!newInputVal.length}
on:click={() => add(newInputVal)}
>
<i class="ri-add-line" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</Toggler>
{/if}
</div>
<style lang="scss">
.formatted-value-input {
padding-left: 10px;
padding-right: 10px;
cursor: pointer;
color: var(--txtPrimaryColor);
}
.dropdown-item {
padding-top: 5px;
padding-bottom: 5px;
}
.new-item-form {
position: sticky;
z-index: 99;
bottom: 0;
padding: 10px;
background: var(--baseColor);
border-bottom-left-radius: var(--baseRadius);
border-bottom-right-radius: var(--baseRadius);
&:not(:first-child) {
margin-top: 5px;
border-top: 1px solid var(--baseAlt1Color);
}
}
.new-item-input {
padding-right: 40px;
padding-left: 10px;
}
.new-item-btn {
right: -5px;
}
</style>
@@ -1,8 +1,7 @@
<script>
import tooltip from "@/actions/tooltip";
import Field from "@/components/base/Field.svelte";
import MultipleValueInput from "@/components/base/MultipleValueInput.svelte";
import ObjectSelect from "@/components/base/ObjectSelect.svelte";
import DynamicOptionsSelect from "@/components/base/DynamicOptionsSelect.svelte";
import SchemaField from "@/components/collections/schema/SchemaField.svelte";
export let field;
@@ -47,15 +46,7 @@
name="fields.{key}.values"
let:uniqueId
>
<div use:tooltip={{ text: "Choices (comma separated)", position: "top-left", delay: 700 }}>
<MultipleValueInput
id={uniqueId}
placeholder="Choices: eg. optionA, optionB"
required
readonly={!interactive}
bind:value={field.values}
/>
</div>
<DynamicOptionsSelect id={uniqueId} bind:items={field.values} />
</Field>
<div class="separator" />
+4
View File
@@ -66,6 +66,10 @@
transition-duration: var(--activeAnimationSpeed);
background: var(--baseAlt2Color);
}
&.plain {
background: none;
cursor: default;
}
&.disabled {
color: var(--txtDisabledColor);
background: none;
+9
View File
@@ -493,6 +493,15 @@ select {
padding-left: var(--hPadding);
padding-right: var(--hPadding);
}
.active:has(.dropdown) > %input {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.toggler-container .dropdown {
border-top-left-radius: 0;
border-top-right-radius: 0;
margin-top: 0;
}
select {
padding-left: 8px;
}