style(ui): unify view toggles at h-8 and View all buttons

Extract a shared view-toggle utility so list/grid switchers use the same 32px control height instead of mixed h-8/h-9 styles. Point section-heading View all links at the shared button class so they match other actions.
This commit is contained in:
Andras Bacsai
2026-09-10 08:40:41 +02:00
parent fbb569a4b3
commit 285684ad3c
13 changed files with 51 additions and 11 deletions
+4
View File
@@ -137,6 +137,10 @@
@apply bg-linear-to-b from-coollabs-100 to-coollabs-200 text-white;
}
@utility view-toggle {
@apply flex h-8 items-center rounded-lg border border-neutral-200 bg-white dark:border-white/[0.08] dark:bg-white/[0.06];
}
@utility loading-indicator {
@apply text-coollabs dark:text-warning;
}
@@ -8,7 +8,7 @@
{{--
Shared section heading: a 14px title, an optional 11px muted subtitle, and an
optional right-aligned action. Pass `href` for the default ghost "View all"
optional right-aligned action. Pass `href` for the default "View all"
button, or an `<x-slot:actions>` for a custom control.
--}}
<div {{ $attributes->merge(['class' => 'mb-3 min-w-0']) }}>
@@ -20,7 +20,7 @@
<div class="shrink-0">{{ $actions }}</div>
@elseif (filled($href))
<a href="{{ $href }}" {{ wireNavigate() }}
class="group inline-flex h-7 shrink-0 items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2.5 text-[12px] font-medium text-neutral-600 transition-[color,background-color,transform] duration-100 ease-out hover:bg-neutral-100 hover:text-black active:scale-[0.97] dark:border-white/[0.08] dark:bg-white/[0.06] dark:text-fg-dim dark:hover:bg-white/[0.1] dark:hover:text-fg">
class="button group">
{{ $actionLabel }}
@if ($icon)
<x-reicon :name="$icon" class="size-3 opacity-70 transition-transform duration-150 ease-out group-hover:translate-x-0.5" />
@@ -14,7 +14,7 @@
</div>
<div
class="flex h-9 w-fit items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.035]">
class="view-toggle w-fit">
<button type="button" @click="viewMode = 'list'; localStorage.setItem('{{ $storageKey }}', 'list')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'list' ? 'control-selected' : 'text-neutral-400 hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg'"
@@ -76,7 +76,7 @@
</x-table.dropdown>
<div
class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.06]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -142,7 +142,7 @@
</x-table.dropdown>
<div
class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.06]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -117,7 +117,7 @@
</div>
<div class="flex w-full items-center justify-between gap-2 sm:w-auto sm:justify-start">
<div
class="flex h-8 items-center rounded-lg border border-neutral-200 bg-white dark:border-white/[0.08] dark:bg-white/[0.06]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -96,7 +96,7 @@
</x-table.dropdown>
<div
class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.06]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -104,7 +104,7 @@
<span x-text="filteredServers.length === 1 ? 'server' : 'servers'"></span>
</span>
<div
class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.035]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -6,7 +6,7 @@
</div>
<div class="flex items-center gap-3">
<span class="text-[11px] text-neutral-500 dark:text-fg-faint"><span x-text="filteredItems.length"></span> <span x-text="filteredItems.length === 1 ? '{{ $singular }}' : '{{ $plural }}'"></span></span>
<div class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.035]">
<div class="view-toggle">
<button type="button" x-on:click="setViewMode('table')" class="flex size-7.5 items-center justify-center rounded-md transition-colors" :class="viewMode === 'table' ? 'control-selected' : 'text-neutral-400 hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg'" aria-label="Table view"><x-reicon name="unordered-list" class="size-3.5" /></button>
<button type="button" x-on:click="setViewMode('grid')" class="flex size-7.5 items-center justify-center rounded-md transition-colors" :class="viewMode === 'grid' ? 'control-selected' : 'text-neutral-400 hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg'" aria-label="Grid view"><x-reicon name="grid" class="size-3.5" /></button>
</div>
+1 -1
View File
@@ -69,7 +69,7 @@
</x-table.dropdown>
<div
class="flex h-9 items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.035]">
class="view-toggle">
<button type="button" x-on:click="setViewMode('table')"
class="flex size-7.5 items-center justify-center rounded-md transition-colors"
:class="viewMode === 'table'
@@ -17,3 +17,11 @@ test('dashboard navbar keeps the original side-by-side tab and actions layout',
->toContain('flex w-full flex-col gap-2 sm:flex-row sm:items-center sm:justify-between')
->toContain('flex min-w-0 w-full items-center gap-0.5 overflow-x-auto');
});
test('dashboard view all links use the shared button style', function () {
$contents = file_get_contents(resource_path('views/components/section-heading.blade.php'));
expect($contents)
->toContain('class="button group"')
->not->toContain('class="group inline-flex h-7');
});
@@ -12,7 +12,7 @@ it('provides grid and table views for compose resources without sorting controls
->toContain('aria-label="Grid view"')
->toContain('mb-3 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between')
->toContain('flex w-full items-center justify-between gap-2 sm:w-auto sm:justify-start')
->toContain('flex h-8 items-center rounded-lg border border-neutral-200 bg-white')
->toContain('class="view-toggle"')
->not->toContain('flex h-9 items-center rounded-lg border border-neutral-200 bg-white')
->toContain("localStorage.setItem('service-compose-resources-view', mode)")
->not->toContain('>Sort</button>')
+28
View File
@@ -0,0 +1,28 @@
<?php
it('uses the shared button-height view toggle on every list and grid page', function () {
$paths = [
'views/components/shared-variables/view-controls.blade.php',
'views/livewire/project/index.blade.php',
'views/livewire/project/resource/index.blade.php',
'views/livewire/project/service/configuration.blade.php',
'views/livewire/project/show.blade.php',
'views/livewire/server/index.blade.php',
'views/livewire/shared/list-search-controls.blade.php',
'views/livewire/tags/show.blade.php',
];
foreach ($paths as $path) {
$contents = file_get_contents(resource_path($path));
expect($contents)
->toContain('class="view-toggle')
->not->toContain('class="flex h-9 items-center rounded-lg border');
}
$utilities = file_get_contents(resource_path('css/utilities.css'));
expect($utilities)
->toContain('@utility view-toggle')
->toContain('h-8');
});