setting-input-field.svelte 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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 label = '';
  15. export let desc = '';
  16. export let required = false;
  17. export let disabled = false;
  18. export let isEdited = false;
  19. const handleInput = (e: Event) => {
  20. value = (e.target as HTMLInputElement).value;
  21. if (inputType === SettingInputFieldType.NUMBER) {
  22. value = Number(value) || 0;
  23. }
  24. };
  25. </script>
  26. <div class="w-full">
  27. <div class={`flex place-items-center gap-1 h-[26px]`}>
  28. <label class={`immich-form-label text-sm`} for={label}>{label}</label>
  29. {#if required}
  30. <div class="text-red-400">*</div>
  31. {/if}
  32. {#if isEdited}
  33. <div
  34. transition:fly={{ x: 10, duration: 200, easing: quintOut }}
  35. class="bg-orange-100 px-2 rounded-full text-orange-900 text-[10px]"
  36. >
  37. Unsaved change
  38. </div>
  39. {/if}
  40. </div>
  41. {#if desc}
  42. <p class="immich-form-label text-xs pb-2" id="{label}-desc">
  43. {desc}
  44. </p>
  45. {/if}
  46. <input
  47. class="immich-form-input pb-2 w-full"
  48. aria-describedby={desc ? `${label}-desc` : undefined}
  49. aria-labelledby="{label}-label"
  50. id={label}
  51. name={label}
  52. type={inputType}
  53. {required}
  54. {value}
  55. on:input={handleInput}
  56. {disabled}
  57. />
  58. </div>