fix(badges): fix search-result layout shift + unify empty/loading states
Scrollbar shift: - Add [scrollbar-gutter:stable] to #ae_main_content in events layout so a scrollbar appearing on first results load no longer reflows the centered search form (was shifting ~8px left on Linux) Empty/loading state consistency: - Move search_status prop into ae_comp__badge_obj_li so it can swap its own empty state: spinner + "Searching..." while a search is in progress, UserSearch icon + prompt text otherwise - Unify p-16 / size-3em / mb-2 / text-xl across all three states (initial load, searching, no results) so height never jumps between transitions - Pass search_status from +page.svelte to the component Transitions: - transition:fade on initial-load spinner div - transition:slide on Create/Upload badge button row (appears with edit mode) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -210,7 +210,7 @@ function clear_sess() {
|
||||
container m-auto flex h-full min-h-full
|
||||
w-full max-w-7xl
|
||||
min-w-full flex-col gap-1
|
||||
overflow-auto
|
||||
overflow-auto [scrollbar-gutter:stable]
|
||||
|
||||
bg-gray-50 text-gray-800
|
||||
dark:bg-gray-900 dark:text-gray-200
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from 'svelte';
|
||||
import { slide, fade } from 'svelte/transition';
|
||||
interface Props {
|
||||
/** @type {import('./$types').PageData} */
|
||||
data: any;
|
||||
@@ -472,7 +473,7 @@ async function handle_search_refresh(params: any) {
|
||||
></Comp_badge_search>
|
||||
|
||||
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||
<div class="flex flex-row gap-1 items-center justify-center">
|
||||
<div transition:slide={{ duration: 200 }} class="flex flex-row gap-1 items-center justify-center">
|
||||
{#if badges_loc.current.enable_add_badge_btn ?? true}
|
||||
<button
|
||||
type="button"
|
||||
@@ -593,12 +594,16 @@ async function handle_search_refresh(params: any) {
|
||||
|
||||
{#if $events_sess?.badges?.search_status === 'loading' && event_badge_id_li.length === 0}
|
||||
<div
|
||||
class="flex flex-col items-center justify-center p-10 text-center opacity-50">
|
||||
<LoaderCircle size="3em" class="mx-auto mb-4 animate-spin" />
|
||||
transition:fade={{ duration: 200 }}
|
||||
class="flex w-full flex-col items-center justify-center p-16 text-center opacity-50">
|
||||
<LoaderCircle size="3em" class="mx-auto mb-2 animate-spin" />
|
||||
<p class="text-xl">Loading badges...</p>
|
||||
</div>
|
||||
{:else}
|
||||
<Comp_badge_obj_li {lq__event_badge_obj_li} log_lvl={1}></Comp_badge_obj_li>
|
||||
<Comp_badge_obj_li
|
||||
{lq__event_badge_obj_li}
|
||||
search_status={$events_sess?.badges?.search_status ?? null}
|
||||
log_lvl={1} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
lq__event_badge_obj_li: any;
|
||||
search_status?: string | null;
|
||||
log_lvl?: number;
|
||||
show_sensitive_fields?: boolean;
|
||||
hide_affiliations?: boolean;
|
||||
@@ -12,6 +13,7 @@ interface Props {
|
||||
let {
|
||||
container_class_li = [],
|
||||
lq__event_badge_obj_li,
|
||||
search_status = null,
|
||||
log_lvl = $bindable(0),
|
||||
show_sensitive_fields = true,
|
||||
hide_affiliations = false,
|
||||
@@ -408,12 +410,16 @@ let visible_badge_obj_li = $derived(
|
||||
</ul>
|
||||
{:else}
|
||||
<div
|
||||
class="flex w-full flex-col items-center justify-center p-20 text-center opacity-50">
|
||||
<UserSearch size="3em" class="mx-auto mb-2 opacity-20" />
|
||||
{#if !is_trusted && !(badges_loc.current.fulltext_search_qry_str ?? '').trim()}
|
||||
<p>Enter your name above to find your badge.</p>
|
||||
class="flex w-full flex-col items-center justify-center p-16 text-center opacity-50">
|
||||
{#if search_status === 'loading'}
|
||||
<LoaderCircle size="3em" class="mx-auto mb-2 animate-spin" />
|
||||
<p class="text-xl">Searching...</p>
|
||||
{:else if !is_trusted && !(badges_loc.current.fulltext_search_qry_str ?? '').trim()}
|
||||
<UserSearch size="3em" class="mx-auto mb-2 opacity-20" />
|
||||
<p class="text-xl">Enter your name above to find your badge.</p>
|
||||
{:else}
|
||||
<p>No badges found matching your criteria. Try adjusting your filters.</p>
|
||||
<UserSearch size="3em" class="mx-auto mb-2 opacity-20" />
|
||||
<p class="text-xl">No badges found matching your criteria.</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user