Remove unused Blade components and templates from the Filament package to streamline the codebase. This includes deleting various components related to forms, notifications, pagination, and widgets, enhancing maintainability and reducing clutter.

This commit is contained in:
Mekan1206
2025-12-21 06:15:33 +05:00
parent 5361c00e7b
commit f433fc3e41
190 changed files with 987 additions and 15036 deletions

View File

@@ -16,6 +16,7 @@ use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets\AccountWidget;
use Filament\Widgets\FilamentInfoWidget;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
@@ -29,8 +30,6 @@ class WorkPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
// #content\.form-actions > div
return $panel
->default()
->id('work')
@@ -47,6 +46,7 @@ class WorkPanelProvider extends PanelProvider
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
->widgets([
AccountWidget::class,
FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"resources/css/filament/work/theme.css": {
"file": "assets/theme-N6DF4L1Y.css",
"file": "assets/theme-D6od5FeK.css",
"src": "resources/css/filament/work/theme.css",
"isEntry": true,
"name": "theme",

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
{"/livewire.js":"df3a17f2"}
{"/livewire.js":"0f6341c0"}

View File

@@ -71,7 +71,7 @@
<img
src="{{ $entry->getMediaUrl($item) }}"
class="w-full h-full object-contain"
class="max-h-[400px] w-fit"
/>
</x-filament::modal>
@else

View File

@@ -1,67 +0,0 @@
@php
use Filament\Actions\View\ActionsRenderHook;
use Filament\Support\Facades\FilamentView;
$actionModalAlignment = $action->getModalAlignment();
$actionIsModalAutofocused = $action->isModalAutofocused();
$actionHasModalCloseButton = $action->hasModalCloseButton();
$actionIsModalClosedByClickingAway = $action->isModalClosedByClickingAway();
$actionIsModalClosedByEscaping = $action->isModalClosedByEscaping();
$actionModalDescription = $action->getModalDescription();
$actionExtraModalWindowAttributeBag = $action->getExtraModalWindowAttributeBag();
$actionModalFooterActions = $action->getVisibleModalFooterActions();
$actionModalFooterActionsAlignment = $action->getModalFooterActionsAlignment();
$actionModalHeading = $action->getModalHeading();
$actionModalIcon = $action->getModalIcon();
$actionModalIconColor = $action->getModalIconColor();
$actionModalId = "fi-{$this->getId()}-action-{$action->getNestingIndex()}";
$actionIsModalSlideOver = $action->isModalSlideOver();
$actionIsModalFooterSticky = $action->isModalFooterSticky();
$actionIsModalHeaderSticky = $action->isModalHeaderSticky();
$actionModalWidth = $action->getModalWidth();
$actionLivewireCallMountedActionName = $action->hasFormWrapper() ? $action->getLivewireCallMountedActionName() : null;
$actionModalWireKey = "{$this->getId()}.actions.{$action->getName()}.modal";
@endphp
<x-filament::modal
:alignment="$actionModalAlignment"
:autofocus="$actionIsModalAutofocused"
:close-button="$actionHasModalCloseButton"
:close-by-clicking-away="$actionIsModalClosedByClickingAway"
:close-by-escaping="$actionIsModalClosedByEscaping"
:description="$actionModalDescription"
:extra-modal-window-attribute-bag="$actionExtraModalWindowAttributeBag"
:footer-actions="$actionModalFooterActions"
:footer-actions-alignment="$actionModalFooterActionsAlignment"
:heading="$actionModalHeading"
:icon="$actionModalIcon"
:icon-color="$actionModalIconColor"
:id="$actionModalId"
:slide-over="$actionIsModalSlideOver"
:sticky-footer="$actionIsModalFooterSticky"
:sticky-header="$actionIsModalHeaderSticky"
:width="$actionModalWidth"
:wire:key="$actionModalWireKey"
:wire:submit.prevent="$actionLivewireCallMountedActionName"
:x-on:modal-closed="'if ($event.detail.id === ' . \Illuminate\Support\Js::from($actionModalId) . ') $wire.unmountAction(false)'"
>
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_BEFORE, scopes: static::class, data: ['action' => $action]) }}
{{ $action->getModalContent() }}
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_AFTER, scopes: static::class, data: ['action' => $action]) }}
@if ($this->mountedActionHasSchema(mountedAction: $action))
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_SCHEMA_BEFORE, scopes: static::class, data: ['action' => $action]) }}
{{ $this->getMountedActionSchema(mountedAction: $action) }}
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_SCHEMA_AFTER, scopes: static::class, data: ['action' => $action]) }}
@endif
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_FOOTER_BEFORE, scopes: static::class, data: ['action' => $action]) }}
{{ $action->getModalContentFooter() }}
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_FOOTER_AFTER, scopes: static::class, data: ['action' => $action]) }}
</x-filament::modal>

View File

@@ -1,59 +0,0 @@
@props([
'actions' => [],
'badge' => null,
'badgeColor' => null,
'button' => false,
'color' => null,
'dropdownMaxHeight' => null,
'dropdownOffset' => null,
'dropdownPlacement' => null,
'dropdownWidth' => null,
'group' => null,
'icon' => null,
'iconSize' => null,
'iconButton' => false,
'label' => null,
'link' => false,
'size' => null,
'tooltip' => null,
'triggerView' => null,
'view' => null,
])
@php
$group ??= \Filament\Actions\ActionGroup::make($actions)
->badgeColor($badgeColor)
->color($color)
->dropdownMaxHeight($dropdownMaxHeight)
->dropdownOffset($dropdownOffset)
->dropdownPlacement($dropdownPlacement)
->dropdownWidth($dropdownWidth)
->icon($icon)
->iconSize($iconSize)
->label($label)
->size($size)
->tooltip($tooltip)
->triggerView($triggerView)
->view($view);
$badge === true
? $group->badge()
: $group->badge($badge);
if ($button) {
$group
->button()
->iconPosition($attributes->get('iconPosition') ?? $attributes->get('icon-position'))
->outlined($attributes->get('outlined') ?? false);
}
if ($iconButton) {
$group->iconButton();
}
if ($link) {
$group->link();
}
@endphp
{{ $group }}

View File

@@ -1,19 +0,0 @@
@if ($this instanceof \Filament\Actions\Contracts\HasActions && (! $this->hasActionsModalRendered))
<div
wire:partial="action-modals"
x-data="filamentActionModals({
livewireId: @js($this->getId()),
})"
style="height: 0"
>
@foreach ($this->getMountedActions() as $action)
@if ((! $loop->last) || $this->mountedActionShouldOpenModal())
{{ $action->toModalHtmlable() }}
@endif
@endforeach
</div>
@php
$this->hasActionsModalRendered = true;
@endphp
@endif

View File

@@ -1,7 +0,0 @@
<x-filament-panels::page>
@foreach ($this->getRegisteredCustomProfileComponents() as $component)
@unless(is_null($component))
@livewire($component)
@endunless
@endforeach
</x-filament-panels::page>

View File

@@ -1,54 +0,0 @@
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div>
<div class="">
<div class="text-sm text-gray-600 fi-in-entry">
<div class="text-sm text-gray-600 dark:text-gray-400">
{{ __('filament-edit-profile::default.browser_sessions_content') }}
</div>
@if (count($data) > 0)
<div class="fi-in-entry">
@foreach ($data as $session)
<div class="fi-sc fi-inline fi-sc-has-gap">
<div>
@if ($session->device['desktop'])
<x-filament::icon
icon="heroicon-o-computer-desktop"
class="w-8 h-8 text-gray-500 dark:text-gray-400"
/>
@else
<x-filament::icon
icon="heroicon-o-device-phone-mobile"
class="w-8 h-8 text-gray-500 dark:text-gray-400"
/>
@endif
</div>
<div class="ms-3">
<div class="text-sm text-gray-600 dark:text-gray-400">
{{ $session->device['platform'] ? $session->device['platform'] : __('Unknown') }} - {{ $session->device['browser'] ? $session->device['browser'] : __('Unknown') }}
</div>
<div>
<div class="text-xs text-gray-500">
{{ $session->ip_address }},
@if ($session->is_current_device)
<span class="font-semibold text-primary-500">{{ __('filament-edit-profile::default.browser_sessions_device') }}</span>
@else
{{ __('filament-edit-profile::default.browser_sessions_last_active') }} {{ $session->last_active }}
@endif
</div>
</div>
</div>
</div>
@endforeach
</div>
@endif
</div>
</div>
</div>
</x-dynamic-component>

View File

@@ -1,12 +0,0 @@
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<div class="text-start">
<div class="text-sm text-gray-600 dark:text-gray-400">
{{ __('filament-edit-profile::default.delete_account_card_description') }}
</div>
</div>
</div>
</x-dynamic-component>

View File

@@ -1,7 +0,0 @@
<div>
<form class="fi-sc-form">
{{ $this->form }}
</form>
<x-filament-actions::modals />
</div>

View File

@@ -1,9 +0,0 @@
<form wire:submit="updateCustomFields" class="fi-sc-form">
{{ $this->form }}
<div class="fi-ac fi-align-end">
<x-filament::button type="submit">
{{ __('filament-edit-profile::default.save') }}
</x-filament::button>
</div>
</form>

View File

@@ -1,7 +0,0 @@
<div>
<form class="fi-sc-form">
{{ $this->form }}
</form>
<x-filament-actions::modals />
</div>

View File

@@ -1,9 +0,0 @@
<form wire:submit="updatePassword" class="fi-sc-form">
{{ $this->form }}
<div class="fi-ac fi-align-end">
<x-filament::button type="submit">
{{ __('filament-edit-profile::default.save') }}
</x-filament::button>
</div>
</form>

View File

@@ -1,9 +0,0 @@
<form wire:submit="updateProfile" class="fi-sc-form">
{{ $this->form }}
<div class="fi-ac fi-align-end">
<x-filament::button type="submit">
{{ __('filament-edit-profile::default.save') }}
</x-filament::button>
</div>
</form>

View File

@@ -1,7 +0,0 @@
<div>
<form class="fi-sc-form">
{{ $this->content }}
</form>
<x-filament-actions::modals />
</div>

View File

@@ -1,11 +0,0 @@
<x-filament::section aside>
<x-slot name="heading">
{{ __('filament-edit-profile::default.token_section_title') }}
</x-slot>
<x-slot name="description">
{{ __('filament-edit-profile::default.token_section_description') }}
</x-slot>
{{ $this->table }}
</x-filament::section>

View File

@@ -1,328 +0,0 @@
@php
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;
$fieldWrapperView = $getFieldWrapperView();
$items = $getItems();
$blockPickerBlocks = $getBlockPickerBlocks();
$blockPickerColumns = $getBlockPickerColumns();
$blockPickerWidth = $getBlockPickerWidth();
$hasBlockPreviews = $hasBlockPreviews();
$hasInteractiveBlockPreviews = $hasInteractiveBlockPreviews();
$addAction = $getAction($getAddActionName());
$addActionAlignment = $getAddActionAlignment();
$addBetweenAction = $getAction($getAddBetweenActionName());
$cloneAction = $getAction($getCloneActionName());
$collapseAllAction = $getAction($getCollapseAllActionName());
$editAction = $getAction($getEditActionName());
$expandAllAction = $getAction($getExpandAllActionName());
$deleteAction = $getAction($getDeleteActionName());
$moveDownAction = $getAction($getMoveDownActionName());
$moveUpAction = $getAction($getMoveUpActionName());
$reorderAction = $getAction($getReorderActionName());
$extraItemActions = $getExtraItemActions();
$isAddable = $isAddable();
$isCloneable = $isCloneable();
$isCollapsible = $isCollapsible();
$isDeletable = $isDeletable();
$isReorderableWithButtons = $isReorderableWithButtons();
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
$collapseAllActionIsVisible = $isCollapsible && $collapseAllAction->isVisible();
$expandAllActionIsVisible = $isCollapsible && $expandAllAction->isVisible();
$key = $getKey();
$statePath = $getStatePath();
$blockLabelHeadingTag = $getHeadingTag();
$isBlockLabelTruncated = $isBlockLabelTruncated();
$labelBetweenItems = $getLabelBetweenItems();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-fo-builder',
'fi-collapsible' => $isCollapsible,
])
}}
>
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
<div
@class([
'fi-fo-builder-actions',
'fi-hidden' => count($items) < 2,
])
>
@if ($collapseAllActionIsVisible)
<span
x-on:click="$dispatch('builder-collapse', '{{ $statePath }}')"
>
{{ $collapseAllAction }}
</span>
@endif
@if ($expandAllActionIsVisible)
<span
x-on:click="$dispatch('builder-expand', '{{ $statePath }}')"
>
{{ $expandAllAction }}
</span>
@endif
</div>
@endif
@if (count($items))
<ul
x-sortable
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
x-on:end.stop="
$event.oldDraggableIndex !== $event.newDraggableIndex &&
$wire.mountAction(
'reorder',
{ items: $event.target.sortable.toArray() },
{ schemaComponent: '{{ $key }}' },
)
"
class="fi-fo-builder-items"
>
@php
$hasBlockLabels = $hasBlockLabels();
$hasBlockIcons = $hasBlockIcons();
$hasBlockNumbers = $hasBlockNumbers();
$hasBlockHeaders = $hasBlockHeaders();
@endphp
@foreach ($items as $itemKey => $item)
@php
$visibleExtraItemActions = array_filter(
$extraItemActions,
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
);
$cloneAction = $cloneAction(['item' => $itemKey]);
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
$deleteAction = $deleteAction(['item' => $itemKey]);
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
$editAction = $editAction(['item' => $itemKey]);
$editActionIsVisible = $hasBlockPreviews && $editAction->isVisible();
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
$hasItemHeader = $hasBlockHeaders && ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $hasBlockIcons || $hasBlockLabels || $editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions);
@endphp
<li
wire:ignore.self
wire:key="{{ $item->getLivewireKey() }}.item"
x-data="{
isCollapsed: @js($isCollapsed($item)),
}"
x-on:builder-expand.window="$event.detail === '{{ $statePath }}' && (isCollapsed = false)"
x-on:builder-collapse.window="$event.detail === '{{ $statePath }}' && (isCollapsed = true)"
x-on:expand="isCollapsed = false"
x-sortable-item="{{ $itemKey }}"
{{
$item->getParentComponent()->getExtraAttributeBag()
->class([
'fi-fo-builder-item',
'fi-fo-builder-item-has-header' => $hasItemHeader,
])
}}
x-bind:class="{ 'fi-collapsed': isCollapsed }"
>
@if ($hasItemHeader)
<div
@if ($isCollapsible)
x-on:click.stop="isCollapsed = !isCollapsed"
@endif
class="fi-fo-builder-item-header"
>
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
<ul
class="fi-fo-builder-item-header-start-actions"
>
@if ($reorderActionIsVisible)
<li x-on:click.stop>
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
</li>
@endif
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
<li x-on:click.stop>
{{ $moveUpAction }}
</li>
<li x-on:click.stop>
{{ $moveDownAction }}
</li>
@endif
</ul>
@endif
@php
$blockIcon = $item->getParentComponent()->getIcon($item->getRawState(), $itemKey);
@endphp
@if ($hasBlockIcons && filled($blockIcon))
{{ \Filament\Support\generate_icon_html($blockIcon, (new \Illuminate\View\ComponentAttributeBag)->class(['fi-fo-builder-item-header-icon'])) }}
@endif
@if ($hasBlockLabels)
<{{ $blockLabelHeadingTag }}
@class([
'fi-fo-builder-item-header-label',
'fi-truncated' => $isBlockLabelTruncated,
])
>
{{ $item->getParentComponent()->getLabel($item->getRawState(), $itemKey) }}
@if ($hasBlockNumbers)
{{ $loop->iteration }}
@endif
</{{ $blockLabelHeadingTag }}>
@endif
@if ($editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
<ul
class="fi-fo-builder-item-header-end-actions"
>
@foreach ($visibleExtraItemActions as $extraItemAction)
<li x-on:click.stop>
{{ $extraItemAction(['item' => $itemKey]) }}
</li>
@endforeach
@if ($editActionIsVisible)
<li x-on:click.stop>
{{ $editAction }}
</li>
@endif
@if ($cloneActionIsVisible)
<li x-on:click.stop>
{{ $cloneAction }}
</li>
@endif
@if ($deleteActionIsVisible)
<li x-on:click.stop>
{{ $deleteAction }}
</li>
@endif
@if ($isCollapsible)
<li
class="fi-fo-builder-item-header-collapsible-actions"
x-on:click.stop="isCollapsed = !isCollapsed"
>
<div
class="fi-fo-builder-item-header-collapse-action"
>
{{ $getAction('collapse') }}
</div>
<div
class="fi-fo-builder-item-header-expand-action"
>
{{ $getAction('expand') }}
</div>
</li>
@endif
</ul>
@endif
</div>
@endif
<div
x-show="! isCollapsed"
@class([
'fi-fo-builder-item-content',
'fi-fo-builder-item-content-has-preview' => $hasBlockPreviews && $item->getParentComponent()->hasPreview(),
])
>
@if ($hasBlockPreviews && $item->getParentComponent()->hasPreview())
<div
@class([
'fi-fo-builder-item-preview',
'fi-interactive' => $hasInteractiveBlockPreviews,
])
>
{{ $item->getParentComponent()->renderPreview($item->getRawState()) }}
</div>
@if ($editActionIsVisible && (! $hasInteractiveBlockPreviews))
<div
class="fi-fo-builder-item-preview-edit-overlay"
role="button"
x-on:click.stop="{{ '$wire.mountAction(\'edit\', { item: \'' . $itemKey . '\' }, { schemaComponent: \'' . $key . '\' })' }}"
></div>
@endif
@else
{{ $item }}
@endif
</div>
</li>
@if (! $loop->last)
@if ($isAddable && $addBetweenAction(['afterItem' => $itemKey])->isVisible())
<li class="fi-fo-builder-add-between-items-ctn">
<div class="fi-fo-builder-add-between-items">
<div class="fi-fo-builder-block-picker-ctn">
<x-filament-forms::builder.block-picker
:action="$addBetweenAction"
:after-item="$itemKey"
:columns="$blockPickerColumns"
:blocks="$blockPickerBlocks"
:key="$key"
:width="$blockPickerWidth"
>
<x-slot name="trigger">
{{ $addBetweenAction(['afterItem' => $itemKey]) }}
</x-slot>
</x-filament-forms::builder.block-picker>
</div>
</div>
</li>
@elseif (filled($labelBetweenItems))
<li class="fi-fo-builder-label-between-items-ctn">
<div
class="fi-fo-builder-label-between-items-divider-before"
></div>
<span class="fi-fo-builder-label-between-items">
{{ $labelBetweenItems }}
</span>
<div
class="fi-fo-builder-label-between-items-divider-after"
></div>
</li>
@endif
@endif
@endforeach
</ul>
@endif
@if ($isAddable && $addAction->isVisible())
<x-filament-forms::builder.block-picker
:action="$addAction"
:action-alignment="$addActionAlignment"
:blocks="$blockPickerBlocks"
:columns="$blockPickerColumns"
:key="$key"
:width="$blockPickerWidth"
>
<x-slot name="trigger">
{{ $addAction }}
</x-slot>
</x-filament-forms::builder.block-picker>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,70 +0,0 @@
@php
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\GridDirection;
use Illuminate\View\ComponentAttributeBag;
@endphp
@props([
'action',
'actionAlignment' => null,
'afterItem' => null,
'blocks',
'columns' => null,
'key',
'trigger',
'width' => null,
])
<x-filament::dropdown
:placement="
match ($actionAlignment) {
Alignment::Start, Alignment::Left => 'bottom-start',
Alignment::End, Alignment::Right => 'bottom-end',
default => null,
}
"
shift
:width="$width"
:attributes="
\Filament\Support\prepare_inherited_attributes(
$attributes->class([
'fi-fo-builder-block-picker',
($actionAlignment instanceof Alignment) ? ('fi-align-' . $actionAlignment->value) : $actionAlignment => $actionAlignment,
]),
)
"
>
<x-slot name="trigger">
{{ $trigger }}
</x-slot>
<x-filament::dropdown.list>
<div
{{ (new ComponentAttributeBag)->grid($columns, GridDirection::Column) }}
>
@foreach ($blocks as $block)
@php
$blockIcon = $block->getIcon();
$wireClickActionArguments = ['block' => $block->getName()];
if (filled($afterItem)) {
$wireClickActionArguments['afterItem'] = $afterItem;
}
$wireClickActionArguments = \Illuminate\Support\Js::from($wireClickActionArguments);
$wireClickAction = "mountAction('{$action->getName()}', {$wireClickActionArguments}, { schemaComponent: '{$key}' })";
@endphp
<x-filament::dropdown.list.item
:icon="$blockIcon"
x-on:click="close"
:wire:click="$wireClickAction"
>
{{ $block->getLabel() }}
</x-filament::dropdown.list.item>
@endforeach
</div>
</x-filament::dropdown.list>
</x-filament::dropdown>

View File

@@ -1,151 +0,0 @@
@php
use Filament\Support\Enums\GridDirection;
$fieldWrapperView = $getFieldWrapperView();
$extraInputAttributeBag = $getExtraInputAttributeBag();
$isHtmlAllowed = $isHtmlAllowed();
$gridDirection = $getGridDirection() ?? GridDirection::Column;
$isBulkToggleable = $isBulkToggleable();
$isDisabled = $isDisabled();
$isSearchable = $isSearchable();
$statePath = $getStatePath();
$options = $getOptions();
$livewireKey = $getLivewireKey();
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('checkbox-list', 'filament/forms') }}"
x-data="checkboxListFormComponent({
livewireId: @js($this->getId()),
})"
{{ $getExtraAlpineAttributeBag()->class(['fi-fo-checkbox-list']) }}
>
@if (! $isDisabled)
@if ($isSearchable)
<x-filament::input.wrapper
inline-prefix
:prefix-icon="\Filament\Support\Icons\Heroicon::MagnifyingGlass"
:prefix-icon-alias="\Filament\Forms\View\FormsIconAlias::COMPONENTS_CHECKBOX_LIST_SEARCH_FIELD"
class="fi-fo-checkbox-list-search-input-wrp"
>
<input
placeholder="{{ $getSearchPrompt() }}"
type="search"
x-model.debounce.{{ $getSearchDebounce() }}="search"
class="fi-input fi-input-has-inline-prefix"
/>
</x-filament::input.wrapper>
@endif
@if ($isBulkToggleable && count($options))
<div
x-cloak
class="fi-fo-checkbox-list-actions"
wire:key="{{ $livewireKey }}.actions"
>
<span
x-show="! areAllCheckboxesChecked"
x-on:click="toggleAllCheckboxes()"
wire:key="{{ $livewireKey }}.actions.select-all"
>
{{ $getAction('selectAll') }}
</span>
<span
x-show="areAllCheckboxesChecked"
x-on:click="toggleAllCheckboxes()"
wire:key="{{ $livewireKey }}.actions.deselect-all"
>
{{ $getAction('deselectAll') }}
</span>
</div>
@endif
@endif
<div
{{
$getExtraAttributeBag()
->grid($getColumns(), $gridDirection)
->merge([
'x-show' => $isSearchable ? 'visibleCheckboxListOptions.length' : null,
], escape: false)
->class([
'fi-fo-checkbox-list-options',
])
}}
>
@forelse ($options as $value => $label)
<div
wire:key="{{ $livewireKey }}.options.{{ $value }}"
@if ($isSearchable)
x-show="
$el
.querySelector('.fi-fo-checkbox-list-option-label')
?.innerText.toLowerCase()
.includes(search.toLowerCase()) ||
$el
.querySelector('.fi-fo-checkbox-list-option-description')
?.innerText.toLowerCase()
.includes(search.toLowerCase())
"
@endif
class="fi-fo-checkbox-list-option-ctn"
>
<label class="fi-fo-checkbox-list-option">
<input
type="checkbox"
{{
$extraInputAttributeBag
->merge([
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
'value' => $value,
'wire:loading.attr' => 'disabled',
$wireModelAttribute => $statePath,
'x-on:change' => $isBulkToggleable ? 'checkIfAllCheckboxesAreChecked()' : null,
], escape: false)
->class([
'fi-checkbox-input',
'fi-valid' => ! $errors->has($statePath),
'fi-invalid' => $errors->has($statePath),
])
}}
/>
<div class="fi-fo-checkbox-list-option-text">
<span class="fi-fo-checkbox-list-option-label">
@if ($isHtmlAllowed)
{!! $label !!}
@else
{{ $label }}
@endif
</span>
@if ($hasDescription($value))
<p
class="fi-fo-checkbox-list-option-description"
>
{{ $getDescription($value) }}
</p>
@endif
</div>
</label>
</div>
@empty
<div wire:key="{{ $livewireKey }}.empty"></div>
@endforelse
</div>
@if ($isSearchable)
<div
x-cloak
x-show="search && ! visibleCheckboxListOptions.length"
class="fi-fo-checkbox-list-no-search-results-message"
>
{{ $getNoSearchResultsMessage() }}
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,34 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$statePath = $getStatePath();
$attributes = $attributes
->merge([
'autofocus' => $isAutofocused(),
'disabled' => $isDisabled(),
'id' => $getId(),
'required' => $isRequired() && (! $isConcealed()),
'wire:loading.attr' => 'disabled',
$applyStateBindingModifiers('wire:model') => $statePath,
], escape: false)
->merge($getExtraAttributes(), escape: false)
->merge($getExtraInputAttributes(), escape: false)
->class([
'fi-checkbox-input',
'fi-valid' => ! $errors->has($statePath),
'fi-invalid' => $errors->has($statePath),
]);
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
@if ($isInline())
<x-slot name="labelPrefix">
<input type="checkbox" {{ $attributes }} />
</x-slot>
@else
<input type="checkbox" {{ $attributes }} />
@endif
</x-dynamic-component>

