aboutsummaryrefslogtreecommitdiffstats
path: root/apps/kit/src/lib/components/input.svelte
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2022-09-28 17:05:08 +0200
committerivarlovlie <git@ivarlovlie.no>2022-09-28 17:05:08 +0200
commitf24de70526d6cb20edfc21bf1ded9c7b405a4f3b (patch)
treeb22ec77eb255210a960e1fac020915034bae9366 /apps/kit/src/lib/components/input.svelte
parentaa79ab6d0e3699118aae0ffde6b2c19192b544d5 (diff)
downloadgreatoffice-f24de70526d6cb20edfc21bf1ded9c7b405a4f3b.tar.xz
greatoffice-f24de70526d6cb20edfc21bf1ded9c7b405a4f3b.zip
feat: Add input component
Diffstat (limited to 'apps/kit/src/lib/components/input.svelte')
-rw-r--r--apps/kit/src/lib/components/input.svelte121
1 files changed, 121 insertions, 0 deletions
diff --git a/apps/kit/src/lib/components/input.svelte b/apps/kit/src/lib/components/input.svelte
new file mode 100644
index 0000000..0847f3e
--- /dev/null
+++ b/apps/kit/src/lib/components/input.svelte
@@ -0,0 +1,121 @@
+<script lang="ts">
+ import { random_string } from "$lib/helpers";
+ import { ExclamationCircle } from "./icons";
+
+ export let label: string | undefined = undefined;
+ export let type: string = "text";
+ export let id: string | undefined = "input__" + random_string(4);
+ export let name: string | undefined = undefined;
+ export let placeholder: string | undefined = undefined;
+ export let helpText: string | undefined = undefined;
+ export let errorText: string | undefined = undefined;
+ export let disabled = false;
+ export let hideLabel = false;
+ export let cornerHint: string | undefined = undefined;
+ export let icon: any = undefined;
+ export let addon: string | undefined = undefined;
+ export let value: string | undefined;
+
+ $: ariaErrorDescribedBy = id + "__" + "error";
+ $: attributes = {
+ "aria-describedby": errorText ? ariaErrorDescribedBy : null,
+ "aria-invalid": errorText ? "true" : null,
+ disabled: disabled || null,
+ } as any;
+ $: hasBling = icon || addon || errorText;
+ const defaultColorClass =
+ "border-gray-300 focus:border-teal-500 focus:ring-teal-500";
+ let colorClass = defaultColorClass;
+ $: if (errorText) {
+ colorClass =
+ "placeholder-red-300 focus:border-red-500 focus:outline-none focus:ring-red-500 text-red-900 pr-10 border-red-300";
+ } else {
+ colorClass = defaultColorClass;
+ }
+
+ function typeAction(node: HTMLInputElement) {
+ node.type = type;
+ }
+</script>
+
+<div>
+ {#if label && !cornerHint && !hideLabel}
+ <label
+ for={id}
+ class={hideLabel
+ ? "sr-only"
+ : "block text-sm font-medium text-gray-700"}
+ >
+ {label}
+ </label>
+ {:else if cornerHint && !hideLabel}
+ <div class="flex justify-between">
+ {#if label}
+ <label
+ for={id}
+ class={hideLabel
+ ? "sr-only"
+ : "block text-sm font-medium text-gray-700"}
+ >
+ {label}
+ </label>
+ {/if}
+ <span class="text-sm text-gray-500">
+ {cornerHint}
+ </span>
+ </div>
+ {/if}
+ <div
+ class="mt-1 {hasBling ? 'relative rounded-md' : ''} {addon
+ ? 'flex'
+ : ''}"
+ >
+ {#if icon}
+ <div
+ class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3"
+ >
+ <svelte:component
+ this={icon}
+ class={errorText ? "text-red-500" : "text-gray-400"}
+ />
+ </div>
+ {:else if addon}
+ <div
+ class="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 bg-gray-50 px-3 text-gray-500 sm:text-sm"
+ >
+ <span class="text-gray-500 sm:text-sm">{addon}</span>
+ </div>
+ {/if}
+ <input
+ use:typeAction
+ {name}
+ {id}
+ {...attributes}
+ bind:value
+ class="block w-full rounded-md shadow-sm sm:text-sm {colorClass} {disabled
+ ? 'disabled:cursor-not-allowed disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500'
+ : ''}
+ {addon ? 'min-w-0 flex-1 rounded-none rounded-r-md' : ''} {icon
+ ? 'pl-10'
+ : ''}"
+ {placeholder}
+ />
+ {#if errorText}
+ <div
+ class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"
+ >
+ <ExclamationCircle class="text-red-500" />
+ </div>
+ {/if}
+ </div>
+ {#if helpText && !errorText}
+ <p class="mt-2 text-sm text-gray-500">
+ {helpText}
+ </p>
+ {/if}
+ {#if errorText}
+ <p class="mt-2 text-sm text-red-600" id={ariaErrorDescribedBy}>
+ {errorText}
+ </p>
+ {/if}
+</div>