From 7c2782b6084173ed6b831d14b7e49fae64bd8403 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Wed, 22 Jan 2025 08:23:01 +0000 Subject: [PATCH 1/2] Dynamic heading levels --- .../src/Concerns/InteractsWithActions.php | 3 +- .../views/components/builder.blade.php | 6 ++-- .../views/components/repeater/index.blade.php | 6 ++-- packages/forms/src/Components/Builder.php | 9 +++++ packages/forms/src/Components/Repeater.php | 9 +++++ .../views/components/section.blade.php | 1 + packages/schemas/src/Components/Component.php | 2 ++ .../src/Components/Concerns/HasHeadings.php | 32 +++++++++++++++++ packages/schemas/src/Components/Section.php | 9 +++++ packages/schemas/src/Concerns/HasHeadings.php | 24 +++++++++++++ packages/schemas/src/Schema.php | 1 + .../components/section/heading.blade.php | 4 +-- .../views/components/section/index.blade.php | 5 +-- .../views/components/filters.blade.php | 5 +-- .../tables/resources/views/index.blade.php | 25 +++++++------ packages/tables/src/Table.php | 1 + .../tables/src/Table/Concerns/HasHeadings.php | 36 +++++++++++++++++++ 17 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 packages/schemas/src/Components/Concerns/HasHeadings.php create mode 100644 packages/schemas/src/Concerns/HasHeadings.php create mode 100644 packages/tables/src/Table/Concerns/HasHeadings.php diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index f1ab5fbff7..116d9c4e4f 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -567,7 +567,8 @@ trait InteractsWithActions ->take($actionNestingIndex + 1) ->pluck('name') ->implode('.'), - ), + ) + ->defaultHeadingLevel(3), ); } diff --git a/packages/forms/resources/views/components/builder.blade.php b/packages/forms/resources/views/components/builder.blade.php index 8230a0d870..7cb2340b0e 100644 --- a/packages/forms/resources/views/components/builder.blade.php +++ b/packages/forms/resources/views/components/builder.blade.php @@ -33,6 +33,8 @@ $key = $getKey(); $statePath = $getStatePath(); + + $blockLabelHeadingTag = $getHeadingTag(); @endphp @@ -157,7 +159,7 @@ @endif @if ($hasBlockLabels) -

$isBlockLabelTruncated(), @@ -168,7 +170,7 @@ @if ($hasBlockNumbers) {{ $loop->iteration }} @endif -

+ @endif @if ($editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions) diff --git a/packages/forms/resources/views/components/repeater/index.blade.php b/packages/forms/resources/views/components/repeater/index.blade.php index f88cc167a0..8bc2f8ae16 100644 --- a/packages/forms/resources/views/components/repeater/index.blade.php +++ b/packages/forms/resources/views/components/repeater/index.blade.php @@ -28,6 +28,8 @@ $key = $getKey(); $statePath = $getStatePath(); + + $itemLabelHeadingTag = $getHeadingTag(); @endphp @@ -147,14 +149,14 @@ @endif @if (filled($itemLabel)) -

$isItemLabelTruncated(), ]) > {{ $itemLabel }} -