View File

@@ -1,40 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributeBag = $getExtraAttributeBag();
$isDisabled = $isDisabled();
$key = $getKey();
$language = $getLanguage();
$statePath = $getStatePath();
$livewireKey = $getLivewireKey();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<x-filament::input.wrapper
:disabled="$isDisabled"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class(['fi-fo-code-editor'])
"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('code-editor', 'filament/forms') }}"
x-data="codeEditorFormComponent({
isDisabled: @js($isDisabled),
language: @js($language?->value),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
$language?->value,
])), 0, 64)
}}"
{{ $getExtraAlpineAttributeBag() }}
>
<div x-ref="editor" x-cloak></div>
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,115 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributeBag = $getExtraAttributeBag();
$isDisabled = $isDisabled();
$isLive = $isLive();
$isLiveOnBlur = $isLiveOnBlur();
$isLiveDebounced = $isLiveDebounced();
$isPrefixInline = $isPrefixInline();
$isSuffixInline = $isSuffixInline();
$liveDebounce = $getLiveDebounce();
$prefixActions = $getPrefixActions();
$prefixIcon = $getPrefixIcon();
$prefixIconColor = $getPrefixIconColor();
$prefixLabel = $getPrefixLabel();
$suffixActions = $getSuffixActions();
$suffixIcon = $getSuffixIcon();
$suffixIconColor = $getSuffixIconColor();
$suffixLabel = $getSuffixLabel();
$statePath = $getStatePath();
$placeholder = $getPlaceholder();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
:inline-suffix="$isSuffixInline"
:prefix="$prefixLabel"
:prefix-actions="$prefixActions"
:prefix-icon="$prefixIcon"
:prefix-icon-color="$prefixIconColor"
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$suffixIconColor"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class('fi-fo-color-picker')
"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('color-picker', 'filament/forms') }}"
x-data="colorPickerFormComponent({
isAutofocused: @js($isAutofocused()),
isDisabled: @js($isDisabled),
isLive: @js($isLive),
isLiveDebounced: @js($isLiveDebounced),
isLiveOnBlur: @js($isLiveOnBlur),
liveDebounce: @js($liveDebounce),
state: $wire.$entangle('{{ $statePath }}'),
})"
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
{{ $getExtraAlpineAttributeBag()->class(['fi-input-wrp-content']) }}
>
<input
x-on:focus="$refs.panel.open($refs.input)"
x-on:keydown.enter.prevent.stop="togglePanelVisibility()"
x-ref="input"
{{
$getExtraInputAttributeBag()
->merge([
'autocomplete' => 'off',
'disabled' => $isDisabled,
'id' => $getId(),
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'required' => $isRequired() && (! $isConcealed()),
'type' => 'text',
'x-model' . ($isLiveDebounced ? '.debounce.' . $liveDebounce : null) => 'state',
'x-on:blur' => $isLiveOnBlur ? 'isOpen() ? null : commitState()' : null,
], escape: false)
->class([
'fi-input',
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
])
}}
/>
<div
class="fi-fo-color-picker-preview my-auto me-3 size-5 shrink-0 rounded-full select-none"
x-on:click="togglePanelVisibility()"
x-bind:class="{
'fi-empty': ! state,
}"
x-bind:style="{ 'background-color': state }"
></div>
<div
wire:ignore.self
wire:key="{{ $getLivewireKey() }}.panel"
x-cloak
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
x-ref="panel"
class="fi-fo-color-picker-panel"
>
@php
$tag = match ($getFormat()) {
'hsl' => 'hsl-string',
'rgb' => 'rgb-string',
'rgba' => 'rgba-string',
default => 'hex',
} . '-color-picker';
@endphp
<{{ $tag }} color="{{ $getState() }}" />
</div>
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,294 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$datalistOptions = $getDatalistOptions();
$disabledDates = $getDisabledDates();
$extraAlpineAttributes = $getExtraAlpineAttributes();
$extraAttributeBag = $getExtraAttributeBag();
$extraInputAttributeBag = $getExtraInputAttributeBag();
$hasDate = $hasDate();
$hasTime = $hasTime();
$hasSeconds = $hasSeconds();
$id = $getId();
$isDisabled = $isDisabled();
$isAutofocused = $isAutofocused();
$isPrefixInline = $isPrefixInline();
$isSuffixInline = $isSuffixInline();
$maxDate = $getMaxDate();
$minDate = $getMinDate();
$prefixActions = $getPrefixActions();
$prefixIcon = $getPrefixIcon();
$prefixIconColor = $getPrefixIconColor();
$prefixLabel = $getPrefixLabel();
$suffixActions = $getSuffixActions();
$suffixIcon = $getSuffixIcon();
$suffixIconColor = $getSuffixIconColor();
$suffixLabel = $getSuffixLabel();
$statePath = $getStatePath();
$placeholder = $getPlaceholder();
$isReadOnly = $isReadOnly();
$isRequired = $isRequired();
$isConcealed = $isConcealed();
$step = $getStep();
$type = $getType();
$livewireKey = $getLivewireKey();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
:inline-suffix="$isSuffixInline"
:prefix="$prefixLabel"
:prefix-actions="$prefixActions"
:prefix-icon="$prefixIcon"
:prefix-icon-color="$prefixIconColor"
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$suffixIconColor"
:valid="! $errors->has($statePath)"
:attributes="\Filament\Support\prepare_inherited_attributes($extraAttributeBag)->class(['fi-fo-date-time-picker'])"
>
@if ($isNative())
<input
{{
$extraInputAttributeBag
->merge($extraAlpineAttributes, escape: false)
->merge([
'autofocus' => $isAutofocused,
'disabled' => $isDisabled,
'id' => $id,
'list' => $datalistOptions ? $id . '-list' : null,
'max' => $hasTime ? $maxDate : ($maxDate ? \Carbon\Carbon::parse($maxDate)->toDateString() : null),
'min' => $hasTime ? $minDate : ($minDate ? \Carbon\Carbon::parse($minDate)->toDateString() : null),
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'readonly' => $isReadOnly,
'required' => $isRequired && (! $isConcealed),
'step' => $step,
'type' => $type,
$applyStateBindingModifiers('wire:model') => $statePath,
'x-data' => count($extraAlpineAttributes) ? '{}' : null,
], escape: false)
->class([
'fi-input',
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
])
}}
/>
@else
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('date-time-picker', 'filament/forms') }}"
x-data="dateTimePickerFormComponent({
defaultFocusedDate: @js($defaultFocusedDate),
displayFormat:
'{{ convert_date_format($getDisplayFormat())->to('day.js') }}',
firstDayOfWeek: {{ $getFirstDayOfWeek() }},
isAutofocused: @js($isAutofocused),
locale: @js($getLocale()),
shouldCloseOnDateSelection: @js($shouldCloseOnDateSelection()),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$disabledDates,
$isDisabled,
$isReadOnly,
$maxDate,
$minDate,
$hasDate,
$hasTime,
$hasSeconds,
])), 0, 64)
}}"
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
{{ $getExtraAlpineAttributeBag() }}
>
<input x-ref="maxDate" type="hidden" value="{{ $maxDate }}" />
<input x-ref="minDate" type="hidden" value="{{ $minDate }}" />
<input
x-ref="disabledDates"
type="hidden"
value="{{ json_encode($disabledDates) }}"
/>
<button
x-ref="button"
x-on:click="togglePanelVisibility()"
x-on:keydown.enter.prevent.stop="
if (! $el.disabled) {
isOpen() ? selectDate() : togglePanelVisibility()
}
"
x-on:keydown.arrow-left.prevent.stop="if (! $el.disabled) focusPreviousDay()"
x-on:keydown.arrow-right.prevent.stop="if (! $el.disabled) focusNextDay()"
x-on:keydown.arrow-up.prevent.stop="if (! $el.disabled) focusPreviousWeek()"
x-on:keydown.arrow-down.prevent.stop="if (! $el.disabled) focusNextWeek()"
x-on:keydown.backspace.prevent.stop="if (! $el.disabled) clearState()"
x-on:keydown.clear.prevent.stop="if (! $el.disabled) clearState()"
x-on:keydown.delete.prevent.stop="if (! $el.disabled) clearState()"
aria-label="{{ $placeholder }}"
type="button"
tabindex="-1"
@disabled($isDisabled || $isReadOnly)
{{
$getExtraTriggerAttributeBag()->class([
'fi-fo-date-time-picker-trigger',
])
}}
>
<input
@disabled($isDisabled)
readonly
placeholder="{{ $placeholder }}"
wire:key="{{ $livewireKey }}.display-text"
x-model="displayText"
@if ($id = $getId()) id="{{ $id }}" @endif
@class([
'fi-fo-date-time-picker-display-text-input',
])
/>
</button>
<div
x-ref="panel"
x-cloak
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
wire:ignore
wire:key="{{ $livewireKey }}.panel"
@class([
'fi-fo-date-time-picker-panel',
])
>
@if ($hasDate)
<div class="fi-fo-date-time-picker-panel-header">
<select
x-model="focusedMonth"
class="fi-fo-date-time-picker-month-select"
>
<template x-for="(month, index) in months">
<option
x-bind:value="index"
x-text="month"
></option>
</template>
</select>
<input
type="number"
inputmode="numeric"
x-model.debounce="focusedYear"
class="fi-fo-date-time-picker-year-input"
/>
</div>
<div class="fi-fo-date-time-picker-calendar-header">
<template
x-for="(day, index) in dayLabels"
x-bind:key="index"
>
<div
x-text="day"
class="fi-fo-date-time-picker-calendar-header-day"
></div>
</template>
</div>
<div
role="grid"
class="fi-fo-date-time-picker-calendar"
>
<template
x-for="day in emptyDaysInFocusedMonth"
x-bind:key="day"
>
<div></div>
</template>
<template
x-for="day in daysInFocusedMonth"
x-bind:key="day"
>
<div
x-text="day"
x-on:click="dayIsDisabled(day) || selectDate(day)"
x-on:mouseenter="setFocusedDay(day)"
role="option"
x-bind:aria-selected="focusedDate.date() === day"
x-bind:class="{
'fi-fo-date-time-picker-calendar-day-today': dayIsToday(day),
'fi-focused': focusedDate.date() === day,
'fi-selected': dayIsSelected(day),
'fi-disabled': dayIsDisabled(day),
}"
class="fi-fo-date-time-picker-calendar-day"
></div>
</template>
</div>
@endif
@if ($hasTime)
<div class="fi-fo-date-time-picker-time-inputs">
<input
max="23"
min="0"
step="{{ $getHoursStep() }}"
type="number"
inputmode="numeric"
x-model.debounce="hour"
/>
<span
class="fi-fo-date-time-picker-time-input-separator"
>
:
</span>
<input
max="59"
min="0"
step="{{ $getMinutesStep() }}"
type="number"
inputmode="numeric"
x-model.debounce="minute"
/>
@if ($hasSeconds)
<span
class="fi-fo-date-time-picker-time-input-separator"
>
:
</span>
<input
max="59"
min="0"
step="{{ $getSecondsStep() }}"
type="number"
inputmode="numeric"
x-model.debounce="second"
/>
@endif
</div>
@endif
</div>
</div>
@endif
</x-filament::input.wrapper>
@if ($datalistOptions)
<datalist id="{{ $id }}-list">
@foreach ($datalistOptions as $option)
<option value="{{ $option }}" />
@endforeach
</datalist>
@endif
</x-dynamic-component>

View File

@@ -1,197 +0,0 @@
@php
use Filament\Support\Enums\VerticalAlignment;
@endphp
@props([
'areHtmlErrorMessagesAllowed' => null,
'errorMessage' => null,
'errorMessages' => null,
'field' => null,
'hasErrors' => true,
'hasInlineLabel' => null,
'hasNestedRecursiveValidationRules' => null,
'id' => null,
'inlineLabelVerticalAlignment' => VerticalAlignment::Start,
'isDisabled' => null,
'label' => null,
'labelPrefix' => null,
'labelSrOnly' => null,
'labelSuffix' => null,
'labelTag' => 'label',
'required' => null,
'shouldShowAllValidationMessages' => null,
'statePath' => null,
])
@php
use Illuminate\Support\Arr;
if ($field) {
$hasInlineLabel ??= $field->hasInlineLabel();
$hasNestedRecursiveValidationRules ??= $field instanceof \Filament\Forms\Components\Contracts\HasNestedRecursiveValidationRules;
$id ??= $field->getId();
$isDisabled ??= $field->isDisabled();
$label ??= $field->getLabel();
$labelSrOnly ??= $field->isLabelHidden();
$required ??= $field->isMarkedAsRequired();
$statePath ??= $field->getStatePath();
$areHtmlErrorMessagesAllowed ??= $field->areHtmlValidationMessagesAllowed();
$shouldShowAllValidationMessages ??= $field->shouldShowAllValidationMessages();
}
$aboveLabelSchema = $field?->getChildSchema($field::ABOVE_LABEL_SCHEMA_KEY)?->toHtmlString();
$belowLabelSchema = $field?->getChildSchema($field::BELOW_LABEL_SCHEMA_KEY)?->toHtmlString();
$beforeLabelSchema = $field?->getChildSchema($field::BEFORE_LABEL_SCHEMA_KEY)?->toHtmlString();
$afterLabelSchema = $field?->getChildSchema($field::AFTER_LABEL_SCHEMA_KEY)?->toHtmlString();
$aboveContentSchema = $field?->getChildSchema($field::ABOVE_CONTENT_SCHEMA_KEY)?->toHtmlString();
$belowContentSchema = $field?->getChildSchema($field::BELOW_CONTENT_SCHEMA_KEY)?->toHtmlString();
$beforeContentSchema = $field?->getChildSchema($field::BEFORE_CONTENT_SCHEMA_KEY)?->toHtmlString();
$afterContentSchema = $field?->getChildSchema($field::AFTER_CONTENT_SCHEMA_KEY)?->toHtmlString();
$aboveErrorMessageSchema = $field?->getChildSchema($field::ABOVE_ERROR_MESSAGE_SCHEMA_KEY)?->toHtmlString();
$belowErrorMessageSchema = $field?->getChildSchema($field::BELOW_ERROR_MESSAGE_SCHEMA_KEY)?->toHtmlString();
$hasError = $hasErrors && (filled($errorMessage) || filled($errorMessages) || (filled($statePath) && ($errors->has($statePath) || ($hasNestedRecursiveValidationRules && $errors->has("{$statePath}.*")))));
if ($hasError && filled($statePath) && blank($errorMessage) && blank($errorMessages)) {
if ($shouldShowAllValidationMessages) {
$errorMessages = $errors->has($statePath) ? $errors->get($statePath) : ($hasNestedRecursiveValidationRules ? $errors->get("{$statePath}.*") : []);
if (count($errorMessages) === 1) {
$errorMessage = Arr::first($errorMessages);
$errorMessages = [];
}
} else {
$errorMessage = $errors->has($statePath) ? $errors->first($statePath) : ($hasNestedRecursiveValidationRules ? $errors->first("{$statePath}.*") : null);
}
}
@endphp
<div
data-field-wrapper
{{
$attributes
->merge($field?->getExtraFieldWrapperAttributes() ?? [], escape: false)
->class([
'fi-fo-field',
'fi-fo-field-has-inline-label' => $hasInlineLabel,
])
}}
>
@if (filled($label) && $labelSrOnly)
<{{ $labelTag }}
@if ($labelTag === 'label')
for="{{ $id }}"
@else
id="{{ $id }}-label"
@endif
class="fi-fo-field-label fi-sr-only"
>
{{ $label }}
</{{ $labelTag }}>
@endif
@if ((filled($label) && (! $labelSrOnly)) || $hasInlineLabel || $aboveLabelSchema || $belowLabelSchema || $beforeLabelSchema || $afterLabelSchema || $labelPrefix || $labelSuffix)
<div
@class([
'fi-fo-field-label-col',
"fi-vertical-align-{$inlineLabelVerticalAlignment->value}" => $hasInlineLabel,
])
>
{{ $aboveLabelSchema }}
<div
@class([
'fi-fo-field-label-ctn',
($label instanceof \Illuminate\View\ComponentSlot) ? $label->attributes->get('class') : null,
])
>
{{ $beforeLabelSchema }}
@if ((filled($label) && (! $labelSrOnly)) || $labelPrefix || $labelSuffix)
<{{ $labelTag }}
@if ($labelTag === 'label')
for="{{ $id }}"
@else
id="{{ $id }}-label"
@endif
class="fi-fo-field-label"
>
{{ $labelPrefix }}
@if (filled($label) && (! $labelSrOnly))
<span class="fi-fo-field-label-content">
{{ $label }}@if ($required && (! $isDisabled))<sup class="fi-fo-field-label-required-mark">*</sup>
@endif
</span>
@endif
{{ $labelSuffix }}
</{{ $labelTag }}>
@endif
{{ $afterLabelSchema }}
</div>
{{ $belowLabelSchema }}
</div>
@endif
@if ((! \Filament\Support\is_slot_empty($slot)) || $hasError || $aboveContentSchema || $belowContentSchema || $beforeContentSchema || $afterContentSchema || $aboveErrorMessageSchema || $belowErrorMessageSchema)
<div class="fi-fo-field-content-col">
{{ $aboveContentSchema }}
@if ($beforeContentSchema || $afterContentSchema)
<div class="fi-fo-field-content-ctn">
{{ $beforeContentSchema }}
<div class="fi-fo-field-content">
{{ $slot }}
</div>
{{ $afterContentSchema }}
</div>
@else
{{ $slot }}
@endif
{{ $belowContentSchema }}
@if ($hasError)
{{ $aboveErrorMessageSchema }}
@if (filled($errorMessages))
<ul
data-validation-error
class="fi-fo-field-wrp-error-list"
>
@foreach ($errorMessages as $errorMessage)
<li class="fi-fo-field-wrp-error-message">
@if ($areHtmlErrorMessagesAllowed)
{!! $errorMessage !!}
@else
{{ $errorMessage }}
@endif
</li>
@endforeach
</ul>
@elseif ($areHtmlErrorMessagesAllowed)
<div
data-validation-error
class="fi-fo-field-wrp-error-message"
>
{!! $errorMessage !!}
</div>
@else
<p
data-validation-error
class="fi-fo-field-wrp-error-message"
>
{{ $errorMessage }}
</p>
@endif
{{ $belowErrorMessageSchema }}
@endif
</div>
@endif
</div>

View File

