Vertical tabs

This commit is contained in:
Dan Harrin
2025-06-02 14:11:34 +01:00
parent d8c69cc5b5
commit 1f52adeb9b
12 changed files with 157 additions and 3 deletions
@@ -199,6 +199,35 @@ class LayoutDemo extends Component implements HasActions, HasSchemas
Tab::make('Meta'),
]),
]),
Group::make()
->id('tabsVertical')
->extraAttributes([
'class' => 'p-16 max-w-2xl',
])
->schema([
Tabs::make('Tabs')
->statePath('tabsVertical')
->schema([
Tab::make('Rate Limiting')
->schema([
TextInput::make('hits')
->default(30),
Select::make('period')
->default('hour')
->options([
'hour' => 'Hour',
]),
TextInput::make('maximum')
->default(100),
Textarea::make('notes')
->columnSpanFull(),
])
->columns(3),
Tab::make('Proxy'),
Tab::make('Meta'),
])
->vertical(),
]),
Group::make()
->id('wizard')
->extraAttributes([
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+9
View File
@@ -1542,6 +1542,15 @@ export default {
deviceScaleFactor: 3,
},
},
'schemas/layout/tabs/vertical': {
url: 'schemas/layout',
selector: '#tabsVertical',
viewport: {
width: 1920,
height: 640,
deviceScaleFactor: 3,
},
},
'schemas/layout/wizard/simple': {
url: 'schemas/layout',
selector: '#wizard',
+20
View File
@@ -131,3 +131,23 @@ By default, a tab's underlying HTML tag is `<button>`. You can change it to be a
{{-- Other tabs --}}
</x-filament::tabs>
```
## Using vertical tabs
You can render the tabs vertically by using the `vertical` attribute:
```blade
<x-filament::tabs vertical>
<x-filament::tabs.item>
Tab 1
</x-filament::tabs.item>
<x-filament::tabs.item>
Tab 2
</x-filament::tabs.item>
<x-filament::tabs.item>
Tab 3
</x-filament::tabs.item>
</x-filament::tabs>
```
+1 -1
View File
File diff suppressed because one or more lines are too long
+42
View File
@@ -177,6 +177,48 @@ Tabs::make('Tabs')
<UtilityInjection set="schemaComponents" version="4.x">As well as allowing a static value, the `columns()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Using vertical tabs
You can render the tabs vertically by using the `vertical()` method:
```php
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
Tabs::make('Tabs')
->tabs([
Tab::make('Tab 1')
->schema([
// ...
]),
Tab::make('Tab 2')
->schema([
// ...
]),
Tab::make('Tab 3')
->schema([
// ...
]),
])
->vertical()
```
<AutoScreenshot name="schemas/layout/tabs/vertical" alt="Vertical tabs" version="4.x" />
Optionally, you can pass a boolean value to the `vertical()` method to control if the tabs should be rendered vertically or not:
```php
use Filament\Schemas\Components\Tabs;
Tabs::make('Tabs')
->tabs([
// ...
])
->vertical(FeatureFlag::active())
```
<UtilityInjection set="schemaComponents" version="4.x">As well as allowing a static value, the `vertical()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Removing the styled container
By default, tabs and their content are wrapped in a container styled as a card. You may remove the styled container using `contained()`:
@@ -22,4 +22,14 @@
}
}
}
&.fi-vertical {
@apply flex-row;
& .fi-sc-tabs-tab {
&.fi-active {
@apply ms-6 mt-0 flex-1;
}
}
}
}
@@ -4,6 +4,7 @@
$activeTab = $getActiveTab();
$isContained = $isContained();
$isVertical = $isVertical();
$label = $getLabel();
$livewireProperty = $getLivewireProperty();
$renderHookScopes = $getRenderHookScopes();
@@ -36,6 +37,7 @@
->class([
'fi-sc-tabs',
'fi-contained' => $isContained,
'fi-vertical' => $isVertical,
])
}}
>
@@ -51,7 +53,12 @@
x-ref="tabsData"
/>
<x-filament::tabs :contained="$isContained" :label="$label" x-cloak>
<x-filament::tabs
:contained="$isContained"
:label="$label"
:vertical="$isVertical"
x-cloak
>
@foreach ($getStartRenderHooks() as $startRenderHook)
{{ \Filament\Support\Facades\FilamentView::renderHook($startRenderHook, scopes: $renderHookScopes) }}
@endforeach
@@ -110,10 +117,15 @@
->class([
'fi-sc-tabs',
'fi-contained' => $isContained,
'fi-vertical' => $isVertical,
])
}}
>
<x-filament::tabs :contained="$isContained" :label="$label">
<x-filament::tabs
:contained="$isContained"
:label="$label"
:vertical="$isVertical"
>
@foreach ($getStartRenderHooks() as $startRenderHook)
{{ \Filament\Support\Facades\FilamentView::renderHook($startRenderHook, scopes: $renderHookScopes) }}
@endforeach
+14
View File
@@ -39,6 +39,8 @@ class Tabs extends Component
protected string | Closure | null $livewireProperty = null;
protected bool | Closure $isVertical = false;
final public function __construct(string | Htmlable | Closure | null $label = null)
{
$this->label($label);
@@ -179,4 +181,16 @@ class Tabs extends Component
{
return $this->evaluate($this->livewireProperty);
}
public function vertical(bool | Closure $condition = true): static
{
$this->isVertical = $condition;
return $this;
}
public function isVertical(): bool
{
return (bool) $this->evaluate($this->isVertical);
}
}
@@ -8,6 +8,22 @@
&:not(.fi-contained) {
@apply mx-auto rounded-xl bg-white p-2 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10;
}
&.fi-vertical {
@apply flex-col gap-x-0 gap-y-1 overflow-x-hidden overflow-y-auto;
&.fi-contained {
@apply border-e border-b-0;
}
&:not(.fi-contained) {
@apply mx-0;
}
& .fi-tabs-item {
@apply justify-start;
}
}
}
.fi-tabs-item {
@@ -1,6 +1,7 @@
@props([
'contained' => false,
'label' => null,
'vertical' => false,
])
<nav
@@ -13,6 +14,7 @@
->class([
'fi-tabs',
'fi-contained' => $contained,
'fi-vertical' => $vertical,
])
}}
>