+ @endif @if ($cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions) diff --git a/packages/forms/src/Components/Builder.php b/packages/forms/src/Components/Builder.php index e8d25b67e8..a7dab71e94 100644 --- a/packages/forms/src/Components/Builder.php +++ b/packages/forms/src/Components/Builder.php @@ -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; + } } diff --git a/packages/forms/src/Components/Repeater.php b/packages/forms/src/Components/Repeater.php index 1d0f45dfb1..c18375f975 100644 --- a/packages/forms/src/Components/Repeater.php +++ b/packages/forms/src/Components/Repeater.php @@ -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; + } } diff --git a/packages/schemas/resources/views/components/section.blade.php b/packages/schemas/resources/views/components/section.blade.php index bc205c74b8..104a0558f8 100644 --- a/packages/schemas/resources/views/components/section.blade.php +++ b/packages/schemas/resources/views/components/section.blade.php @@ -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()" diff --git a/packages/schemas/src/Components/Component.php b/packages/schemas/src/Components/Component.php index 03407b64b5..fd8d9122c9 100644 --- a/packages/schemas/src/Components/Component.php +++ b/packages/schemas/src/Components/Component.php @@ -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; diff --git a/packages/schemas/src/Components/Concerns/HasHeadings.php b/packages/schemas/src/Components/Concerns/HasHeadings.php new file mode 100644 index 0000000000..82bd24b945 --- /dev/null +++ b/packages/schemas/src/Components/Concerns/HasHeadings.php @@ -0,0 +1,32 @@ +getContainer()->getDefaultHeadingLevel() + $index; + } + + public function getHeadingTag(int $index = 0): string + { + $level = $this->getHeadingLevel($index); + + if ($level > 6) { + return 'p'; + } + + return "h{$level}"; + } + + public function getChildComponentContainerDefaultHeadingLevel(): int + { + return $this->getHeadingLevel() + $this->getHeadingsCount(); + } + + public function getHeadingsCount(): int + { + return 0; + } +} diff --git a/packages/schemas/src/Components/Section.php b/packages/schemas/src/Components/Section.php index f949b0c7cd..9c19905c3a 100644 --- a/packages/schemas/src/Components/Section.php +++ b/packages/schemas/src/Components/Section.php @@ -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; + } } diff --git a/packages/schemas/src/Concerns/HasHeadings.php b/packages/schemas/src/Concerns/HasHeadings.php new file mode 100644 index 0000000000..c76a350a4d --- /dev/null +++ b/packages/schemas/src/Concerns/HasHeadings.php @@ -0,0 +1,24 @@ +defaultHeadingLevel = $level; + + return $this; + } + + public function getDefaultHeadingLevel(): int + { + if ($parentComponent = $this->getParentComponent()) { + return $parentComponent->getChildComponentContainerDefaultHeadingLevel(); + } + + return $this->defaultHeadingLevel; + } +} diff --git a/packages/schemas/src/Schema.php b/packages/schemas/src/Schema.php index 4993882521..210a7767da 100644 --- a/packages/schemas/src/Schema.php +++ b/packages/schemas/src/Schema.php @@ -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; diff --git a/packages/support/resources/views/components/section/heading.blade.php b/packages/support/resources/views/components/section/heading.blade.php index 739281b010..c4b2413916 100644 --- a/packages/support/resources/views/components/section/heading.blade.php +++ b/packages/support/resources/views/components/section/heading.blade.php @@ -1,5 +1,5 @@ -

class(['fi-section-header-heading']) }} > {{ $slot }} -

+ diff --git a/packages/support/resources/views/components/section/index.blade.php b/packages/support/resources/views/components/section/index.blade.php index 211574d95b..e9b3556641 100644 --- a/packages/support/resources/views/components/section/index.blade.php +++ b/packages/support/resources/views/components/section/index.blade.php @@ -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)
@if ($hasHeading) -

+ <{{ $headingTag }} class="fi-section-header-heading"> {{ $heading }} -

+ @endif @if ($hasDescription) diff --git a/packages/tables/resources/views/components/filters.blade.php b/packages/tables/resources/views/components/filters.blade.php index 7f6c78aefb..48c117bb18 100644 --- a/packages/tables/resources/views/components/filters.blade.php +++ b/packages/tables/resources/views/components/filters.blade.php @@ -1,13 +1,14 @@ @props([ 'applyAction', 'form', + 'headingTag' => 'h3', ])
class(['fi-ta-filters']) }}>
-

+ <{{ $headingTag }} class="fi-ta-filters-heading"> {{ __('filament-tables::table.filters.heading') }} -

+
@if ($heading) -

+ <{{ $headingTag }} class="fi-ta-header-heading"> {{ $heading }} -

