Simplify TextInput

Extracts the validation message out of the `TextInput` component.
For a nice and flexible layout we should render the validation message
outside of the `TextInput` component and just do text input.
This commit is contained in:
Sebastian Martinez
2023-12-21 14:05:17 +00:00
committed by Rūdolfs Ošiņš
parent 851a444b5d
commit 2472938bf1
3 changed files with 55 additions and 79 deletions
+29 -76
View File
@@ -17,7 +17,6 @@
export let disabled: boolean = false;
export let loading: boolean = false;
export let valid: boolean = true;
export let validationMessage: string | undefined = undefined;
export let showKeyHint: boolean = true;
const dispatch = createEventDispatcher<{
@@ -27,7 +26,6 @@
}>();
let rightContainerWidth: number;
let leftContainerWidth: number;
let inputElement: HTMLInputElement | undefined = undefined;
let isFocused = false;
let success = false;
@@ -116,18 +114,6 @@
input[disabled] {
cursor: not-allowed;
}
.left-container {
color: var(--color-fill-secondary);
position: absolute;
left: 0;
top: 0;
display: flex;
align-items: center;
padding-right: 0.5rem;
padding-left: 0.5rem;
gap: 0.5rem;
height: 100%;
}
.right-container {
border: 1px solid transparent;
color: var(--color-fill-gray);
@@ -140,16 +126,6 @@
overflow: hidden;
height: 100%;
}
.validation-message {
color: var(--color-foreground-red);
position: relative;
margin-top: 0.5rem;
}
.validation-wrapper {
position: absolute;
width: 100%;
height: 100%;
}
.invalid {
border: 1px solid var(--color-border-error);
}
@@ -184,61 +160,38 @@
class="wrapper"
class:small={size === "small"}
class:regular={size === "regular"}>
<div class="validation-wrapper">
{#if $$slots.left}
<div class="left-container" bind:clientWidth={leftContainerWidth}>
<slot name="left" />
</div>
<input
class:invalid={!valid && value}
style:padding-right={rightContainerWidth
? `${rightContainerWidth}px`
: "auto"}
bind:this={inputElement}
type="text"
{name}
{placeholder}
{disabled}
bind:value
on:input
on:focus={handleFocusEvent}
on:blur={handleFocusEvent}
on:keydown|stopPropagation={handleKeydown}
on:click
on:change />
<div
class="right-container"
class:small={size === "small"}
bind:clientWidth={rightContainerWidth}>
{#if loading}
<Loading small noDelay />
{/if}
<input
class:invalid={!valid && value}
style:padding-left={leftContainerWidth
? `${leftContainerWidth}px`
: "auto"}
style:padding-right={rightContainerWidth
? `${rightContainerWidth}px`
: "auto"}
bind:this={inputElement}
type="text"
{name}
{placeholder}
{disabled}
bind:value
on:input
on:focus={handleFocusEvent}
on:blur={handleFocusEvent}
on:keydown|stopPropagation={handleKeydown}
on:click
on:change />
<div
class="right-container"
class:small={size === "small"}
bind:clientWidth={rightContainerWidth}>
{#if loading}
<Loading small noDelay />
{#if valid && !loading && isFocused && showKeyHint}
{#if success}
<IconSmall name="checkmark" />
{:else}
<KeyHint>⏎</KeyHint>
{/if}
{#if valid && !loading && isFocused && showKeyHint}
{#if success}
<IconSmall name="checkmark" />
{:else}
<KeyHint>⏎</KeyHint>
{/if}
{/if}
{#if $$slots.right}
<slot name="right" />
{/if}
</div>
{#if !valid && validationMessage}
<div class="validation-message">
<div style="display: flex; align-items: center; gap: 0.25rem;">
<IconSmall name="exclamation-circle" />{validationMessage}
</div>
</div>
{/if}
</div>
</div>
+13 -1
View File
@@ -79,6 +79,14 @@
width: 100%;
gap: 0.25rem;
}
.validation-message {
display: flex;
align-items: center;
gap: 0.25rem;
color: var(--color-foreground-red);
position: relative;
margin-top: 0.5rem;
}
</style>
<div>
@@ -108,7 +116,6 @@
<div style="width:100%; display: flex; align-items: center;">
<TextInput
{valid}
{validationMessage}
autofocus
disabled={submitInProgress}
bind:value={inputValue}
@@ -126,6 +133,11 @@
<IconSmall name="checkmark" />
</IconButton>
</div>
{#if !valid && validationMessage}
<div class="validation-message">
<IconSmall name="exclamation-circle" />{validationMessage}
</div>
{/if}
{:else}
<Badge
variant="outline"
+13 -2
View File
@@ -68,6 +68,14 @@
flex-direction: row;
gap: 0.5rem;
}
.validation-message {
display: flex;
align-items: center;
gap: 0.25rem;
color: var(--color-foreground-red);
position: relative;
margin-top: 0.5rem;
}
</style>
<div>
@@ -93,9 +101,7 @@
<TextInput
autofocus
{valid}
{validationMessage}
disabled={submitInProgress}
size="small"
placeholder="Add label"
bind:value={inputValue}
on:submit={addLabel} />
@@ -111,6 +117,11 @@
<IconSmall name="checkmark" />
</IconButton>
</div>
{#if !valid && validationMessage}
<div class="validation-message">
<IconSmall name="exclamation-circle" />{validationMessage}
</div>
{/if}
{:else}
<Badge
variant="outline"