Skip to content

Commit 8ebb8cc

Browse files
fix: table header height consistency and button loading height (#20249)
* fix: table header height consistency and button loading height * fix button loading height with `align-middle` and scope header action margins to `sm` * apply header action negative margins to the container so wrapped rows keep their gap * remove vestigial `-mt-px` from table header so its optics match a section header * keep the table heading visible while reordering, only hiding the header actions * remove reordering header test * pin link and badge baselines to their labels so loading indicators do not shift them in inline flow * wrap the link label in optimized rendering paths to match the Blade component --------- Co-authored-by: Dan Harrin <git@danharrin.com>
1 parent 16ed789 commit 8ebb8cc

10 files changed

Lines changed: 59 additions & 30 deletions

File tree

packages/actions/src/Action.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -890,13 +890,13 @@ protected function toOptimizedLinkHtml(): string
890890
$iconHtml = $icon ? generate_icon_html($icon, size: IconSize::Small)?->toHtml() : '';
891891
$hrefHtml = generate_href_html($url)->toHtml();
892892

893-
return "<a {$hrefHtml}{$wireKeyAttribute} class=\"{$classString}\"{$styleString}>{$iconHtml}{$label}</a>";
893+
return "<a {$hrefHtml}{$wireKeyAttribute} class=\"{$classString}\"{$styleString}>{$iconHtml}<span class=\"fi-link-label\">{$label}</span></a>";
894894
}
895895

896896
$handler = $this->getLivewireClickHandler();
897897

898898
if (blank($handler)) {
899-
return "<span{$wireKeyAttribute} class=\"{$classString}\"{$styleString}>{$label}</span>";
899+
return "<span{$wireKeyAttribute} class=\"{$classString}\"{$styleString}><span class=\"fi-link-label\">{$label}</span></span>";
900900
}
901901

902902
$loadingDelay = config('filament.livewire_loading_delay', 'default');
@@ -921,7 +921,7 @@ protected function toOptimizedLinkHtml(): string
921921
// Match `ComponentAttributeBag::__toString()` attribute escaping (only `"` → `\"`).
922922
$handler = str_replace('"', '\\"', $handler);
923923

924-
return "<button type=\"button\" wire:loading.attr=\"disabled\" wire:click=\"{$handler}\"{$wireKeyAttribute} class=\"{$classString}\"{$styleString}>{$iconHtml}{$loadingHtml}{$label}</button>";
924+
return "<button type=\"button\" wire:loading.attr=\"disabled\" wire:click=\"{$handler}\"{$wireKeyAttribute} class=\"{$classString}\"{$styleString}>{$iconHtml}{$loadingHtml}<span class=\"fi-link-label\">{$label}</span></button>";
925925
}
926926

927927
protected function canRenderOptimizedGrouped(): bool

packages/panels/dist/theme.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/support/resources/css/components/badge.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
}
1515
}
1616

17+
/* Pinning the badge's baseline to the label keeps it aligned with surrounding text, even when the loading indicator is the first flex item. */
1718
& .fi-badge-label-ctn {
18-
@apply grid;
19+
@apply grid self-baseline;
1920
}
2021