+ @endif @if ($description) @@ -171,6 +173,7 @@ @@ -426,6 +429,7 @@ @endif @@ -447,9 +451,9 @@
-

+ <{{ $secondLevelHeadingTag }} class="fi-ta-col-toggle-heading"> {{ __('filament-tables::table.column_toggle.heading') }} -

+ {{ $getColumnToggleForm() }}
@@ -823,13 +827,13 @@ @endif
-

+ <{{ $secondLevelHeadingTag }} class="fi-ta-group-heading"> @if (filled($recordGroupLabel = ($group->isTitlePrefixedWithLabel() ? $group->getLabel() : null))) {{ $recordGroupLabel }}: @endif {{ $recordGroupTitle }} -

+ @if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))

-

@if (filled($recordGroupLabel = ($group->isTitlePrefixedWithLabel() ? $group->getLabel() : null))) @@ -1479,7 +1483,7 @@ @endif {{ $recordGroupTitle }} -

+ @if (filled($recordGroupDescription = $group->getDescription($record, $recordGroupTitle)))

-

+ <{{ $secondLevelHeadingTag }} class="fi-ta-empty-state-heading"> {{ $getEmptyStateHeading() }} -

+ @if ($emptyStateDescription = $getEmptyStateDescription())

@@ -1857,6 +1861,7 @@ @endif diff --git a/packages/tables/src/Table.php b/packages/tables/src/Table.php index 38a5fd00a8..e7db9d0ab9 100644 --- a/packages/tables/src/Table.php +++ b/packages/tables/src/Table.php @@ -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; diff --git a/packages/tables/src/Table/Concerns/HasHeadings.php b/packages/tables/src/Table/Concerns/HasHeadings.php new file mode 100644 index 0000000000..1aeb6e9a35 --- /dev/null +++ b/packages/tables/src/Table/Concerns/HasHeadings.php @@ -0,0 +1,36 @@ +defaultHeadingLevel = $level; + + return $this; + } + + public function getDefaultHeadingLevel(): int + { + return $this->defaultHeadingLevel; + } + + public function getHeadingLevel(int $index = 0): int + { + return $this->getDefaultHeadingLevel() + $index; + } + + public function getHeadingTag(int $index = 0): string + { + $level = $this->getHeadingLevel($index); + + if ($level > 6) { + return 'p'; + } + + return "h{$level}"; + } +} From a9441f4cefee65db985442aa89e1cc35a98dd034 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Wed, 22 Jan 2025 08:24:15 +0000 Subject: [PATCH 2/2] Rename --- .../src/Concerns/InteractsWithActions.php | 2 +- .../src/Components/Concerns/HasHeadings.php | 4 ++-- packages/schemas/src/Concerns/HasHeadings.php | 12 ++++++------ packages/tables/resources/views/index.blade.php | 16 ++++++++++++---- .../tables/src/Table/Concerns/HasHeadings.php | 12 ++++++------ 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index 116d9c4e4f..72eada12e0 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -568,7 +568,7 @@ trait InteractsWithActions ->pluck('name') ->implode('.'), ) - ->defaultHeadingLevel(3), + ->rootHeadingLevel(3), ); } diff --git a/packages/schemas/src/Components/Concerns/HasHeadings.php b/packages/schemas/src/Components/Concerns/HasHeadings.php index 82bd24b945..59d18e5506 100644 --- a/packages/schemas/src/Components/Concerns/HasHeadings.php +++ b/packages/schemas/src/Components/Concerns/HasHeadings.php @@ -6,7 +6,7 @@ trait HasHeadings { public function getHeadingLevel(int $index = 0): int { - return $this->getContainer()->getDefaultHeadingLevel() + $index; + return $this->getContainer()->getRootHeadingLevel() + $index; } public function getHeadingTag(int $index = 0): string @@ -20,7 +20,7 @@ trait HasHeadings return "h{$level}"; } - public function getChildComponentContainerDefaultHeadingLevel(): int + public function getChildComponentContainerRootHeadingLevel(): int { return $this->getHeadingLevel() + $this->getHeadingsCount(); } diff --git a/packages/schemas/src/Concerns/HasHeadings.php b/packages/schemas/src/Concerns/HasHeadings.php index c76a350a4d..cd48b82086 100644 --- a/packages/schemas/src/Concerns/HasHeadings.php +++ b/packages/schemas/src/Concerns/HasHeadings.php @@ -4,21 +4,21 @@ namespace Filament\Schemas\Concerns; trait HasHeadings { - protected int $defaultHeadingLevel = 2; + protected int $rootHeadingLevel = 2; - public function defaultHeadingLevel(int $level): static + public function rootHeadingLevel(int $level): static { - $this->defaultHeadingLevel = $level; + $this->rootHeadingLevel = $level; return $this; } - public function getDefaultHeadingLevel(): int + public function getRootHeadingLevel(): int { if ($parentComponent = $this->getParentComponent()) { - return $parentComponent->getChildComponentContainerDefaultHeadingLevel(); + return $parentComponent->getChildComponentContainerRootHeadingLevel(); } - return $this->defaultHeadingLevel; + return $this->rootHeadingLevel; } } diff --git a/packages/tables/resources/views/index.blade.php b/packages/tables/resources/views/index.blade.php index 579d030edb..0ef03b9ef8 100644 --- a/packages/tables/resources/views/index.blade.php +++ b/packages/tables/resources/views/index.blade.php @@ -137,7 +137,9 @@ @if ($heading || $description)