@@ -1,344 +0,0 @@
@php
use Filament\Support\Enums\Alignment;
$fieldWrapperView = $getFieldWrapperView();
$id = $getId();
$imageCropAspectRatio = $getImageCropAspectRatio();
$imageResizeTargetHeight = $getImageResizeTargetHeight();
$imageResizeTargetWidth = $getImageResizeTargetWidth();
$isAvatar = $isAvatar();
$isMultiple = $isMultiple();
$key = $getKey();
$statePath = $getStatePath();
$isDisabled = $isDisabled();
$hasImageEditor = $hasImageEditor();
$hasCircleCropper = $hasCircleCropper();
$livewireKey = $getLivewireKey();
$alignment = $getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
label-tag="div"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('file-upload', 'filament/forms') }}"
x-data="fileUploadFormComponent({
acceptedFileTypes: @js($getAcceptedFileTypes()),
imageEditorEmptyFillColor: @js($getImageEditorEmptyFillColor()),
imageEditorMode: @js($getImageEditorMode()),
imageEditorViewportHeight: @js($getImageEditorViewportHeight()),
imageEditorViewportWidth: @js($getImageEditorViewportWidth()),
deleteUploadedFileUsing: async (fileKey) => {
return await $wire.callSchemaComponentMethod(
@js($key),
'deleteUploadedFile',
{ fileKey },
)
},
getUploadedFilesUsing: async () => {
return await $wire.callSchemaComponentMethod(
@js($key),
'getUploadedFiles',
)
},
hasImageEditor: @js($hasImageEditor),
hasCircleCropper: @js($hasCircleCropper),
canEditSvgs: @js($canEditSvgs()),
isSvgEditingConfirmed: @js($isSvgEditingConfirmed()),
confirmSvgEditingMessage: @js(__('filament-forms::components.file_upload.editor.svg.messages.confirmation')),
disabledSvgEditingMessage: @js(__('filament-forms::components.file_upload.editor.svg.messages.disabled')),
imageCropAspectRatio: @js($imageCropAspectRatio),
imagePreviewHeight: @js($getImagePreviewHeight()),
imageResizeMode: @js($getImageResizeMode()),
imageResizeTargetHeight: @js($imageResizeTargetHeight),
imageResizeTargetWidth: @js($imageResizeTargetWidth),
imageResizeUpscale: @js($getImageResizeUpscale()),
isAvatar: @js($isAvatar),
isDeletable: @js($isDeletable()),
isDisabled: @js($isDisabled),
isDownloadable: @js($isDownloadable()),
isMultiple: @js($isMultiple),
isOpenable: @js($isOpenable()),
isPasteable: @js($isPasteable()),
isPreviewable: @js($isPreviewable()),
isReorderable: @js($isReorderable()),
itemPanelAspectRatio: @js($getItemPanelAspectRatio()),
loadingIndicatorPosition: @js($getLoadingIndicatorPosition()),
locale: @js(app()->getLocale()),
panelAspectRatio: @js($getPanelAspectRatio()),
panelLayout: @js($getPanelLayout()),
placeholder: @js($getPlaceholder()),
maxFiles: @js($maxFiles = $getMaxFiles()),
maxFilesValidationMessage: @js($maxFiles ? trans_choice('validation.max.array', $maxFiles, ['attribute' => $getValidationAttribute(), 'max' => $maxFiles]) : null),
maxSize: @js(($size = $getMaxSize()) ? "{$size}KB" : null),
minSize: @js(($size = $getMinSize()) ? "{$size}KB" : null),
mimeTypeMap: @js($getMimeTypeMap()),
maxParallelUploads: @js($getMaxParallelUploads()),
removeUploadedFileUsing: async (fileKey) => {
return await $wire.callSchemaComponentMethod(
@js($key),
'removeUploadedFile',
{ fileKey },
)
},
removeUploadedFileButtonPosition: @js($getRemoveUploadedFileButtonPosition()),
reorderUploadedFilesUsing: async (fileKeys) => {
return await $wire.callSchemaComponentMethod(
@js($key),
'reorderUploadedFiles',
{ fileKeys },
)
},
shouldAppendFiles: @js($shouldAppendFiles()),
shouldOrientImageFromExif: @js($shouldOrientImagesFromExif()),
shouldTransformImage: @js($imageCropAspectRatio || $imageResizeTargetHeight || $imageResizeTargetWidth),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
uploadButtonPosition: @js($getUploadButtonPosition()),
uploadingMessage: @js($getUploadingMessage()),
uploadProgressIndicatorPosition: @js($getUploadProgressIndicatorPosition()),
uploadUsing: (fileKey, file, success, error, progress) => {
$wire.upload(
`{{ $statePath }}.${fileKey}`,
file,
() => {
success(fileKey)
},
error,
(progressEvent) => {
progress(true, progressEvent.detail.progress, 100)
},
)
},
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
])), 0, 64)
}}"
{{
$attributes
->merge([
'aria-labelledby' => "{$id}-label",
'id' => $id,
'role' => 'group',
], escape: false)
->merge($getExtraAttributes(), escape: false)
->merge($getExtraAlpineAttributes(), escape: false)
->class([
'fi-fo-file-upload',
'fi-fo-file-upload-avatar' => $isAvatar,
($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : $alignment,
])
}}
>
<div class="fi-fo-file-upload-input-ctn">
<input
x-ref="input"
{{
$getExtraInputAttributeBag()
->merge([
'aria-labelledby' => "{$id}-label",
'disabled' => $isDisabled,
'multiple' => $isMultiple,
'type' => 'file',
], escape: false)
}}
/>
</div>
<div
x-show="error"
x-text="error"
x-cloak
class="fi-fo-file-upload-error-message"
></div>
@if ($hasImageEditor && (! $isDisabled))
<div
x-show="isEditorOpen"
x-cloak
x-on:click.stop=""
x-trap.noscroll="isEditorOpen"
x-on:keydown.escape.prevent.stop="closeEditor"
@class([
'fi-fo-file-upload-editor',
'fi-fo-file-upload-editor-circle-cropper' => $hasCircleCropper,
])
>
<div
aria-hidden="true"
class="fi-fo-file-upload-editor-overlay"
></div>
<div class="fi-fo-file-upload-editor-window">
<div class="fi-fo-file-upload-editor-image-ctn">
<img
x-ref="editor"
class="fi-fo-file-upload-editor-image"
/>
</div>
<div class="fi-fo-file-upload-editor-control-panel">
<div
class="fi-fo-file-upload-editor-control-panel-main"
>
<div
class="fi-fo-file-upload-editor-control-panel-group"
>
@foreach ([
[
'label' => __('filament-forms::components.file_upload.editor.fields.x_position.label'),
'ref' => 'xPositionInput',
'unit' => __('filament-forms::components.file_upload.editor.fields.x_position.unit'),
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), x: +$el.value})',
],
[
'label' => __('filament-forms::components.file_upload.editor.fields.y_position.label'),
'ref' => 'yPositionInput',
'unit' => __('filament-forms::components.file_upload.editor.fields.y_position.unit'),
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), y: +$el.value})',
],
[
'label' => __('filament-forms::components.file_upload.editor.fields.width.label'),
'ref' => 'widthInput',
'unit' => __('filament-forms::components.file_upload.editor.fields.width.unit'),
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), width: +$el.value})',
],
[
'label' => __('filament-forms::components.file_upload.editor.fields.height.label'),
'ref' => 'heightInput',
'unit' => __('filament-forms::components.file_upload.editor.fields.height.unit'),
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), height: +$el.value})',
],
[
'label' => __('filament-forms::components.file_upload.editor.fields.rotation.label'),
'ref' => 'rotationInput',
'unit' => __('filament-forms::components.file_upload.editor.fields.rotation.unit'),
'alpineSaveHandler' => 'editor.rotateTo(+$el.value)',
],
] as $input)
<label>
<x-filament::input.wrapper>
<x-slot name="prefix">
{{ $input['label'] }}
</x-slot>
<input
x-on:keyup.enter.prevent.stop="editor && {!! $input['alpineSaveHandler'] !!}"
x-on:blur="editor && {!! $input['alpineSaveHandler'] !!}"
x-ref="{{ $input['ref'] }}"
x-on:keydown.enter.prevent
type="text"
class="fi-input"
/>
<x-slot name="suffix">
{{ $input['unit'] }}
</x-slot>
</x-filament::input.wrapper>
</label>
@endforeach
</div>
<div
class="fi-fo-file-upload-editor-control-panel-group"
>
@foreach ($getImageEditorActions() as $groupedActions)
<div class="fi-btn-group">
@foreach ($groupedActions as $action)
<button
aria-label="{{ $action['label'] }}"
type="button"
x-on:click.prevent.stop="{{ $action['alpineClickHandler'] }}"
x-tooltip="{ content: @js($action['label']), theme: $store.theme }"
class="fi-btn"
>
{{ $action['iconHtml'] }}
</button>
@endforeach
</div>
@endforeach
</div>
@if (count($aspectRatios = $getImageEditorAspectRatiosForJs()))
<div
class="fi-fo-file-upload-editor-control-panel-group"
>
<div
class="fi-fo-file-upload-editor-control-panel-group-title"
>
{{ __('filament-forms::components.file_upload.editor.aspect_ratios.label') }}
</div>
@foreach (collect($aspectRatios)->chunk(5) as $ratiosChunk)
<div class="fi-btn-group">
@foreach ($ratiosChunk as $label => $ratio)
<button
type="button"
x-on:click.prevent.stop="
currentRatio = @js($label) {!! ';' !!}
editor.setAspectRatio(@js($ratio))
"
x-tooltip="{ content: @js(__('filament-forms::components.file_upload.editor.actions.set_aspect_ratio.label', ['ratio' => $label])), theme: $store.theme }"
x-bind:class="{ 'fi-active': currentRatio === @js($label) }"
class="fi-btn"
>
{{ $label }}
</button>
@endforeach
</div>
@endforeach
</div>
@endif
</div>
<div
class="fi-fo-file-upload-editor-control-panel-footer"
>
<button
type="button"
x-on:click.prevent="pond.imageEditEditor.oncancel"
class="fi-btn"
>
{{ __('filament-forms::components.file_upload.editor.actions.cancel.label') }}
</button>
<button
type="button"
x-on:click.prevent.stop="editor.reset()"
{{
(new \Illuminate\View\ComponentAttributeBag)
->color(\Filament\Support\View\Components\ButtonComponent::class, 'danger')
->class(['fi-btn fi-fo-file-upload-editor-control-panel-reset-action'])
}}
>
{{ __('filament-forms::components.file_upload.editor.actions.reset.label') }}
</button>
<button
type="button"
x-on:click.prevent="saveEditor"
{{
(new \Illuminate\View\ComponentAttributeBag)
->color(\Filament\Support\View\Components\ButtonComponent::class, 'success')
->class(['fi-btn'])
}}
>
{{ __('filament-forms::components.file_upload.editor.actions.save.label') }}
</button>
</div>
</div>
</div>
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,12 +0,0 @@
<input
{{
$attributes
->merge([
'id' => $getId(),
'type' => 'hidden',
$applyStateBindingModifiers('wire:model') => $getStatePath(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->class(['fi-fo-hidden'])
}}
/>

View File

@@ -1,148 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributeBag = $getExtraAttributeBag();
$canEditKeys = $canEditKeys();
$canEditValues = $canEditValues();
$keyPlaceholder = $getKeyPlaceholder();
$valuePlaceholder = $getValuePlaceholder();
$debounce = $getLiveDebounce();
$isAddable = $isAddable();
$isDeletable = $isDeletable();
$isDisabled = $isDisabled();
$isReorderable = $isReorderable();
$statePath = $getStatePath();
$livewireKey = $getLivewireKey();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-key-value-wrp"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class(['fi-fo-key-value'])
"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('key-value', 'filament/forms') }}"
x-data="keyValueFormComponent({
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
])), 0, 64)
}}"
{{
$attributes
->merge($getExtraAlpineAttributes(), escape: false)
->class(['fi-fo-key-value-table-ctn'])
}}
>
<table class="fi-fo-key-value-table">
<thead>
<tr>
@if ($isReorderable && (! $isDisabled))
<th
scope="col"
x-show="rows.length"
class="fi-has-action"
></th>
@endif
<th scope="col">
{{ $getKeyLabel() }}
</th>
<th scope="col">
{{ $getValueLabel() }}
</th>
@if ($isDeletable && (! $isDisabled))
<th
scope="col"
x-show="rows.length"
class="fi-has-action"
></th>
@endif
</tr>
</thead>
<tbody
@if ($isReorderable)
x-on:end.stop="reorderRows($event)"
x-sortable
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
@endif
>
<template
x-bind:key="index"
x-for="(row, index) in rows"
>
<tr
@if ($isReorderable)
x-bind:x-sortable-item="row.key"
@endif
>
@if ($isReorderable && (! $isDisabled))
<td class="fi-has-action">
<div
x-sortable-handle
class="fi-fo-key-value-table-row-sortable-handle"
>
{{ $getAction('reorder') }}
</div>
</td>
@endif
<td>
<input
@disabled((! $canEditKeys) || $isDisabled)
placeholder="{{ $keyPlaceholder }}"
type="text"
x-model="row.key"
x-on:input.debounce.{{ $debounce ?? '500ms' }}="updateState"
class="fi-input"
/>
</td>
<td>
<input
@disabled((! $canEditValues) || $isDisabled)
placeholder="{{ $valuePlaceholder }}"
type="text"
x-model="row.value"
x-on:input.debounce.{{ $debounce ?? '500ms' }}="updateState"
class="fi-input"
/>
</td>
@if ($isDeletable && (! $isDisabled))
<td class="fi-has-action">
<div x-on:click="deleteRow(index)">
{{ $getAction('delete') }}
</div>
</td>
@endif
</tr>
</template>
</tbody>
</table>
@if ($isAddable && (! $isDisabled))
<div
x-on:click="addRow"
class="fi-fo-key-value-add-action-ctn"
>
{{ $getAction('add') }}
</div>
@endif
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,30 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributes = $getExtraAttributes();
$id = $getId();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
@if (filled($id) || filled($extraAttributes))
{!! '<div' !!}
{{-- Avoid formatting issues with unclosed elements --}}
{{
$attributes
->merge([
'id' => $id,
], escape: false)
->merge($extraAttributes, escape: false)
}}
>
@endif
@if (filled($key = $getLivewireKey()))
@livewire($getComponent(), $getComponentProperties(), key($key))
@else
@livewire($getComponent(), $getComponentProperties())
@endif
@if (filled($id) || filled($extraAttributes))
{!! '</div>' !!}
{{-- Avoid formatting issues with unclosed elements --}}
@endif
</x-dynamic-component>

View File

@@ -1,77 +0,0 @@
@php
$id = $getId();
$fieldWrapperView = $getFieldWrapperView();
$extraAttributeBag = $getExtraAttributeBag();
$key = $getKey();
$statePath = $getStatePath();
$fileAttachmentsMaxSize = $getFileAttachmentsMaxSize();
$fileAttachmentsAcceptedFileTypes = $getFileAttachmentsAcceptedFileTypes();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
@if ($isDisabled())
<div id="{{ $id }}" class="fi-fo-markdown-editor fi-disabled fi-prose">
{!! str($getState())->markdown($getCommonMarkOptions(), $getCommonMarkExtensions())->sanitizeHtml() !!}
</div>
@else
<x-filament::input.wrapper
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class(['fi-fo-markdown-editor'])
"
>
<div
aria-labelledby="{{ $id }}-label"
id="{{ $id }}"
role="group"
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('markdown-editor', 'filament/forms') }}"
x-data="markdownEditorFormComponent({
canAttachFiles: @js($hasToolbarButton('attachFiles')),
isLiveDebounced: @js($isLiveDebounced()),
isLiveOnBlur: @js($isLiveOnBlur()),
liveDebounce: @js($getNormalizedLiveDebounce()),
maxHeight: @js($getMaxHeight()),
minHeight: @js($getMinHeight()),
placeholder: @js($getPlaceholder()),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')", isOptimisticallyLive: false) }},
toolbarButtons: @js($getToolbarButtons()),
translations: @js(__('filament-forms::components.markdown_editor')),
uploadFileAttachmentUsing: async (file, onSuccess, onError) => {
const acceptedTypes = @js($fileAttachmentsAcceptedFileTypes)
if (acceptedTypes && ! acceptedTypes.includes(file.type)) {
return onError(@js($fileAttachmentsAcceptedFileTypes ? __('filament-forms::components.markdown_editor.file_attachments_accepted_file_types_message', ['values' => implode(', ', $fileAttachmentsAcceptedFileTypes)]) : null))
}
const maxSize = @js($fileAttachmentsMaxSize)
if (maxSize && file.size > +maxSize * 1024) {
return onError(@js($fileAttachmentsMaxSize ? trans_choice('filament-forms::components.markdown_editor.file_attachments_max_size_message', $fileAttachmentsMaxSize, ['max' => $fileAttachmentsMaxSize]) : null))
}
$wire.upload(`componentFileAttachments.{{ $statePath }}`, file, () => {
$wire
.callSchemaComponentMethod(
'{{ $key }}',
'saveUploadedFileAttachmentAndGetUrl',
)
.then((url) => {
if (! url) {
return onError()
}
onSuccess(url)
})
})
},
})"
wire:ignore
{{ $getExtraAlpineAttributeBag() }}
>
<textarea x-ref="editor" x-cloak></textarea>
</div>
</x-filament::input.wrapper>
@endif
</x-dynamic-component>

View File

@@ -1,69 +0,0 @@
@php
use Filament\Forms\Components\TableSelect\Livewire\TableSelectLivewireComponent;
$fieldWrapperView = $getFieldWrapperView();
$extraAttributes = $getExtraAttributes();
$id = $getId();
$isDisabled = $isDisabled();
$isMultiple = $isMultiple();
$hasBadges = $hasBadges();
$badgeColor = $getBadgeColor();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$attributes
->merge([
'id' => $id,
], escape: false)
->merge($extraAttributes, escape: false)
->class([
'fi-fo-modal-table-select',
'fi-fo-modal-table-select-disabled' => $isDisabled,
'fi-fo-modal-table-select-multiple' => $isMultiple,
])
}}
>
@if (((! $isMultiple) && filled($optionLabel = $getOptionLabel())) ||
($isMultiple && filled($optionLabels = $getOptionLabels())))
@if ($isMultiple && $hasBadges)
<div class="fi-fo-modal-table-select-badges-ctn">
@foreach ($optionLabels as $optionLabel)
@if ($hasBadges)
<x-filament::badge :color="$badgeColor">
{{ $optionLabel }}
</x-filament::badge>
@else
{{ $optionLabel }}
@endif
@endforeach
</div>
@else
<div>
@if ($hasBadges)
<x-filament::badge :color="$badgeColor">
{{ $optionLabel }}
</x-filament::badge>
@elseif ($isMultiple)
@foreach ($optionLabels as $optionLabel)
{{ $optionLabel . ($loop->last ? '' : ', ') }}
@endforeach
@else
{{ $optionLabel }}
@endif
</div>
@endif
@elseif (filled($placeholder = $getPlaceholder()))
<div class="fi-fo-modal-table-select-placeholder">
{{ $placeholder }}
</div>
@endif
@if (! $isDisabled)
<div>
{{ $getAction('select') }}
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,24 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$placeholder = $getPlaceholder();
$extraAttributes = $getExtraAttributeBag()
->merge($getExtraInputAttributes(), escape: false)
->merge($getExtraAlpineAttributes(), escape: false)
->merge([
'autocomplete' => false,
'autofocus' => $isAutofocused(),
'disabled' => $isDisabled(),
'id' => $getId(),
'length' => $getLength(),
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'readonly' => $isReadOnly(),
'required' => $isRequired() && (! $isConcealed()),
$applyStateBindingModifiers('wire:model') => $getStatePath(),
], escape: false);
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<x-filament::input.one-time-code
:attributes="\Filament\Support\prepare_inherited_attributes($extraAttributes)"
/>
</x-dynamic-component>

View File

@@ -1,41 +0,0 @@
@props([
'field' => null,
'id' => null,
'label' => null,
'labelTag' => 'label',
])
@php
use Illuminate\View\ComponentAttributeBag;
if ($field) {
$id ??= $field->getId();
$label ??= $field->getLabel();
}
@endphp
<div
data-field-wrapper
{{
(new ComponentAttributeBag)
->merge($field?->getExtraFieldWrapperAttributes() ?? [], escape: false)
->class([
'fi-fo-field',
])
}}
>
@if (filled($label))
<{{ $labelTag }}
@if ($labelTag === 'label')
for="{{ $id }}"
@else
id="{{ $id }}-label"
@endif
class="fi-fo-field-label fi-sr-only"
>
{{ $label }}
</{{ $labelTag }}>
@endif
{{ $slot }}
</div>

View File

@@ -1,64 +0,0 @@
@php
use Filament\Support\Enums\GridDirection;
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$extraInputAttributeBag = $getExtraInputAttributeBag();
$gridDirection = $getGridDirection() ?? GridDirection::Column;
$id = $getId();
$isDisabled = $isDisabled();
$isInline = $isInline();
$statePath = $getStatePath();
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$getExtraAttributeBag()
->when(! $isInline, fn (ComponentAttributeBag $attributes) => $attributes->grid($getColumns(), $gridDirection))
->class([
'fi-fo-radio',
'fi-inline' => $isInline,
])
}}
>
@foreach ($getOptions() as $value => $label)
@php
$inputAttributes = $extraInputAttributeBag
->merge([
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
'id' => $id . '-' . $value,
'name' => $id,
'value' => $value,
$wireModelAttribute => $statePath,
], escape: false);
@endphp
<label class="fi-fo-radio-label">
<input
type="radio"
{{
$inputAttributes->class([
'fi-radio-input',
'fi-valid' => ! $errors->has($statePath),
'fi-invalid' => $errors->has($statePath),
])
}}
/>
<div class="fi-fo-radio-label-text">
<p>
{{ $label }}
</p>
@if ($hasDescription($value))
<p class="fi-fo-radio-label-description">
{{ $getDescription($value) }}
</p>
@endif
</div>
</label>
@endforeach
</div>
</x-dynamic-component>

View File

@@ -1,263 +0,0 @@
@php
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$items = $getItems();
$addAction = $getAction($getAddActionName());
$addActionAlignment = $getAddActionAlignment();
$addBetweenAction = $getAction($getAddBetweenActionName());
$cloneAction = $getAction($getCloneActionName());
$collapseAllAction = $getAction($getCollapseAllActionName());
$expandAllAction = $getAction($getExpandAllActionName());
$deleteAction = $getAction($getDeleteActionName());
$moveDownAction = $getAction($getMoveDownActionName());
$moveUpAction = $getAction($getMoveUpActionName());
$reorderAction = $getAction($getReorderActionName());
$extraItemActions = $getExtraItemActions();
$hasItemNumbers = $hasItemNumbers();
$hasItemHeaders = $hasItemHeaders();
$isAddable = $isAddable();
$isCloneable = $isCloneable();
$isCollapsible = $isCollapsible();
$isDeletable = $isDeletable();
$isReorderableWithButtons = $isReorderableWithButtons();
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
$collapseAllActionIsVisible = $isCollapsible && $collapseAllAction->isVisible();
$expandAllActionIsVisible = $isCollapsible && $expandAllAction->isVisible();
$key = $getKey();
$statePath = $getStatePath();
$itemLabelHeadingTag = $getHeadingTag();
$isItemLabelTruncated = $isItemLabelTruncated();
$labelBetweenItems = $getLabelBetweenItems();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-fo-repeater',
'fi-collapsible' => $isCollapsible,
])
}}
>
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
<div
@class([
'fi-fo-repeater-actions',
'fi-hidden' => count($items) < 2,
])
>
@if ($collapseAllActionIsVisible)
<span
x-on:click="$dispatch('repeater-collapse', '{{ $statePath }}')"
>
{{ $collapseAllAction }}
</span>
@endif
@if ($expandAllActionIsVisible)
<span
x-on:click="$dispatch('repeater-expand', '{{ $statePath }}')"
>
{{ $expandAllAction }}
</span>
@endif
</div>
@endif
@if (count($items))
<ul
x-sortable
{{
(new ComponentAttributeBag)
->grid($getGridColumns())
->merge([
'data-sortable-animation-duration' => $getReorderAnimationDuration(),
'x-on:end.stop' => '$event.oldDraggableIndex !== $event.newDraggableIndex && $wire.mountAction(\'reorder\', { items: $event.target.sortable.toArray() }, { schemaComponent: \'' . $key . '\' })',
], escape: false)
->class(['fi-fo-repeater-items'])
}}
>
@foreach ($items as $itemKey => $item)
@php
$itemLabel = $getItemLabel($itemKey);
$visibleExtraItemActions = array_filter(
$extraItemActions,
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
);
$cloneAction = $cloneAction(['item' => $itemKey]);
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
$deleteAction = $deleteAction(['item' => $itemKey]);
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
$hasItemHeader = $hasItemHeaders && ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || filled($itemLabel) || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions);
@endphp
<li
wire:ignore.self
wire:key="{{ $item->getLivewireKey() }}.item"
x-data="{
isCollapsed: @js($isCollapsed($item)),
}"
x-on:repeater-expand.window="$event.detail === '{{ $statePath }}' && (isCollapsed = false)"
x-on:repeater-collapse.window="$event.detail === '{{ $statePath }}' && (isCollapsed = true)"
x-on:expand="isCollapsed = false"
x-sortable-item="{{ $itemKey }}"
@class([
'fi-fo-repeater-item',
'fi-fo-repeater-item-has-header' => $hasItemHeader,
])
x-bind:class="{ 'fi-collapsed': isCollapsed }"
>
@if ($hasItemHeader)
<div
@if ($isCollapsible)
x-on:click.stop="isCollapsed = !isCollapsed"
@endif
class="fi-fo-repeater-item-header"
>
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
<ul
class="fi-fo-repeater-item-header-start-actions"
>
@if ($reorderActionIsVisible)
<li x-on:click.stop>
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
</li>
@endif
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
<li x-on:click.stop>
{{ $moveUpAction }}
</li>
<li x-on:click.stop>
{{ $moveDownAction }}
</li>
@endif
</ul>
@endif
@if (filled($itemLabel))
<{{ $itemLabelHeadingTag }}
@class([
'fi-fo-repeater-item-header-label',
'fi-truncated' => $isItemLabelTruncated,
])
>
{{ $itemLabel }}
@if ($hasItemNumbers)
{{ $loop->iteration }}
@endif
</{{ $itemLabelHeadingTag }}>
@endif
@if ($cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
<ul
class="fi-fo-repeater-item-header-end-actions"
>
@foreach ($visibleExtraItemActions as $extraItemAction)
<li x-on:click.stop>
{{ $extraItemAction(['item' => $itemKey]) }}
</li>
@endforeach
@if ($cloneActionIsVisible)
<li x-on:click.stop>
{{ $cloneAction }}
</li>
@endif
@if ($deleteActionIsVisible)
<li x-on:click.stop>
{{ $deleteAction }}
</li>
@endif
@if ($isCollapsible)
<li
class="fi-fo-repeater-item-header-collapsible-actions"
x-on:click.stop="isCollapsed = !isCollapsed"
>
<div
class="fi-fo-repeater-item-header-collapse-action"
>
{{ $getAction('collapse') }}
</div>
<div
class="fi-fo-repeater-item-header-expand-action"
>
{{ $getAction('expand') }}
</div>
</li>
@endif
</ul>
@endif
</div>
@endif
<div
x-show="! isCollapsed"
class="fi-fo-repeater-item-content"
>
{{ $item }}
</div>
</li>
@if (! $loop->last)
@if ($isAddable && $addBetweenAction(['afterItem' => $itemKey])->isVisible())
<li class="fi-fo-repeater-add-between-items-ctn">
<div class="fi-fo-repeater-add-between-items">
{{ $addBetweenAction(['afterItem' => $itemKey]) }}
</div>
</li>
@elseif (filled($labelBetweenItems))
<li class="fi-fo-repeater-label-between-items-ctn">
<div
class="fi-fo-repeater-label-between-items-divider-before"
></div>
<span
class="fi-fo-repeater-label-between-items"
>
{{ $labelBetweenItems }}
</span>
<div
class="fi-fo-repeater-label-between-items-divider-after"
></div>
</li>
@endif
@endif
@endforeach
</ul>
@endif
@if ($isAddable && $addAction->isVisible())
<div
@class([
'fi-fo-repeater-add',
($addActionAlignment instanceof Alignment) ? ('fi-align-' . $addActionAlignment->value) : $addActionAlignment,
])
>
{{ $addAction }}
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,129 +0,0 @@
@php
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$items = $getItems();
$addAction = $getAction($getAddActionName());
$addActionAlignment = $getAddActionAlignment();
$cloneAction = $getAction($getCloneActionName());
$deleteAction = $getAction($getDeleteActionName());
$moveDownAction = $getAction($getMoveDownActionName());
$moveUpAction = $getAction($getMoveUpActionName());
$reorderAction = $getAction($getReorderActionName());
$extraItemActions = $getExtraItemActions();
$isAddable = $isAddable();
$isCloneable = $isCloneable();
$isDeletable = $isDeletable();
$isReorderableWithButtons = $isReorderableWithButtons();
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
$key = $getKey();
$statePath = $getStatePath();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class(['fi-fo-simple-repeater'])
}}
>
@if (count($items))
<ul
x-sortable
{{
(new ComponentAttributeBag)
->grid($getGridColumns())
->merge([
'data-sortable-animation-duration' => $getReorderAnimationDuration(),
'x-on:end.stop' => '$event.oldDraggableIndex !== $event.newDraggableIndex && $wire.mountAction(\'reorder\', { items: $event.target.sortable.toArray() }, { schemaComponent: \'' . $key . '\' })',
], escape: false)
->class(['fi-fo-simple-repeater-items'])
}}
>
@foreach ($items as $itemKey => $item)
@php
$visibleExtraItemActions = array_filter(
$extraItemActions,
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
);
$cloneAction = $cloneAction(['item' => $itemKey]);
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
$deleteAction = $deleteAction(['item' => $itemKey]);
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
@endphp
<li
wire:key="{{ $item->getLivewireKey() }}.item"
x-sortable-item="{{ $itemKey }}"
class="fi-fo-simple-repeater-item"
>
<div class="fi-fo-simple-repeater-item-content">
{{ $item }}
</div>
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $visibleExtraItemActions)
<ul class="fi-fo-simple-repeater-item-actions">
@if ($reorderActionIsVisible)
<li x-on:click.stop>
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
</li>
@endif
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
<li x-on:click.stop>
{{ $moveUpAction }}
</li>
<li x-on:click.stop>
{{ $moveDownAction }}
</li>
@endif
@foreach ($visibleExtraItemActions as $extraItemAction)
<li x-on:click.stop>
{{ $extraItemAction(['item' => $itemKey]) }}
</li>
@endforeach
@if ($cloneActionIsVisible)
<li x-on:click.stop>
{{ $cloneAction }}
</li>
@endif
@if ($deleteActionIsVisible)
<li x-on:click.stop>
{{ $deleteAction }}
</li>
@endif
</ul>
@endif
</li>
@endforeach
</ul>
@endif
@if ($isAddable && $addAction->isVisible())
<div
@class([
'fi-fo-simple-repeater-add',
($addActionAlignment instanceof Alignment) ? ('fi-align-' . $addActionAlignment->value) : $addActionAlignment,
])
>
{{ $addAction }}
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,231 +0,0 @@
@php
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Support\Enums\Alignment;
use Illuminate\Support\Js;
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$items = $getItems();
$addAction = $getAction($getAddActionName());
$addActionAlignment = $getAddActionAlignment();
$addBetweenAction = $getAction($getAddBetweenActionName());
$cloneAction = $getAction($getCloneActionName());
$deleteAction = $getAction($getDeleteActionName());
$moveDownAction = $getAction($getMoveDownActionName());
$moveUpAction = $getAction($getMoveUpActionName());
$reorderAction = $getAction($getReorderActionName());
$extraItemActions = $getExtraItemActions();
$isAddable = $isAddable();
$isCloneable = $isCloneable();
$isDeletable = $isDeletable();
$isReorderableWithButtons = $isReorderableWithButtons();
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
$key = $getKey();
$statePath = $getStatePath();
$tableColumns = $getTableColumns();
$isCompact = $isCompact();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{ $attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-fo-table-repeater',
'fi-compact' => $isCompact,
]) }}
>
@if (count($items))
<table>
<thead>
<tr>
@if ((count($items) > 1) && ($isReorderableWithButtons || $isReorderableWithDragAndDrop))
<th
class="fi-fo-table-repeater-empty-header-cell"
></th>
@endif
@foreach ($tableColumns as $column)
<th
@class([
'fi-wrapped' => $column->canHeaderWrap(),
(($columnAlignment = $column->getAlignment()) instanceof Alignment) ? ('fi-align-' . $columnAlignment->value) : $columnAlignment,
])
@style([
('width: ' . ($columnWidth = $column->getWidth())) => filled($columnWidth),
])
>
@if (! $column->isHeaderLabelHidden())
{{ $column->getLabel() }}@if ($column->isMarkedAsRequired())<sup class="fi-fo-table-repeater-header-required-mark">*</sup>
@endif
@else
<span class="fi-sr-only">
{{ $column->getLabel() }}
</span>
@endif
</th>
@endforeach
@if (count($extraItemActions) || $isCloneable || $isDeletable)
<th
class="fi-fo-table-repeater-empty-header-cell"
></th>
@endif
</tr>
</thead>
<tbody
x-sortable
{{ (new ComponentAttributeBag)
->merge([
'data-sortable-animation-duration' => $getReorderAnimationDuration(),
'x-on:end.stop' => '$event.oldDraggableIndex !== $event.newDraggableIndex && $wire.mountAction(\'reorder\', { items: $event.target.sortable.toArray() }, { schemaComponent: \'' . $key . '\' })',
], escape: false) }}
>
@foreach ($items as $itemKey => $item)
@php
$visibleExtraItemActions = array_filter(
$extraItemActions,
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
);
$cloneAction = $cloneAction(['item' => $itemKey]);
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
$deleteAction = $deleteAction(['item' => $itemKey]);
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
$itemStatePath = $item->getStatePath();
@endphp
<tr
wire:key="{{ $item->getLivewireKey() }}.item"
x-sortable-item="{{ $itemKey }}"
>
@if ((count($items) > 1) && ($isReorderableWithButtons || $isReorderableWithDragAndDrop))
<td>
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
<div
class="fi-fo-table-repeater-actions"
>
@if ($reorderActionIsVisible)
<div x-on:click.stop>
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
</div>
@endif
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
<div x-on:click.stop>
{{ $moveUpAction }}
</div>
<div x-on:click.stop>
{{ $moveDownAction }}
</div>
@endif
</div>
@endif
</td>
@endif
@php
$counter = 0
@endphp
@foreach ($item->getComponents(withHidden: true) as $schemaComponent)
@php
throw_unless(
$schemaComponent instanceof \Filament\Schemas\Components\Component,
new \Exception('Table repeaters must only contain schema components, but [' . $schemaComponent::class . '] was used.'),
);
@endphp
@if (count($tableColumns) > $counter)
@if ($schemaComponent instanceof \Filament\Forms\Components\Hidden)
{{ $schemaComponent }}
@else
@php
$counter++
@endphp
@if ($schemaComponent->isVisible())
@php
$schemaComponentStatePath = $schemaComponent->getStatePath();
@endphp
<td
x-data="filamentSchemaComponent({
path: @js($schemaComponentStatePath),
containerPath: @js($itemStatePath),
$wire,
})"
@if ($afterStateUpdatedJs = $schemaComponent->getAfterStateUpdatedJs())
x-init="{{ implode(';', array_map(
fn (string $js): string => '$wire.watch(' . Js::from($schemaComponentStatePath) . ', ($state, $old) => isStateChanged($state, $old) && eval(' . Js::from($js) . '))',
$afterStateUpdatedJs,
)) }}"
@endif
>
{{ $schemaComponent }}
</td>
@else
<td class="fi-hidden"></td>
@endif
@endif
@endif
@endforeach
@if (count($extraItemActions) || $isCloneable || $isDeletable)
<td>
@if ($visibleExtraItemActions || $cloneActionIsVisible || $deleteActionIsVisible)
<div
class="fi-fo-table-repeater-actions"
>
@foreach ($visibleExtraItemActions as $extraItemAction)
<div x-on:click.stop>
{{ $extraItemAction(['item' => $itemKey]) }}
</div>
@endforeach
@if ($cloneActionIsVisible)
<div x-on:click.stop>
{{ $cloneAction }}
</div>
@endif
@if ($deleteActionIsVisible)
<div x-on:click.stop>
{{ $deleteAction }}
</div>
@endif
</div>
@endif
</td>
@endif
</tr>
@endforeach
</tbody>
</table>
@endif
@if ($isAddable && $addAction->isVisible())
<div
@class([
'fi-fo-table-repeater-add',
($addActionAlignment instanceof Alignment) ? ('fi-align-' . $addActionAlignment->value) : $addActionAlignment,
])
>
{{ $addAction }}
</div>
@endif
</div>
</x-dynamic-component>

