|
1 | 1 | <script lang="ts"> |
2 | 2 | import { resource, useMutationObserver, watch } from "runed"; |
| 3 | + import LucideLoaderCircle from "~icons/lucide/loader-circle"; |
| 4 | + import LucideSearch from "~icons/lucide/search"; |
3 | 5 | import LucideX from "~icons/lucide/x"; |
4 | 6 | import { mod } from "../../lib/mod"; |
5 | 7 | import { scrollIntoView } from "../../lib/scroll-into-view"; |
|
117 | 119 |
|
118 | 120 | <!-- Remove transition to let search input autofocus; see https://github.com/saadeghi/daisyui/issues/3440 --> |
119 | 121 | <dialog bind:this={dialog} class="modal [transition:unset]"> |
120 | | - <div class="modal-box [transition:unset]"> |
| 122 | + <div class="modal-box max-w-2xl [transition:unset]"> |
121 | 123 | <form method="dialog"> |
122 | 124 | <button class="btn btn-sm btn-circle btn-ghost absolute top-2 right-2"> |
123 | 125 | <LucideX class="size-5" /> |
124 | 126 | </button> |
125 | 127 | </form> |
126 | 128 |
|
127 | | - <h3 class="text-lg font-bold">Search npm packages</h3> |
128 | | - |
129 | | - <label for="npm-package-search-input" class="sr-only">Search packages on npm</label> |
130 | | - <!-- svelte-ignore a11y_autofocus --> |
131 | | - <input |
132 | | - id="npm-package-search-input" |
133 | | - type="search" |
134 | | - autocomplete="off" |
135 | | - class="input w-full" |
136 | | - bind:value={query} |
137 | | - onkeydown={handleInputKeydown} |
138 | | - autofocus |
139 | | - /> |
140 | | - |
141 | | - <div class="mt-4 h-64 overflow-hidden overflow-y-auto"> |
142 | | - {#if results.loading} |
143 | | - <div>Searching npm...</div> |
144 | | - {:else if results.error} |
145 | | - <div>Error searching npm</div> |
146 | | - {:else if results.current.length > 0} |
147 | | - <ul bind:this={resultsList}> |
148 | | - {#each results.current as result, i (result.name)} |
149 | | - <li> |
150 | | - <a |
151 | | - class={[ |
152 | | - "hover:bg-base-content hover:text-base-300 flex flex-col rounded px-2 py-1", |
153 | | - i === resultsCursor && "bg-base-content text-base-300", |
154 | | - ]} |
155 | | - href="/package/{result.name}" |
156 | | - onclick={closeDialog} |
157 | | - > |
158 | | - <span class="truncate font-bold">{result.name}</span> |
159 | | - <span class="truncate text-sm">{result.description}</span> |
160 | | - </a> |
161 | | - </li> |
162 | | - {/each} |
163 | | - </ul> |
164 | | - {:else if results.current.length === 0 && query.length > 0} |
165 | | - <div |
166 | | - class="bg-base-content text-base-300 flex items-center justify-between gap-4 rounded px-2 py-1" |
167 | | - > |
168 | | - <span class="truncate">No results</span> |
169 | | - <span class="opacity-70">¯\_(ツ)_/¯</span> |
170 | | - </div> |
171 | | - {/if} |
| 129 | + <div class="grid gap-4"> |
| 130 | + <h3 class="text-lg font-bold">Search npm packages</h3> |
| 131 | + |
| 132 | + <label class="input w-full text-base"> |
| 133 | + <span class="sr-only">Search packages on npm</span> |
| 134 | + |
| 135 | + {#if results.loading} |
| 136 | + <LucideLoaderCircle class="size-4 animate-spin" /> |
| 137 | + {:else} |
| 138 | + <LucideSearch class="size-4" /> |
| 139 | + {/if} |
| 140 | + |
| 141 | + <!-- svelte-ignore a11y_autofocus --> |
| 142 | + <input |
| 143 | + type="search" |
| 144 | + autocomplete="off" |
| 145 | + bind:value={query} |
| 146 | + onkeydown={handleInputKeydown} |
| 147 | + autofocus |
| 148 | + /> |
| 149 | + </label> |
| 150 | + |
| 151 | + <div class="h-96 overflow-hidden overflow-y-auto"> |
| 152 | + {#if results.loading} |
| 153 | + <!-- Empty slot to clear area between searches --> |
| 154 | + {:else if results.error} |
| 155 | + <div>Error searching npm</div> |
| 156 | + {:else if results.current.length > 0} |
| 157 | + <ul bind:this={resultsList}> |
| 158 | + {#each results.current as result, i (result.name)} |
| 159 | + <li> |
| 160 | + <a |
| 161 | + class={[ |
| 162 | + "flex flex-col rounded px-2 py-1", |
| 163 | + i === resultsCursor && "bg-primary text-primary-content", |
| 164 | + i !== resultsCursor && "hover:bg-primary hover:text-primary-content/85", |
| 165 | + ]} |
| 166 | + href="/package/{result.name}" |
| 167 | + onclick={closeDialog} |
| 168 | + > |
| 169 | + <span class="truncate font-bold">{result.name}</span> |
| 170 | + <span class="truncate text-sm">{result.description}</span> |
| 171 | + </a> |
| 172 | + </li> |
| 173 | + {/each} |
| 174 | + </ul> |
| 175 | + {:else if results.current.length === 0 && query.length > 0} |
| 176 | + <div |
| 177 | + class="bg-primary text-primary-content flex items-center justify-between gap-4 rounded px-2 py-1" |
| 178 | + > |
| 179 | + <div class="flex flex-col"> |
| 180 | + <span class="truncate font-bold">No results</span> |
| 181 | + <span class="truncate text-sm">Try another query</span> |
| 182 | + </div> |
| 183 | + <span class="opacity-85">¯\_(ツ)_/¯</span> |
| 184 | + </div> |
| 185 | + {/if} |
| 186 | + </div> |
172 | 187 | </div> |
173 | 188 | </div> |
174 | 189 |
|
|
0 commit comments