2122
& .fi-badge-label {

packages/support/resources/css/components/button.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.fi-btn {
2-
@apply relative inline-grid grid-flow-col items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium transition duration-75 outline-none;
2+
/* `align-middle` keeps the button's placement in inline flow independent of its internal baseline, which shifts when the loading indicator is the first grid item. */
3+
@apply relative inline-grid grid-flow-col items-center justify-center gap-1.5 rounded-lg px-3 py-2 align-middle text-sm font-medium transition duration-75 outline-none;
34

45
&.fi-force-enabled,
56
&:not(.fi-disabled):not([disabled]) {

packages/support/resources/css/components/link.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
.fi-link {
22
@apply relative inline-flex items-center justify-center gap-1.5 font-medium text-gray-700 outline-none dark:text-gray-200;
33

4+
/* Pinning the link's baseline to the label keeps it aligned with surrounding text, even when the loading indicator is the first flex item. */
5+
& > .fi-link-label {
6+
@apply self-baseline;
7+
}
8+
49
&.fi-force-enabled,
510
&:not(.fi-disabled):not([disabled]) {
611
@apply hover:underline focus-visible:rounded-sm focus-visible:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current;

packages/support/resources/css/components/section.css

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -187,26 +187,25 @@
187187
@apply leading-6;
188188
}
189189

190-
& .fi-btn:not(.fi-section-header-after-ctn .fi-dropdown-panel *) {
191-
&.fi-size-xs {
192-
@apply -my-0.5;
193-
}
190+
/* The negative margins let the buttons overhang the header's vertical padding, so a header with actions matches the height of one without them. They are applied to the container instead of the buttons so wrapped rows of actions keep their gap, laddered so the largest button size present wins. */
191+
&:has(.fi-btn.fi-size-xs:not(.fi-dropdown-panel *)) {
192+
@apply -my-0.5;
193+
}
194194

195-
&.fi-size-sm {
196-
@apply -my-1;
197-
}
195+
&:has(.fi-btn.fi-size-sm:not(.fi-dropdown-panel *)) {
196+
@apply -my-1;
197+
}
198198

199-
&.fi-size-md {
200-
@apply -my-1.5;
201-
}
199+
&:has(.fi-btn.fi-size-md:not(.fi-dropdown-panel *)) {
200+
@apply -my-1.5;
201+
}
202202

203-
&.fi-size-lg {
204-
@apply -my-2;
205-
}
203+
&:has(.fi-btn.fi-size-lg:not(.fi-dropdown-panel *)) {
204+
@apply -my-2;
205+
}
206206

207-
&.fi-size-xl {
208-
@apply -my-2.5;
209-
}
207+
&:has(.fi-btn.fi-size-xl:not(.fi-dropdown-panel *)) {
208+
@apply -my-2.5;
210209
}
211210
}
212211

packages/support/resources/views/components/link.blade.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@
140140
@endif
141141

142142
@if (! $labelSrOnly)
143-
{{ $slot }}
143+
<span class="fi-link-label">
144+
{{ $slot }}
145+
</span>
144146
@endif
145147

146148
@if ($iconPosition === IconPosition::After)

packages/support/src/View/Concerns/CanGenerateLinkHtml.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ public function generateLinkHtml(
169169
<?php } ?>
170170

171171
<?php if (! $isLabelSrOnly) { ?>
172-
<?= e($label) ?>
172+
<span class="fi-link-label">
173+
<?= e($label) ?>
174+
</span>
173175
<?php } ?>
174176

175177
<?php if ($iconPosition === IconPosition::After) { ?>

packages/tables/resources/css/container.css

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
@apply animate-pulse;
1010
}
1111

12-
& .fi-ta-header-ctn {
13-
@apply -mt-px;
14-
}
15-
1612
& .fi-ta-header {
1713
@apply flex flex-col gap-3 border-b border-gray-200 p-4 sm:px-6 dark:border-white/10;
1814

@@ -32,6 +28,29 @@
3228
}
3329
}
3430

31+
& .fi-ta-actions {
32+
/* The negative margins let the buttons overhang the header's vertical padding, so a header with actions matches the height of one without them. They are applied to the container instead of the buttons so wrapped rows of actions keep their gap, laddered so the largest button size present wins, and scoped to `sm` since the header stacks vertically below it. */
33+
&:has(.fi-btn.fi-size-xs:not(.fi-dropdown-panel *)) {
34+
@apply sm:-my-0.5;
35+
}
36+
37+
&:has(.fi-btn.fi-size-sm:not(.fi-dropdown-panel *)) {
38+
@apply sm:-my-1;
39+
}
40+
41+
&:has(.fi-btn.fi-size-md:not(.fi-dropdown-panel *)) {
42+
@apply sm:-my-1.5;
43+
}
44+
45+
&:has(.fi-btn.fi-size-lg:not(.fi-dropdown-panel *)) {
46+
@apply sm:-my-2;
47+
}
48+
49+
&:has(.fi-btn.fi-size-xl:not(.fi-dropdown-panel *)) {
50+
@apply sm:-my-2.5;
51+
}
52+
}
53+
3554
& .fi-ta-header-heading {
3655
@apply text-base leading-6 font-semibold text-gray-950 dark:text-white;
3756
}

packages/tables/resources/views/index.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,11 @@ class="fi-ta-header-ctn"
272272

273273
@if ($header)
274274
{{ $header }}
275-
@elseif (($heading || $description || $headerActions) && ! $isReordering)
275+
@elseif ($heading || $description || ($headerActions && (! $isReordering)))
276276
<div
277277
@class([
278278
'fi-ta-header',
279-
'fi-ta-header-adaptive-actions-position' => $headerActions && ($headerActionsPosition === HeaderActionsPosition::Adaptive),
279+
'fi-ta-header-adaptive-actions-position' => $headerActions && (! $isReordering) && ($headerActionsPosition === HeaderActionsPosition::Adaptive),
280280
])
281281
>
282282
@if ($heading || $description)

0 commit comments

Comments
 (0)