@if ($heading) - <{{ $headingTag }} class="fi-ta-header-heading"> + <{{ $headingTag }} + class="fi-ta-header-heading" + > {{ $heading }} @endif @@ -451,7 +453,9 @@
- <{{ $secondLevelHeadingTag }} class="fi-ta-col-toggle-heading"> + <{{ $secondLevelHeadingTag }} + class="fi-ta-col-toggle-heading" + > {{ __('filament-tables::table.column_toggle.heading') }} @@ -827,7 +831,9 @@ @endif
- <{{ $secondLevelHeadingTag }} class="fi-ta-group-heading"> + <{{ $secondLevelHeadingTag }} + class="fi-ta-group-heading" + > @if (filled($recordGroupLabel = ($group->isTitlePrefixedWithLabel() ? $group->getLabel() : null))) {{ $recordGroupLabel }}: @endif @@ -1821,7 +1827,9 @@ {{ \Filament\Support\generate_icon_html($getEmptyStateIcon()) }}
- <{{ $secondLevelHeadingTag }} class="fi-ta-empty-state-heading"> + <{{ $secondLevelHeadingTag }} + class="fi-ta-empty-state-heading" + > {{ $getEmptyStateHeading() }} diff --git a/packages/tables/src/Table/Concerns/HasHeadings.php b/packages/tables/src/Table/Concerns/HasHeadings.php index 1aeb6e9a35..b969fd687a 100644 --- a/packages/tables/src/Table/Concerns/HasHeadings.php +++ b/packages/tables/src/Table/Concerns/HasHeadings.php @@ -4,23 +4,23 @@ namespace Filament\Tables\Table\Concerns; trait HasHeadings { - protected int $defaultHeadingLevel = 2; + protected int $rootHeadingLevel = 2; - public function defaultHeadingLevel(int $level): static + public function rootHeadingLevel(int $level): static { - $this->defaultHeadingLevel = $level; + $this->rootHeadingLevel = $level; return $this; } - public function getDefaultHeadingLevel(): int + public function getRootHeadingLevel(): int { - return $this->defaultHeadingLevel; + return $this->rootHeadingLevel; } public function getHeadingLevel(int $index = 0): int { - return $this->getDefaultHeadingLevel() + $index; + return $this->getRootHeadingLevel() + $index; } public function getHeadingTag(int $index = 0): string