View File

@@ -1,227 +0,0 @@
@php
$customBlocks = $getCustomBlocks();
$extraAttributeBag = $getExtraAttributeBag();
$fieldWrapperView = $getFieldWrapperView();
$id = $getId();
$isDisabled = $isDisabled();
$livewireKey = $getLivewireKey();
$key = $getKey();
$mergeTags = $getMergeTags();
$statePath = $getStatePath();
$tools = $getTools();
$toolbarButtons = $getToolbarButtons();
$floatingToolbars = $getFloatingToolbars();
$fileAttachmentsMaxSize = $getFileAttachmentsMaxSize();
$fileAttachmentsAcceptedFileTypes = $getFileAttachmentsAcceptedFileTypes();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<x-filament::input.wrapper
:valid="! $errors->has($statePath)"
x-cloak
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class(['fi-fo-rich-editor'])
"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('rich-editor', 'filament/forms') }}"
x-data="richEditorFormComponent({
acceptedFileTypes: @js($fileAttachmentsAcceptedFileTypes),
acceptedFileTypesValidationMessage: @js($fileAttachmentsAcceptedFileTypes ? __('filament-forms::components.rich_editor.file_attachments_accepted_file_types_message', ['values' => implode(', ', $fileAttachmentsAcceptedFileTypes)]) : null),
activePanel: @js($getActivePanel()),
deleteCustomBlockButtonIconHtml: @js(\Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::Trash, alias: \Filament\Forms\View\FormsIconAlias::COMPONENTS_RICH_EDITOR_PANELS_CUSTOM_BLOCK_DELETE_BUTTON)->toHtml()),
editCustomBlockButtonIconHtml: @js(\Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::PencilSquare, alias: \Filament\Forms\View\FormsIconAlias::COMPONENTS_RICH_EDITOR_PANELS_CUSTOM_BLOCK_EDIT_BUTTON)->toHtml()),
extensions: @js($getTipTapJsExtensions()),
key: @js($key),
isDisabled: @js($isDisabled),
isLiveDebounced: @js($isLiveDebounced()),
isLiveOnBlur: @js($isLiveOnBlur()),
liveDebounce: @js($getNormalizedLiveDebounce()),
livewireId: @js($this->getId()),
maxFileSize: @js($fileAttachmentsMaxSize),
maxFileSizeValidationMessage: @js($fileAttachmentsMaxSize ? trans_choice('filament-forms::components.rich_editor.file_attachments_max_size_message', $fileAttachmentsMaxSize, ['max' => $fileAttachmentsMaxSize]) : null),
mergeTags: @js($mergeTags),
noMergeTagSearchResultsMessage: @js($getNoMergeTagSearchResultsMessage()),
placeholder: @js($getPlaceholder()),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')", isOptimisticallyLive: false) }},
statePath: @js($statePath),
textColors: @js($getTextColorsForJs()),
uploadingFileMessage: @js($getUploadingFileMessage()),
floatingToolbars: @js($floatingToolbars),
})"
x-bind:class="{
'fi-fo-rich-editor-uploading-file': isUploadingFile,
}"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
])), 0, 64)
}}"
>
@if ((! $isDisabled) && filled($toolbarButtons))
<div class="fi-fo-rich-editor-toolbar">
@foreach ($toolbarButtons as $button => $buttonGroup)
<div class="fi-fo-rich-editor-toolbar-group">
@foreach ($buttonGroup as $button)
{{ $tools[$button] ?? throw new LogicException("Toolbar button [{$button}] cannot be found.") }}
@endforeach
</div>
@endforeach
</div>
@endif
<div
x-show="isUploadingFile"
x-cloak
class="fi-fo-rich-editor-uploading-file-message"
>
{{ \Filament\Support\generate_loading_indicator_html() }}
<span>
{{ $getUploadingFileMessage() }}
</span>
</div>
<div
x-show="! isUploadingFile && fileValidationMessage"
x-cloak
class="fi-fo-rich-editor-file-validation-message"
>
<span
x-text="fileValidationMessage"
x-show="! isUploadingFile && fileValidationMessage"
></span>
</div>
<div
{{ $getExtraInputAttributeBag()->class(['fi-fo-rich-editor-main']) }}
>
<div class="fi-fo-rich-editor-content fi-prose" x-ref="editor">
@foreach ($floatingToolbars as $nodeName => $buttons)
<div
x-ref="floatingToolbar::{{ $nodeName }}"
class="fi-fo-rich-editor-floating-toolbar fi-not-prose"
>
@foreach ($buttons as $button)
{{ $tools[$button] }}
@endforeach
</div>
@endforeach
</div>
@if (! $isDisabled)
<div
x-show="isPanelActive()"
x-cloak
class="fi-fo-rich-editor-panels"
>
<div
x-show="isPanelActive('customBlocks')"
x-cloak
class="fi-fo-rich-editor-panel"
>
<div class="fi-fo-rich-editor-panel-header">
<p class="fi-fo-rich-editor-panel-heading">
{{ __('filament-forms::components.rich_editor.tools.custom_blocks') }}
</p>
<div
class="fi-fo-rich-editor-panel-close-btn-ctn"
>
<button
type="button"
x-on:click="togglePanel()"
class="fi-icon-btn"
>
{{ \Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::XMark, alias: \Filament\Forms\View\FormsIconAlias::COMPONENTS_RICH_EDITOR_PANELS_CUSTOM_BLOCKS_CLOSE_BUTTON) }}
</button>
</div>
</div>
<div class="fi-fo-rich-editor-custom-blocks-list">
@foreach ($customBlocks as $block)
@php
$blockId = $block::getId();
@endphp
<button
draggable="true"
type="button"
x-data="{ isLoading: false }"
x-on:click="
isLoading = true
$wire.mountAction(
'customBlock',
{ editorSelection, id: @js($blockId), mode: 'insert' },
{ schemaComponent: @js($key) },
)
"
x-on:dragstart="$event.dataTransfer.setData('customBlock', @js($blockId))"
x-on:open-modal.window="isLoading = false"
x-on:run-rich-editor-commands.window="isLoading = false"
class="fi-fo-rich-editor-custom-block-btn"
>
{{
\Filament\Support\generate_loading_indicator_html((new \Illuminate\View\ComponentAttributeBag([
'x-show' => 'isLoading',
])))
}}
{{ $block::getLabel() }}
</button>
@endforeach
</div>
</div>
<div
x-show="isPanelActive('mergeTags')"
x-cloak
class="fi-fo-rich-editor-panel"
>
<div class="fi-fo-rich-editor-panel-header">
<p class="fi-fo-rich-editor-panel-heading">
{{ __('filament-forms::components.rich_editor.tools.merge_tags') }}
</p>
<div
class="fi-fo-rich-editor-panel-close-btn-ctn"
>
<button
type="button"
x-on:click="togglePanel()"
class="fi-icon-btn"
>
{{ \Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::XMark, alias: \Filament\Forms\View\FormsIconAlias::COMPONENTS_RICH_EDITOR_PANELS_MERGE_TAGS_CLOSE_BUTTON) }}
</button>
</div>
</div>
<div class="fi-fo-rich-editor-merge-tags-list">
@foreach ($mergeTags as $tagId => $tagLabel)
<button
draggable="true"
type="button"
x-on:click="insertMergeTag(@js($tagId))"
x-on:dragstart="$event.dataTransfer.setData('mergeTag', @js($tagId))"
class="fi-fo-rich-editor-merge-tag-btn"
>
<span
data-type="mergeTag"
data-id="{{ $tagId }}"
>
{{ $tagLabel }}
</span>
</button>
@endforeach
</div>
</div>
</div>
@endif
</div>
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,200 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraInputAttributeBag = $getExtraInputAttributeBag();
$canSelectPlaceholder = $canSelectPlaceholder();
$isAutofocused = $isAutofocused();
$isDisabled = $isDisabled();
$isMultiple = $isMultiple();
$isSearchable = $isSearchable();
$canOptionLabelsWrap = $canOptionLabelsWrap();
$isRequired = $isRequired();
$isConcealed = $isConcealed();
$isHtmlAllowed = $isHtmlAllowed();
$isNative = (! ($isSearchable || $isMultiple) && $isNative());
$isPrefixInline = $isPrefixInline();
$isSuffixInline = $isSuffixInline();
$key = $getKey();
$id = $getId();
$prefixActions = $getPrefixActions();
$prefixIcon = $getPrefixIcon();
$prefixIconColor = $getPrefixIconColor();
$prefixLabel = $getPrefixLabel();
$suffixActions = $getSuffixActions();
$suffixIcon = $getSuffixIcon();
$suffixIconColor = $getSuffixIconColor();
$suffixLabel = $getSuffixLabel();
$statePath = $getStatePath();
$state = $getState();
$livewireKey = $getLivewireKey();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-select-wrp"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
:inline-suffix="$isSuffixInline"
:prefix="$prefixLabel"
:prefix-actions="$prefixActions"
:prefix-icon="$prefixIcon"
:prefix-icon-color="$prefixIconColor"
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$suffixIconColor"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
->class([
'fi-fo-select',
'fi-fo-select-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'fi-fo-select-native' => $isNative,
])
"
>
@if ($isNative)
<select
{{
$extraInputAttributeBag
->merge([
'autofocus' => $isAutofocused,
'disabled' => $isDisabled,
'id' => $id,
'required' => $isRequired && (! $isConcealed),
$applyStateBindingModifiers('wire:model') => $statePath,
], escape: false)
->class([
'fi-select-input',
'fi-select-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
])
}}
>
@if ($canSelectPlaceholder)
<option value="">
@if (! $isDisabled)
{{ $getPlaceholder() }}
@endif
</option>
@endif
@foreach ($getOptions() as $value => $label)
@if (is_array($label))
<optgroup label="{{ $value }}">
@foreach ($label as $groupedValue => $groupedLabel)
<option
@disabled($isOptionDisabled($groupedValue, $groupedLabel))
value="{{ $groupedValue }}"
>
@if ($isHtmlAllowed)
{!! $groupedLabel !!}
@else
{{ $groupedLabel }}
@endif
</option>
@endforeach
</optgroup>
@else
<option
@disabled($isOptionDisabled($value, $label))
value="{{ $value }}"
>
@if ($isHtmlAllowed)
{!! $label !!}
@else
{{ $label }}
@endif
</option>
@endif
@endforeach
</select>
@else
<div
class="fi-hidden"
x-data="{
isDisabled: @js($isDisabled),
init() {
const container = $el.nextElementSibling
container.dispatchEvent(
new CustomEvent('set-select-property', {
detail: { isDisabled: this.isDisabled },
}),
)
},
}"
></div>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('select', 'filament/forms') }}"
x-data="selectFormComponent({
canOptionLabelsWrap: @js($canOptionLabelsWrap),
canSelectPlaceholder: @js($canSelectPlaceholder),
isHtmlAllowed: @js($isHtmlAllowed),
getOptionLabelUsing: async () => {
return await $wire.callSchemaComponentMethod(@js($key), 'getOptionLabel')
},
getOptionLabelsUsing: async () => {
return await $wire.callSchemaComponentMethod(
@js($key),
'getOptionLabelsForJs',
)
},
getOptionsUsing: async () => {
return await $wire.callSchemaComponentMethod(
@js($key),
'getOptionsForJs',
)
},
getSearchResultsUsing: async (search) => {
return await $wire.callSchemaComponentMethod(
@js($key),
'getSearchResultsForJs',
{ search },
)
},
initialOptionLabel: @js((blank($state) || $isMultiple) ? null : $getOptionLabel()),
initialOptionLabels: @js((filled($state) && $isMultiple) ? $getOptionLabelsForJs() : []),
initialState: @js($state),
isAutofocused: @js($isAutofocused),
isDisabled: @js($isDisabled),
isMultiple: @js($isMultiple),
isSearchable: @js($isSearchable),
livewireId: @js($this->getId()),
hasDynamicOptions: @js($hasDynamicOptions()),
hasDynamicSearchResults: @js($hasDynamicSearchResults()),
loadingMessage: @js($getLoadingMessage()),
maxItems: @js($getMaxItems()),
maxItemsMessage: @js($getMaxItemsMessage()),
noSearchResultsMessage: @js($getNoSearchResultsMessage()),
options: @js($getOptionsForJs()),
optionsLimit: @js($getOptionsLimit()),
placeholder: @js($getPlaceholder()),
position: @js($getPosition()),
searchDebounce: @js($getSearchDebounce()),
searchingMessage: @js($getSearchingMessage()),
searchPrompt: @js($getSearchPrompt()),
searchableOptionFields: @js($getSearchableOptionFields()),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
statePath: @js($statePath),
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
])), 0, 64)
}}"
x-on:keydown.esc="select.dropdown.isActive && $event.stopPropagation()"
x-on:set-select-property="$event.detail.isDisabled ? select.disable() : select.enable()"
{{
$attributes
->merge($getExtraAlpineAttributes(), escape: false)
->class(['fi-select-input'])
}}
>
<div x-ref="select"></div>
</div>
@endif
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,61 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$isVertical = $isVertical();
$pipsMode = $getPipsMode();
$livewireKey = $getLivewireKey();
$isDisabled = $isDisabled();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('slider', 'filament/forms') }}"
x-data="sliderFormComponent({
arePipsStepped: @js($arePipsStepped()),
behavior: @js($getBehaviorForJs()),
decimalPlaces: @js($getDecimalPlaces()),
fillTrack: @js($getFillTrack()),
isDisabled: @js($isDisabled),
isRtl: @js($isRtl()),
isVertical: @js($isVertical),
maxDifference: @js($getMaxDifference()),
minDifference: @js($getMinDifference()),
maxValue: @js($getMaxValue()),
minValue: @js($getMinValue()),
nonLinearPoints: @js($getNonLinearPoints()),
pipsDensity: @js($getPipsDensity()),
pipsFilter: @js($getPipsFilterForJs()),
pipsFormatter: @js($getPipsFormatterForJs()),
pipsMode: @js($pipsMode),
pipsValues: @js($getPipsValues()),
rangePadding: @js($getRangePadding()),
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }},
step: @js($getStep()),
tooltips: @js($getTooltipsForJs()),
})"
wire:ignore
wire:key="{{ $livewireKey }}.{{
substr(md5(serialize([
$isDisabled,
])), 0, 64)
}}"
{{
$attributes
->merge([
'id' => $getId(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->merge($getExtraAlpineAttributes(), escape: false)
->class([
'fi-fo-slider',
'fi-fo-slider-has-pips' => $pipsMode,
'fi-fo-slider-has-tooltips' => $hasTooltips(),
'fi-fo-slider-vertical' => $isVertical,
])
}}
></div>
</x-dynamic-component>

View File

@@ -1,30 +0,0 @@
@php
use Filament\Forms\Components\TableSelect\Livewire\TableSelectLivewireComponent;
$fieldWrapperView = $getFieldWrapperView();
$extraAttributes = $getExtraAttributes();
$id = $getId();
@endphp
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
<div
{{
$attributes
->merge([
'id' => $id,
], escape: false)
->merge($extraAttributes, escape: false)
}}
>
@livewire(TableSelectLivewireComponent::class, [
'isDisabled' => $isDisabled(),
'maxSelectableRecords' => $getMaxItems(),
'model' => $getModel(),
'record' => $getRecord(),
'relationshipName' => $getRelationshipName(),
'tableConfiguration' => base64_encode($getTableConfiguration()),
'tableArguments' => $getTableArguments(),
$applyStateBindingModifiers('wire:model') => $getStatePath(),
], key($getLivewireKey()))
</div>
</x-dynamic-component>

View File

@@ -1,131 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributes = $getExtraAttributes();
$extraInputAttributeBag = $getExtraInputAttributeBag();
$color = $getColor() ?? 'primary';
$id = $getId();
$isAutofocused = $isAutofocused();
$isDisabled = $isDisabled();
$isPrefixInline = $isPrefixInline();
$isReorderable = (! $isDisabled) && $isReorderable();
$isSuffixInline = $isSuffixInline();
$placeholder = $getPlaceholder();
$prefixActions = $getPrefixActions();
$prefixIcon = $getPrefixIcon();
$prefixIconColor = $getPrefixIconColor();
$prefixLabel = $getPrefixLabel();
$statePath = $getStatePath();
$suffixActions = $getSuffixActions();
$suffixIcon = $getSuffixIcon();
$suffixIconColor = $getSuffixIconColor();
$suffixLabel = $getSuffixLabel();
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-tags-input-wrp"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
:inline-suffix="$isSuffixInline"
:prefix="$prefixLabel"
:prefix-actions="$prefixActions"
:prefix-icon="$prefixIcon"
:prefix-icon-color="$prefixIconColor"
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$suffixIconColor"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->merge($extraAttributes, escape: false)
->class([
'fi-fo-tags-input',
'fi-disabled' => $isDisabled,
])
"
>
<div
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('tags-input', 'filament/forms') }}"
x-data="tagsInputFormComponent({
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
splitKeys: @js($getSplitKeys()),
})"
{{ $getExtraAlpineAttributeBag() }}
>
<input
{{
$extraInputAttributeBag
->merge([
'autocomplete' => 'off',
'autofocus' => $isAutofocused,
'disabled' => $isDisabled,
'id' => $id,
'list' => $id . '-suggestions',
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'type' => 'text',
'x-bind' => 'input',
], escape: false)
->class([
'fi-input',
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
])
}}
/>
<datalist id="{{ $id }}-suggestions">
@foreach ($getSuggestions() as $suggestion)
<template
x-bind:key="@js($suggestion)"
x-if="! (state?.includes(@js($suggestion)) ?? true)"
>
<option value="{{ $suggestion }}" />
</template>
@endforeach
</datalist>
<div wire:ignore>
<template x-cloak x-if="state?.length">
<div
@if ($isReorderable)
x-on:end.stop="reorderTags($event)"
x-sortable
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
@endif
class="fi-fo-tags-input-tags-ctn"
>
<template
x-for="(tag, index) in state"
x-bind:key="`${tag}-${index}`"
>
<x-filament::badge
:color="$color"
:x-bind:x-sortable-item="$isReorderable ? 'index' : null"
:x-sortable-handle="$isReorderable ? '' : null"
@class([
'fi-reorderable' => $isReorderable,
])
>
{{ $getTagPrefix() }}
<span x-text="tag"></span>
{{ $getTagSuffix() }}
<x-slot
name="deleteButton"
x-on:click.stop="deleteTag(tag)"
></x-slot>
</x-filament::badge>
</template>
</div>
</template>
</div>
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,115 +0,0 @@
@php
use Filament\Forms\Components\TextInput\Actions\HidePasswordAction;
use Filament\Forms\Components\TextInput\Actions\ShowPasswordAction;
$fieldWrapperView = $getFieldWrapperView();
$datalistOptions = $getDatalistOptions();
$extraAlpineAttributes = $getExtraAlpineAttributes();
$extraAttributeBag = $getExtraAttributeBag();
$id = $getId();
$isConcealed = $isConcealed();
$isDisabled = $isDisabled();
$isPasswordRevealable = $isPasswordRevealable();
$isPrefixInline = $isPrefixInline();
$isSuffixInline = $isSuffixInline();
$mask = $getMask();
$prefixActions = $getPrefixActions();
$prefixIcon = $getPrefixIcon();
$prefixIconColor = $getPrefixIconColor();
$prefixLabel = $getPrefixLabel();
$suffixActions = $getSuffixActions();
$suffixIcon = $getSuffixIcon();
$suffixIconColor = $getSuffixIconColor();
$suffixLabel = $getSuffixLabel();
$statePath = $getStatePath();
$placeholder = $getPlaceholder();
if ($isPasswordRevealable) {
$xData = '{ isPasswordRevealed: false }';
} elseif (count($extraAlpineAttributes) || filled($mask)) {
$xData = '{}';
} else {
$xData = null;
}
if ($isPasswordRevealable) {
$type = null;
} elseif (filled($mask)) {
$type = 'text';
} else {
$type = $getType();
}
$inputAttributes = $getExtraInputAttributeBag()
->merge($extraAlpineAttributes, escape: false)
->merge([
'autocapitalize' => $getAutocapitalize(),
'autocomplete' => $getAutocomplete(),
'autofocus' => $isAutofocused(),
'disabled' => $isDisabled,
'id' => $id,
'inlinePrefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'inlineSuffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
'inputmode' => $getInputMode(),
'list' => $datalistOptions ? $id . '-list' : null,
'max' => (! $isConcealed) ? $getMaxValue() : null,
'maxlength' => (! $isConcealed) ? $getMaxLength() : null,
'min' => (! $isConcealed) ? $getMinValue() : null,
'minlength' => (! $isConcealed) ? $getMinLength() : null,
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'readonly' => $isReadOnly(),
'required' => $isRequired() && (! $isConcealed),
'step' => $getStep(),
'type' => $type,
$applyStateBindingModifiers('wire:model') => $statePath,
'x-bind:type' => $isPasswordRevealable ? 'isPasswordRevealed ? \'text\' : \'password\'' : null,
'x-mask' . ($mask instanceof \Filament\Support\RawJs ? ':dynamic' : '') => filled($mask) ? $mask : null,
], escape: false)
->class([
'fi-revealable' => $isPasswordRevealable,
]);
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:inline-prefix="$isPrefixInline"
:inline-suffix="$isSuffixInline"
:prefix="$prefixLabel"
:prefix-actions="$prefixActions"
:prefix-icon="$prefixIcon"
:prefix-icon-color="$prefixIconColor"
:suffix="$suffixLabel"
:suffix-actions="$suffixActions"
:suffix-icon="$suffixIcon"
:suffix-icon-color="$suffixIconColor"
:valid="! $errors->has($statePath)"
:x-data="$xData"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class(['fi-fo-text-input'])
"
>
<input
{{
$inputAttributes->class([
'fi-input',
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
])
}}
/>
</x-filament::input.wrapper>
@if ($datalistOptions)
<datalist id="{{ $id }}-list">
@foreach ($datalistOptions as $option)
<option value="{{ $option }}"></option>
@endforeach
</datalist>
@endif
</x-dynamic-component>

