fix(files): responsive file rows + restore button cursor (v0.9.55)
- File manager: on tablet widths the lg table grid squeezed the name column (minmax(0,1fr)) to near-zero behind the perms/size/modified columns + wide action buttons, so the filename was unreadable/overlapped. The rows now render as a stacked card below xl — name on its own full-width line, a folded perms·size·modified line and the actions beneath — and only switch to the table grid at xl (tightened columns). Mobile tidied up to match. - Restore the pointer cursor: Tailwind v4's preflight makes buttons use the default cursor, so clickable controls (folder names, every button) didn't show a hand. Added a base rule giving enabled button/[role=button]/summary/label the pointer cursor. Verified the row at desktop / tablet / mobile widths (name readable at every breakpoint, table only when wide). 374 tests pass (the Livewire test renders the blade), Tailwind build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/v1-foundation v0.9.55
parent
359aa86aea
commit
8914f5f746
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -13,7 +13,17 @@ getaggte Releases (Kanal `stable`, optional `beta`) — niemals Entwicklungs-Bui
|
|||
|
||||
_Keine offenen Änderungen — der nächste Stand wird hier gesammelt und als `vX.Y.Z` getaggt._
|
||||
|
||||
## [0.9.54] - 2026-06-22
|
||||
## [0.9.55] - 2026-06-22
|
||||
|
||||
### Behoben
|
||||
- **Datei-Manager: Dateiname im Tablet-Modus vom Rechte-Block überdeckt.** Die Tabellenspalten
|
||||
(Rechte/Größe/Geändert) + Aktions-Buttons quetschten die Namensspalte auf nahezu null. Die Liste
|
||||
rendert jetzt **unterhalb großer Bildschirme als gestapelte Karte** (Name in voller Breite, Meta-Zeile
|
||||
und Aktionen darunter); die Tabellenansicht erscheint erst auf breiten Displays. Die mobile Ansicht
|
||||
wurde dabei mit aufgeräumt.
|
||||
- **Zeiger-Cursor auf Buttons fehlte.** Tailwind v4 stellt Buttons standardmäßig auf den
|
||||
Standard-Cursor; auf anklickbaren Elementen (z. B. Ordnernamen, alle Buttons) erscheint jetzt wieder
|
||||
der Hand-Zeiger.
|
||||
|
||||
### Behoben
|
||||
- **Datei-Manager: „undefined is not valid JSON" beim Öffnen mancher Dateien.** Öffnete man eine
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
return [
|
||||
// First tagged release is v0.1.0 (semantic, not -dev).
|
||||
'version' => '0.9.54',
|
||||
'version' => '0.9.55',
|
||||
|
||||
// Deployed commit + branch. install.sh bakes these into .env from the host's .git (the prod
|
||||
// image ships no .git); the Versions page prefers them and falls back to a live .git read in
|
||||
|
|
|
|||
|
|
@ -112,6 +112,15 @@
|
|||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Tailwind v4's preflight makes buttons use the default cursor — restore the pointer on
|
||||
enabled interactive controls so clickable elements feel clickable (e.g. folder names). */
|
||||
button:not(:disabled),
|
||||
[role="button"]:not([aria-disabled="true"]),
|
||||
summary,
|
||||
label[for] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* keyboard focus — visible token ring on the dark UI (a11y) */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-accent);
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@
|
|||
</label>
|
||||
</x-slot:actions>
|
||||
|
||||
{{-- Column header (desktop only) --}}
|
||||
<div class="hidden border-b border-line px-4 py-2 sm:px-5 lg:grid lg:grid-cols-[minmax(0,1fr)_8rem_6rem_11rem_auto] lg:items-center lg:gap-4">
|
||||
{{-- Column header (wide desktop only — below xl the rows render as stacked cards) --}}
|
||||
<div class="hidden border-b border-line px-4 py-2 sm:px-5 xl:grid xl:grid-cols-[minmax(0,1fr)_7rem_5rem_10rem_auto] xl:items-center xl:gap-4">
|
||||
<span class="font-mono text-[10px] uppercase tracking-wider text-ink-4">{{ __('files.col_name') }}</span>
|
||||
<span class="font-mono text-[10px] uppercase tracking-wider text-ink-4">{{ __('files.col_perms') }}</span>
|
||||
<span class="text-right font-mono text-[10px] uppercase tracking-wider text-ink-4">{{ __('files.col_size') }}</span>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
<div class="flex items-center gap-3 px-4 py-3 sm:px-5">
|
||||
<x-skeleton class="h-8 w-8 rounded-sm" />
|
||||
<x-skeleton class="h-3 w-48 max-w-full" />
|
||||
<x-skeleton class="ml-auto hidden h-3 w-24 lg:block" />
|
||||
<x-skeleton class="ml-auto hidden h-3 w-24 xl:block" />
|
||||
</div>
|
||||
@endfor
|
||||
@else
|
||||
|
|
@ -80,8 +80,10 @@
|
|||
@php $isDir = $e['type'] === 'dir'; @endphp
|
||||
{{-- Stable wire:key per row: without it Livewire's morph clones nodes by position and
|
||||
the inline Alpine x-data (modalTrigger) loses its scope → "pending is not defined". --}}
|
||||
{{-- Below xl: a stacked card (name on its own full-width line, meta + actions beneath) so
|
||||
the filename is never squeezed by the meta/action columns. xl+: a real table grid. --}}
|
||||
<div wire:key="fe-{{ md5($e['type'].'/'.$e['name']) }}"
|
||||
class="group grid grid-cols-1 gap-x-4 gap-y-2 px-4 py-3 transition-colors hover:bg-raised sm:px-5 lg:grid-cols-[minmax(0,1fr)_8rem_6rem_11rem_auto] lg:items-center">
|
||||
class="group px-4 py-3 transition-colors hover:bg-raised sm:px-5 xl:grid xl:grid-cols-[minmax(0,1fr)_7rem_5rem_10rem_auto] xl:items-center xl:gap-4">
|
||||
{{-- Name + icon (directories look clickable) --}}
|
||||
<div class="flex min-w-0 items-center gap-3">
|
||||
<span @class([
|
||||
|
|
@ -94,7 +96,7 @@
|
|||
|
||||
@if ($isDir)
|
||||
<button type="button" wire:click="open({{ $loop->index }})" class="min-w-0 flex-1 text-left">
|
||||
<span class="truncate font-mono text-sm text-ink group-hover:text-accent-text">{{ $e['name'] }}/</span>
|
||||
<span class="block truncate font-mono text-sm text-ink group-hover:text-accent-text">{{ $e['name'] }}/</span>
|
||||
</button>
|
||||
@else
|
||||
{{-- Filename opens the editor modal too — inline modalTrigger keeps the
|
||||
|
|
@ -110,26 +112,22 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Permissions (hidden on mobile; shown inline below name on tablet+) --}}
|
||||
<p class="hidden font-mono text-xs text-ink-3 lg:block">{{ $e['perms'] }}</p>
|
||||
{{-- Meta as real table cells (xl only) --}}
|
||||
<p class="hidden truncate font-mono text-xs text-ink-3 xl:block">{{ $e['perms'] }}</p>
|
||||
<p class="hidden font-mono text-xs text-ink-3 xl:block xl:text-right">{{ $fmtSize($e['size']) }}</p>
|
||||
<p class="hidden truncate font-mono text-xs text-ink-3 xl:block">{{ $e['modified'] }}</p>
|
||||
|
||||
{{-- Size (hidden on mobile) --}}
|
||||
<p class="hidden font-mono text-xs text-ink-3 sm:block lg:text-right">{{ $fmtSize($e['size']) }}</p>
|
||||
|
||||
{{-- Modified --}}
|
||||
<p class="hidden font-mono text-xs text-ink-3 sm:block">{{ $e['modified'] }}</p>
|
||||
|
||||
{{-- Compact meta line for mobile (perms · size · modified) --}}
|
||||
<p class="flex flex-wrap items-center gap-x-2 font-mono text-[11px] text-ink-4 sm:hidden">
|
||||
{{-- Folded meta line under the name (mobile + tablet) --}}
|
||||
<p class="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 pl-11 font-mono text-[11px] text-ink-4 xl:hidden">
|
||||
<span>{{ $e['perms'] }}</span>
|
||||
<span>·</span>
|
||||
<span class="opacity-50">·</span>
|
||||
<span>{{ $fmtSize($e['size']) }}</span>
|
||||
<span>·</span>
|
||||
<span class="opacity-50">·</span>
|
||||
<span>{{ $e['modified'] }}</span>
|
||||
</p>
|
||||
|
||||
{{-- Row actions --}}
|
||||
<div class="flex shrink-0 items-center gap-1 lg:justify-end">
|
||||
<div class="mt-2.5 flex flex-wrap items-center gap-1.5 pl-11 xl:mt-0 xl:justify-end xl:gap-1 xl:pl-0">
|
||||
@unless ($isDir)
|
||||
<x-btn variant="secondary" wire:click="download({{ $loop->index }})">{{ __('files.download') }}</x-btn>
|
||||
<x-modal-trigger variant="secondary" action="edit({{ $loop->index }})">{{ __('common.edit') }}</x-modal-trigger>
|
||||
|
|
|
|||
Loading…
Reference in New Issue