mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
Merge pull request #15398 from filamentphp/dynamic-heading-levels
Dynamic heading levels
This commit is contained in:
@@ -567,7 +567,8 @@ trait InteractsWithActions
|
||||
->take($actionNestingIndex + 1)
|
||||
->pluck('name')
|
||||
->implode('.'),
|
||||
),
|
||||
)
|
||||
->rootHeadingLevel(3),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
$blockLabelHeadingTag = $getHeadingTag();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
@@ -157,7 +159,7 @@
|
||||
@endif
|
||||
|
||||
@if ($hasBlockLabels)
|
||||
<h4
|
||||
<{{ $blockLabelHeadingTag }}
|
||||
@class([
|
||||
'text-sm font-medium text-gray-950 dark:text-white',
|
||||
'truncate' => $isBlockLabelTruncated(),
|
||||
@@ -168,7 +170,7 @@
|
||||
@if ($hasBlockNumbers)
|
||||
{{ $loop->iteration }}
|
||||
@endif
|
||||
</h4>
|
||||
</{{ $blockLabelHeadingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
$itemLabelHeadingTag = $getHeadingTag();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
@@ -147,14 +149,14 @@
|
||||
@endif
|
||||
|
||||
@if (filled($itemLabel))
|
||||
<h4
|
||||
<{{ $itemLabelHeadingTag }}
|
||||
@class([
|
||||
'text-sm font-medium text-gray-950 dark:text-white',
|
||||
'truncate' => $isItemLabelTruncated(),
|
||||
])
|
||||
>
|
||||
{{ $itemLabel }}
|
||||
</h4>
|
||||
</{{ $itemLabelHeadingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
|
||||
@@ -1134,4 +1134,13 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions
|
||||
{
|
||||
return $this->getChildComponentContainer($uuid)->getRawState();
|
||||
}
|
||||
|
||||
public function getHeadingsCount(): int
|
||||
{
|
||||
if (! $this->hasBlockLabels()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1315,4 +1315,13 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction
|
||||
{
|
||||
return $this->getChildComponentContainer($uuid)->getRawState();
|
||||
}
|
||||
|
||||
public function getHeadingsCount(): int
|
||||
{
|
||||
if (! $this->hasItemLabels()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
:footer="$getChildComponentContainer($schemaComponent::FOOTER_CONTAINER)?->toHtmlString()"
|
||||
:has-content-el="false"
|
||||
:heading="$getHeading()"
|
||||
:heading-tag="$getHeadingTag()"
|
||||
:icon="$getIcon()"
|
||||
:icon-color="$getIconColor()"
|
||||
:icon-size="$getIconSize()"
|
||||
|
||||
@@ -16,6 +16,7 @@ use Filament\Schemas\Components\Concerns\HasActions;
|
||||
use Filament\Schemas\Components\Concerns\HasChildComponents;
|
||||
use Filament\Schemas\Components\Concerns\HasEntryWrapper;
|
||||
use Filament\Schemas\Components\Concerns\HasFieldWrapper;
|
||||
use Filament\Schemas\Components\Concerns\HasHeadings;
|
||||
use Filament\Schemas\Components\Concerns\HasId;
|
||||
use Filament\Schemas\Components\Concerns\HasInlineLabel;
|
||||
use Filament\Schemas\Components\Concerns\HasKey;
|
||||
@@ -55,6 +56,7 @@ class Component extends ViewComponent
|
||||
use HasExtraAttributes;
|
||||
use HasFieldWrapper;
|
||||
use HasGap;
|
||||
use HasHeadings;
|
||||
use HasId;
|
||||
use HasInlineLabel;
|
||||
use HasKey;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Schemas\Components\Concerns;
|
||||
|
||||
trait HasHeadings
|
||||
{
|
||||
public function getHeadingLevel(int $index = 0): int
|
||||
{
|
||||
return $this->getContainer()->getRootHeadingLevel() + $index;
|
||||
}
|
||||
|
||||
public function getHeadingTag(int $index = 0): string
|
||||
{
|
||||
$level = $this->getHeadingLevel($index);
|
||||
|
||||
if ($level > 6) {
|
||||
return 'p';
|
||||
}
|
||||
|
||||
return "h{$level}";
|
||||
}
|
||||
|
||||
public function getChildComponentContainerRootHeadingLevel(): int
|
||||
{
|
||||
return $this->getHeadingLevel() + $this->getHeadingsCount();
|
||||
}
|
||||
|
||||
public function getHeadingsCount(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -245,4 +245,13 @@ class Section extends Component implements CanConcealComponents, CanEntangleWith
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
public function getHeadingsCount(): int
|
||||
{
|
||||
if (blank($this->getHeading())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Schemas\Concerns;
|
||||
|
||||
trait HasHeadings
|
||||
{
|
||||
protected int $rootHeadingLevel = 2;
|
||||
|
||||
public function rootHeadingLevel(int $level): static
|
||||
{
|
||||
$this->rootHeadingLevel = $level;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRootHeadingLevel(): int
|
||||
{
|
||||
if ($parentComponent = $this->getParentComponent()) {
|
||||
return $parentComponent->getChildComponentContainerRootHeadingLevel();
|
||||
}
|
||||
|
||||
return $this->rootHeadingLevel;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ class Schema extends ViewComponent
|
||||
use Concerns\HasEntryWrapper;
|
||||
use Concerns\HasFieldWrapper;
|
||||
use Concerns\HasGap;
|
||||
use Concerns\HasHeadings;
|
||||
use Concerns\HasInlineLabels;
|
||||
use Concerns\HasKey;
|
||||
use Concerns\HasOperation;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<h3
|
||||
<h2
|
||||
{{ $attributes->class(['fi-section-header-heading']) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</h3>
|
||||
</h2>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
'footer' => null,
|
||||
'hasContentEl' => true,
|
||||
'heading' => null,
|
||||
'headingTag' => 'h2',
|
||||
'icon' => null,
|
||||
'iconColor' => 'gray',
|
||||
'iconSize' => IconSize::Large,
|
||||
@@ -88,9 +89,9 @@
|
||||
@if ($hasHeading || $hasDescription)
|
||||
<div class="fi-section-header-text-ctn">
|
||||
@if ($hasHeading)
|
||||
<h3 class="fi-section-header-heading">
|
||||
<{{ $headingTag }} class="fi-section-header-heading">
|
||||
{{ $heading }}
|
||||
</h3>
|
||||
</{{ $headingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($hasDescription)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
@props([
|
||||
'applyAction',
|
||||
'form',
|
||||
'headingTag' => 'h3',
|
||||
])
|
||||
|
||||
<div {{ $attributes->class(['fi-ta-filters']) }}>
|
||||
<div class="fi-ta-filters-header">
|
||||
<h4 class="fi-ta-filters-heading">
|
||||
<{{ $headingTag }} class="fi-ta-filters-heading">
|
||||
{{ __('filament-tables::table.filters.heading') }}
|
||||
</h4>
|
||||
</{{ $headingTag }}>
|
||||
|
||||
<div>
|
||||
<x-filament::link
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
$hasColumnToggleDropdown = $hasToggleableColumns();
|
||||
$hasHeader = $header || $heading || $description || ($headerActions && (! $isReordering)) || $isReorderable || $areGroupingSettingsVisible || $isGlobalSearchVisible || $hasFilters || count($filterIndicators) || $hasColumnToggleDropdown;
|
||||
$hasHeaderToolbar = $isReorderable || $areGroupingSettingsVisible || $isGlobalSearchVisible || $hasFiltersDialog || $hasColumnToggleDropdown;
|
||||
$headingTag = $getHeadingTag();
|
||||
$secondLevelHeadingTag = $heading ? $getHeadingTag(1) : $headingTag;
|
||||
$pluralModelLabel = $getPluralModelLabel();
|
||||
$records = $isLoaded ? $getRecords() : null;
|
||||
$searchDebounce = $getSearchDebounce();
|
||||
@@ -135,9 +137,11 @@
|
||||
@if ($heading || $description)
|
||||
<div>
|
||||
@if ($heading)
|
||||
<h3 class="fi-ta-header-heading">
|
||||
<{{ $headingTag }}
|
||||
class="fi-ta-header-heading"
|
||||
>
|
||||
{{ $heading }}
|
||||
</h3>
|
||||
</{{ $headingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($description)
|
||||
@@ -171,6 +175,7 @@
|
||||
<x-filament-tables::filters
|
||||
:apply-action="$getFiltersApplyAction()"
|
||||
:form="$getFiltersForm()"
|
||||
:heading-tag="$secondLevelHeadingTag"
|
||||
x-cloak
|
||||
x-show="areFiltersOpen"
|
||||
/>
|
||||
@@ -426,6 +431,7 @@
|
||||
<x-filament-tables::filters
|
||||
:apply-action="$getFiltersApplyAction()"
|
||||
:form="$getFiltersForm()"
|
||||
:heading-tag="$secondLevelHeadingTag"
|
||||
/>
|
||||
</x-filament::dropdown>
|
||||
@endif
|
||||
@@ -447,9 +453,11 @@
|
||||
</x-slot>
|
||||
|
||||
<div class="fi-ta-col-toggle-form-ctn">
|
||||
<h4 class="fi-ta-col-toggle-heading">
|
||||
<{{ $secondLevelHeadingTag }}
|
||||
class="fi-ta-col-toggle-heading"
|
||||
>
|
||||
{{ __('filament-tables::table.column_toggle.heading') }}
|
||||
</h4>
|
||||
</{{ $secondLevelHeadingTag }}>
|
||||
|
||||
{{ $getColumnToggleForm() }}
|
||||
</div>
|
||||
@@ -823,13 +831,15 @@
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<h4 class="fi-ta-group-heading">
|
||||
<{{ $secondLevelHeadingTag }}
|
||||
class="fi-ta-group-heading"
|
||||
>
|
||||
@if (filled($recordGroupLabel = ($group->isTitlePrefixedWithLabel() ? $group->getLabel() : null)))
|
||||
{{ $recordGroupLabel }}:
|
||||
@endif
|
||||
|
||||
{{ $recordGroupTitle }}
|
||||
</h4>
|
||||
</{{ $secondLevelHeadingTag }}>
|
||||
|
||||
@if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))
|
||||
<p
|
||||
@@ -1471,7 +1481,7 @@
|
||||
])
|
||||
>
|
||||
<div>
|
||||
<h4
|
||||
<{{ $secondLevelHeadingTag }}
|
||||
class="fi-ta-group-heading"
|
||||
>
|
||||
@if (filled($recordGroupLabel = ($group->isTitlePrefixedWithLabel() ? $group->getLabel() : null)))
|
||||
@@ -1479,7 +1489,7 @@
|
||||
@endif
|
||||
|
||||
{{ $recordGroupTitle }}
|
||||
</h4>
|
||||
</{{ $secondLevelHeadingTag }}>
|
||||
|
||||
@if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))
|
||||
<p
|
||||
@@ -1817,9 +1827,11 @@
|
||||
{{ \Filament\Support\generate_icon_html($getEmptyStateIcon()) }}
|
||||
</div>
|
||||
|
||||
<h4 class="fi-ta-empty-state-heading">
|
||||
<{{ $secondLevelHeadingTag }}
|
||||
class="fi-ta-empty-state-heading"
|
||||
>
|
||||
{{ $getEmptyStateHeading() }}
|
||||
</h4>
|
||||
</{{ $secondLevelHeadingTag }}>
|
||||
|
||||
@if ($emptyStateDescription = $getEmptyStateDescription())
|
||||
<p class="fi-ta-empty-state-description">
|
||||
@@ -1857,6 +1869,7 @@
|
||||
<x-filament-tables::filters
|
||||
:apply-action="$getFiltersApplyAction()"
|
||||
:form="$getFiltersForm()"
|
||||
:heading-tag="$secondLevelHeadingTag"
|
||||
class="fi-ta-filters-below-content"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@@ -27,6 +27,7 @@ class Table extends ViewComponent
|
||||
use Table\Concerns\HasFilters;
|
||||
use Table\Concerns\HasHeader;
|
||||
use Table\Concerns\HasHeaderActions;
|
||||
use Table\Concerns\HasHeadings;
|
||||
use Table\Concerns\HasQuery;
|
||||
use Table\Concerns\HasQueryStringIdentifier;
|
||||
use Table\Concerns\HasRecordAction;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Tables\Table\Concerns;
|
||||
|
||||
trait HasHeadings
|
||||
{
|
||||
protected int $rootHeadingLevel = 2;
|
||||
|
||||
public function rootHeadingLevel(int $level): static
|
||||
{
|
||||
$this->rootHeadingLevel = $level;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRootHeadingLevel(): int
|
||||
{
|
||||
return $this->rootHeadingLevel;
|
||||
}
|
||||
|
||||
public function getHeadingLevel(int $index = 0): int
|
||||
{
|
||||
return $this->getRootHeadingLevel() + $index;
|
||||
}
|
||||
|
||||
public function getHeadingTag(int $index = 0): string
|
||||
{
|
||||
$level = $this->getHeadingLevel($index);
|
||||
|
||||
if ($level > 6) {
|
||||
return 'p';
|
||||
}
|
||||
|
||||
return "h{$level}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user