View File

@@ -1,71 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$extraAttributeBag = $getExtraAttributeBag();
$isConcealed = $isConcealed();
$isDisabled = $isDisabled();
$rows = $getRows();
$placeholder = $getPlaceholder();
$shouldAutosize = $shouldAutosize();
$placeholder = $getPlaceholder();
$statePath = $getStatePath();
$initialHeight = (($rows ?? 2) * 1.5) + 0.75;
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-textarea-wrp"
>
<x-filament::input.wrapper
:disabled="$isDisabled"
:valid="! $errors->has($statePath)"
:attributes="
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
->class([
'fi-fo-textarea',
'fi-autosizable' => $shouldAutosize,
])
"
>
<div wire:ignore.self style="height: '{{ $initialHeight . 'rem' }}'">
<textarea
x-load
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('textarea', 'filament/forms') }}"
x-data="textareaFormComponent({
initialHeight: @js($initialHeight),
shouldAutosize: @js($shouldAutosize),
state: $wire.$entangle('{{ $statePath }}'),
})"
@if ($shouldAutosize)
x-intersect.once="resize()"
x-on:resize.window="resize()"
@endif
x-model="state"
@if ($isGrammarlyDisabled())
data-gramm="false"
data-gramm_editor="false"
data-enable-grammarly="false"
@endif
{{ $getExtraAlpineAttributeBag() }}
{{
$getExtraInputAttributeBag()
->merge([
'autocomplete' => $getAutocomplete(),
'autofocus' => $isAutofocused(),
'cols' => $getCols(),
'disabled' => $isDisabled,
'id' => $getId(),
'maxlength' => (! $isConcealed) ? $getMaxLength() : null,
'minlength' => (! $isConcealed) ? $getMinLength() : null,
'placeholder' => filled($placeholder) ? e($placeholder) : null,
'readonly' => $isReadOnly(),
'required' => $isRequired() && (! $isConcealed),
'rows' => $rows,
$applyStateBindingModifiers('wire:model') => $statePath,
], escape: false)
}}
></textarea>
</div>
</x-filament::input.wrapper>
</x-dynamic-component>

View File

@@ -1,54 +0,0 @@
@php
$fieldWrapperView = $getFieldWrapperView();
$id = $getId();
$isDisabled = $isDisabled();
$isMultiple = $isMultiple();
$statePath = $getStatePath();
$areButtonLabelsHidden = $areButtonLabelsHidden();
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
$extraInputAttributeBag = $getExtraInputAttributeBag()->class(['fi-fo-toggle-buttons-input']);
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-toggle-buttons-wrp"
>
<div
{{ $getExtraAttributeBag()->class(['fi-fo-toggle-buttons fi-btn-group']) }}
>
@foreach ($getOptions() as $value => $label)
@php
$inputId = "{$id}-{$value}";
$shouldOptionBeDisabled = $isDisabled || $isOptionDisabled($value, $label);
$color = $getColor($value);
$icon = $getIcon($value);
@endphp
<input
@disabled($shouldOptionBeDisabled)
id="{{ $inputId }}"
@if (! $isMultiple)
name="{{ $id }}"
@endif
type="{{ $isMultiple ? 'checkbox' : 'radio' }}"
value="{{ $value }}"
wire:loading.attr="disabled"
{{ $wireModelAttribute }}="{{ $statePath }}"
{{ $extraInputAttributeBag }}
/>
<x-filament::button
:color="$color"
:disabled="$shouldOptionBeDisabled"
:for="$inputId"
grouped
:icon="$icon"
:label-sr-only="$areButtonLabelsHidden"
tag="label"
>
{{ $label }}
</x-filament::button>
@endforeach
</div>
</x-dynamic-component>

View File

@@ -1,66 +0,0 @@
@php
use Filament\Support\Enums\GridDirection;
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$gridDirection = $getGridDirection() ?? GridDirection::Column;
$id = $getId();
$isDisabled = $isDisabled();
$isInline = $isInline();
$isMultiple = $isMultiple();
$statePath = $getStatePath();
$areButtonLabelsHidden = $areButtonLabelsHidden();
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
$extraInputAttributeBag = $getExtraInputAttributeBag()->class(['fi-fo-toggle-buttons-input']);
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
class="fi-fo-toggle-buttons-wrp"
>
<div
{{
$getExtraAttributeBag()
->when(! $isInline, fn (ComponentAttributeBag $attributes) => $attributes->grid($getColumns(), $gridDirection))
->class([
'fi-fo-toggle-buttons',
'fi-inline' => $isInline,
])
}}
>
@foreach ($getOptions() as $value => $label)
@php
$inputId = "{$id}-{$value}";
$shouldOptionBeDisabled = $isDisabled || $isOptionDisabled($value, $label);
$color = $getColor($value);
$icon = $getIcon($value);
@endphp
<div class="fi-fo-toggle-buttons-btn-ctn">
<input
@disabled($shouldOptionBeDisabled)
id="{{ $inputId }}"
@if (! $isMultiple)
name="{{ $id }}"
@endif
type="{{ $isMultiple ? 'checkbox' : 'radio' }}"
value="{{ $value }}"
{{ $wireModelAttribute }}="{{ $statePath }}"
{{ $extraInputAttributeBag }}
/>
<x-filament::button
:color="$color"
:disabled="$shouldOptionBeDisabled"
:for="$inputId"
:icon="$icon"
:label-sr-only="$areButtonLabelsHidden"
tag="label"
>
{{ $label }}
</x-filament::button>
</div>
@endforeach
</div>
</x-dynamic-component>

View File

@@ -1,42 +0,0 @@
@php
use Illuminate\View\ComponentAttributeBag;
$fieldWrapperView = $getFieldWrapperView();
$statePath = $getStatePath();
$attributes = (new ComponentAttributeBag)
->merge([
'aria-checked' => 'false',
'autofocus' => $isAutofocused(),
'disabled' => $isDisabled(),
'id' => $getId(),
'offColor' => $getOffColor() ?? 'gray',
'offIcon' => $getOffIcon(),
'onColor' => $getOnColor() ?? 'primary',
'onIcon' => $getOnIcon(),
'state' => '$wire.' . $applyStateBindingModifiers('$entangle(\'' . $statePath . '\')'),
'wire:loading.attr' => 'disabled',
'wire:target' => $statePath,
], escape: false)
->merge($getExtraAttributes(), escape: false)
->merge($getExtraAlpineAttributes(), escape: false)
->class(['fi-fo-toggle']);
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:field="$field"
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
>
@if ($isInline())
<x-slot name="labelPrefix">
<x-filament::toggle
:attributes="\Filament\Support\prepare_inherited_attributes($attributes)"
/>
</x-slot>
@else
<x-filament::toggle
:attributes="\Filament\Support\prepare_inherited_attributes($attributes)"
/>
@endif
</x-dynamic-component>

View File

@@ -1,132 +0,0 @@
@props([
'alignment' => null,
'entry' => null,
'hasInlineLabel' => null,
'label' => null,
'labelSrOnly' => null,
])
@php
use Filament\Support\Enums\Alignment;
use Illuminate\View\ComponentAttributeBag;
if ($entry) {
$action ??= $entry->getAction();
$alignment ??= $entry->getAlignment();
$hasInlineLabel ??= $entry->hasInlineLabel();
$label ??= $entry->getLabel();
$labelSrOnly ??= $entry->isLabelHidden();
$url ??= $entry->getUrl();
$shouldOpenUrlInNewTab ??= $entry->shouldOpenUrlInNewTab();
}
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
$beforeLabelContainer = $entry?->getChildSchema($entry::BEFORE_LABEL_SCHEMA_KEY)?->toHtmlString();
$afterLabelContainer = $entry?->getChildSchema($entry::AFTER_LABEL_SCHEMA_KEY)?->toHtmlString();
$beforeContentContainer = $entry?->getChildSchema($entry::BEFORE_CONTENT_SCHEMA_KEY)?->toHtmlString();
$afterContentContainer = $entry?->getChildSchema($entry::AFTER_CONTENT_SCHEMA_KEY)?->toHtmlString();
@endphp
<div
{{
$attributes
->merge($entry?->getExtraEntryWrapperAttributes() ?? [], escape: false)
->class([
'fi-in-entry',
'fi-in-entry-has-inline-label' => $hasInlineLabel,
])
}}
>
@if ($label && $labelSrOnly)
<dt class="fi-in-entry-label fi-sr-only">
{{ $label }}
</dt>
@endif
<div class="fi-in-entry-label-col">
{{ $entry?->getChildSchema($entry::ABOVE_LABEL_SCHEMA_KEY) }}
@if (($label && (! $labelSrOnly)) || $beforeLabelContainer || $afterLabelContainer)
<div
@class([
'fi-in-entry-label-ctn',
($label instanceof \Illuminate\View\ComponentSlot) ? $label->attributes->get('class') : null,
])
>
{{ $beforeLabelContainer }}
@if ($label && (! $labelSrOnly))
<dt
{{
(
($label instanceof \Illuminate\View\ComponentSlot)
? $label->attributes
: (new ComponentAttributeBag)
)
->class(['fi-in-entry-label'])
}}
>
{{ $label }}
</dt>
@endif
{{ $afterLabelContainer }}
</div>
@endif
{{ $entry?->getChildSchema($entry::BELOW_LABEL_SCHEMA_KEY) }}
</div>
<div class="fi-in-entry-content-col">
{{ $entry?->getChildSchema($entry::ABOVE_CONTENT_SCHEMA_KEY) }}
<dd class="fi-in-entry-content-ctn">
{{ $beforeContentContainer }}
@if (filled($url))
<a
{{ \Filament\Support\generate_href_html($url, $shouldOpenUrlInNewTab) }}
@class([
'fi-in-entry-content',
(($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : (is_string($alignment) ? $alignment : '')),
])
>
{{ $slot }}
</a>
@elseif (filled($action))
@php
$wireClickAction = $action->getLivewireClickHandler();
@endphp
<button
type="button"
wire:click="{{ $wireClickAction }}"
wire:loading.attr="disabled"
wire:target="{{ $wireClickAction }}"
@class([
'fi-in-entry-content',
(($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : (is_string($alignment) ? $alignment : '')),
])
>
{{ $slot }}
</button>
@else
<div
@class([
'fi-in-entry-content',
(($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : (is_string($alignment) ? $alignment : '')),
])
>
{{ $slot }}
</div>
@endif
{{ $afterContentContainer }}
</dd>
{{ $entry?->getChildSchema($entry::BELOW_CONTENT_SCHEMA_KEY) }}
</div>
</div>

View File

@@ -1,38 +0,0 @@
<x-filament::dropdown placement="bottom-start" maxHeight="36rem">
<x-slot name="trigger" style="justify-self: center; align-self: center; padding: 5px 0;">
@if (isset($currentLanguage) && $showFlags)
<x-filament::link tag="button">
<div style="width: 2rem; height: 2rem; border-radius: 9999px; overflow: hidden;">
{{ svg('flag-1x1-'.$currentLanguage['flag'], '') }}
</div>
</x-filament::link>
@else
<x-filament::icon-button icon="heroicon-o-language" label="Language switcher"/>
@endif
</x-slot>
<x-filament::dropdown.list style="max-height: 20rem; overflow-y: auto;">
@foreach ($otherLanguages as $language)
@php
$isCurrent = false;
if (isset($currentLanguage)) {
$isCurrent = $currentLanguage['code'] === $language['code'];
}
@endphp
<x-filament::dropdown.list.item :href="route('filament-language-switcher.switch', ['code' => $language['code']])" tag="a">
<span class="fi-dropdown-list-item-label" style="text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: 100%; text-align: left; display: flex; justify-content: flex-start; gap: 0.75rem;">
@if ($showFlags)
<div style="width: 1.5rem; height: 1.5rem; flex-shrink: 0;">
{{ svg('flag-4x3-'.$language['flag'], '') }}
</div>
<span>{{ $language['name'] }}</span>
@else
<span style="{{ $isCurrent ? 'font-weight: 600;' : '' }}">
{{ str($language['code'])->upper()->value() . " - {$language['name']}" }}
</span>
@endif
</span>
</x-filament::dropdown.list.item>
@endforeach
</x-filament::dropdown.list>
</x-filament::dropdown>

View File

@@ -1,147 +0,0 @@
<div class="w-full flex flex-col justify-center items-center h-full"
x-data="{
loading: true,
autoplayed: false,
init() {
this.loading = true;
let mediaElement = this.$refs.mediaFrame;
if (!mediaElement) {
this.loading = false;
return;
}
if (mediaElement.tagName === 'VIDEO' || mediaElement.tagName === 'AUDIO') {
mediaElement.load();
mediaElement.onload = () => {
this.loading = false;
};
mediaElement.oncanplaythrough = () => {
this.loading = false;
};
mediaElement.onloadstart = () => {
this.loading = true;
};
mediaElement.onerror = () => {
this.loading = false;
};
if (mediaElement.readyState >= 3) {
this.loading = false;
}
// Autoplay logic
if (@js($autoplay) && mediaElement.play) {
this.autoplayed = true;
mediaElement.play().catch(() => {
console.log('Autoplay failed or was blocked.');
});
}
} else {
this.loading = true;
mediaElement.onload = () => {
setTimeout(() => {
this.loading = false;
}, 200);
};
mediaElement.onerror = () => {
this.loading = false;
};
}
},
resetAutoplay() {
this.autoplayed = false;
}
}"
@open-modal.window="resetAutoplay"
>
<div class="flex h-full flex-col justify-center items-center" x-show="loading">
<x-filament::loading-indicator class="h-10 w-10" />
<span class="text-center font-bold">{{ __('filament-media-action::media-action.loading') }}</span>
</div>
<div class="mediaContainer w-full flex flex-col justify-center items-center h-full" x-show="!loading">
@if ($mediaType === \Hugomyb\FilamentMediaAction\Actions\MediaAction::TYPE_YOUTUBE)
@php
$youtubeId = '';
// Parse the URL to get components
$parsedUrl = parse_url($media);
if (isset($parsedUrl['host'])) {
// Check if it's a youtu.be short URL
if (str_contains($parsedUrl['host'], 'youtu.be')) {
$youtubeId = ltrim($parsedUrl['path'], '/');
}
// Check if it's a regular youtube.com URL
elseif (str_contains($parsedUrl['host'], 'youtube.com')) {
parse_str($parsedUrl['query'] ?? '', $queryParams);
$youtubeId = $queryParams['v'] ?? '';
}
}
@endphp
@if ($youtubeId)
<iframe x-ref="mediaFrame" class="rounded-lg" width="100%"
src="https://www.youtube.com/embed/{{ $youtubeId }}{{ $autoplay ? '?autoplay=1' : '' }}"
frameborder="0"
style="aspect-ratio: 16 / 9;"
allowfullscreen
></iframe>
@else
<p>Invalid YouTube URL.</p>
@endif
@elseif ($mediaType === \Hugomyb\FilamentMediaAction\Actions\MediaAction::TYPE_AUDIO)
<audio
x-ref="mediaFrame"
class="rounded-lg w-full"
style="width: 100%"
controls
@if($controlsList) controlsList="{{ $controlsList }}" @endif
@canplay="loading = false"
@loadeddata="loading = false"
@play="loading = false"
{{ $preload ? '' : 'preload="none"' }}
>
<source src="{{ $media }}" @if($mime && $mime !== 'unknown') type="{{ $mime }}" @endif>
Your browser does not support the audio element.
</audio>
@elseif ($mediaType === \Hugomyb\FilamentMediaAction\Actions\MediaAction::TYPE_VIDEO)
<video
x-ref="mediaFrame"
class="rounded-lg w-full"
width="100%"
style="aspect-ratio: 16 / 9;"
controls
playsinline
@if($controlsList) controlsList="{{ $controlsList }}" @endif
@canplaythrough="loading = false"
{{ $preload ? '' : 'preload="none"' }}
>
<source src="{{ $media }}" @if($mime && $mime !== 'unknown') type="{{ $mime }}" @endif>
Your browser does not support the video tag.
</video>
@elseif ($mediaType === \Hugomyb\FilamentMediaAction\Actions\MediaAction::TYPE_IMAGE)
<img x-ref="mediaFrame" class="rounded-lg" src="{{ $media }}" alt="Media Image"
style="max-width: 100%; height: auto;" @load="loading = false">
@elseif ($mediaType === \Hugomyb\FilamentMediaAction\Actions\MediaAction::TYPE_PDF)
<iframe x-ref="mediaFrame" class="rounded-lg" style="min-height: 600px"
src="{{ $media }}" width="100%" height="100%"
@load="loading = false"></iframe>
@else
<p>{{ __('filament-media-action::unsupported-media-type') }}</p>
@endif
</div>
</div>

View File

@@ -1,114 +0,0 @@
@php
use Filament\Support\Enums\Alignment;
use Filament\Support\View\Components\BadgeComponent;
use Illuminate\View\ComponentAttributeBag;
$notifications = $this->getNotifications();
$unreadNotificationsCount = $this->getUnreadNotificationsCount();
$hasNotifications = $notifications->count();
$isPaginated = $notifications instanceof \Illuminate\Contracts\Pagination\Paginator && $notifications->hasPages();
$pollingInterval = $this->getPollingInterval();
@endphp
<div class="fi-no-database">
<x-filament::modal
:alignment="$hasNotifications ? null : Alignment::Center"
close-button
:description="$hasNotifications ? null : __('filament-notifications::database.modal.empty.description')"
:heading="$hasNotifications ? null : __('filament-notifications::database.modal.empty.heading')"
:icon="$hasNotifications ? null : \Filament\Support\Icons\Heroicon::OutlinedBellSlash"
:icon-alias="
$hasNotifications
? null
: \Filament\Notifications\View\NotificationsIconAlias::DATABASE_MODAL_EMPTY_STATE
"
:icon-color="$hasNotifications ? null : 'gray'"
id="database-notifications"
slide-over
:sticky-header="$hasNotifications"
teleport="body"
width="md"
class="fi-no-database"
:attributes="
new \Illuminate\View\ComponentAttributeBag([
'wire:poll.' . $pollingInterval => $pollingInterval ? '' : false,
])
"
>
@if ($trigger = $this->getTrigger())
<x-slot name="trigger">
{{ $trigger->with(['unreadNotificationsCount' => $unreadNotificationsCount]) }}
</x-slot>
@endif
@if ($hasNotifications)
<x-slot name="header">
<div>
<h2 class="fi-modal-heading">
{{ __('filament-notifications::database.modal.heading') }}
@if ($unreadNotificationsCount)
<span
{{
(new ComponentAttributeBag)->color(BadgeComponent::class, 'primary')->class([
'fi-badge fi-size-xs',
])
}}
>
{{ $unreadNotificationsCount }}
</span>
@endif
</h2>
<div class="fi-ac">
@if ($unreadNotificationsCount && $this->markAllNotificationsAsReadAction?->isVisible())
{{ $this->markAllNotificationsAsReadAction }}
@endif
@if ($this->clearNotificationsAction?->isVisible())
{{ $this->clearNotificationsAction }}
@endif
</div>
</div>
</x-slot>
@foreach ($notifications as $notification)
<div
@class([
'fi-no-notification-unread-ctn' => $notification->unread(),
])
>
{{ $this->getNotification($notification)->inline() }}
</div>
@endforeach
@if ($broadcastChannel = $this->getBroadcastChannel())
@script
<script>
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($broadcastChannel)).listen(
'.database-notifications.sent',
() => {
setTimeout(
() => $wire.call('$refresh'),
500,
)
},
)
})
if (window.Echo) {
window.dispatchEvent(new CustomEvent('EchoLoaded'))
}
</script>
@endscript
@endif
@if ($isPaginated)
<x-slot name="footer">
<x-filament::pagination :paginator="$notifications" />
</x-slot>
@endif
@endif
</x-filament::modal>
</div>

View File

@@ -1,43 +0,0 @@
@php
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\VerticalAlignment;
@endphp
<div>
<div
@class([
'fi-no',
'fi-align-' . static::$alignment->value,
'fi-vertical-align-' . static::$verticalAlignment->value,
])
role="status"
>
@foreach ($notifications as $notification)
{{ $notification }}
@endforeach
</div>
@if ($broadcastChannel = $this->getBroadcastChannel())
@script
<script>
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($broadcastChannel)).notification(
(notification) => {
setTimeout(
() =>
$wire.handleBroadcastNotification(
notification,
),
500,
)
},
)
})
if (window.Echo) {
window.dispatchEvent(new CustomEvent('EchoLoaded'))
}
</script>
@endscript
@endif
</div>

View File

@@ -1,7 +0,0 @@
@php
$pageComponent = static::isSimple() ? 'filament-panels::page.simple' : 'filament-panels::page';
@endphp
<x-dynamic-component :component="$pageComponent">
{{ $this->content }}
</x-dynamic-component>

View File

@@ -1,18 +0,0 @@
@props([
'tenant' => filament()->getTenant(),
])
@php
$src = filament()->getTenantAvatarUrl($tenant);
$alt = __('filament-panels::layout.avatar.alt', ['name' => filament()->getTenantName($tenant)]);
@endphp
<x-filament::avatar
:circular="false"
:src="$src"
:alt="$alt"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-tenant-avatar'])
"
/>

View File

@@ -1,17 +0,0 @@
@props([
'user' => filament()->auth()->user(),
])
@php
$src = filament()->getUserAvatarUrl($user);
$alt = __('filament-panels::layout.avatar.alt', ['name' => filament()->getUserName($user)]);
@endphp
<x-filament::avatar
:src="$src"
:alt="$alt"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-user-avatar'])
"
/>

View File

@@ -1,48 +0,0 @@
@props([
'actions' => [],
'breadcrumbs' => [],
'heading',
'subheading' => null,
])
<header
{{
$attributes->class([
'fi-header',
'fi-header-has-breadcrumbs' => $breadcrumbs,
])
}}
>
<div>
@if ($breadcrumbs)
<x-filament::breadcrumbs :breadcrumbs="$breadcrumbs" />
@endif
<h1 class="fi-header-heading">
{{ $heading }}
</h1>
@if ($subheading)
<p class="fi-header-subheading">
{{ $subheading }}
</p>
@endif
</div>
@php
$beforeActions = \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_HEADER_ACTIONS_BEFORE, scopes: $this->getRenderHookScopes());
$afterActions = \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_HEADER_ACTIONS_AFTER, scopes: $this->getRenderHookScopes());
@endphp
@if (filled($beforeActions) || $actions || filled($afterActions))
<div class="fi-header-actions-ctn">
{{ $beforeActions }}
@if ($actions)
<x-filament::actions :actions="$actions" />
@endif
{{ $afterActions }}
</div>
@endif
</header>

View File

@@ -1,23 +0,0 @@
@props([
'heading' => null,
'logo' => true,
'subheading' => null,
])
<header class="fi-simple-header">
@if ($logo)
<x-filament-panels::logo />
@endif
@if (filled($heading))
<h1 class="fi-simple-header-heading">
{{ $heading }}
</h1>
@endif
@if (filled($subheading))
<p class="fi-simple-header-subheading">
{{ $subheading }}
</p>
@endif
</header>

View File

