diff options
| author | ivarlovlie <git@ivarlovlie.no> | 2022-09-28 17:05:08 +0200 |
|---|---|---|
| committer | ivarlovlie <git@ivarlovlie.no> | 2022-09-28 17:05:08 +0200 |
| commit | f24de70526d6cb20edfc21bf1ded9c7b405a4f3b (patch) | |
| tree | b22ec77eb255210a960e1fac020915034bae9366 /apps/kit/src/lib/components | |
| parent | aa79ab6d0e3699118aae0ffde6b2c19192b544d5 (diff) | |
| download | greatoffice-f24de70526d6cb20edfc21bf1ded9c7b405a4f3b.tar.xz greatoffice-f24de70526d6cb20edfc21bf1ded9c7b405a4f3b.zip | |
feat: Add input component
Diffstat (limited to 'apps/kit/src/lib/components')
| -rw-r--r-- | apps/kit/src/lib/components/icons/exclamation-circle.svelte | 13 | ||||
| -rw-r--r-- | apps/kit/src/lib/components/icons/index.ts | 3 | ||||
| -rw-r--r-- | apps/kit/src/lib/components/input.svelte | 121 |
3 files changed, 137 insertions, 0 deletions
diff --git a/apps/kit/src/lib/components/icons/exclamation-circle.svelte b/apps/kit/src/lib/components/icons/exclamation-circle.svelte new file mode 100644 index 0000000..2ce79b1 --- /dev/null +++ b/apps/kit/src/lib/components/icons/exclamation-circle.svelte @@ -0,0 +1,13 @@ +<svg + class="h-5 w-5 {$$restProps.class ?? ''}" + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 20" + fill="currentColor" + aria-hidden="true" +> + <path + fill-rule="evenodd" + d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" + clip-rule="evenodd" + /> +</svg> diff --git a/apps/kit/src/lib/components/icons/index.ts b/apps/kit/src/lib/components/icons/index.ts index b220f37..e846dc4 100644 --- a/apps/kit/src/lib/components/icons/index.ts +++ b/apps/kit/src/lib/components/icons/index.ts @@ -9,6 +9,8 @@ import XCircle from "./x-circle.svelte"; import CheckCircle from "./check-circle.svelte"; import XMark from "./x-mark.svelte"; import Spinner from "./spinner.svelte"; +import ExclamationCircle from "./exclamation-circle.svelte"; + export { XIcon, MenuIcon, @@ -17,6 +19,7 @@ export { AdjustmentsIcon, InformationCircle, ExclamationTriangle, + ExclamationCircle, XCircle, CheckCircle, XMark, 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> |
