setting-input-field.svelte 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <script lang="ts" context="module">
  2. export enum SettingInputFieldType {
  3. EMAIL = 'email',
  4. TEXT = 'text',
  5. NUMBER = 'number',
  6. PASSWORD = 'password',
  7. }
  8. </script>
  9. <script lang="ts">
  10. import { quintOut } from 'svelte/easing';
  11. import { fly } from 'svelte/transition';
  12. export let inputType: SettingInputFieldType;
  13. export let value: string | number;
  14. export let min = Number.MIN_SAFE_INTEGER.toString();
  15. export let max = Number.MAX_SAFE_INTEGER.toString();
  16. export let step = '1';
  17. export let label = '';
  18. export let desc = '';
  19. export let required = false;
  20. export let disabled = false;
  21. export let isEdited = false;
  22. const handleInput = (e: Event) => {
  23. value = (e.target as HTMLInputElement).value;
  24. if (inputType === SettingInputFieldType.NUMBER) {
  25. value = Number(value) || 0;
  26. }
  27. };
  28. </script>
  29. <div class="mb-4 w-full">
  30. <div class={`flex h-[26px] place-items-center gap-1`}>
  31. <label class={`immich-form-label text-sm`} for={label}>{label}</label>
  32. {#if required}
  33. <div class="text-red-400">*</div>
  34. {/if}
  35. {#if isEdited}
  36. <div
  37. transition:fly={{ x: 10, duration: 200, easing: quintOut }}
  38. class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
  39. >
  40. Unsaved change
  41. </div>
  42. {/if}
  43. </div>
  44. {#if desc}
  45. <p class="immich-form-label pb-2 text-sm" id="{label}-desc">
  46. {desc}
  47. </p>
  48. {:else}
  49. <slot name="desc" />
  50. {/if}
  51. <input
  52. class="immich-form-input w-full pb-2"
  53. aria-describedby={desc ? `${label}-desc` : undefined}
  54. aria-labelledby="{label}-label"
  55. id={label}
  56. name={label}
  57. type={inputType}
  58. {min}
  59. {max}
  60. {step}
  61. {required}
  62. {value}
  63. on:input={handleInput}
  64. {disabled}
  65. />
  66. </div>