@@ -1,158 +0,0 @@
@props([
'livewire' => null,
])
@php
$renderHookScopes = $livewire?->getRenderHookScopes();
@endphp
<!DOCTYPE html>
<html
lang="{{ str_replace('_', '-', app()->getLocale()) }}"
dir="{{ __('filament-panels::layout.direction') ?? 'ltr' }}"
@class([
'fi',
'dark' => filament()->hasDarkModeForced(),
])
>
<head>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::HEAD_START, scopes: $renderHookScopes) }}
<meta charset="utf-8" />
<meta name="csrf-token" content="{{ csrf_token() }}" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
@if ($favicon = filament()->getFavicon())
<link rel="icon" href="{{ $favicon }}" />
@endif
@php
$title = trim(strip_tags($livewire?->getTitle() ?? ''));
$brandName = trim(strip_tags(filament()->getBrandName()));
@endphp
<title>
{{ filled($title) ? "{$title} - " : null }} {{ $brandName }}
</title>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::STYLES_BEFORE, scopes: $renderHookScopes) }}
<style>
[x-cloak=''],
[x-cloak='x-cloak'],
[x-cloak='1'] {
display: none !important;
}
[x-cloak='inline-flex'] {
display: inline-flex !important;
}
@media (max-width: 1023px) {
[x-cloak='-lg'] {
display: none !important;
}
}
@media (min-width: 1024px) {
[x-cloak='lg'] {
display: none !important;
}
}
</style>
@filamentStyles
{{ filament()->getTheme()->getHtml() }}
{{ filament()->getFontHtml() }}
{{ filament()->getMonoFontHtml() }}
{{ filament()->getSerifFontHtml() }}
<style>
:root {
--font-family: '{!! filament()->getFontFamily() !!}';
--mono-font-family: '{!! filament()->getMonoFontFamily() !!}';
--serif-font-family: '{!! filament()->getSerifFontFamily() !!}';
--sidebar-width: {{ filament()->getSidebarWidth() }};
--collapsed-sidebar-width: {{ filament()->getCollapsedSidebarWidth() }};
--default-theme-mode: {{ filament()->getDefaultThemeMode()->value }};
}
</style>
@stack('styles')
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::STYLES_AFTER, scopes: $renderHookScopes) }}
@if (! filament()->hasDarkMode())
<script>
localStorage.setItem('theme', 'light')
</script>
@elseif (filament()->hasDarkModeForced())
<script>
localStorage.setItem('theme', 'dark')
</script>
@else
<script>
const loadDarkMode = () => {
window.theme = localStorage.getItem('theme') ?? @js(filament()->getDefaultThemeMode()->value)
if (
window.theme === 'dark' ||
(window.theme === 'system' &&
window.matchMedia('(prefers-color-scheme: dark)')
.matches)
) {
document.documentElement.classList.add('dark')
}
}
loadDarkMode()
document.addEventListener('livewire:navigated', loadDarkMode)
</script>
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::HEAD_END, scopes: $renderHookScopes) }}
</head>
<body
{{
$attributes
->merge($livewire?->getExtraBodyAttributes() ?? [], escape: false)
->class([
'fi-body',
'fi-panel-' . filament()->getId(),
])
}}
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::BODY_START, scopes: $renderHookScopes) }}
{{ $slot }}
@livewire(Filament\Livewire\Notifications::class)
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SCRIPTS_BEFORE, scopes: $renderHookScopes) }}
@filamentScripts(withCore: true)
@if (filament()->hasBroadcasting() && config('filament.broadcasting.echo'))
<script data-navigate-once>
window.Echo = new window.EchoFactory(@js(config('filament.broadcasting.echo')))
window.dispatchEvent(new CustomEvent('EchoLoaded'))
</script>
@endif
@if (filament()->hasDarkMode() && (! filament()->hasDarkModeForced()))
<script>
loadDarkMode()
</script>
@endif
@stack('scripts')
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SCRIPTS_AFTER, scopes: $renderHookScopes) }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::BODY_END, scopes: $renderHookScopes) }}
</body>
</html>

View File

@@ -1,119 +0,0 @@
@php
use Filament\Support\Enums\Width;
$livewire ??= null;
$hasTopbar = filament()->hasTopbar();
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
$isSidebarFullyCollapsibleOnDesktop = filament()->isSidebarFullyCollapsibleOnDesktop();
$hasTopNavigation = filament()->hasTopNavigation();
$hasNavigation = filament()->hasNavigation();
$renderHookScopes = $livewire?->getRenderHookScopes();
$maxContentWidth ??= (filament()->getMaxContentWidth() ?? Width::SevenExtraLarge);
if (is_string($maxContentWidth)) {
$maxContentWidth = Width::tryFrom($maxContentWidth) ?? $maxContentWidth;
}
@endphp
<x-filament-panels::layout.base
:livewire="$livewire"
@class([
'fi-body-has-navigation' => $hasNavigation,
'fi-body-has-sidebar-collapsible-on-desktop' => $isSidebarCollapsibleOnDesktop,
'fi-body-has-sidebar-fully-collapsible-on-desktop' => $isSidebarFullyCollapsibleOnDesktop,
'fi-body-has-topbar' => $hasTopbar,
'fi-body-has-top-navigation' => $hasTopNavigation,
])
>
@if ($hasTopbar)
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_BEFORE, scopes: $renderHookScopes) }}
@livewire(filament()->getTopbarLivewireComponent())
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_AFTER, scopes: $renderHookScopes) }}
@elseif ($hasNavigation)
<div
@if ($isSidebarFullyCollapsibleOnDesktop)
x-data="{}"
x-bind:class="{ 'lg:fi-hidden': $store.sidebar.isOpen }"
@endif
@class([
'fi-layout-sidebar-toggle-btn-ctn',
'lg:fi-hidden' => ! $isSidebarFullyCollapsibleOnDesktop,
])
>
<x-filament::icon-button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::OutlinedBars3"
:icon-alias="\Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.expand.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.open()"
class="fi-layout-sidebar-toggle-btn"
/>
</div>
@endif
<div class="fi-layout">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::LAYOUT_START, scopes: $renderHookScopes) }}
@if ($hasNavigation)
<div
x-cloak
x-data="{}"
x-on:click="$store.sidebar.close()"
x-show="$store.sidebar.isOpen"
x-transition.opacity.300ms
class="fi-sidebar-close-overlay"
></div>
@livewire(filament()->getSidebarLivewireComponent())
@endif
<div
@if ($isSidebarCollapsibleOnDesktop)
x-data="{}"
x-bind:class="{
'fi-main-ctn-sidebar-open': $store.sidebar.isOpen,
}"
x-bind:style="'display: flex; opacity:1;'"
{{-- Mimics `x-cloak`, as using `x-cloak` causes visual issues with chart widgets --}}
@elseif ($isSidebarFullyCollapsibleOnDesktop)
x-data="{}"
x-bind:class="{
'fi-main-ctn-sidebar-open': $store.sidebar.isOpen,
}"
x-bind:style="'display: flex; opacity:1;'"
{{-- Mimics `x-cloak`, as using `x-cloak` causes visual issues with chart widgets --}}
@elseif (! ($isSidebarCollapsibleOnDesktop || $isSidebarFullyCollapsibleOnDesktop || $hasTopNavigation || (! $hasNavigation)))
x-data="{}"
x-bind:style="'display: flex; opacity:1;'" {{-- Mimics `x-cloak`, as using `x-cloak` causes visual issues with chart widgets --}}
@endif
class="fi-main-ctn"
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::CONTENT_BEFORE, scopes: $renderHookScopes) }}
<main
@class([
'fi-main',
($maxContentWidth instanceof Width) ? "fi-width-{$maxContentWidth->value}" : $maxContentWidth,
])
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::CONTENT_START, scopes: $renderHookScopes) }}
{{ $slot }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::CONTENT_END, scopes: $renderHookScopes) }}
</main>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::CONTENT_AFTER, scopes: $renderHookScopes) }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::FOOTER, scopes: $renderHookScopes) }}
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::LAYOUT_END, scopes: $renderHookScopes) }}
</div>
</x-filament-panels::layout.base>

View File

@@ -1,54 +0,0 @@
@php
use Filament\Support\Enums\Width;
$livewire ??= null;
$renderHookScopes = $livewire?->getRenderHookScopes();
$maxContentWidth ??= (filament()->getSimplePageMaxContentWidth() ?? Width::Large);
if (is_string($maxContentWidth)) {
$maxContentWidth = Width::tryFrom($maxContentWidth) ?? $maxContentWidth;
}
@endphp
<x-filament-panels::layout.base :livewire="$livewire">
@props([
'after' => null,
'heading' => null,
'subheading' => null,
])
<div class="fi-simple-layout">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIMPLE_LAYOUT_START, scopes: $renderHookScopes) }}
@if (($hasTopbar ?? true) && filament()->auth()->check())
<div class="fi-simple-layout-header">
@if (filament()->hasDatabaseNotifications())
@livewire(Filament\Livewire\DatabaseNotifications::class, [
'lazy' => filament()->hasLazyLoadedDatabaseNotifications(),
'position' => \Filament\Enums\DatabaseNotificationsPosition::Topbar,
])
@endif
@if (filament()->hasUserMenu())
@livewire(Filament\Livewire\SimpleUserMenu::class)
@endif
</div>
@endif
<div class="fi-simple-main-ctn">
<main
@class([
'fi-simple-main',
($maxContentWidth instanceof Width) ? "fi-width-{$maxContentWidth->value}" : $maxContentWidth,
])
>
{{ $slot }}
</main>
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::FOOTER, scopes: $renderHookScopes) }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIMPLE_LAYOUT_END, scopes: $renderHookScopes) }}
</div>
</x-filament-panels::layout.base>

View File

@@ -1,55 +0,0 @@
@php
$brandName = filament()->getBrandName();
$brandLogo = filament()->getBrandLogo();
$brandLogoHeight = filament()->getBrandLogoHeight() ?? '1.5rem';
$darkModeBrandLogo = filament()->getDarkModeBrandLogo();
$hasDarkModeBrandLogo = filled($darkModeBrandLogo);
$getLogoClasses = fn (bool $isDarkMode): string => \Illuminate\Support\Arr::toCssClasses([
'fi-logo',
'fi-logo-light' => $hasDarkModeBrandLogo && (! $isDarkMode),
'fi-logo-dark' => $isDarkMode,
]);
$logoStyles = "height: {$brandLogoHeight}";
@endphp
@capture($content, $logo, $isDarkMode = false)
@if ($logo instanceof \Illuminate\Contracts\Support\Htmlable)
<div
{{
$attributes
->class([$getLogoClasses($isDarkMode)])
->style([$logoStyles])
}}
>
{{ $logo }}
</div>
@elseif (filled($logo))
<img
alt="{{ __('filament-panels::layout.logo.alt', ['name' => $brandName]) }}"
src="{{ $logo }}"
{{
$attributes
->class([$getLogoClasses($isDarkMode)])
->style([$logoStyles])
}}
/>
@else
<div
{{
$attributes->class([
$getLogoClasses($isDarkMode),
])
}}
>
{{ $brandName }}
</div>
@endif
@endcapture
{{ $content($brandLogo) }}
@if ($hasDarkModeBrandLogo)
{{ $content($darkModeBrandLogo, isDarkMode: true) }}
@endif

View File

@@ -1,201 +0,0 @@
@props([
'fullHeight' => false,
])
@php
use Filament\Pages\Enums\SubNavigationPosition;
$subNavigation = $this->getCachedSubNavigation();
$subNavigationPosition = $this->getSubNavigationPosition();
$widgetData = $this->getWidgetData();
@endphp
<div
{{
$attributes->class([
'fi-page',
'fi-height-full' => $fullHeight,
'fi-page-has-sub-navigation' => $subNavigation,
"fi-page-has-sub-navigation-{$subNavigationPosition->value}" => $subNavigation,
...$this->getPageClasses(),
])
}}
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_START, scopes: $this->getRenderHookScopes()) }}
<div class="fi-page-header-main-ctn">
@if ($subNavigation)
<div
class="fi-page-main-sub-navigation-mobile-menu-render-hook-ctn"
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_MOBILE_MENU_BEFORE, scopes: $this->getRenderHookScopes()) }}
</div>
<x-filament-panels::page.sub-navigation.mobile-menu
:navigation="$subNavigation"
/>
<div
class="fi-page-main-sub-navigation-mobile-menu-render-hook-ctn"
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_MOBILE_MENU_AFTER, scopes: $this->getRenderHookScopes()) }}
</div>
@endif
@if ($header = $this->getHeader())
{{ $header }}
@elseif ($heading = $this->getHeading())
@php
$headerActions = $this->getCachedHeaderActions();
$breadcrumbs = filament()->hasBreadcrumbs() ? $this->getBreadcrumbs() : [];
$subheading = $this->getSubheading();
@endphp
<x-filament-panels::header
:actions="$headerActions"
:breadcrumbs="$breadcrumbs"
:heading="$heading"
:subheading="$subheading"
>
@if ($heading instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="heading">
{{ $heading }}
</x-slot>
@endif
@if ($subheading instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="subheading">
{{ $subheading }}
</x-slot>
@endif
</x-filament-panels::header>
@endif
<div class="fi-page-main">
@if ($subNavigation)
@if ($subNavigationPosition === SubNavigationPosition::Start)
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_START_BEFORE, scopes: $this->getRenderHookScopes()) }}
<x-filament-panels::page.sub-navigation.sidebar
:navigation="$subNavigation"
/>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_START_AFTER, scopes: $this->getRenderHookScopes()) }}
@endif
@if ($subNavigationPosition === SubNavigationPosition::Top)
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_TOP_BEFORE, scopes: $this->getRenderHookScopes()) }}
<x-filament-panels::page.sub-navigation.tabs
:navigation="$subNavigation"
/>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_TOP_AFTER, scopes: $this->getRenderHookScopes()) }}
@endif
@endif
<div class="fi-page-content">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_HEADER_WIDGETS_BEFORE, scopes: $this->getRenderHookScopes()) }}
{{ $this->headerWidgets }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_HEADER_WIDGETS_AFTER, scopes: $this->getRenderHookScopes()) }}
{{ $slot }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_FOOTER_WIDGETS_BEFORE, scopes: $this->getRenderHookScopes()) }}
{{ $this->footerWidgets }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_FOOTER_WIDGETS_AFTER, scopes: $this->getRenderHookScopes()) }}
</div>
@if ($subNavigation && $subNavigationPosition === SubNavigationPosition::End)
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_END_BEFORE, scopes: $this->getRenderHookScopes()) }}
<x-filament-panels::page.sub-navigation.sidebar
:navigation="$subNavigation"
/>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_END_AFTER, scopes: $this->getRenderHookScopes()) }}
@endif
</div>
@if ($footer = $this->getFooter())
{{ $footer }}
@endif
</div>
@if (! ($this instanceof \Filament\Tables\Contracts\HasTable))
<x-filament-actions::modals />
@elseif ($this->isTableLoaded() && filled($this->defaultTableAction))
<div
wire:init="mountAction(@js($this->defaultTableAction) , @if (filled($this->defaultTableActionArguments)) @js($this->defaultTableActionArguments) @else {} @endif , @js(['table' => true, 'recordKey' => $this->defaultTableActionRecord]))"
></div>
@endif
@if (filled($this->defaultAction))
<div
wire:init="mountAction(@js($this->defaultAction) @if (filled($this->defaultActionArguments) || filled($this->defaultActionContext)) , @if (filled($this->defaultActionArguments)) @js($this->defaultActionArguments) @else {} @endif @endif @if (filled($this->defaultActionContext)) , @js($this->defaultActionContext) @endif)"
></div>
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_END, scopes: $this->getRenderHookScopes()) }}
@if (method_exists($this, 'hasUnsavedDataChangesAlert') && $this->hasUnsavedDataChangesAlert())
@if (\Filament\Support\Facades\FilamentView::hasSpaMode())
@script
<script>
setUpSpaModeUnsavedDataChangesAlert({
body: @js(__('filament-panels::unsaved-changes-alert.body')),
resolveLivewireComponentUsing: () => @this,
$wire,
})
</script>
@endscript
@else
@script
<script>
setUpUnsavedDataChangesAlert({ $wire })
</script>
@endscript
@endif
@endif
@if ((! app()->hasDebugModeEnabled()) && $this->hasErrorNotifications())
@script
<script>
const errorNotifications = @js($this->getErrorNotifications())
Livewire.hook('request', ({ payload, fail }) => {
fail(({ status, preventDefault }) => {
if (JSON.parse(payload).components.length === 1) {
for (const component of JSON.parse(payload)
.components) {
if (
JSON.parse(component.snapshot).data
.isFilamentNotificationsComponent
) {
return
}
}
}
preventDefault()
const errorNotification =
errorNotifications[status] ?? errorNotifications['']
new FilamentNotification()
.title(errorNotification.title)
.body(errorNotification.body)
.danger()
.send()
})
})
</script>
@endscript
@endif
<x-filament-panels::unsaved-action-changes-alert />
</div>

View File

@@ -1,30 +0,0 @@
@props([
'heading' => null,
'subheading' => null,
])
@php
$heading ??= $this->getHeading();
$subheading ??= $this->getSubHeading();
$hasLogo = $this->hasLogo();
@endphp
<div {{ $attributes->class(['fi-simple-page']) }}>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIMPLE_PAGE_START, scopes: $this->getRenderHookScopes()) }}
<div class="fi-simple-page-content">
<x-filament-panels::header.simple
:heading="$heading"
:logo="$hasLogo"
:subheading="$subheading"
/>
{{ $slot }}
</div>
@if (! $this instanceof \Filament\Tables\Contracts\HasTable)
<x-filament-actions::modals />
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIMPLE_PAGE_END, scopes: $this->getRenderHookScopes()) }}
</div>

View File

@@ -1,72 +0,0 @@
@props([
'navigation',
])
<x-filament::dropdown
placement="bottom-start"
width="xs"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-page-sub-navigation-dropdown'])
"
>
<x-slot name="trigger">
@php
$activeItem = null;
foreach ($navigation as $navigationGroup) {
foreach ($navigationGroup->getItems() as $navigationItem) {
foreach ([$navigationItem, ...$navigationItem->getChildItems()] as $navigationItemChild) {
if ($navigationItemChild->isActive()) {
$activeItem = $navigationItemChild;
break 3;
}
}
}
}
@endphp
<x-filament::button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::ChevronDown"
:icon-alias="\Filament\View\PanelsIconAlias::SUB_NAVIGATION_MOBILE_MENU_BUTTON"
icon-position="after"
>
{{ $activeItem?->getLabel() }}
</x-filament::button>
</x-slot>
@foreach ($navigation as $navigationGroup)
@if (filled($navigationGroupLabel = $navigationGroup->getLabel()))
<x-filament::dropdown.header>
{{ $navigationGroupLabel }}
</x-filament::dropdown.header>
@endif
<x-filament::dropdown.list>
@foreach ($navigationGroup->getItems() as $navigationItem)
@foreach ([$navigationItem, ...$navigationItem->getChildItems()] as $navigationItemChild)
@php
$navigationItemBadge = $navigationItem->getBadge();
$navigationItemBadgeColor = $navigationItem->getBadgeColor();
$navigationItemIcon = $navigationItem->isActive() ? ($navigationItem->getActiveIcon() ?? $navigationItem->getIcon()) : $navigationItem->getIcon();
$navigationItemUrl = $navigationItem->getUrl();
$shouldNavigationItemOpenUrlInNewTab = $navigationItem->shouldOpenUrlInNewTab();
@endphp
<x-filament::dropdown.list.item
:badge="$navigationItemBadge"
:badge-color="$navigationItemBadgeColor"
:href="$navigationItemUrl"
:icon="$navigationItemIcon"
tag="a"
:target="$shouldNavigationItemOpenUrlInNewTab ? '_blank' : null"
>
{{ $navigationItemChild->getLabel() }}
</x-filament::dropdown.list.item>
@endforeach
@endforeach
</x-filament::dropdown.list>
@endforeach
</x-filament::dropdown>

View File

@@ -1,35 +0,0 @@
@props([
'navigation',
])
<div
{{ $attributes->class(['fi-page-sub-navigation-sidebar-ctn']) }}
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_SIDEBAR_BEFORE, scopes: $this->getRenderHookScopes()) }}
<ul wire:ignore class="fi-page-sub-navigation-sidebar">
@foreach ($navigation as $navigationGroup)
@php
$isNavigationGroupActive = $navigationGroup->isActive();
$isNavigationGroupCollapsible = $navigationGroup->isCollapsible();
$navigationGroupIcon = $navigationGroup->getIcon();
$navigationGroupItems = $navigationGroup->getItems();
$navigationGroupLabel = $navigationGroup->getLabel();
$navigationGroupExtraSidebarAttributeBag = $navigationGroup->getExtraSidebarAttributeBag();
@endphp
<x-filament-panels::sidebar.group
:active="$isNavigationGroupActive"
:collapsible="$isNavigationGroupCollapsible"
:icon="$navigationGroupIcon"
:items="$navigationGroupItems"
:label="$navigationGroupLabel"
:sidebar-collapsible="false"
sub-navigation
:attributes="\Filament\Support\prepare_inherited_attributes($navigationGroupExtraSidebarAttributeBag)"
/>
@endforeach
</ul>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::PAGE_SUB_NAVIGATION_SIDEBAR_AFTER, scopes: $this->getRenderHookScopes()) }}
</div>

View File

