浏览代码

feat(web): UI/UX improvement for date time edit form (#5505)

Alex 1 年之前
父节点
当前提交
84c5b08c25

+ 7 - 1
web/src/lib/components/elements/dropdown.svelte

@@ -15,8 +15,12 @@
   import { fly } from 'svelte/transition';
   import { createEventDispatcher } from 'svelte';
 
+  let className = '';
+  export { className as class };
+
   const dispatch = createEventDispatcher<{
     select: T;
+    'click-outside': void;
   }>();
 
   export let options: T[];
@@ -36,6 +40,8 @@
     if (!controlable) {
       showMenu = false;
     }
+
+    dispatch('click-outside');
   };
 
   const handleSelectOption = (option: T) => {
@@ -76,7 +82,7 @@
   {#if showMenu}
     <div
       transition:fly={{ y: -30, x: 30, duration: 100 }}
-      class="text-md fixed z-50 flex min-w-[250px] max-h-[70vh] overflow-y-scroll immich-scrollbar flex-col rounded-2xl bg-gray-100 py-2 text-black shadow-lg dark:bg-gray-700 dark:text-white"
+      class="text-md fixed z-50 flex min-w-[250px] max-h-[70vh] overflow-y-scroll immich-scrollbar flex-col rounded-2xl bg-gray-100 py-2 text-black shadow-lg dark:bg-gray-700 dark:text-white {className}"
     >
       {#each options as option (option)}
         {@const renderedOption = renderOption(option)}

+ 25 - 6
web/src/lib/components/shared-components/change-date.svelte

@@ -59,12 +59,27 @@
       dispatch('confirm', value);
     }
   };
+
   const handleKeydown = (event: KeyboardEvent) => {
     if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
       event.stopPropagation();
     }
   };
+
   let isDropdownOpen = false;
+  let isSearching = false;
+
+  const onSearchFocused = () => {
+    isSearching = true;
+
+    openDropdown();
+  };
+
+  const onSearchBlurred = () => {
+    isSearching = false;
+
+    closeDropdown();
+  };
 
   const openDropdown = () => {
     isDropdownOpen = true;
@@ -84,42 +99,46 @@
   <ConfirmDialogue
     confirmColor="primary"
     cancelColor="secondary"
-    title="Change Date"
+    title="Edit date & time"
     prompt="Please select a new date:"
     {disabled}
     on:confirm={handleConfirm}
     on:cancel={handleCancel}
   >
-    <div class="flex flex-col text-md px-4 py-5 text-center gap-2" slot="prompt">
+    <div class="flex flex-col text-md px-4 text-center gap-2" slot="prompt">
       <div class="mt-2" />
       <div class="flex flex-col">
         <label for="datetime">Date and Time</label>
         <input
-          class="immich-form-label text-sm mt-2 w-full text-black"
+          class="text-sm my-4 w-full bg-gray-200 p-4 rounded-lg dark:text-white dark:bg-gray-600"
           id="datetime"
           type="datetime-local"
           bind:value={selectedDate}
         />
       </div>
-      <div class="flex flex-col w-full">
+      <div class="flex flex-col w-full mt-2">
         <label for="timezone">Timezone</label>
+
         <div class="relative">
           <input
-            class="immich-form-label text-sm mt-2 w-full text-black"
+            class="text-sm my-4 w-full bg-gray-200 p-3 rounded-lg dark:text-white dark:bg-gray-600"
             id="timezoneSearch"
             type="text"
             placeholder="Search timezone..."
             bind:value={searchQuery}
             on:input={updateSearchQuery}
-            on:focus={openDropdown}
+            on:focus={onSearchFocused}
+            on:blur={onSearchBlurred}
           />
           <Dropdown
+            class="h-[400px]"
             selectedOption={initialOption}
             options={filteredTimezones}
             render={(item) => (item ? `${item.zone} (${item.offset})` : '(not selected)')}
             on:select={({ detail: item }) => handleSelectTz(item)}
             controlable={true}
             bind:showMenu={isDropdownOpen}
+            on:click-outside={isSearching ? null : closeDropdown}
           />
         </div>
       </div>

+ 6 - 2
web/src/lib/components/shared-components/confirm-dialogue.svelte

@@ -13,7 +13,7 @@
   export let hideCancelButton = false;
   export let disabled = false;
 
-  const dispatch = createEventDispatcher<{ cancel: void; confirm: void }>();
+  const dispatch = createEventDispatcher<{ cancel: void; confirm: void; 'click-outside': void }>();
 
   let isConfirmButtonDisabled = false;
 
@@ -28,9 +28,13 @@
     isConfirmButtonDisabled = true;
     dispatch('confirm');
   };
+
+  const handleClickOutside = () => {
+    dispatch('click-outside');
+  };
 </script>
 
-<FullScreenModal on:clickOutside={handleCancel} on:escape={() => handleEscape()}>
+<FullScreenModal on:clickOutside={handleClickOutside} on:escape={() => handleEscape()}>
   <div
     class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
   >