fix(bulk-upload): add gradient overflow indicators to chip strip
Adds pointer-events-none left/right gradient fade overlays on the FileSwitcherStrip track div so mouse-only users can see when more chips are hidden beyond the visible area. The scrollbar is hidden (scrollbar-width:none) so gradients are the only overflow signal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,18 +83,26 @@ $effect(() => {
|
|||||||
>‹</button
|
>‹</button
|
||||||
>
|
>
|
||||||
|
|
||||||
<div bind:this={trackEl} class="flex flex-1 gap-1 overflow-x-auto" style="scrollbar-width:none">
|
<!-- Gradient fade overlays signal hidden overflow to pointer-only users -->
|
||||||
<ul bind:this={listEl} role="list" class="flex flex-row gap-1 py-1">
|
<div class="relative flex flex-1 overflow-hidden">
|
||||||
{#each files as entry, i (entry.id)}
|
<div
|
||||||
<li role="listitem" class="inline-flex shrink-0 items-center">
|
class="pointer-events-none absolute inset-y-0 left-0 z-10 w-6 bg-gradient-to-r from-pdf-ctrl to-transparent"
|
||||||
<button
|
></div>
|
||||||
type="button"
|
<div
|
||||||
tabindex="0"
|
class="pointer-events-none absolute inset-y-0 right-0 z-10 w-6 bg-gradient-to-l from-pdf-ctrl to-transparent"
|
||||||
aria-current={entry.id === activeId ? 'true' : undefined}
|
></div>
|
||||||
data-status={entry.status}
|
<div bind:this={trackEl} class="flex flex-1 gap-1 overflow-x-auto" style="scrollbar-width:none">
|
||||||
data-chip-id={entry.id}
|
<ul bind:this={listEl} role="list" class="flex flex-row gap-1 py-1">
|
||||||
onclick={() => onSelect(entry.id)}
|
{#each files as entry, i (entry.id)}
|
||||||
class={[
|
<li role="listitem" class="inline-flex shrink-0 items-center">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
tabindex="0"
|
||||||
|
aria-current={entry.id === activeId ? 'true' : undefined}
|
||||||
|
data-status={entry.status}
|
||||||
|
data-chip-id={entry.id}
|
||||||
|
onclick={() => onSelect(entry.id)}
|
||||||
|
class={[
|
||||||
'inline-flex cursor-pointer items-center gap-1 rounded-[2px] px-1.5 py-0.5 text-xs font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent',
|
'inline-flex cursor-pointer items-center gap-1 rounded-[2px] px-1.5 py-0.5 text-xs font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent',
|
||||||
entry.id === activeId
|
entry.id === activeId
|
||||||
? 'bg-accent text-primary'
|
? 'bg-accent text-primary'
|
||||||
@@ -103,32 +111,33 @@ $effect(() => {
|
|||||||
? '!border !border-dashed !border-red-400 !bg-red-50/80 !text-red-700'
|
? '!border !border-dashed !border-red-400 !bg-red-50/80 !text-red-700'
|
||||||
: ''
|
: ''
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class={[
|
class={[
|
||||||
'rounded-[2px] px-0.5 text-[11px] font-extrabold opacity-85',
|
'rounded-[2px] px-0.5 text-[11px] font-extrabold opacity-85',
|
||||||
entry.id === activeId ? 'bg-black/20' : 'bg-black/10'
|
entry.id === activeId ? 'bg-black/20' : 'bg-black/10'
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
>{i + 1}</span
|
>{i + 1}</span
|
||||||
|
>
|
||||||
|
<span class="max-w-[8rem] truncate" title={entry.title}>{entry.title}</span>
|
||||||
|
{#if entry.status === 'error'}
|
||||||
|
<span class="sr-only">{m.bulk_file_error_chip_label()}</span>
|
||||||
|
<span aria-hidden="true" class="ml-0.5 font-extrabold text-red-600">!</span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={m.bulk_remove_file()}
|
||||||
|
data-remove-id={entry.id}
|
||||||
|
onclick={() => handleRemove(entry, i)}
|
||||||
|
class="ml-0.5 flex h-[44px] w-[44px] items-center justify-center text-base text-ink-3 hover:text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
||||||
>
|
>
|
||||||
<span class="max-w-[8rem] truncate" title={entry.title}>{entry.title}</span>
|
×
|
||||||
{#if entry.status === 'error'}
|
</button>
|
||||||
<span class="sr-only">{m.bulk_file_error_chip_label()}</span>
|
</li>
|
||||||
<span aria-hidden="true" class="ml-0.5 font-extrabold text-red-600">!</span>
|
{/each}
|
||||||
{/if}
|
</ul>
|
||||||
</button>
|
</div>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
aria-label={m.bulk_remove_file()}
|
|
||||||
data-remove-id={entry.id}
|
|
||||||
onclick={() => handleRemove(entry, i)}
|
|
||||||
class="ml-0.5 flex h-[44px] w-[44px] items-center justify-center text-base text-ink-3 hover:text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-accent"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user