@@ -1,90 +0,0 @@
@props([
'navigation',
])
<x-filament::tabs
wire:ignore
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-page-sub-navigation-tabs'])
"
>
@foreach ($navigation as $navigationGroup)
@php
$navigationGroupLabel = $navigationGroup->getLabel();
$isNavigationGroupActive = $navigationGroup->isActive();
$navigationGroupIcon = $navigationGroup->getIcon();
@endphp
@if ($navigationGroupLabel)
<x-filament::dropdown placement="bottom-start">
<x-slot name="trigger">
<x-filament::tabs.item
:active="$isNavigationGroupActive"
:icon="$navigationGroupIcon"
>
{{ $navigationGroupLabel }}
</x-filament::tabs.item>
</x-slot>
<x-filament::dropdown.list>
@foreach ($navigationGroup->getItems() as $navigationItem)
@php
$navigationItemBadge = $navigationItem->getBadge();
$navigationItemBadgeColor = $navigationItem->getBadgeColor();
$navigationItemIcon = $navigationItem->isActive() ? ($navigationItem->getActiveIcon() ?? $navigationItem->getIcon()) : $navigationItem->getIcon();
$navigationItemUrl = $navigationItem->getUrl();
$shouldNavigationItemOpenUrlInNewTab = $navigationItem->shouldOpenUrlInNewTab();
@endphp
<x-filament::dropdown.list.item
:badge="$navigationItemBadge"
:badge-color="$navigationItemBadgeColor"
:href="$navigationItemUrl"
:icon="$navigationItemIcon"
tag="a"
:target="$shouldNavigationItemOpenUrlInNewTab ? '_blank' : null"
>
{{ $navigationItem->getLabel() }}
@if ($navigationItemIcon instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="icon">
{{ $navigationItemIcon }}
</x-slot>
@endif
</x-filament::dropdown.list.item>
@endforeach
</x-filament::dropdown.list>
</x-filament::dropdown>
@else
@foreach ($navigationGroup->getItems() as $navigationItem)
@php
$isNavigationItemActive = $navigationItem->isActive();
$navigationItemBadge = $navigationItem->getBadge();
$navigationItemBadgeColor = $navigationItem->getBadgeColor();
$navigationItemIcon = $navigationItem->isActive() ? ($navigationItem->getActiveIcon() ?? $navigationItem->getIcon()) : $navigationItem->getIcon();
$navigationItemUrl = $navigationItem->getUrl();
$shouldNavigationItemOpenUrlInNewTab = $navigationItem->shouldOpenUrlInNewTab();
@endphp
<x-filament::tabs.item
:active="$isNavigationItemActive"
:badge="$navigationItemBadge"
:badge-color="$navigationItemBadgeColor"
:href="$navigationItemUrl"
:icon="$navigationItemIcon"
tag="a"
:target="$shouldNavigationItemOpenUrlInNewTab ? '_blank' : null"
>
{{ $navigationItem->getLabel() }}
@if ($navigationItemIcon instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="icon">
{{ $navigationItemIcon }}
</x-slot>
@endif
</x-filament::tabs.item>
@endforeach
@endif
@endforeach
</x-filament::tabs>

View File

@@ -1,35 +0,0 @@
@php
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
@endphp
<button class="fi-sidebar-database-notifications-btn">
{{ \Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::OutlinedBell, alias: \Filament\View\PanelsIconAlias::SIDEBAR_OPEN_DATABASE_NOTIFICATIONS_BUTTON, size: \Filament\Support\Enums\IconSize::Large) }}
<span
@if ($isSidebarCollapsibleOnDesktop)
x-show="$store.sidebar.isOpen"
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-database-notifications-btn-label"
>
{{ __('filament-panels::layout.actions.open_database_notifications.label') }}
</span>
@if ($unreadNotificationsCount)
<span
@if ($isSidebarCollapsibleOnDesktop)
x-show="$store.sidebar.isOpen"
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-database-notifications-btn-badge-ctn"
>
<x-filament::badge>
{{ $unreadNotificationsCount }}
</x-filament::badge>
</span>
@endif
</button>

View File

@@ -1,225 +0,0 @@
@props([
'active' => false,
'collapsible' => true,
'icon' => null,
'items' => [],
'label' => null,
'sidebarCollapsible' => true,
'subNavigation' => false,
])
@php
$sidebarCollapsible = $sidebarCollapsible && filament()->isSidebarCollapsibleOnDesktop();
$hasDropdown = filled($label) && filled($icon) && $sidebarCollapsible;
@endphp
<li
x-data="{ label: @js($subNavigation ? "sub_navigation_{$label}" : $label) }"
data-group-label="{{ $subNavigation ? "sub_navigation_{$label}" : $label }}"
x-bind:class="{ 'fi-collapsed': $store.sidebar.groupIsCollapsed(label) }"
{{
$attributes->class([
'fi-sidebar-group',
'fi-active' => $active,
'fi-collapsible' => $collapsible,
])
}}
>
@if ($label)
<div
@if ($collapsible)
x-on:click="$store.sidebar.toggleCollapsedGroup(label)"
role="button"
@endif
@if ($sidebarCollapsible)
x-show="$store.sidebar.isOpen"
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-group-btn"
>
@if ($icon)
{{ \Filament\Support\generate_icon_html($icon, size: \Filament\Support\Enums\IconSize::Large) }}
@endif
<span class="fi-sidebar-group-label">
{{ $label }}
</span>
@if ($collapsible)
<x-filament::icon-button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::ChevronUp"
:icon-alias="\Filament\View\PanelsIconAlias::SIDEBAR_GROUP_COLLAPSE_BUTTON"
:label="$label"
x-bind:aria-expanded="! $store.sidebar.groupIsCollapsed(label)"
x-on:click.stop="$store.sidebar.toggleCollapsedGroup(label)"
class="fi-sidebar-group-collapse-btn"
/>
@endif
</div>
@endif
@if ($hasDropdown)
<x-filament::dropdown
:placement="(__('filament-panels::layout.direction') === 'rtl') ? 'left-start' : 'right-start'"
teleport
x-show="! $store.sidebar.isOpen"
>
<x-slot name="trigger">
<button
x-data="{ tooltip: false }"
x-effect="
tooltip = $store.sidebar.isOpen
? false
: {
content: @js($label),
placement: document.dir === 'rtl' ? 'left' : 'right',
theme: $store.theme,
}
"
x-tooltip.html="tooltip"
class="fi-sidebar-group-dropdown-trigger-btn"
>
{{ \Filament\Support\generate_icon_html($icon, size: \Filament\Support\Enums\IconSize::Large) }}
</button>
</x-slot>
@php
$lists = [];
foreach ($items as $item) {
if ($childItems = $item->getChildItems()) {
$lists[] = [
$item,
...$childItems,
];
$lists[] = [];
continue;
}
if (empty($lists)) {
$lists[] = [$item];
continue;
}
$lists[count($lists) - 1][] = $item;
}
if (empty($lists[count($lists) - 1])) {
array_pop($lists);
}
@endphp
@if (filled($label))
<x-filament::dropdown.header>
{{ $label }}
</x-filament::dropdown.header>
@endif
@foreach ($lists as $list)
<x-filament::dropdown.list>
@foreach ($list as $item)
@php
$itemIsActive = $item->isActive();
$itemBadge = $item->getBadge();
$itemBadgeColor = $item->getBadgeColor();
$itemBadgeTooltip = $item->getBadgeTooltip();
$itemUrl = $item->getUrl();
$itemIcon = $itemIsActive ? ($item->getActiveIcon() ?? $item->getIcon()) : $item->getIcon();
$shouldItemOpenUrlInNewTab = $item->shouldOpenUrlInNewTab();
@endphp
<x-filament::dropdown.list.item
:badge="$itemBadge"
:badge-color="$itemBadgeColor"
:badge-tooltip="$itemBadgeTooltip"
:color="$itemIsActive ? 'primary' : 'gray'"
:href="$itemUrl"
:icon="$itemIcon"
tag="a"
:target="$shouldItemOpenUrlInNewTab ? '_blank' : null"
>
{{ $item->getLabel() }}
</x-filament::dropdown.list.item>
@endforeach
</x-filament::dropdown.list>
@endforeach
</x-filament::dropdown>
@endif
<ul
@if (filled($label))
@if ($sidebarCollapsible)
x-show="$store.sidebar.isOpen ? ! $store.sidebar.groupIsCollapsed(label) : ! @js($hasDropdown)"
@else
x-show="! $store.sidebar.groupIsCollapsed(label)"
@endif
x-collapse.duration.200ms
@endif
@if ($sidebarCollapsible)
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-group-items"
>
@foreach ($items as $item)
@php
$isItemChildItemsActive = $item->isChildItemsActive();
$isItemActive = (! $isItemChildItemsActive) && $item->isActive();
$itemActiveIcon = $item->getActiveIcon();
$itemBadge = $item->getBadge();
$itemBadgeColor = $item->getBadgeColor();
$itemBadgeTooltip = $item->getBadgeTooltip();
$itemChildItems = $item->getChildItems();
$itemIcon = $item->getIcon();
$shouldItemOpenUrlInNewTab = $item->shouldOpenUrlInNewTab();
$itemUrl = $item->getUrl();
if ($icon) {
if ($hasDropdown || (blank($itemIcon) && blank($itemActiveIcon))) {
$itemIcon = null;
$itemActiveIcon = null;
} else {
throw new \Exception('Navigation group [' . $label . '] has an icon but one or more of its items also have icons. Either the group or its items can have icons, but not both. This is to ensure a proper user experience.');
}
}
@endphp
<x-filament-panels::sidebar.item
:active="$isItemActive"
:active-child-items="$isItemChildItemsActive"
:active-icon="$itemActiveIcon"
:badge="$itemBadge"
:badge-color="$itemBadgeColor"
:badge-tooltip="$itemBadgeTooltip"
:child-items="$itemChildItems"
:first="$loop->first"
:grouped="filled($label)"
:icon="$itemIcon"
:last="$loop->last"
:should-open-url-in-new-tab="$shouldItemOpenUrlInNewTab"
:sidebar-collapsible="$sidebarCollapsible"
:url="$itemUrl"
>
{{ $item->getLabel() }}
@if ($itemIcon instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="icon">
{{ $itemIcon }}
</x-slot>
@endif
@if ($itemActiveIcon instanceof \Illuminate\Contracts\Support\Htmlable)
<x-slot name="activeIcon">
{{ $itemActiveIcon }}
</x-slot>
@endif
</x-filament-panels::sidebar.item>
@endforeach
</ul>
</li>

View File

@@ -1,149 +0,0 @@
@props([
'active' => false,
'activeChildItems' => false,
'activeIcon' => null,
'badge' => null,
'badgeColor' => null,
'badgeTooltip' => null,
'childItems' => [],
'first' => false,
'grouped' => false,
'icon' => null,
'last' => false,
'shouldOpenUrlInNewTab' => false,
'sidebarCollapsible' => true,
'subGrouped' => false,
'url',
])
@php
$sidebarCollapsible = $sidebarCollapsible && filament()->isSidebarCollapsibleOnDesktop();
@endphp
<li
{{
$attributes->class([
'fi-sidebar-item',
'fi-active' => $active,
'fi-sidebar-item-has-active-child-items' => $activeChildItems,
'fi-sidebar-item-has-url' => filled($url),
])
}}
>
<a
{{ \Filament\Support\generate_href_html($url, $shouldOpenUrlInNewTab) }}
x-on:click="window.matchMedia(`(max-width: 1024px)`).matches && $store.sidebar.close()"
@if ($sidebarCollapsible)
x-data="{ tooltip: false }"
x-effect="
tooltip = $store.sidebar.isOpen
? false
: {
content: @js($slot->toHtml()),
placement: document.dir === 'rtl' ? 'left' : 'right',
theme: $store.theme,
}
"
x-tooltip.html="tooltip"
@endif
class="fi-sidebar-item-btn"
>
@if (filled($icon) && ((! $subGrouped) || $sidebarCollapsible))
{{
\Filament\Support\generate_icon_html(($active && $activeIcon) ? $activeIcon : $icon, attributes: (new \Illuminate\View\ComponentAttributeBag([
'x-show' => ($subGrouped && $sidebarCollapsible) ? '! $store.sidebar.isOpen' : false,
]))->class(['fi-sidebar-item-icon']), size: \Filament\Support\Enums\IconSize::Large)
}}
@endif
@if ((blank($icon) && $grouped) || $subGrouped)
<div
@if (filled($icon) && $subGrouped && $sidebarCollapsible)
x-show="$store.sidebar.isOpen"
@endif
class="fi-sidebar-item-grouped-border"
>
@if (! $first)
<div
class="fi-sidebar-item-grouped-border-part-not-first"
></div>
@endif
@if (! $last)
<div
class="fi-sidebar-item-grouped-border-part-not-last"
></div>
@endif
<div class="fi-sidebar-item-grouped-border-part"></div>
</div>
@endif
<span
@if ($sidebarCollapsible)
x-show="$store.sidebar.isOpen"
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-item-label"
>
{{ $slot }}
</span>
@if (filled($badge))
<span
@if ($sidebarCollapsible)
x-show="$store.sidebar.isOpen"
x-transition:enter="fi-transition-enter"
x-transition:enter-start="fi-transition-enter-start"
x-transition:enter-end="fi-transition-enter-end"
@endif
class="fi-sidebar-item-badge-ctn"
>
<x-filament::badge
:color="$badgeColor"
:tooltip="$badgeTooltip"
>
{{ $badge }}
</x-filament::badge>
</span>
@endif
</a>
@if (($active || $activeChildItems) && $childItems)
<ul class="fi-sidebar-sub-group-items">
@foreach ($childItems as $childItem)
@php
$isChildItemChildItemsActive = $childItem->isChildItemsActive();
$isChildActive = (! $isChildItemChildItemsActive) && $childItem->isActive();
$childItemActiveIcon = $childItem->getActiveIcon();
$childItemBadge = $childItem->getBadge();
$childItemBadgeColor = $childItem->getBadgeColor();
$childItemBadgeTooltip = $childItem->getBadgeTooltip();
$childItemIcon = $childItem->getIcon();
$shouldChildItemOpenUrlInNewTab = $childItem->shouldOpenUrlInNewTab();
$childItemUrl = $childItem->getUrl();
@endphp
<x-filament-panels::sidebar.item
:active="$isChildActive"
:active-child-items="$isChildItemChildItemsActive"
:active-icon="$childItemActiveIcon"
:badge="$childItemBadge"
:badge-color="$childItemBadgeColor"
:badge-tooltip="$childItemBadgeTooltip"
:first="$loop->first"
grouped
:icon="$childItemIcon"
:last="$loop->last"
:should-open-url-in-new-tab="$shouldChildItemOpenUrlInNewTab"
sub-grouped
:url="$childItemUrl"
>
{{ $childItem->getLabel() }}
</x-filament-panels::sidebar.item>
@endforeach
</ul>
@endif
</li>

View File

@@ -1,152 +0,0 @@
@props([
'teleport' => false,
])
@php
use Filament\Actions\Action;
use Illuminate\Support\Arr;
$currentTenant = filament()->getTenant();
$currentTenantName = filament()->getTenantName($currentTenant);
$items = $this->getTenantMenuItems();
$canSwitchTenants = count($tenants = array_filter(
filament()->getUserTenants(filament()->auth()->user()),
fn (\Illuminate\Database\Eloquent\Model $tenant): bool => ! $tenant->is($currentTenant),
));
$isSearchable = filled($canSwitchTenants) ? (filament()->isTenantMenuSearchable() ?? (count($tenants) >= 10)) : false;
$itemsBeforeAndAfterTenantSwitcher = collect($items)
->groupBy(fn (Action $item): bool => $canSwitchTenants && ($item->getSort() < 0), preserveKeys: true)
->all();
$itemsBeforeTenantSwitcher = $itemsBeforeAndAfterTenantSwitcher[true] ?? collect();
$itemsAfterTenantSwitcher = $itemsBeforeAndAfterTenantSwitcher[false] ?? collect();
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
@endphp
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TENANT_MENU_BEFORE) }}
<x-filament::dropdown
placement="bottom-start"
size
:teleport="$teleport"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-tenant-menu'])
"
>
<x-slot name="trigger">
<button
@if ($isSidebarCollapsibleOnDesktop)
x-data="{ tooltip: false }"
x-effect="
tooltip = $store.sidebar.isOpen
? false
: {
content: @js($currentTenantName),
placement: document.dir === 'rtl' ? 'left' : 'right',
theme: $store.theme,
}
"
x-tooltip.html="tooltip"
@endif
type="button"
class="fi-tenant-menu-trigger"
>
<x-filament-panels::avatar.tenant
:tenant="$currentTenant"
loading="lazy"
/>
<span
@if ($isSidebarCollapsibleOnDesktop)
x-show="$store.sidebar.isOpen"
@endif
class="fi-tenant-menu-trigger-text"
>
@if ($currentTenant instanceof \Filament\Models\Contracts\HasCurrentTenantLabel)
<span class="fi-tenant-menu-trigger-current-tenant-label">
{{ $currentTenant->getCurrentTenantLabel() }}
</span>
@endif
<span class="fi-tenant-menu-trigger-tenant-name">
{{ $currentTenantName }}
</span>
</span>
{{
\Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::ChevronDown, alias: \Filament\View\PanelsIconAlias::TENANT_MENU_TOGGLE_BUTTON, attributes: new \Illuminate\View\ComponentAttributeBag([
'x-show' => $isSidebarCollapsibleOnDesktop ? '$store.sidebar.isOpen' : null,
]))
}}
</button>
</x-slot>
@if ($itemsBeforeTenantSwitcher->isNotEmpty())
<x-filament::dropdown.list>
@foreach ($itemsBeforeTenantSwitcher as $item)
{{ $item }}
@endforeach
</x-filament::dropdown.list>
@endif
@if ($canSwitchTenants)
<div x-data="{ search: '' }">
<x-filament::dropdown.list>
@if ($isSearchable)
<div x-id="['input']">
<label x-bind:for="$id('input')" class="fi-sr-only">
{{ __('filament-panels::layout.tenant_menu.search_field.label') }}
</label>
<x-filament::input
x-bind:id="$id('input')"
x-model="search"
placeholder="{{ __('filament-panels::layout.tenant_menu.search_field.placeholder') }}"
type="search"
/>
</div>
@endif
@foreach ($tenants as $tenant)
@php
$tenantImage = filament()->getTenantAvatarUrl($tenant);
$tenantName = filament()->getTenantName($tenant);
$tenantUrl = filament()->getUrl($tenant);
@endphp
<div
x-show="
search === '' ||
@js($tenantName).replace(/ /g, '')
.toLowerCase()
.includes(search.replace(/ /g, '').toLowerCase())
"
>
<x-filament::dropdown.list.item
:href="$tenantUrl"
:image="$tenantImage"
tag="a"
>
{{ $tenantName }}
</x-filament::dropdown.list.item>
</div>
@endforeach
</x-filament::dropdown.list>
</div>
@endif
@if ($itemsAfterTenantSwitcher->isNotEmpty())
<x-filament::dropdown.list>
@foreach ($itemsAfterTenantSwitcher as $item)
{{ $item }}
@endforeach
</x-filament::dropdown.list>
@endif
</x-filament::dropdown>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TENANT_MENU_AFTER) }}

View File

@@ -1,28 +0,0 @@
@props([
'icon',
'theme',
])
@php
$label = __("filament-panels::layout.actions.theme_switcher.{$theme}.label");
@endphp
<button
aria-label="{{ $label }}"
type="button"
x-on:click="(theme = @js($theme)) && close()"
x-tooltip="{
content: @js($label),
theme: $store.theme,
}"
x-bind:class="{ 'fi-active': theme === @js($theme) }"
class="fi-theme-switcher-btn"
>
{{
\Filament\Support\generate_icon_html($icon, alias: match ($theme) {
'light' => \Filament\View\PanelsIconAlias::THEME_SWITCHER_LIGHT_BUTTON,
'dark' => \Filament\View\PanelsIconAlias::THEME_SWITCHER_DARK_BUTTON,
'system' => \Filament\View\PanelsIconAlias::THEME_SWITCHER_SYSTEM_BUTTON,
})
}}
</button>

View File

@@ -1,26 +0,0 @@
<div
x-data="{ theme: null }"
x-init="
$watch('theme', () => {
$dispatch('theme-changed', theme)
})
theme = localStorage.getItem('theme') || @js(filament()->getDefaultThemeMode()->value)
"
class="fi-theme-switcher"
>
<x-filament-panels::theme-switcher.button
:icon="\Filament\Support\Icons\Heroicon::Sun"
theme="light"
/>
<x-filament-panels::theme-switcher.button
:icon="\Filament\Support\Icons\Heroicon::Moon"
theme="dark"
/>
<x-filament-panels::theme-switcher.button
:icon="\Filament\Support\Icons\Heroicon::ComputerDesktop"
theme="system"
/>
</div>

View File

@@ -1,9 +0,0 @@
<x-filament::icon-button
:badge="$unreadNotificationsCount ?: null"
color="gray"
:icon="\Filament\Support\Icons\Heroicon::OutlinedBell"
:icon-alias="\Filament\View\PanelsIconAlias::TOPBAR_OPEN_DATABASE_NOTIFICATIONS_BUTTON"
icon-size="lg"
:label="__('filament-panels::layout.actions.open_database_notifications.label')"
class="fi-topbar-database-notifications-btn"
/>

View File

@@ -1,50 +0,0 @@
@props([
'active' => false,
'activeIcon' => null,
'badge' => null,
'badgeColor' => null,
'badgeTooltip' => null,
'icon' => null,
'shouldOpenUrlInNewTab' => false,
'url' => null,
])
@php
$tag = $url ? 'a' : 'button';
@endphp
<li @class([
'fi-topbar-item',
'fi-active' => $active,
])>
<{{ $tag }}
@if ($url)
{{ \Filament\Support\generate_href_html($url, $shouldOpenUrlInNewTab) }}
@else
type="button"
@endif
class="fi-topbar-item-btn"
>
@if ($icon || $activeIcon)
{{ \Filament\Support\generate_icon_html(($active && $activeIcon) ? $activeIcon : $icon, attributes: (new \Illuminate\View\ComponentAttributeBag)->class(['fi-topbar-item-icon'])) }}
@endif
<span class="fi-topbar-item-label">
{{ $slot }}
</span>
@if (filled($badge))
<x-filament::badge
:color="$badgeColor"
size="sm"
:tooltip="$badgeTooltip"
>
{{ $badge }}
</x-filament::badge>
@endif
@if (! $url)
{{ \Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::ChevronDown, alias: \Filament\View\PanelsIconAlias::TOPBAR_GROUP_TOGGLE_BUTTON, attributes: (new \Illuminate\View\ComponentAttributeBag)->class(['fi-topbar-group-toggle-icon'])) }}
@endif
</{{ $tag }}>
</li>

View File

@@ -1,10 +0,0 @@
@if (filament()->hasUnsavedChangesAlerts())
@script
<script>
setUpUnsavedActionChangesAlert({
resolveLivewireComponentUsing: () => @this,
$wire,
})
</script>
@endscript
@endif

View File

@@ -1,135 +0,0 @@
@props([
'position' => null,
])
@php
use Filament\Actions\Action;
use Filament\Enums\UserMenuPosition;
use Illuminate\Support\Arr;
$user = filament()->auth()->user();
$items = $this->getUserMenuItems();
$itemsBeforeAndAfterThemeSwitcher = collect($items)
->groupBy(fn (Action $item): bool => $item->getSort() < 0, preserveKeys: true)
->all();
$itemsBeforeThemeSwitcher = $itemsBeforeAndAfterThemeSwitcher[true] ?? collect();
$itemsAfterThemeSwitcher = $itemsBeforeAndAfterThemeSwitcher[false] ?? collect();
$hasProfileHeader = $itemsBeforeThemeSwitcher->has('profile') &&
blank(($item = Arr::first($itemsBeforeThemeSwitcher))->getUrl()) &&
(! $item->hasAction());
if ($itemsBeforeThemeSwitcher->has('profile')) {
$itemsBeforeThemeSwitcher = $itemsBeforeThemeSwitcher->prepend($itemsBeforeThemeSwitcher->pull('profile'), 'profile');
}
$position ??= filament()->getUserMenuPosition();
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
@endphp
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_BEFORE) }}
<x-filament::dropdown
:placement="($position === UserMenuPosition::Topbar) ? 'bottom-end' : 'top-end'"
:teleport="$position === UserMenuPosition::Topbar"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-user-menu'])
"
>
<x-slot name="trigger">
@if ($position === UserMenuPosition::Topbar)
<button
aria-label="{{ __('filament-panels::layout.actions.open_user_menu.label') }}"
type="button"
class="fi-user-menu-trigger"
>
<x-filament-panels::avatar.user :user="$user" loading="lazy" />
</button>
@else
<button
aria-label="{{ __('filament-panels::layout.actions.open_user_menu.label') }}"
type="button"
class="fi-user-menu-trigger"
>
<x-filament-panels::avatar.user :user="$user" loading="lazy" />
<span
@if ($isSidebarCollapsibleOnDesktop)
x-show="$store.sidebar.isOpen"
@endif
class="fi-user-menu-trigger-text"
>
{{ filament()->getUserName($user) }}
</span>
{{
\Filament\Support\generate_icon_html(\Filament\Support\Icons\Heroicon::ChevronUp, alias: \Filament\View\PanelsIconAlias::USER_MENU_TOGGLE_BUTTON, attributes: new \Illuminate\View\ComponentAttributeBag([
'x-show' => $isSidebarCollapsibleOnDesktop ? '$store.sidebar.isOpen' : null,
]))
}}
</button>
@endif
</x-slot>
@if ($hasProfileHeader)
@php
$item = $itemsBeforeThemeSwitcher['profile'];
$itemColor = $item->getColor();
$itemIcon = $item->getIcon();
unset($itemsBeforeThemeSwitcher['profile']);
@endphp
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_BEFORE) }}
<x-filament::dropdown.header :color="$itemColor" :icon="$itemIcon">
{{ $item->getLabel() }}
</x-filament::dropdown.header>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_AFTER) }}
@endif
@if ($itemsBeforeThemeSwitcher->isNotEmpty())
<x-filament::dropdown.list>
@foreach ($itemsBeforeThemeSwitcher as $key => $item)
@if ($key === 'profile')
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_BEFORE) }}
{{ $item }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_AFTER) }}
@else
{{ $item }}
@endif
@endforeach
</x-filament::dropdown.list>
@endif
@if (filament()->hasDarkMode() && (! filament()->hasDarkModeForced()))
<x-filament::dropdown.list>
<x-filament-panels::theme-switcher />
</x-filament::dropdown.list>
@endif
@if ($itemsAfterThemeSwitcher->isNotEmpty())
<x-filament::dropdown.list>
@foreach ($itemsAfterThemeSwitcher as $key => $item)
@if ($key === 'profile')
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_BEFORE) }}
{{ $item }}
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_PROFILE_AFTER) }}
@else
{{ $item }}
@endif
@endforeach
</x-filament::dropdown.list>
@endif
</x-filament::dropdown>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::USER_MENU_AFTER) }}

View File

@@ -1,153 +0,0 @@
@php
$debounce = filament()->getGlobalSearchDebounce();
$keyBindings = filament()->getGlobalSearchKeyBindings();
$suffix = filament()->getGlobalSearchFieldSuffix();
@endphp
<div class="fi-global-search-ctn">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::GLOBAL_SEARCH_START) }}
<div
x-on:focus-first-global-search-result.stop="$el.querySelector('.fi-global-search-result-link')?.focus()"
class="fi-global-search"
>
<div x-id="['input']" class="fi-global-search-field">
<label x-bind:for="$id('input')" class="fi-sr-only">
{{ __('filament-panels::global-search.field.label') }}
</label>
<x-filament::input.wrapper
:prefix-icon="\Filament\Support\Icons\Heroicon::MagnifyingGlass"
:prefix-icon-alias="\Filament\View\PanelsIconAlias::GLOBAL_SEARCH_FIELD"
inline-prefix
:suffix="$suffix"
inline-suffix
wire:target="search"
>
<input
autocomplete="off"
maxlength="1000"
placeholder="{{ __('filament-panels::global-search.field.placeholder') }}"
type="search"
wire:key="global-search.field.input"
x-bind:id="$id('input')"
x-on:keydown.down.prevent.stop="$dispatch('focus-first-global-search-result')"
wire:model.live.debounce.{{ $debounce }}="search"
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($id('input')).focus()"
class="fi-input fi-input-has-inline-prefix"
/>
</x-filament::input.wrapper>
</div>
@if ($results !== null)
<div
x-data="{
isOpen: false,
open(event) {
this.isOpen = true
},
close(event) {
this.isOpen = false
},
}"
x-init="$nextTick(() => open())"
x-on:click.away="close()"
x-on:keydown.escape.window="close()"
x-on:keydown.up.prevent="$focus.wrap().previous()"
x-on:keydown.down.prevent="$focus.wrap().next()"
x-on:open-global-search-results.window="$nextTick(() => open())"
x-show="isOpen"
x-transition:enter-start="fi-transition-enter-start"
x-transition:leave-end="fi-transition-leave-end"
class="fi-global-search-results-ctn"
>
@if ($results->getCategories()->isEmpty())
<p class="fi-global-search-no-results-message">
{{ __('filament-panels::global-search.no_results_message') }}
</p>
@else
<ul class="fi-global-search-results">
@foreach ($results->getCategories() as $group => $groupedResults)
<li class="fi-global-search-result-group">
<h3
class="fi-global-search-result-group-header"
>
{{ $group }}
</h3>
<ul
class="fi-global-search-result-group-results"
>
@foreach ($groupedResults as $result)
@php
$resultVisibleActions = $result->getVisibleActions();
@endphp
<li
@class([
'fi-global-search-result',
'fi-global-search-result-has-actions' => $resultVisibleActions,
])
>
<a
{{ \Filament\Support\generate_href_html($result->url) }}
x-on:click="close()"
class="fi-global-search-result-link"
>
<h4
class="fi-global-search-result-heading"
>
{{ $result->title }}
</h4>
@if ($result->details)
<dl
class="fi-global-search-result-details"
>
@foreach ($result->details as $label => $value)
<div
class="fi-global-search-result-detail"
>
@if ($isAssoc ??= \Illuminate\Support\Arr::isAssoc($result->details))
<dt
class="fi-global-search-result-detail-label"
>
{{ $label }}:
</dt>
@endif
<dd
class="fi-global-search-result-detail-value"
>
{{ $value }}
</dd>
</div>
@endforeach
</dl>
@endif
</a>
@if ($resultVisibleActions)
<div
class="fi-global-search-result-actions"
>
@foreach ($resultVisibleActions as $action)
{{ $action }}
@endforeach
</div>
@endif
</li>
@endforeach
</ul>
</li>
@endforeach
</ul>
@endif
</div>
@endif
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::GLOBAL_SEARCH_END) }}
</div>

