This commit is contained in:
2025-10-22 20:08:22 +05:00
commit 736e3bef18
2573 changed files with 120385 additions and 0 deletions

View File

@@ -0,0 +1,263 @@
@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

@@ -0,0 +1,129 @@
@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

@@ -0,0 +1,231 @@
@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>