View File

@@ -1,198 +0,0 @@
<div>
@php
$navigation = filament()->getNavigation();
$isRtl = __('filament-panels::layout.direction') === 'rtl';
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
$isSidebarFullyCollapsibleOnDesktop = filament()->isSidebarFullyCollapsibleOnDesktop();
$hasNavigation = filament()->hasNavigation();
$hasTopbar = filament()->hasTopbar();
@endphp
{{-- format-ignore-start --}}
<aside
x-data="{}"
@if ($isSidebarCollapsibleOnDesktop || $isSidebarFullyCollapsibleOnDesktop)
x-cloak
@else
x-cloak="-lg"
@endif
x-bind:class="{ 'fi-sidebar-open': $store.sidebar.isOpen }"
class="fi-sidebar fi-main-sidebar"
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_START) }}
<div class="fi-sidebar-header-ctn">
<header
class="fi-sidebar-header"
>
@if ((! $hasTopbar) && $isSidebarCollapsibleOnDesktop)
<x-filament::icon-button
color="gray"
:icon="$isRtl ? \Filament\Support\Icons\Heroicon::OutlinedChevronLeft : \Filament\Support\Icons\Heroicon::OutlinedChevronRight"
{{-- @deprecated Use `PanelsIconAlias::SIDEBAR_EXPAND_BUTTON_RTL` instead of `PanelsIconAlias::SIDEBAR_EXPAND_BUTTON` for RTL. --}}
:icon-alias="
$isRtl
? [
\Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON_RTL,
\Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON,
]
: \Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON
"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.expand.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.open()"
x-show="! $store.sidebar.isOpen"
class="fi-sidebar-open-collapse-sidebar-btn"
/>
@endif
@if ((! $hasTopbar) && ($isSidebarCollapsibleOnDesktop || $isSidebarFullyCollapsibleOnDesktop))
<x-filament::icon-button
color="gray"
:icon="$isRtl ? \Filament\Support\Icons\Heroicon::OutlinedChevronRight : \Filament\Support\Icons\Heroicon::OutlinedChevronLeft"
{{-- @deprecated Use `PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON_RTL` instead of `PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON` for RTL. --}}
:icon-alias="
$isRtl
? [
\Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON_RTL,
\Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON,
]
: \Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON
"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.collapse.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.close()"
x-show="$store.sidebar.isOpen"
class="fi-sidebar-close-collapse-sidebar-btn"
/>
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_LOGO_BEFORE) }}
<div x-show="$store.sidebar.isOpen" class="fi-sidebar-header-logo-ctn">
@if ($homeUrl = filament()->getHomeUrl())
<a {{ \Filament\Support\generate_href_html($homeUrl) }}>
<x-filament-panels::logo />
</a>
@else
<x-filament-panels::logo />
@endif
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_LOGO_AFTER) }}
</header>
</div>
@if (filament()->hasTenancy() && filament()->hasTenantMenu())
<x-filament-panels::tenant-menu />
@endif
@if (filament()->isGlobalSearchEnabled() && filament()->getGlobalSearchPosition() === \Filament\Enums\GlobalSearchPosition::Sidebar)
<div
@if ($isSidebarCollapsibleOnDesktop || $isSidebarFullyCollapsibleOnDesktop)
x-show="$store.sidebar.isOpen"
@endif
>
@livewire(Filament\Livewire\GlobalSearch::class)
</div>
@endif
<nav class="fi-sidebar-nav">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_NAV_START) }}
<ul class="fi-sidebar-nav-groups">
@foreach ($navigation as $group)
@php
$isGroupActive = $group->isActive();
$isGroupCollapsible = $group->isCollapsible();
$groupIcon = $group->getIcon();
$groupItems = $group->getItems();
$groupLabel = $group->getLabel();
$groupExtraSidebarAttributeBag = $group->getExtraSidebarAttributeBag();
@endphp
<x-filament-panels::sidebar.group
:active="$isGroupActive"
:collapsible="$isGroupCollapsible"
:icon="$groupIcon"
:items="$groupItems"
:label="$groupLabel"
:attributes="\Filament\Support\prepare_inherited_attributes($groupExtraSidebarAttributeBag)"
/>
@endforeach
</ul>
<script>
var collapsedGroups = JSON.parse(
localStorage.getItem('collapsedGroups'),
)
if (collapsedGroups === null || collapsedGroups === 'null') {
localStorage.setItem(
'collapsedGroups',
JSON.stringify(@js(
collect($navigation)
->filter(fn (\Filament\Navigation\NavigationGroup $group): bool => $group->isCollapsed())
->map(fn (\Filament\Navigation\NavigationGroup $group): string => $group->getLabel())
->values()
->all()
)),
)
}
collapsedGroups = JSON.parse(
localStorage.getItem('collapsedGroups'),
)
document
.querySelectorAll('.fi-sidebar-group')
.forEach((group) => {
if (
!collapsedGroups.includes(group.dataset.groupLabel)
) {
return
}
// Alpine.js loads too slow, so attempt to hide a
// collapsed sidebar group earlier.
group.querySelector(
'.fi-sidebar-group-items',
).style.display = 'none'
group.classList.add('fi-collapsed')
})
</script>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_NAV_END) }}
</nav>
@php
$isAuthenticated = filament()->auth()->check();
$hasDatabaseNotificationsInSidebar = filament()->hasDatabaseNotifications() && filament()->getDatabaseNotificationsPosition() === \Filament\Enums\DatabaseNotificationsPosition::Sidebar;
$hasUserMenuInSidebar = filament()->hasUserMenu() && filament()->getUserMenuPosition() === \Filament\Enums\UserMenuPosition::Sidebar;
$shouldRenderFooter = $isAuthenticated && ($hasDatabaseNotificationsInSidebar || $hasUserMenuInSidebar);
@endphp
@if ($shouldRenderFooter)
<div class="fi-sidebar-footer">
@if ($hasDatabaseNotificationsInSidebar)
@livewire(Filament\Livewire\DatabaseNotifications::class, [
'lazy' => filament()->hasLazyLoadedDatabaseNotifications(),
])
@endif
@if ($hasUserMenuInSidebar)
<x-filament-panels::user-menu />
@endif
</div>
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::SIDEBAR_FOOTER) }}
</aside>
{{-- format-ignore-end --}}
<x-filament-actions::modals />
</div>

View File

@@ -1,9 +0,0 @@
<div>
<div class="fi-simple-user-menu-ctn">
<x-filament-panels::user-menu
:position="\Filament\Enums\UserMenuPosition::Topbar"
/>
</div>
<x-filament-actions::modals />
</div>

View File

@@ -1,258 +0,0 @@
<div class="fi-topbar-ctn">
@php
$isRtl = __('filament-panels::layout.direction') === 'rtl';
$isSidebarCollapsibleOnDesktop = filament()->isSidebarCollapsibleOnDesktop();
$isSidebarFullyCollapsibleOnDesktop = filament()->isSidebarFullyCollapsibleOnDesktop();
$hasTopNavigation = filament()->hasTopNavigation();
$hasNavigation = filament()->hasNavigation();
$hasTenancy = filament()->hasTenancy();
@endphp
<nav class="fi-topbar">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_START) }}
@if ($hasNavigation)
<x-filament::icon-button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::OutlinedBars3"
:icon-alias="\Filament\View\PanelsIconAlias::TOPBAR_OPEN_SIDEBAR_BUTTON"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.expand.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.open()"
x-show="! $store.sidebar.isOpen"
class="fi-topbar-open-sidebar-btn"
/>
<x-filament::icon-button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::OutlinedXMark"
:icon-alias="\Filament\View\PanelsIconAlias::TOPBAR_CLOSE_SIDEBAR_BUTTON"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.collapse.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.close()"
x-show="$store.sidebar.isOpen"
class="fi-topbar-close-sidebar-btn"
/>
@endif
<div class="fi-topbar-start">
@if ($isSidebarCollapsibleOnDesktop)
<x-filament::icon-button
color="gray"
:icon="$isRtl ? \Filament\Support\Icons\Heroicon::OutlinedChevronLeft : \Filament\Support\Icons\Heroicon::OutlinedChevronRight"
{{-- @deprecated Use `PanelsIconAlias::SIDEBAR_EXPAND_BUTTON_RTL` instead of `PanelsIconAlias::SIDEBAR_EXPAND_BUTTON` for RTL. --}}
:icon-alias="
$isRtl
? [
\Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON_RTL,
\Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON,
]
: \Filament\View\PanelsIconAlias::SIDEBAR_EXPAND_BUTTON
"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.expand.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.open()"
x-show="! $store.sidebar.isOpen"
class="fi-topbar-open-collapse-sidebar-btn"
/>
@endif
@if ($isSidebarCollapsibleOnDesktop || $isSidebarFullyCollapsibleOnDesktop)
<x-filament::icon-button
color="gray"
:icon="$isRtl ? \Filament\Support\Icons\Heroicon::OutlinedChevronRight : \Filament\Support\Icons\Heroicon::OutlinedChevronLeft"
{{-- @deprecated Use `PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON_RTL` instead of `PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON` for RTL. --}}
:icon-alias="
$isRtl
? [
\Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON_RTL,
\Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON,
]
: \Filament\View\PanelsIconAlias::SIDEBAR_COLLAPSE_BUTTON
"
icon-size="lg"
:label="__('filament-panels::layout.actions.sidebar.collapse.label')"
x-cloak
x-data="{}"
x-on:click="$store.sidebar.close()"
x-show="$store.sidebar.isOpen"
class="fi-topbar-close-collapse-sidebar-btn"
/>
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_LOGO_BEFORE) }}
@if ($homeUrl = filament()->getHomeUrl())
<a {{ \Filament\Support\generate_href_html($homeUrl) }}>
<x-filament-panels::logo />
</a>
@else
<x-filament-panels::logo />
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_LOGO_AFTER) }}
</div>
@if ($hasTopNavigation || (! $hasNavigation))
@if ($hasTenancy && filament()->hasTenantMenu())
<x-filament-panels::tenant-menu teleport />
@endif
@if ($hasNavigation)
@php
$navigation = filament()->getNavigation();
@endphp
<ul class="fi-topbar-nav-groups">
@foreach ($navigation as $group)
@php
$groupLabel = $group->getLabel();
$groupExtraTopbarAttributeBag = $group->getExtraTopbarAttributeBag();
$isGroupActive = $group->isActive();
$groupIcon = $group->getIcon();
@endphp
@if ($groupLabel)
<x-filament::dropdown
placement="bottom-start"
teleport
:attributes="\Filament\Support\prepare_inherited_attributes($groupExtraTopbarAttributeBag)"
>
<x-slot name="trigger">
<x-filament-panels::topbar.item
:active="$isGroupActive"
:icon="$groupIcon"
>
{{ $groupLabel }}
</x-filament-panels::topbar.item>
</x-slot>
@php
$lists = [];
foreach ($group->getItems() as $item) {
if ($childItems = $item->getChildItems()) {
$lists[] = [
$item,
...$childItems,
];
$lists[] = [];
continue;
}
if (empty($lists)) {
$lists[] = [$item];
continue;
}
$lists[count($lists) - 1][] = $item;
}
if (empty($lists[count($lists) - 1])) {
array_pop($lists);
}
@endphp
@foreach ($lists as $list)
<x-filament::dropdown.list>
@foreach ($list as $item)
@php
$isItemActive = $item->isActive();
$itemBadge = $item->getBadge();
$itemBadgeColor = $item->getBadgeColor();
$itemBadgeTooltip = $item->getBadgeTooltip();
$itemUrl = $item->getUrl();
$itemIcon = $isItemActive ? ($item->getActiveIcon() ?? $item->getIcon()) : $item->getIcon();
$shouldItemOpenUrlInNewTab = $item->shouldOpenUrlInNewTab();
@endphp
<x-filament::dropdown.list.item
:badge="$itemBadge"
:badge-color="$itemBadgeColor"
:badge-tooltip="$itemBadgeTooltip"
:color="$isItemActive ? 'primary' : 'gray'"
:href="$itemUrl"
:icon="$itemIcon"
tag="a"
:target="$shouldItemOpenUrlInNewTab ? '_blank' : null"
>
{{ $item->getLabel() }}
</x-filament::dropdown.list.item>
@endforeach
</x-filament::dropdown.list>
@endforeach
</x-filament::dropdown>
@else
@foreach ($group->getItems() as $item)
@php
$isItemActive = $item->isActive();
$itemActiveIcon = $item->getActiveIcon();
$itemBadge = $item->getBadge();
$itemBadgeColor = $item->getBadgeColor();
$itemBadgeTooltip = $item->getBadgeTooltip();
$itemIcon = $item->getIcon();
$shouldItemOpenUrlInNewTab = $item->shouldOpenUrlInNewTab();
$itemUrl = $item->getUrl();
@endphp
<x-filament-panels::topbar.item
:active="$isItemActive"
:active-icon="$itemActiveIcon"
:badge="$itemBadge"
:badge-color="$itemBadgeColor"
:badge-tooltip="$itemBadgeTooltip"
:icon="$itemIcon"
:should-open-url-in-new-tab="$shouldItemOpenUrlInNewTab"
:url="$itemUrl"
>
{{ $item->getLabel() }}
</x-filament-panels::topbar.item>
@endforeach
@endif
@endforeach
</ul>
@endif
@endif
<div
@if ($hasTenancy)
x-persist="topbar.end.panel-{{ filament()->getId() }}.tenant-{{ filament()->getTenant()?->getKey() }}"
@else
x-persist="topbar.end.panel-{{ filament()->getId() }}"
@endif
class="fi-topbar-end"
>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::GLOBAL_SEARCH_BEFORE) }}
@if (filament()->isGlobalSearchEnabled() && filament()->getGlobalSearchPosition() === \Filament\Enums\GlobalSearchPosition::Topbar)
@livewire(Filament\Livewire\GlobalSearch::class)
@endif
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::GLOBAL_SEARCH_AFTER) }}
@if (filament()->auth()->check())
@if (filament()->hasDatabaseNotifications() && filament()->getDatabaseNotificationsPosition() === \Filament\Enums\DatabaseNotificationsPosition::Topbar)
@livewire(Filament\Livewire\DatabaseNotifications::class, [
'lazy' => filament()->hasLazyLoadedDatabaseNotifications(),
])
@endif
@if (filament()->hasUserMenu() && filament()->getUserMenuPosition() === \Filament\Enums\UserMenuPosition::Topbar)
<x-filament-panels::user-menu />
@endif
@endif
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_END) }}
</nav>
<x-filament-actions::modals />
</div>

View File

@@ -1,3 +0,0 @@
<x-filament-panels::page>
{{ $this->content }}
</x-filament-panels::page>

View File

@@ -1,3 +0,0 @@
<x-filament-panels::page.simple>
{{ $this->content }}
</x-filament-panels::page.simple>

View File

@@ -1,5 +0,0 @@
<div class="fi-resource-relation-manager">
{{ $this->content }}
<x-filament-panels::unsaved-action-changes-alert />
</div>

View File

@@ -1,42 +0,0 @@
@php
$user = filament()->auth()->user();
@endphp
<x-filament-widgets::widget class="fi-account-widget">
<x-filament::section>
<x-filament-panels::avatar.user
size="lg"
:user="$user"
loading="lazy"
/>
<div class="fi-account-widget-main">
<h2 class="fi-account-widget-heading">
{{ __('filament-panels::widgets/account-widget.welcome', ['app' => config('app.name')]) }}
</h2>
<p class="fi-account-widget-user-name">
{{ filament()->getUserName($user) }}
</p>
</div>
<form
action="{{ filament()->getLogoutUrl() }}"
method="post"
class="fi-account-widget-logout-form"
>
@csrf
<x-filament::button
color="gray"
:icon="\Filament\Support\Icons\Heroicon::ArrowLeftEndOnRectangle"
:icon-alias="\Filament\View\PanelsIconAlias::WIDGETS_ACCOUNT_LOGOUT_BUTTON"
labeled-from="sm"
tag="button"
type="submit"
>
{{ __('filament-panels::widgets/account-widget.actions.logout.label') }}
</x-filament::button>
</form>
</x-filament::section>
</x-filament-widgets::widget>

File diff suppressed because one or more lines are too long

View File

@@ -1,58 +0,0 @@
@php
use Filament\Support\Enums\VerticalAlignment;
$actions = $getChildSchema()->getComponents();
$alignment = $getAlignment();
$isFullWidth = $isFullWidth();
$verticalAlignment = $getVerticalAlignment();
if (! $verticalAlignment instanceof VerticalAlignment) {
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
}
@endphp
<div
@if ($isSticky())
x-data="filamentActionsSchemaComponent()"
x-intersect:enter.half="disableSticky"
x-intersect:leave="enableSticky"
x-bind:class="{ 'fi-sticky': isSticky }"
@endif
{{
$attributes
->merge([
'id' => $getId(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->class([
'fi-sc-actions',
($verticalAlignment instanceof VerticalAlignment) ? "fi-vertical-align-{$verticalAlignment->value}" : $verticalAlignment,
])
}}
>
@if (filled($label = $getLabel()))
<div class="fi-sc-actions-label-ctn">
{{ $getChildSchema($schemaComponent::BEFORE_LABEL_SCHEMA_KEY) }}
<div class="fi-sc-actions-label">
{{ $label }}
</div>
{{ $getChildSchema($schemaComponent::AFTER_LABEL_SCHEMA_KEY) }}
</div>
@endif
@if ($aboveContentContainer = $getChildSchema($schemaComponent::ABOVE_CONTENT_SCHEMA_KEY)?->toHtmlString())
{{ $aboveContentContainer }}
@endif
<x-filament::actions
:actions="$actions"
:alignment="$alignment"
:full-width="$isFullWidth"
/>
@if ($belowContentContainer = $getChildSchema($schemaComponent::BELOW_CONTENT_SCHEMA_KEY)?->toHtmlString())
{{ $belowContentContainer }}
@endif
</div>

View File

@@ -1,27 +0,0 @@
@php
$description = $getDescription();
$footer = $getChildSchema($schemaComponent::FOOTER_SCHEMA_KEY)?->toHtmlString();
$heading = $getHeading();
$headingTag = $getHeadingTag();
$icon = $getIcon();
$iconColor = $getIconColor();
$iconSize = $getIconSize();
@endphp
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class(['fi-sc-empty-state'])
}}
>
<x-filament::empty-state
:description="$description"
:footer="$footer"
:heading="$heading"
:heading-tag="$headingTag"
:icon="$icon"
:icon-color="$iconColor"
:icon-size="$iconSize"
/>
</div>

View File

@@ -1,24 +0,0 @@
@php
$extraAttributes = $getExtraAttributes();
$id = $getId();
$isLabelHidden = $isLabelHidden();
$label = $getLabel();
$isContained = $isContained();
@endphp
<x-filament::fieldset
:contained="$isContained"
:label="$label"
:label-hidden="$isLabelHidden"
:required="isset($isMarkedAsRequired) ? $isMarkedAsRequired() : false"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->merge([
'id' => $id,
], escape: false)
->merge($extraAttributes, escape: false)
->class(['fi-sc-fieldset'])
"
>
{{ $getChildSchema() }}
</x-filament::fieldset>

View File

@@ -1,71 +0,0 @@
@php
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Schemas\Components\Component;
use Filament\Support\Enums\VerticalAlignment;
$statePath = $getStatePath();
$fromBreakpoint = $getFromBreakpoint();
$verticalAlignment = $getVerticalAlignment();
if (! $verticalAlignment instanceof VerticalAlignment) {
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
}
@endphp
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-sc-flex',
'fi-dense' => $isDense(),
'fi-from-' . ($fromBreakpoint ?? 'default'),
($verticalAlignment instanceof VerticalAlignment) ? "fi-vertical-align-{$verticalAlignment->value}" : $verticalAlignment,
])
}}
>
@foreach ($getChildSchema()->getComponents() as $component)
@if (($component instanceof Action) || ($component instanceof ActionGroup))
<div>
{{ $component }}
</div>
@else
@php
$hiddenJs = $component->getHiddenJs();
$visibleJs = $component->getVisibleJs();
$componentStatePath = $component->getStatePath();
@endphp
<div
x-data="filamentSchemaComponent({
path: @js($componentStatePath),
containerPath: @js($statePath),
$wire,
})"
@if ($afterStateUpdatedJs = $schemaComponent->getAfterStateUpdatedJs())
x-init="{!! implode(';', array_map(
fn (string $js): string => '$wire.watch(' . Js::from($componentStatePath) . ', ($state, $old) => isStateChanged($state, $old) && eval(' . Js::from($js) . '))',
$afterStateUpdatedJs,
)) !!}"
@endif
@if (filled($visibilityJs = match ([filled($hiddenJs), filled($visibleJs)]) {
[true, true] => "(! ({$hiddenJs})) && ({$visibleJs})",
[true, false] => "! ({$hiddenJs})",
[false, true] => $visibleJs,
default => null,
}))
x-bind:class="{ 'fi-hidden': ! ({!! $visibilityJs !!}) }"
x-cloak
@endif
@class([
'fi-growable' => ($component instanceof Component) && $component->canGrow(),
])
>
{{ $component }}
</div>
@endif
@endforeach
</div>

View File

@@ -1,20 +0,0 @@
<form
{{
$attributes
->merge([
'id' => $getId(),
'wire:submit' => $getLivewireSubmitHandler(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->class([
'fi-sc-form',
'fi-dense' => $isDense(),
])
}}
>
{{ $getChildSchema($schemaComponent::HEADER_SCHEMA_KEY) }}
{{ $getChildSchema() }}
{{ $getChildSchema($schemaComponent::FOOTER_SCHEMA_KEY) }}
</form>

View File

@@ -1,73 +0,0 @@
@php
use Filament\Forms\Components\Contracts\HasNestedRecursiveValidationRules;
use Filament\Forms\Components\Field;
$fieldWrapperView = $getFieldWrapperView();
$errorMessages = null;
$errorMessage = null;
foreach ($getChildComponentContainer()->getComponents() as $childComponent) {
if (! ($childComponent instanceof Field)) {
continue;
}
$statePath = $childComponent->getStatePath();
if (blank($statePath)) {
continue;
}
if ($errors->has($statePath)) {
if ($childComponent->shouldShowAllValidationMessages()) {
$errorMessages = $errors->get($statePath);
$shouldShowAllValidationMessages = true;
} else {
$errorMessage = $errors->first($statePath);
}
$areHtmlValidationMessagesAllowed = $childComponent->areHtmlValidationMessagesAllowed();
break;
}
if (! ($childComponent instanceof HasNestedRecursiveValidationRules)) {
continue;
}
if ($errors->has("{$statePath}.*")) {
if ($childComponent->shouldShowAllValidationMessages()) {
$errorMessages = $errors->get("{$statePath}.*");
$shouldShowAllValidationMessages = true;
} else {
$errorMessage = $errors->first("{$statePath}.*");
}
$areHtmlValidationMessagesAllowed = $childComponent->areHtmlValidationMessagesAllowed();
break;
}
}
@endphp
<x-dynamic-component
:component="$fieldWrapperView"
:error-message="$errorMessage"
:error-messages="$errorMessages"
:are-html-error-messages-allowed="$areHtmlValidationMessagesAllowed ?? false"
:should-show-all-validation-messages="$shouldShowAllValidationMessages ?? false"
:field="$schemaComponent"
>
<div
{{
$attributes
->merge([
'id' => $getId(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
->class(['fi-sc-fused-group'])
}}
>
{{ $getChildSchema() }}
</div>
</x-dynamic-component>

View File

@@ -1,11 +0,0 @@
<div
{{
$attributes
->merge([
'id' => $getId(),
], escape: false)
->merge($getExtraAttributes(), escape: false)
}}
>
{{ $getChildSchema() }}
</div>

Some files were not shown because too many files have changed in this diff Show More