[增添]添加了datasource的setting数据库以及默认值
This commit is contained in:
104
vendor/filament/forms/resources/views/component-container.blade.php
vendored
Normal file
104
vendor/filament/forms/resources/views/component-container.blade.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
@php
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Illuminate\Support\Js;
|
||||
|
||||
$isRoot = $isRoot();
|
||||
@endphp
|
||||
|
||||
<x-filament::grid
|
||||
:x-data="$isRoot ? '{}' : null"
|
||||
:x-on:form-validation-error.window="
|
||||
$isRoot ? ('if ($event.detail.livewireId !== ' . Js::from($this->getId()) . ') {
|
||||
return
|
||||
}
|
||||
|
||||
$nextTick(() => {
|
||||
let error = $el.querySelector(\'[data-validation-error]\')
|
||||
|
||||
if (! error) {
|
||||
return
|
||||
}
|
||||
|
||||
let elementToExpand = error
|
||||
|
||||
while (elementToExpand) {
|
||||
elementToExpand.dispatchEvent(new CustomEvent(\'expand\'))
|
||||
|
||||
elementToExpand = elementToExpand.parentNode
|
||||
}
|
||||
|
||||
setTimeout(
|
||||
() =>
|
||||
error.closest(\'[data-field-wrapper]\').scrollIntoView({
|
||||
behavior: \'smooth\',
|
||||
block: \'start\',
|
||||
inline: \'start\',
|
||||
}),
|
||||
200,
|
||||
)
|
||||
})') : null
|
||||
"
|
||||
:default="$getColumns('default')"
|
||||
:sm="$getColumns('sm')"
|
||||
:md="$getColumns('md')"
|
||||
:lg="$getColumns('lg')"
|
||||
:xl="$getColumns('xl')"
|
||||
:two-xl="$getColumns('2xl')"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-component-ctn gap-6'])
|
||||
"
|
||||
>
|
||||
@foreach ($getComponents(withHidden: true) as $formComponent)
|
||||
@php
|
||||
/**
|
||||
* Instead of only rendering the hidden components, we should
|
||||
* render the `<div>` wrappers for all fields, regardless of
|
||||
* if they are hidden or not. This is to solve Livewire DOM
|
||||
* diffing issues.
|
||||
*
|
||||
* Additionally, any `<div>` elements that wrap hidden
|
||||
* components need to have `class="hidden"`, so that they
|
||||
* don't consume grid space.
|
||||
*/
|
||||
$isHidden = $formComponent->isHidden();
|
||||
@endphp
|
||||
|
||||
<x-filament::grid.column
|
||||
:wire:key="$formComponent instanceof \Filament\Forms\Components\Field ? $this->getId() . '.' . $formComponent->getStatePath() . '.' . $formComponent::class : null"
|
||||
:hidden="$isHidden"
|
||||
:default="$formComponent->getColumnSpan('default')"
|
||||
:sm="$formComponent->getColumnSpan('sm')"
|
||||
:md="$formComponent->getColumnSpan('md')"
|
||||
:lg="$formComponent->getColumnSpan('lg')"
|
||||
:xl="$formComponent->getColumnSpan('xl')"
|
||||
:twoXl="$formComponent->getColumnSpan('2xl')"
|
||||
:defaultStart="$formComponent->getColumnStart('default')"
|
||||
:smStart="$formComponent->getColumnStart('sm')"
|
||||
:mdStart="$formComponent->getColumnStart('md')"
|
||||
:lgStart="$formComponent->getColumnStart('lg')"
|
||||
:xlStart="$formComponent->getColumnStart('xl')"
|
||||
:twoXlStart="$formComponent->getColumnStart('2xl')"
|
||||
@class([
|
||||
match ($maxWidth = $formComponent->getMaxWidth()) {
|
||||
MaxWidth::ExtraSmall, 'xs' => 'max-w-xs',
|
||||
MaxWidth::Small, 'sm' => 'max-w-sm',
|
||||
MaxWidth::Medium, 'md' => 'max-w-md',
|
||||
MaxWidth::Large, 'lg' => 'max-w-lg',
|
||||
MaxWidth::ExtraLarge, 'xl' => 'max-w-xl',
|
||||
MaxWidth::TwoExtraLarge, '2xl' => 'max-w-2xl',
|
||||
MaxWidth::ThreeExtraLarge, '3xl' => 'max-w-3xl',
|
||||
MaxWidth::FourExtraLarge, '4xl' => 'max-w-4xl',
|
||||
MaxWidth::FiveExtraLarge, '5xl' => 'max-w-5xl',
|
||||
MaxWidth::SixExtraLarge, '6xl' => 'max-w-6xl',
|
||||
MaxWidth::SevenExtraLarge, '7xl' => 'max-w-7xl',
|
||||
default => $maxWidth,
|
||||
},
|
||||
])
|
||||
>
|
||||
@if (! $isHidden)
|
||||
{{ $formComponent }}
|
||||
@endif
|
||||
</x-filament::grid.column>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
34
vendor/filament/forms/resources/views/components/actions.blade.php
vendored
Normal file
34
vendor/filament/forms/resources/views/components/actions.blade.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
|
||||
$verticalAlignment = $getVerticalAlignment();
|
||||
|
||||
if (! $verticalAlignment instanceof VerticalAlignment) {
|
||||
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-actions flex h-full flex-col',
|
||||
match ($verticalAlignment) {
|
||||
VerticalAlignment::Start => 'justify-start',
|
||||
VerticalAlignment::Center => 'justify-center',
|
||||
VerticalAlignment::End => 'justify-end',
|
||||
default => $verticalAlignment,
|
||||
},
|
||||
])
|
||||
}}
|
||||
>
|
||||
<x-filament::actions
|
||||
:actions="$getChildComponentContainer()->getComponents()"
|
||||
:alignment="$getAlignment()"
|
||||
:full-width="$isFullWidth()"
|
||||
/>
|
||||
</div>
|
||||
5
vendor/filament/forms/resources/views/components/actions/action-container.blade.php
vendored
Normal file
5
vendor/filament/forms/resources/views/components/actions/action-container.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
@foreach ($getActions() as $action)
|
||||
@if ($action->isVisible())
|
||||
{{ $action }}
|
||||
@endif
|
||||
@endforeach
|
||||
300
vendor/filament/forms/resources/views/components/builder.blade.php
vendored
Normal file
300
vendor/filament/forms/resources/views/components/builder.blade.php
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
@php
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
|
||||
$containers = $getChildComponentContainers();
|
||||
$blockPickerBlocks = $getBlockPickerBlocks();
|
||||
$blockPickerColumns = $getBlockPickerColumns();
|
||||
$blockPickerWidth = $getBlockPickerWidth();
|
||||
$hasBlockPreviews = $hasBlockPreviews();
|
||||
$hasInteractiveBlockPreviews = $hasInteractiveBlockPreviews();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$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();
|
||||
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
<div
|
||||
x-data="{}"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-builder grid gap-y-4'])
|
||||
}}
|
||||
>
|
||||
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
|
||||
<div
|
||||
@class([
|
||||
'flex gap-x-3',
|
||||
'hidden' => count($containers) < 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($containers))
|
||||
<ul
|
||||
x-sortable
|
||||
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
|
||||
wire:end.stop="{{ 'mountFormComponentAction(\'' . $statePath . '\', \'reorder\', { items: $event.target.sortable.toArray() })' }}"
|
||||
class="space-y-4"
|
||||
>
|
||||
@php
|
||||
$hasBlockLabels = $hasBlockLabels();
|
||||
$hasBlockNumbers = $hasBlockNumbers();
|
||||
@endphp
|
||||
|
||||
@foreach ($containers as $uuid => $item)
|
||||
@php
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $uuid])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $uuid]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $uuid]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$editAction = $editAction(['item' => $uuid]);
|
||||
$editActionIsVisible = $hasBlockPreviews && $editAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $uuid])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $uuid])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:key="{{ $this->getId() }}.{{ $item->getStatePath() }}.{{ $field::class }}.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="{{ $uuid }}"
|
||||
class="fi-fo-builder-item rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-white/5 dark:ring-white/10"
|
||||
x-bind:class="{ 'fi-collapsed overflow-hidden': isCollapsed }"
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $hasBlockLabels || $editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<div
|
||||
@if ($isCollapsible)
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
@endif
|
||||
@class([
|
||||
'fi-fo-builder-item-header flex items-center gap-x-3 overflow-hidden px-4 py-3',
|
||||
'cursor-pointer select-none' => $isCollapsible,
|
||||
])
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<ul class="flex items-center gap-x-3">
|
||||
@if ($reorderActionIsVisible)
|
||||
<li
|
||||
x-sortable-handle
|
||||
x-on:click.stop
|
||||
>
|
||||
{{ $reorderAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li x-on:click.stop>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($hasBlockLabels)
|
||||
<h4
|
||||
@class([
|
||||
'text-sm font-medium text-gray-950 dark:text-white',
|
||||
'truncate' => $isBlockLabelTruncated(),
|
||||
])
|
||||
>
|
||||
{{ $item->getParentComponent()->getLabel($item->getRawState(), $uuid) }}
|
||||
|
||||
@if ($hasBlockNumbers)
|
||||
{{ $loop->iteration }}
|
||||
@endif
|
||||
</h4>
|
||||
@endif
|
||||
|
||||
@if ($editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<ul
|
||||
class="ms-auto flex items-center gap-x-3"
|
||||
>
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li x-on:click.stop>
|
||||
{{ $extraItemAction(['item' => $uuid]) }}
|
||||
</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="relative transition"
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
x-bind:class="{ '-rotate-180': isCollapsed }"
|
||||
>
|
||||
<div
|
||||
class="transition"
|
||||
x-bind:class="{ 'opacity-0 pointer-events-none': isCollapsed }"
|
||||
>
|
||||
{{ $getAction('collapse') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute inset-0 rotate-180 transition"
|
||||
x-bind:class="{ 'opacity-0 pointer-events-none': ! isCollapsed }"
|
||||
>
|
||||
{{ $getAction('expand') }}
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
x-show="! isCollapsed"
|
||||
@class([
|
||||
'fi-fo-builder-item-content relative border-t border-gray-100 dark:border-white/10',
|
||||
'p-4' => ! $hasBlockPreviews,
|
||||
])
|
||||
>
|
||||
@if ($hasBlockPreviews)
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-builder-item-preview',
|
||||
'pointer-events-none' => ! $hasInteractiveBlockPreviews,
|
||||
])
|
||||
>
|
||||
{{ $item->getParentComponent()->renderPreview($item->getRawState()) }}
|
||||
</div>
|
||||
|
||||
@if ($editActionIsVisible && (! $hasInteractiveBlockPreviews))
|
||||
<div
|
||||
class="absolute inset-0 z-[1] cursor-pointer"
|
||||
role="button"
|
||||
x-on:click.stop="{{ '$wire.mountFormComponentAction(\'' . $statePath . '\', \'edit\', { item: \'' . $uuid . '\' })' }}"
|
||||
></div>
|
||||
@endif
|
||||
@else
|
||||
{{ $item }}
|
||||
@endif
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@if (! $loop->last)
|
||||
@if ($isAddable && $addBetweenAction(['afterItem' => $uuid])->isVisible())
|
||||
<li class="relative -top-2 !mt-0 h-0">
|
||||
<div
|
||||
class="flex w-full justify-center opacity-0 transition duration-75 hover:opacity-100"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-builder-block-picker-ctn rounded-lg bg-white dark:bg-gray-900"
|
||||
>
|
||||
<x-filament-forms::builder.block-picker
|
||||
:action="$addBetweenAction"
|
||||
:after-item="$uuid"
|
||||
:columns="$blockPickerColumns"
|
||||
:blocks="$blockPickerBlocks"
|
||||
:state-path="$statePath"
|
||||
:width="$blockPickerWidth"
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $addBetweenAction(['afterItem' => $uuid]) }}
|
||||
</x-slot>
|
||||
</x-filament-forms::builder.block-picker>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@elseif (filled($labelBetweenItems = $getLabelBetweenItems()))
|
||||
<li
|
||||
class="relative border-t border-gray-200 dark:border-white/10"
|
||||
>
|
||||
<span
|
||||
class="absolute -top-3 left-3 px-1 text-sm font-medium"
|
||||
>
|
||||
{{ $labelBetweenItems }}
|
||||
</span>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<x-filament-forms::builder.block-picker
|
||||
:action="$addAction"
|
||||
:blocks="$blockPickerBlocks"
|
||||
:columns="$blockPickerColumns"
|
||||
:state-path="$statePath"
|
||||
:width="$blockPickerWidth"
|
||||
class="flex justify-center"
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $addAction }}
|
||||
</x-slot>
|
||||
</x-filament-forms::builder.block-picker>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
52
vendor/filament/forms/resources/views/components/builder/block-picker.blade.php
vendored
Normal file
52
vendor/filament/forms/resources/views/components/builder/block-picker.blade.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
@props([
|
||||
'action',
|
||||
'afterItem' => null,
|
||||
'blocks',
|
||||
'columns' => null,
|
||||
'statePath',
|
||||
'trigger',
|
||||
'width' => null,
|
||||
])
|
||||
|
||||
<x-filament::dropdown
|
||||
:width="$width"
|
||||
{{ $attributes->class(['fi-fo-builder-block-picker']) }}
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $trigger }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::dropdown.list>
|
||||
<x-filament::grid
|
||||
:default="$columns['default'] ?? 1"
|
||||
:sm="$columns['sm'] ?? null"
|
||||
:md="$columns['md'] ?? null"
|
||||
:lg="$columns['lg'] ?? null"
|
||||
:xl="$columns['xl'] ?? null"
|
||||
:two-xl="$columns['2xl'] ?? null"
|
||||
direction="column"
|
||||
>
|
||||
@foreach ($blocks as $block)
|
||||
@php
|
||||
$wireClickActionArguments = ['block' => $block->getName()];
|
||||
|
||||
if (filled($afterItem)) {
|
||||
$wireClickActionArguments['afterItem'] = $afterItem;
|
||||
}
|
||||
|
||||
$wireClickActionArguments = \Illuminate\Support\Js::from($wireClickActionArguments);
|
||||
|
||||
$wireClickAction = "mountFormComponentAction('{$statePath}', '{$action->getName()}', {$wireClickActionArguments})";
|
||||
@endphp
|
||||
|
||||
<x-filament::dropdown.list.item
|
||||
:icon="$block->getIcon()"
|
||||
x-on:click="close"
|
||||
:wire:click="$wireClickAction"
|
||||
>
|
||||
{{ $block->getLabel() }}
|
||||
</x-filament::dropdown.list.item>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</x-filament::dropdown.list>
|
||||
</x-filament::dropdown>
|
||||
231
vendor/filament/forms/resources/views/components/checkbox-list.blade.php
vendored
Normal file
231
vendor/filament/forms/resources/views/components/checkbox-list.blade.php
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
@php
|
||||
$gridDirection = $getGridDirection() ?? 'column';
|
||||
$isBulkToggleable = $isBulkToggleable();
|
||||
$isDisabled = $isDisabled();
|
||||
$isSearchable = $isSearchable();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
<div
|
||||
x-data="{
|
||||
areAllCheckboxesChecked: false,
|
||||
|
||||
checkboxListOptions: Array.from(
|
||||
$root.querySelectorAll('.fi-fo-checkbox-list-option-label'),
|
||||
),
|
||||
|
||||
search: '',
|
||||
|
||||
visibleCheckboxListOptions: [],
|
||||
|
||||
checkIfAllCheckboxesAreChecked: function () {
|
||||
this.areAllCheckboxesChecked =
|
||||
this.visibleCheckboxListOptions.length ===
|
||||
this.visibleCheckboxListOptions.filter((checkboxLabel) =>
|
||||
checkboxLabel.querySelector('input[type=checkbox]:checked'),
|
||||
).length
|
||||
},
|
||||
|
||||
toggleAllCheckboxes: function () {
|
||||
state = ! this.areAllCheckboxesChecked
|
||||
|
||||
this.visibleCheckboxListOptions.forEach((checkboxLabel) => {
|
||||
checkbox = checkboxLabel.querySelector('input[type=checkbox]')
|
||||
|
||||
checkbox.checked = state
|
||||
checkbox.dispatchEvent(new Event('change'))
|
||||
})
|
||||
|
||||
this.areAllCheckboxesChecked = state
|
||||
},
|
||||
|
||||
updateVisibleCheckboxListOptions: function () {
|
||||
this.visibleCheckboxListOptions = this.checkboxListOptions.filter(
|
||||
(checkboxListItem) => {
|
||||
if (
|
||||
checkboxListItem
|
||||
.querySelector('.fi-fo-checkbox-list-option-label')
|
||||
?.innerText.toLowerCase()
|
||||
.includes(this.search.toLowerCase())
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return checkboxListItem
|
||||
.querySelector('.fi-fo-checkbox-list-option-description')
|
||||
?.innerText.toLowerCase()
|
||||
.includes(this.search.toLowerCase())
|
||||
},
|
||||
)
|
||||
},
|
||||
}"
|
||||
x-init="
|
||||
updateVisibleCheckboxListOptions()
|
||||
|
||||
$nextTick(() => {
|
||||
checkIfAllCheckboxesAreChecked()
|
||||
})
|
||||
|
||||
Livewire.hook('commit', ({ component, commit, succeed, fail, respond }) => {
|
||||
succeed(({ snapshot, effect }) => {
|
||||
$nextTick(() => {
|
||||
if (component.id !== @js($this->getId())) {
|
||||
return
|
||||
}
|
||||
|
||||
checkboxListOptions = Array.from(
|
||||
$root.querySelectorAll('.fi-fo-checkbox-list-option-label'),
|
||||
)
|
||||
|
||||
updateVisibleCheckboxListOptions()
|
||||
|
||||
checkIfAllCheckboxesAreChecked()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
$watch('search', () => {
|
||||
updateVisibleCheckboxListOptions()
|
||||
checkIfAllCheckboxesAreChecked()
|
||||
})
|
||||
"
|
||||
>
|
||||
@if (! $isDisabled)
|
||||
@if ($isSearchable)
|
||||
<x-filament::input.wrapper
|
||||
inline-prefix
|
||||
prefix-icon="heroicon-m-magnifying-glass"
|
||||
prefix-icon-alias="forms:components.checkbox-list.search-field"
|
||||
class="mb-4"
|
||||
>
|
||||
<x-filament::input
|
||||
inline-prefix
|
||||
:placeholder="$getSearchPrompt()"
|
||||
type="search"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'x-model.debounce.' . $getSearchDebounce() => 'search',
|
||||
])
|
||||
)
|
||||
"
|
||||
/>
|
||||
</x-filament::input.wrapper>
|
||||
@endif
|
||||
|
||||
@if ($isBulkToggleable && count($getOptions()))
|
||||
<div
|
||||
x-cloak
|
||||
class="mb-2"
|
||||
wire:key="{{ $this->getId() }}.{{ $getStatePath() }}.{{ $field::class }}.actions"
|
||||
>
|
||||
<span
|
||||
x-show="! areAllCheckboxesChecked"
|
||||
x-on:click="toggleAllCheckboxes()"
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.actions.select-all"
|
||||
>
|
||||
{{ $getAction('selectAll') }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
x-show="areAllCheckboxesChecked"
|
||||
x-on:click="toggleAllCheckboxes()"
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.actions.deselect-all"
|
||||
>
|
||||
{{ $getAction('deselectAll') }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<x-filament::grid
|
||||
:default="$getColumns('default')"
|
||||
:sm="$getColumns('sm')"
|
||||
:md="$getColumns('md')"
|
||||
:lg="$getColumns('lg')"
|
||||
:xl="$getColumns('xl')"
|
||||
:two-xl="$getColumns('2xl')"
|
||||
:direction="$gridDirection"
|
||||
:x-show="$isSearchable ? 'visibleCheckboxListOptions.length' : null"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-checkbox-list gap-4',
|
||||
'-mt-4' => $gridDirection === 'column',
|
||||
])
|
||||
"
|
||||
>
|
||||
@forelse ($getOptions() as $value => $label)
|
||||
<div
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.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([
|
||||
'break-inside-avoid pt-4' => $gridDirection === 'column',
|
||||
])
|
||||
>
|
||||
<label
|
||||
class="fi-fo-checkbox-list-option-label flex gap-x-3"
|
||||
>
|
||||
<x-filament::input.checkbox
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())
|
||||
->merge([
|
||||
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
|
||||
'value' => $value,
|
||||
'wire:loading.attr' => 'disabled',
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
'x-on:change' => $isBulkToggleable ? 'checkIfAllCheckboxesAreChecked()' : null,
|
||||
], escape: false)
|
||||
->class(['mt-1'])
|
||||
"
|
||||
/>
|
||||
|
||||
<div class="grid text-sm leading-6">
|
||||
<span
|
||||
class="fi-fo-checkbox-list-option-label overflow-hidden break-words font-medium text-gray-950 dark:text-white"
|
||||
>
|
||||
{{ $label }}
|
||||
</span>
|
||||
|
||||
@if ($hasDescription($value))
|
||||
<p
|
||||
class="fi-fo-checkbox-list-option-description text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
{{ $getDescription($value) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
@empty
|
||||
<div
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.empty"
|
||||
></div>
|
||||
@endforelse
|
||||
</x-filament::grid>
|
||||
|
||||
@if ($isSearchable)
|
||||
<div
|
||||
x-cloak
|
||||
x-show="search && ! visibleCheckboxListOptions.length"
|
||||
class="fi-fo-checkbox-list-no-search-results-message text-sm text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
{{ $getNoSearchResultsMessage() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
36
vendor/filament/forms/resources/views/components/checkbox.blade.php
vendored
Normal file
36
vendor/filament/forms/resources/views/components/checkbox.blade.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
@php
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
|
||||
>
|
||||
@capture($content)
|
||||
<x-filament::input.checkbox
|
||||
:valid="! $errors->has($statePath)"
|
||||
: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)
|
||||
"
|
||||
/>
|
||||
@endcapture
|
||||
|
||||
@if ($isInline())
|
||||
<x-slot name="labelPrefix">
|
||||
{{ $content() }}
|
||||
</x-slot>
|
||||
@else
|
||||
{{ $content() }}
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
118
vendor/filament/forms/resources/views/components/color-picker.blade.php
vendored
Normal file
118
vendor/filament/forms/resources/views/components/color-picker.blade.php
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$isDisabled = $isDisabled();
|
||||
$isLive = $isLive();
|
||||
$isLiveOnBlur = $isLiveOnBlur();
|
||||
$isLiveDebounced = $isLiveDebounced();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$liveDebounce = $getLiveDebounce();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
: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="$getPrefixIconColor()"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$getSuffixIconColor()"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class('fi-fo-color-picker')
|
||||
"
|
||||
>
|
||||
<div
|
||||
x-ignore
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-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(['flex']) }}
|
||||
>
|
||||
<x-filament::input
|
||||
x-on:focus="$refs.panel.open($refs.input)"
|
||||
x-on:keydown.enter.stop.prevent="togglePanelVisibility()"
|
||||
x-ref="input"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())
|
||||
->merge([
|
||||
'autocomplete' => 'off',
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $getId(),
|
||||
'inlinePrefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
|
||||
'inlineSuffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
|
||||
'placeholder' => $getPlaceholder(),
|
||||
'required' => $isRequired() && (! $isConcealed()),
|
||||
'type' => 'text',
|
||||
'x-model' . ($isLiveDebounced ? '.debounce.' . $liveDebounce : null) => 'state',
|
||||
'x-on:blur' => $isLiveOnBlur ? 'isOpen() ? null : commitState()' : null,
|
||||
], escape: false)
|
||||
"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="flex min-h-full items-center pe-3"
|
||||
x-on:click="togglePanelVisibility()"
|
||||
>
|
||||
<div
|
||||
class="h-5 w-5 select-none rounded-full"
|
||||
x-bind:class="{
|
||||
'ring-1 ring-inset ring-gray-200 dark:ring-white/10': ! state,
|
||||
}"
|
||||
x-bind:style="{ 'background-color': state }"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
wire:ignore.self
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.panel"
|
||||
x-cloak
|
||||
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
|
||||
x-ref="panel"
|
||||
class="fi-fo-color-picker-panel absolute z-10 hidden rounded-lg shadow-lg"
|
||||
>
|
||||
@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>
|
||||
293
vendor/filament/forms/resources/views/components/date-time-picker.blade.php
vendored
Normal file
293
vendor/filament/forms/resources/views/components/date-time-picker.blade.php
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$datalistOptions = $getDatalistOptions();
|
||||
$extraAlpineAttributes = $getExtraAlpineAttributes();
|
||||
$hasTime = $hasTime();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$maxDate = $getMaxDate();
|
||||
$minDate = $getMinDate();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
: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="$getPrefixIconColor()"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$getSuffixIconColor()"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())"
|
||||
>
|
||||
@if ($isNative())
|
||||
<x-filament::input
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())
|
||||
->merge($extraAlpineAttributes, escape: false)
|
||||
->merge([
|
||||
'autofocus' => $isAutofocused(),
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $id,
|
||||
'inlinePrefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
|
||||
'inlineSuffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
|
||||
'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' => $getPlaceholder(),
|
||||
'readonly' => $isReadOnly(),
|
||||
'required' => $isRequired() && (! $isConcealed()),
|
||||
'step' => $getStep(),
|
||||
'type' => $getType(),
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
'x-data' => count($extraAlpineAttributes) ? '{}' : null,
|
||||
], escape: false)
|
||||
"
|
||||
/>
|
||||
@else
|
||||
<div
|
||||
x-ignore
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('date-time-picker', 'filament/forms') }}"
|
||||
x-data="dateTimePickerFormComponent({
|
||||
displayFormat:
|
||||
'{{ convert_date_format($getDisplayFormat())->to('day.js') }}',
|
||||
firstDayOfWeek: {{ $getFirstDayOfWeek() }},
|
||||
isAutofocused: @js($isAutofocused()),
|
||||
locale: @js($getLocale()),
|
||||
shouldCloseOnDateSelection: @js($shouldCloseOnDateSelection()),
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
})"
|
||||
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class(['fi-fo-date-time-picker'])
|
||||
}}
|
||||
>
|
||||
<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($getDisabledDates()) }}"
|
||||
/>
|
||||
|
||||
<button
|
||||
x-ref="button"
|
||||
x-on:click="togglePanelVisibility()"
|
||||
x-on:keydown.enter.stop.prevent="
|
||||
if (! $el.disabled) {
|
||||
isOpen() ? selectDate() : togglePanelVisibility()
|
||||
}
|
||||
"
|
||||
x-on:keydown.arrow-left.stop.prevent="if (! $el.disabled) focusPreviousDay()"
|
||||
x-on:keydown.arrow-right.stop.prevent="if (! $el.disabled) focusNextDay()"
|
||||
x-on:keydown.arrow-up.stop.prevent="if (! $el.disabled) focusPreviousWeek()"
|
||||
x-on:keydown.arrow-down.stop.prevent="if (! $el.disabled) focusNextWeek()"
|
||||
x-on:keydown.backspace.stop.prevent="if (! $el.disabled) clearState()"
|
||||
x-on:keydown.clear.stop.prevent="if (! $el.disabled) clearState()"
|
||||
x-on:keydown.delete.stop.prevent="if (! $el.disabled) clearState()"
|
||||
aria-label="{{ $getPlaceholder() }}"
|
||||
type="button"
|
||||
tabindex="-1"
|
||||
@disabled($isDisabled)
|
||||
{{
|
||||
$getExtraTriggerAttributeBag()->class([
|
||||
'w-full',
|
||||
])
|
||||
}}
|
||||
>
|
||||
<input
|
||||
@disabled($isDisabled)
|
||||
readonly
|
||||
placeholder="{{ $getPlaceholder() }}"
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.display-text"
|
||||
x-model="displayText"
|
||||
@if ($id = $getId()) id="{{ $id }}" @endif
|
||||
@class([
|
||||
'fi-fo-date-time-picker-display-text-input w-full border-none bg-transparent px-3 py-1.5 text-base text-gray-950 outline-none transition duration-75 placeholder:text-gray-400 focus:ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray.500)] dark:text-white dark:placeholder:text-gray-500 dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray.400)] sm:text-sm sm:leading-6',
|
||||
])
|
||||
/>
|
||||
</button>
|
||||
|
||||
<div
|
||||
x-ref="panel"
|
||||
x-cloak
|
||||
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
|
||||
wire:ignore
|
||||
wire:key="{{ $this->getId() }}.{{ $statePath }}.{{ $field::class }}.panel"
|
||||
@class([
|
||||
'fi-fo-date-time-picker-panel absolute z-10 rounded-lg bg-white p-4 shadow-lg ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10',
|
||||
])
|
||||
>
|
||||
<div class="grid gap-y-3">
|
||||
@if ($hasDate())
|
||||
<div class="flex items-center justify-between">
|
||||
<select
|
||||
x-model="focusedMonth"
|
||||
class="grow cursor-pointer border-none bg-transparent p-0 text-sm font-medium text-gray-950 focus:ring-0 dark:bg-gray-900 dark:text-white"
|
||||
>
|
||||
<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="w-16 border-none bg-transparent p-0 text-right text-sm text-gray-950 focus:ring-0 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-7 gap-1">
|
||||
<template
|
||||
x-for="(day, index) in dayLabels"
|
||||
x-bind:key="index"
|
||||
>
|
||||
<div
|
||||
x-text="day"
|
||||
class="text-center text-xs font-medium text-gray-500 dark:text-gray-400"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div
|
||||
role="grid"
|
||||
class="grid grid-cols-[repeat(7,minmax(theme(spacing.7),1fr))] gap-1"
|
||||
>
|
||||
<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="{
|
||||
'text-gray-950 dark:text-white': ! dayIsToday(day) && ! dayIsSelected(day),
|
||||
'cursor-pointer': ! dayIsDisabled(day),
|
||||
'text-primary-600 dark:text-primary-400':
|
||||
dayIsToday(day) &&
|
||||
! dayIsSelected(day) &&
|
||||
focusedDate.date() !== day &&
|
||||
! dayIsDisabled(day),
|
||||
'bg-gray-50 dark:bg-white/5':
|
||||
focusedDate.date() === day &&
|
||||
! dayIsSelected(day) &&
|
||||
! dayIsDisabled(day),
|
||||
'text-primary-600 bg-gray-50 dark:bg-white/5 dark:text-primary-400':
|
||||
dayIsSelected(day),
|
||||
'pointer-events-none': dayIsDisabled(day),
|
||||
'opacity-50': dayIsDisabled(day),
|
||||
}"
|
||||
class="rounded-full text-center text-sm leading-loose transition duration-75"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($hasTime)
|
||||
<div
|
||||
class="flex items-center justify-center rtl:flex-row-reverse"
|
||||
>
|
||||
<input
|
||||
max="23"
|
||||
min="0"
|
||||
step="{{ $getHoursStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="hour"
|
||||
class="me-1 w-10 border-none bg-transparent p-0 text-center text-sm text-gray-950 focus:ring-0 dark:text-white"
|
||||
/>
|
||||
|
||||
<span
|
||||
class="text-sm font-medium text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
:
|
||||
</span>
|
||||
|
||||
<input
|
||||
max="59"
|
||||
min="0"
|
||||
step="{{ $getMinutesStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="minute"
|
||||
class="me-1 w-10 border-none bg-transparent p-0 text-center text-sm text-gray-950 focus:ring-0 dark:text-white"
|
||||
/>
|
||||
|
||||
@if ($hasSeconds())
|
||||
<span
|
||||
class="text-sm font-medium text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
:
|
||||
</span>
|
||||
|
||||
<input
|
||||
max="59"
|
||||
min="0"
|
||||
step="{{ $getSecondsStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="second"
|
||||
class="me-1 w-10 border-none bg-transparent p-0 text-center text-sm text-gray-950 focus:ring-0 dark:text-white"
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</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>
|
||||
10
vendor/filament/forms/resources/views/components/field-wrapper/error-message.blade.php
vendored
Normal file
10
vendor/filament/forms/resources/views/components/field-wrapper/error-message.blade.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<p
|
||||
data-validation-error
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-fo-field-wrp-error-message text-sm text-danger-600 dark:text-danger-400',
|
||||
])
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</p>
|
||||
5
vendor/filament/forms/resources/views/components/field-wrapper/helper-text.blade.php
vendored
Normal file
5
vendor/filament/forms/resources/views/components/field-wrapper/helper-text.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<div
|
||||
{{ $attributes->class(['fi-fo-field-wrp-helper-text text-sm text-gray-500']) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
66
vendor/filament/forms/resources/views/components/field-wrapper/hint.blade.php
vendored
Normal file
66
vendor/filament/forms/resources/views/components/field-wrapper/hint.blade.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
@props([
|
||||
'actions' => [],
|
||||
'color' => 'gray',
|
||||
'icon' => null,
|
||||
'tooltip' => null,
|
||||
])
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-fo-field-wrp-hint flex items-center gap-x-3 text-sm',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (! \Filament\Support\is_slot_empty($slot))
|
||||
<span
|
||||
@class([
|
||||
'fi-fo-field-wrp-hint-label',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-500',
|
||||
default => 'fi-color-custom text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'forms::components.field-wrapper.hint.label',
|
||||
),
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
x-data="{}"
|
||||
:icon="$icon"
|
||||
:x-tooltip="filled($tooltip) ? '{ content: ' . \Illuminate\Support\Js::from($tooltip) . ', theme: $store.theme }' : null"
|
||||
@class([
|
||||
'fi-fo-field-wrp-hint-icon h-5 w-5',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500 dark:text-custom-400',
|
||||
},
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 500],
|
||||
alias: 'forms::components.field-wrapper.hint.icon',
|
||||
),
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (count($actions))
|
||||
<div class="fi-fo-field-wrp-hint-action flex items-center gap-3">
|
||||
@foreach ($actions as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
136
vendor/filament/forms/resources/views/components/field-wrapper/index.blade.php
vendored
Normal file
136
vendor/filament/forms/resources/views/components/field-wrapper/index.blade.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'field' => null,
|
||||
'hasInlineLabel' => null,
|
||||
'hasNestedRecursiveValidationRules' => null,
|
||||
'helperText' => null,
|
||||
'hint' => null,
|
||||
'hintActions' => null,
|
||||
'hintColor' => null,
|
||||
'hintIcon' => null,
|
||||
'hintIconTooltip' => null,
|
||||
'id' => null,
|
||||
'inlineLabelVerticalAlignment' => VerticalAlignment::Start,
|
||||
'isDisabled' => null,
|
||||
'label' => null,
|
||||
'labelPrefix' => null,
|
||||
'labelSrOnly' => null,
|
||||
'labelSuffix' => null,
|
||||
'required' => null,
|
||||
'statePath' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
if ($field) {
|
||||
$hasInlineLabel ??= $field->hasInlineLabel();
|
||||
$hasNestedRecursiveValidationRules ??= $field instanceof \Filament\Forms\Components\Contracts\HasNestedRecursiveValidationRules;
|
||||
$helperText ??= $field->getHelperText();
|
||||
$hint ??= $field->getHint();
|
||||
$hintActions ??= $field->getHintActions();
|
||||
$hintColor ??= $field->getHintColor();
|
||||
$hintIcon ??= $field->getHintIcon();
|
||||
$hintIconTooltip ??= $field->getHintIconTooltip();
|
||||
$id ??= $field->getId();
|
||||
$isDisabled ??= $field->isDisabled();
|
||||
$label ??= $field->getLabel();
|
||||
$labelSrOnly ??= $field->isLabelHidden();
|
||||
$required ??= $field->isMarkedAsRequired();
|
||||
$statePath ??= $field->getStatePath();
|
||||
}
|
||||
|
||||
$hintActions = array_filter(
|
||||
$hintActions ?? [],
|
||||
fn (\Filament\Forms\Components\Actions\Action $hintAction): bool => $hintAction->isVisible(),
|
||||
);
|
||||
|
||||
$hasError = filled($statePath) && ($errors->has($statePath) || ($hasNestedRecursiveValidationRules && $errors->has("{$statePath}.*")));
|
||||
@endphp
|
||||
|
||||
<div
|
||||
data-field-wrapper
|
||||
{{
|
||||
$attributes
|
||||
->merge($field?->getExtraFieldWrapperAttributes() ?? [])
|
||||
->class(['fi-fo-field-wrp'])
|
||||
}}
|
||||
>
|
||||
@if ($label && $labelSrOnly)
|
||||
<label for="{{ $id }}" class="sr-only">
|
||||
{{ $label }}
|
||||
</label>
|
||||
@endif
|
||||
|
||||
<div
|
||||
@class([
|
||||
'grid gap-y-2',
|
||||
'sm:grid-cols-3 sm:gap-x-4' => $hasInlineLabel,
|
||||
match ($inlineLabelVerticalAlignment) {
|
||||
VerticalAlignment::Start => 'sm:items-start',
|
||||
VerticalAlignment::Center => 'sm:items-center',
|
||||
VerticalAlignment::End => 'sm:items-end',
|
||||
} => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
@if (($label && (! $labelSrOnly)) || $labelPrefix || $labelSuffix || filled($hint) || $hintIcon || count($hintActions))
|
||||
<div
|
||||
@class([
|
||||
'flex items-center justify-between gap-x-3',
|
||||
($label instanceof \Illuminate\View\ComponentSlot) ? $label->attributes->get('class') : null,
|
||||
])
|
||||
>
|
||||
@if ($label && (! $labelSrOnly))
|
||||
<x-filament-forms::field-wrapper.label
|
||||
:for="$id"
|
||||
:disabled="$isDisabled"
|
||||
:prefix="$labelPrefix"
|
||||
:required="$required"
|
||||
:suffix="$labelSuffix"
|
||||
>
|
||||
{{ $label }}
|
||||
</x-filament-forms::field-wrapper.label>
|
||||
@elseif ($labelPrefix)
|
||||
{{ $labelPrefix }}
|
||||
@elseif ($labelSuffix)
|
||||
{{ $labelSuffix }}
|
||||
@endif
|
||||
|
||||
@if (filled($hint) || $hintIcon || count($hintActions))
|
||||
<x-filament-forms::field-wrapper.hint
|
||||
:actions="$hintActions"
|
||||
:color="$hintColor"
|
||||
:icon="$hintIcon"
|
||||
:tooltip="$hintIconTooltip"
|
||||
>
|
||||
{{ $hint }}
|
||||
</x-filament-forms::field-wrapper.hint>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ((! \Filament\Support\is_slot_empty($slot)) || $hasError || filled($helperText))
|
||||
<div
|
||||
@class([
|
||||
'grid gap-y-2',
|
||||
'sm:col-span-2' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
|
||||
@if ($hasError)
|
||||
<x-filament-forms::field-wrapper.error-message>
|
||||
{{ $errors->has($statePath) ? $errors->first($statePath) : ($hasNestedRecursiveValidationRules ? $errors->first("{$statePath}.*") : null) }}
|
||||
</x-filament-forms::field-wrapper.error-message>
|
||||
@endif
|
||||
|
||||
@if (filled($helperText))
|
||||
<x-filament-forms::field-wrapper.helper-text>
|
||||
{{ $helperText }}
|
||||
</x-filament-forms::field-wrapper.helper-text>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
20
vendor/filament/forms/resources/views/components/field-wrapper/label.blade.php
vendored
Normal file
20
vendor/filament/forms/resources/views/components/field-wrapper/label.blade.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
@props([
|
||||
'disabled' => false,
|
||||
'prefix' => null,
|
||||
'required' => false,
|
||||
'suffix' => null,
|
||||
])
|
||||
|
||||
<label
|
||||
{{ $attributes->class(['fi-fo-field-wrp-label inline-flex items-center gap-x-3']) }}
|
||||
>
|
||||
{{ $prefix }}
|
||||
|
||||
<span class="text-sm font-medium leading-6 text-gray-950 dark:text-white">
|
||||
{{-- Deliberately poor formatting to ensure that the asterisk sticks to the final word in the label. --}}
|
||||
{{ $slot }}@if ($required && (! $disabled))<sup class="text-danger-600 dark:text-danger-400 font-medium">*</sup>
|
||||
@endif
|
||||
</span>
|
||||
|
||||
{{ $suffix }}
|
||||
</label>
|
||||
13
vendor/filament/forms/resources/views/components/fieldset.blade.php
vendored
Normal file
13
vendor/filament/forms/resources/views/components/fieldset.blade.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<x-filament::fieldset
|
||||
:label="$getLabel()"
|
||||
:label-hidden="$isLabelHidden()"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
"
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</x-filament::fieldset>
|
||||
330
vendor/filament/forms/resources/views/components/file-upload.blade.php
vendored
Normal file
330
vendor/filament/forms/resources/views/components/file-upload.blade.php
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
@php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$imageCropAspectRatio = $getImageCropAspectRatio();
|
||||
$imageResizeTargetHeight = $getImageResizeTargetHeight();
|
||||
$imageResizeTargetWidth = $getImageResizeTargetWidth();
|
||||
$isAvatar = $isAvatar();
|
||||
$statePath = $getStatePath();
|
||||
$isDisabled = $isDisabled();
|
||||
$hasImageEditor = $hasImageEditor();
|
||||
$hasCircleCropper = $hasCircleCropper();
|
||||
|
||||
$alignment = $getAlignment() ?? Alignment::Start;
|
||||
|
||||
if (! $alignment instanceof Alignment) {
|
||||
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:label-sr-only="$isLabelHidden()"
|
||||
>
|
||||
<div
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-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.deleteUploadedFile(@js($statePath), fileKey)
|
||||
},
|
||||
getUploadedFilesUsing: async () => {
|
||||
return await $wire.getFormUploadedFiles(@js($statePath))
|
||||
},
|
||||
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()),
|
||||
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($getMaxFiles()),
|
||||
maxSize: @js(($size = $getMaxSize()) ? "{$size}KB" : null),
|
||||
minSize: @js(($size = $getMinSize()) ? "{$size}KB" : null),
|
||||
removeUploadedFileUsing: async (fileKey) => {
|
||||
return await $wire.removeFormUploadedFile(@js($statePath), fileKey)
|
||||
},
|
||||
removeUploadedFileButtonPosition: @js($getRemoveUploadedFileButtonPosition()),
|
||||
reorderUploadedFilesUsing: async (files) => {
|
||||
return await $wire.reorderFormUploadedFiles(@js($statePath), files)
|
||||
},
|
||||
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
|
||||
x-ignore
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-file-upload flex [&_.filepond--root]:font-sans',
|
||||
match ($alignment) {
|
||||
Alignment::Start => 'justify-start',
|
||||
Alignment::Center => 'justify-center',
|
||||
Alignment::End => 'justify-end',
|
||||
Alignment::Left => 'justify-left',
|
||||
Alignment::Right => 'justify-right',
|
||||
Alignment::Between, Alignment::Justify => 'justify-between',
|
||||
default => $alignment,
|
||||
},
|
||||
])
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@class([
|
||||
'h-full',
|
||||
'w-32' => $isAvatar,
|
||||
'w-full' => ! $isAvatar,
|
||||
])
|
||||
>
|
||||
<input
|
||||
x-ref="input"
|
||||
{{
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
'disabled' => $isDisabled,
|
||||
'multiple' => $isMultiple(),
|
||||
'type' => 'file',
|
||||
], escape: false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@if ($hasImageEditor && (! $isDisabled))
|
||||
<div
|
||||
x-show="isEditorOpen"
|
||||
x-cloak
|
||||
x-on:click.stop=""
|
||||
x-trap.noscroll="isEditorOpen"
|
||||
x-on:keydown.escape.window="closeEditor"
|
||||
@class([
|
||||
'fixed inset-0 isolate z-50 h-[100dvh] w-screen p-2 sm:p-10 md:p-20',
|
||||
'fi-fo-file-upload-circle-cropper' => $hasCircleCropper,
|
||||
])
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fixed inset-0 h-full w-full cursor-pointer bg-black/50"
|
||||
style="will-change: transform"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="isolate z-10 flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<div
|
||||
class="mx-auto flex h-full w-full flex-col overflow-hidden rounded-xl bg-white ring-1 ring-gray-900/10 dark:bg-gray-800 dark:ring-gray-50/10 lg:flex-row"
|
||||
>
|
||||
<div class="w-full flex-1 overflow-auto p-4 lg:h-full">
|
||||
<div class="h-full w-full">
|
||||
<img x-ref="editor" class="h-full w-auto" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="shadow-top z-[1] flex h-96 w-full flex-col overflow-auto bg-gray-50 dark:bg-gray-900/30 lg:h-full lg:max-w-xs lg:shadow-none"
|
||||
>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<div
|
||||
class="flex h-full flex-col overflow-y-auto"
|
||||
>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<div class="space-y-6 p-4">
|
||||
<div class="w-full space-y-3">
|
||||
@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
|
||||
class="flex w-full items-center rounded-lg border border-gray-300 bg-gray-100 text-sm shadow-sm dark:border-gray-700 dark:bg-gray-800"
|
||||
>
|
||||
<span
|
||||
class="flex w-20 shrink-0 items-center justify-center self-stretch border-e border-gray-300 px-2 dark:border-gray-700"
|
||||
>
|
||||
{{ $input['label'] }}
|
||||
</span>
|
||||
|
||||
<input
|
||||
@class([
|
||||
'block w-full border-none text-sm transition duration-75 focus-visible:border-primary-500 focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary-500 disabled:opacity-70 dark:bg-gray-700 dark:text-white dark:focus-visible:border-primary-500',
|
||||
])
|
||||
x-on:keyup.enter.stop.prevent="{{ $input['alpineSaveHandler'] }}"
|
||||
x-on:blur="{{ $input['alpineSaveHandler'] }}"
|
||||
x-ref="{{ $input['ref'] }}"
|
||||
x-on:keydown.enter.prevent
|
||||
type="text"
|
||||
/>
|
||||
|
||||
<span
|
||||
class="flex w-16 items-center justify-center self-stretch border-s border-gray-300 px-2 dark:border-gray-700"
|
||||
>
|
||||
{{ $input['unit'] }}
|
||||
</span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
@foreach ($getImageEditorActions(iconSizeClasses: 'h-5 w-5 mx-auto') as $groupedActions)
|
||||
<x-filament::button.group
|
||||
class="w-full"
|
||||
>
|
||||
@foreach ($groupedActions as $action)
|
||||
<x-filament::button
|
||||
color="gray"
|
||||
grouped
|
||||
:icon="new \Illuminate\Support\HtmlString($action['iconHtml'])"
|
||||
label-sr-only
|
||||
x-on:click.stop.prevent="{{ $action['alpineClickHandler'] }}"
|
||||
:x-tooltip="'{ content: ' . \Illuminate\Support\Js::from($action['label']) . ', theme: $store.theme }'"
|
||||
>
|
||||
{{ $action['label'] }}
|
||||
</x-filament::button>
|
||||
@endforeach
|
||||
</x-filament::button.group>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@if (count($aspectRatios = $getImageEditorAspectRatiosForJs()))
|
||||
<div class="space-y-3">
|
||||
<div
|
||||
class="text-xs text-gray-950 dark:text-white"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.aspect_ratios.label') }}
|
||||
</div>
|
||||
|
||||
@foreach (collect($aspectRatios)->chunk(5) as $ratiosChunk)
|
||||
<x-filament::button.group
|
||||
class="w-full"
|
||||
>
|
||||
@foreach ($ratiosChunk as $label => $ratio)
|
||||
<x-filament::button
|
||||
:x-tooltip="'{ content: ' . \Illuminate\Support\Js::from(__('filament-forms::components.file_upload.editor.actions.set_aspect_ratio.label', ['ratio' => $label])) . ', theme: $store.theme }'"
|
||||
x-on:click.stop.prevent="currentRatio = '{{ $label }}'; editor.setAspectRatio({{ $ratio }})"
|
||||
color="gray"
|
||||
x-bind:class="{'!bg-gray-50 dark:!bg-gray-700': currentRatio === '{{ $label }}'}"
|
||||
grouped
|
||||
>
|
||||
{{ $label }}
|
||||
</x-filament::button>
|
||||
@endforeach
|
||||
</x-filament::button.group>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex items-center gap-3 px-4 py-3"
|
||||
>
|
||||
<x-filament::button
|
||||
color="gray"
|
||||
x-on:click.prevent="pond.imageEditEditor.oncancel"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.cancel.label') }}
|
||||
</x-filament::button>
|
||||
|
||||
<x-filament::button
|
||||
color="warning"
|
||||
x-on:click.stop.prevent="editor.reset()"
|
||||
class="ml-auto"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.reset.label') }}
|
||||
</x-filament::button>
|
||||
|
||||
<x-filament::button
|
||||
color="success"
|
||||
x-on:click.prevent="saveEditor"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.save.label') }}
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
11
vendor/filament/forms/resources/views/components/grid.blade.php
vendored
Normal file
11
vendor/filament/forms/resources/views/components/grid.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
11
vendor/filament/forms/resources/views/components/group.blade.php
vendored
Normal file
11
vendor/filament/forms/resources/views/components/group.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
12
vendor/filament/forms/resources/views/components/hidden.blade.php
vendored
Normal file
12
vendor/filament/forms/resources/views/components/hidden.blade.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<input
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
'type' => 'hidden',
|
||||
$applyStateBindingModifiers('wire:model') => $getStatePath(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-hidden'])
|
||||
}}
|
||||
/>
|
||||
171
vendor/filament/forms/resources/views/components/key-value.blade.php
vendored
Normal file
171
vendor/filament/forms/resources/views/components/key-value.blade.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$debounce = $getLiveDebounce();
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$isAddable = $isAddable();
|
||||
$isDeletable = $isDeletable();
|
||||
$isDisabled = $isDisabled();
|
||||
$isReorderable = $isReorderable();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-key-value'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('key-value', 'filament/forms') }}"
|
||||
wire:ignore
|
||||
x-data="keyValueFormComponent({
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
})"
|
||||
x-ignore
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class(['divide-y divide-gray-200 dark:divide-white/10'])
|
||||
}}
|
||||
>
|
||||
<table
|
||||
class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
@if ($isReorderable && (! $isDisabled))
|
||||
<th
|
||||
scope="col"
|
||||
x-show="rows.length"
|
||||
class="w-9"
|
||||
></th>
|
||||
@endif
|
||||
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-2 text-start text-sm font-medium text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
{{ $getKeyLabel() }}
|
||||
</th>
|
||||
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-2 text-start text-sm font-medium text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
{{ $getValueLabel() }}
|
||||
</th>
|
||||
|
||||
@if ($isDeletable && (! $isDisabled))
|
||||
<th
|
||||
scope="col"
|
||||
x-show="rows.length"
|
||||
class="w-9"
|
||||
></th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody
|
||||
@if ($isReorderable)
|
||||
x-on:end.stop="reorderRows($event)"
|
||||
x-sortable
|
||||
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
|
||||
@endif
|
||||
class="divide-y divide-gray-200 dark:divide-white/5"
|
||||
>
|
||||
<template
|
||||
x-bind:key="index"
|
||||
x-for="(row, index) in rows"
|
||||
>
|
||||
<tr
|
||||
@if ($isReorderable)
|
||||
x-bind:x-sortable-item="row.key"
|
||||
@endif
|
||||
class="divide-x divide-gray-200 dark:divide-white/5 rtl:divide-x-reverse"
|
||||
>
|
||||
@if ($isReorderable && (! $isDisabled))
|
||||
<td class="p-0.5">
|
||||
<div x-sortable-handle class="flex">
|
||||
{{ $getAction('reorder') }}
|
||||
</div>
|
||||
</td>
|
||||
@endif
|
||||
|
||||
<td class="w-1/2 p-0">
|
||||
<x-filament::input
|
||||
:disabled="(! $canEditKeys()) || $isDisabled"
|
||||
:placeholder="filled($placeholder = $getKeyPlaceholder()) ? $placeholder : null"
|
||||
type="text"
|
||||
x-model="row.key"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'x-on:input.debounce.' . ($debounce ?? '500ms') => 'updateState',
|
||||
])
|
||||
)
|
||||
"
|
||||
class="font-mono"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td class="w-1/2 p-0">
|
||||
<x-filament::input
|
||||
:disabled="(! $canEditValues()) || $isDisabled"
|
||||
:placeholder="filled($placeholder = $getValuePlaceholder()) ? $placeholder : null"
|
||||
type="text"
|
||||
x-model="row.value"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'x-on:input.debounce.' . ($debounce ?? '500ms') => 'updateState',
|
||||
])
|
||||
)
|
||||
"
|
||||
class="font-mono"
|
||||
/>
|
||||
</td>
|
||||
|
||||
@if ($isDeletable && (! $isDisabled))
|
||||
<td class="p-0.5">
|
||||
<div x-on:click="deleteRow(index)">
|
||||
{{ $getAction('delete') }}
|
||||
</div>
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@if ($isAddable && (! $isDisabled))
|
||||
<div class="flex justify-center px-3 py-2">
|
||||
<span x-on:click="addRow" class="flex">
|
||||
{{ $getAction('add') }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
7
vendor/filament/forms/resources/views/components/livewire.blade.php
vendored
Normal file
7
vendor/filament/forms/resources/views/components/livewire.blade.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<div>
|
||||
@if (filled($key = $getKey()))
|
||||
@livewire($getComponent(), $getComponentProperties(), key($key))
|
||||
@else
|
||||
@livewire($getComponent(), $getComponentProperties())
|
||||
@endif
|
||||
</div>
|
||||
58
vendor/filament/forms/resources/views/components/markdown-editor.blade.php
vendored
Normal file
58
vendor/filament/forms/resources/views/components/markdown-editor.blade.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
@if ($isDisabled())
|
||||
<div
|
||||
class="fi-fo-markdown-editor fi-disabled prose block w-full max-w-none rounded-lg bg-gray-50 px-3 py-3 text-gray-500 shadow-sm ring-1 ring-gray-950/10 dark:prose-invert dark:bg-transparent dark:text-gray-400 dark:ring-white/10 sm:text-sm"
|
||||
>
|
||||
{!! str($getState())->markdown()->sanitizeHtml() !!}
|
||||
</div>
|
||||
@else
|
||||
<x-filament::input.wrapper
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-markdown-editor max-w-full overflow-hidden font-mono text-base text-gray-950 dark:text-white sm:text-sm'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
ax-load="visible"
|
||||
ax-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) => {
|
||||
$wire.upload(`componentFileAttachments.{{ $statePath }}`, file, () => {
|
||||
$wire
|
||||
.getFormComponentFileAttachmentUrl('{{ $statePath }}')
|
||||
.then((url) => {
|
||||
if (! url) {
|
||||
return onError()
|
||||
}
|
||||
|
||||
onSuccess(url)
|
||||
})
|
||||
})
|
||||
},
|
||||
})"
|
||||
x-ignore
|
||||
wire:ignore
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<textarea x-ref="editor" class="hidden"></textarea>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
24
vendor/filament/forms/resources/views/components/placeholder.blade.php
vendored
Normal file
24
vendor/filament/forms/resources/views/components/placeholder.blade.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:has-inline-label="$hasInlineLabel()"
|
||||
:id="$getId()"
|
||||
:label="$getLabel()"
|
||||
:label-sr-only="$isLabelHidden()"
|
||||
:helper-text="$getHelperText()"
|
||||
:hint="$getHint()"
|
||||
:hint-actions="$getHintActions()"
|
||||
:hint-color="$getHintColor()"
|
||||
:hint-icon="$getHintIcon()"
|
||||
:hint-icon-tooltip="$getHintIconTooltip()"
|
||||
:state-path="$getStatePath()"
|
||||
>
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-placeholder text-sm leading-6'])
|
||||
}}
|
||||
>
|
||||
{{ $getContent() }}
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
67
vendor/filament/forms/resources/views/components/radio.blade.php
vendored
Normal file
67
vendor/filament/forms/resources/views/components/radio.blade.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
@php
|
||||
$gridDirection = $getGridDirection() ?? 'column';
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isInline = $isInline();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
<x-filament::grid
|
||||
:default="$getColumns('default')"
|
||||
:sm="$getColumns('sm')"
|
||||
:md="$getColumns('md')"
|
||||
:lg="$getColumns('lg')"
|
||||
:xl="$getColumns('xl')"
|
||||
:two-xl="$getColumns('2xl')"
|
||||
:is-grid="! $isInline"
|
||||
:direction="$gridDirection"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-radio gap-4',
|
||||
'-mt-4' => (! $isInline) && ($gridDirection === 'column'),
|
||||
'flex flex-wrap' => $isInline,
|
||||
])
|
||||
"
|
||||
>
|
||||
@foreach ($getOptions() as $value => $label)
|
||||
<div
|
||||
@class([
|
||||
'break-inside-avoid pt-4' => (! $isInline) && ($gridDirection === 'column'),
|
||||
])
|
||||
>
|
||||
<label class="flex gap-x-3">
|
||||
<x-filament::input.radio
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())
|
||||
->merge([
|
||||
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
|
||||
'id' => $id . '-' . $value,
|
||||
'name' => $id,
|
||||
'value' => $value,
|
||||
'wire:loading.attr' => 'disabled',
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
], escape: false)
|
||||
->class(['mt-1'])
|
||||
"
|
||||
/>
|
||||
|
||||
<div class="grid text-sm leading-6">
|
||||
<span class="font-medium text-gray-950 dark:text-white">
|
||||
{{ $label }}
|
||||
</span>
|
||||
|
||||
@if ($hasDescription($value))
|
||||
<p class="text-gray-500 dark:text-gray-400">
|
||||
{{ $getDescription($value) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</x-dynamic-component>
|
||||
246
vendor/filament/forms/resources/views/components/repeater/index.blade.php
vendored
Normal file
246
vendor/filament/forms/resources/views/components/repeater/index.blade.php
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
@php
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
|
||||
$containers = $getChildComponentContainers();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$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();
|
||||
|
||||
$isAddable = $isAddable();
|
||||
$isCloneable = $isCloneable();
|
||||
$isCollapsible = $isCollapsible();
|
||||
$isDeletable = $isDeletable();
|
||||
$isReorderableWithButtons = $isReorderableWithButtons();
|
||||
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
|
||||
|
||||
$collapseAllActionIsVisible = $isCollapsible && $collapseAllAction->isVisible();
|
||||
$expandAllActionIsVisible = $isCollapsible && $expandAllAction->isVisible();
|
||||
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
<div
|
||||
x-data="{}"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-repeater grid gap-y-4'])
|
||||
}}
|
||||
>
|
||||
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
|
||||
<div
|
||||
@class([
|
||||
'flex gap-x-3',
|
||||
'hidden' => count($containers) < 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($containers))
|
||||
<ul>
|
||||
<x-filament::grid
|
||||
:default="$getGridColumns('default')"
|
||||
:sm="$getGridColumns('sm')"
|
||||
:md="$getGridColumns('md')"
|
||||
:lg="$getGridColumns('lg')"
|
||||
:xl="$getGridColumns('xl')"
|
||||
:two-xl="$getGridColumns('2xl')"
|
||||
:wire:end.stop="'mountFormComponentAction(\'' . $statePath . '\', \'reorder\', { items: $event.target.sortable.toArray() })'"
|
||||
x-sortable
|
||||
:data-sortable-animation-duration="$getReorderAnimationDuration()"
|
||||
class="items-start gap-4"
|
||||
>
|
||||
@foreach ($containers as $uuid => $item)
|
||||
@php
|
||||
$itemLabel = $getItemLabel($uuid);
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $uuid])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $uuid]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $uuid]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $uuid])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $uuid])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:key="{{ $this->getId() }}.{{ $item->getStatePath() }}.{{ $field::class }}.item"
|
||||
x-data="{
|
||||
isCollapsed: @js($isCollapsed($item)),
|
||||
}"
|
||||
x-on:expand="isCollapsed = false"
|
||||
x-on:repeater-expand.window="$event.detail === '{{ $statePath }}' && (isCollapsed = false)"
|
||||
x-on:repeater-collapse.window="$event.detail === '{{ $statePath }}' && (isCollapsed = true)"
|
||||
x-sortable-item="{{ $uuid }}"
|
||||
class="fi-fo-repeater-item divide-y divide-gray-100 rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-white/5 dark:ring-white/10"
|
||||
x-bind:class="{ 'fi-collapsed overflow-hidden': isCollapsed }"
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || filled($itemLabel) || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<div
|
||||
@if ($isCollapsible)
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
@endif
|
||||
@class([
|
||||
'fi-fo-repeater-item-header flex items-center gap-x-3 overflow-hidden px-4 py-3',
|
||||
'cursor-pointer select-none' => $isCollapsible,
|
||||
])
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<ul class="flex items-center gap-x-3">
|
||||
@if ($reorderActionIsVisible)
|
||||
<li
|
||||
x-sortable-handle
|
||||
x-on:click.stop
|
||||
>
|
||||
{{ $reorderAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li
|
||||
x-on:click.stop
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
x-on:click.stop
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if (filled($itemLabel))
|
||||
<h4
|
||||
@class([
|
||||
'text-sm font-medium text-gray-950 dark:text-white',
|
||||
'truncate' => $isItemLabelTruncated(),
|
||||
])
|
||||
>
|
||||
{{ $itemLabel }}
|
||||
</h4>
|
||||
@endif
|
||||
|
||||
@if ($cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<ul
|
||||
class="ms-auto flex items-center gap-x-3"
|
||||
>
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li x-on:click.stop>
|
||||
{{ $extraItemAction(['item' => $uuid]) }}
|
||||
</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="relative transition"
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
x-bind:class="{ '-rotate-180': isCollapsed }"
|
||||
>
|
||||
<div
|
||||
class="transition"
|
||||
x-bind:class="{ 'opacity-0 pointer-events-none': isCollapsed }"
|
||||
>
|
||||
{{ $getAction('collapse') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute inset-0 rotate-180 transition"
|
||||
x-bind:class="{ 'opacity-0 pointer-events-none': ! isCollapsed }"
|
||||
>
|
||||
{{ $getAction('expand') }}
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
x-show="! isCollapsed"
|
||||
class="fi-fo-repeater-item-content p-4"
|
||||
>
|
||||
{{ $item }}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@if (! $loop->last)
|
||||
@if ($isAddable && $addBetweenAction(['afterItem' => $uuid])->isVisible())
|
||||
<li class="flex w-full justify-center">
|
||||
<div
|
||||
class="fi-fo-repeater-add-between-action-ctn rounded-lg bg-white dark:bg-gray-900"
|
||||
>
|
||||
{{ $addBetweenAction(['afterItem' => $uuid]) }}
|
||||
</div>
|
||||
</li>
|
||||
@elseif (filled($labelBetweenItems = $getLabelBetweenItems()))
|
||||
<li
|
||||
class="relative border-t border-gray-200 dark:border-white/10"
|
||||
>
|
||||
<span
|
||||
class="absolute -top-3 left-3 px-1 text-sm font-medium"
|
||||
>
|
||||
{{ $labelBetweenItems }}
|
||||
</span>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<div class="flex justify-center">
|
||||
{{ $addAction }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
125
vendor/filament/forms/resources/views/components/repeater/simple.blade.php
vendored
Normal file
125
vendor/filament/forms/resources/views/components/repeater/simple.blade.php
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
@php
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
|
||||
$containers = $getChildComponentContainers();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$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();
|
||||
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
<div
|
||||
x-data="{}"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-simple-repeater grid gap-y-4'])
|
||||
}}
|
||||
>
|
||||
@if (count($containers))
|
||||
<ul>
|
||||
<x-filament::grid
|
||||
:default="$getGridColumns('default')"
|
||||
:sm="$getGridColumns('sm')"
|
||||
:md="$getGridColumns('md')"
|
||||
:lg="$getGridColumns('lg')"
|
||||
:xl="$getGridColumns('xl')"
|
||||
:two-xl="$getGridColumns('2xl')"
|
||||
:wire:end.stop="'mountFormComponentAction(\'' . $statePath . '\', \'reorder\', { items: $event.target.sortable.toArray() })'"
|
||||
x-sortable
|
||||
:data-sortable-animation-duration="$getReorderAnimationDuration()"
|
||||
class="gap-4"
|
||||
>
|
||||
@foreach ($containers as $uuid => $item)
|
||||
@php
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $uuid])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $uuid]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $uuid]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $uuid])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $uuid])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:key="{{ $this->getId() }}.{{ $item->getStatePath() }}.{{ $field::class }}.item"
|
||||
x-sortable-item="{{ $uuid }}"
|
||||
class="fi-fo-repeater-item simple flex justify-start gap-x-3"
|
||||
>
|
||||
<div class="flex-1">
|
||||
{{ $item }}
|
||||
</div>
|
||||
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $visibleExtraItemActions)
|
||||
<ul class="flex items-center gap-x-1">
|
||||
@if ($reorderActionIsVisible)
|
||||
<li x-sortable-handle>
|
||||
{{ $reorderAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li>
|
||||
{{ $extraItemAction(['item' => $uuid]) }}
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
@if ($cloneActionIsVisible)
|
||||
<li>
|
||||
{{ $cloneAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($deleteActionIsVisible)
|
||||
<li>
|
||||
{{ $deleteAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<div class="flex justify-center">
|
||||
{{ $addAction }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
512
vendor/filament/forms/resources/views/components/rich-editor.blade.php
vendored
Normal file
512
vendor/filament/forms/resources/views/components/rich-editor.blade.php
vendored
Normal file
@@ -0,0 +1,512 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$id = $getId();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
|
||||
@if ($isDisabled())
|
||||
<div
|
||||
x-data="{
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
}"
|
||||
x-html="state"
|
||||
class="fi-fo-rich-editor fi-disabled prose block w-full max-w-none rounded-lg bg-gray-50 px-3 py-3 text-gray-500 shadow-sm ring-1 ring-gray-950/10 dark:prose-invert dark:bg-transparent dark:text-gray-400 dark:ring-white/10 sm:text-sm"
|
||||
></div>
|
||||
@else
|
||||
<x-filament::input.wrapper
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-rich-editor max-w-full overflow-x-auto'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('rich-editor', 'filament/forms') }}"
|
||||
x-data="richEditorFormComponent({
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')", isOptimisticallyLive: false) }},
|
||||
})"
|
||||
x-ignore
|
||||
x-on:trix-attachment-add="
|
||||
if (! $event.attachment.file) return
|
||||
|
||||
let attachment = $event.attachment
|
||||
|
||||
$wire.upload(
|
||||
`componentFileAttachments.{{ $statePath }}`,
|
||||
attachment.file,
|
||||
() => {
|
||||
$wire
|
||||
.getFormComponentFileAttachmentUrl('{{ $statePath }}')
|
||||
.then((url) => {
|
||||
attachment.setAttributes({
|
||||
url: url,
|
||||
href: url,
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
"
|
||||
x-on:trix-change="
|
||||
let value = $event.target.value
|
||||
|
||||
$nextTick(() => {
|
||||
if (! $refs.trix) {
|
||||
return
|
||||
}
|
||||
|
||||
state = value
|
||||
})
|
||||
"
|
||||
@if ($isLiveDebounced())
|
||||
x-on:trix-change.debounce.{{ $getLiveDebounce() }}="
|
||||
$nextTick(() => {
|
||||
if (! $refs.trix) {
|
||||
return
|
||||
}
|
||||
|
||||
$wire.call('$refresh')
|
||||
})
|
||||
"
|
||||
@endif
|
||||
@if (! $hasToolbarButton('attachFiles'))
|
||||
x-on:trix-file-accept="$event.preventDefault()"
|
||||
@endif
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<input
|
||||
id="trix-value-{{ $id }}"
|
||||
x-ref="trixValue"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<trix-toolbar
|
||||
id="trix-toolbar-{{ $id }}"
|
||||
@class([
|
||||
'fi-fo-rich-editor-toolbar relative flex flex-col gap-x-3 border-b border-gray-100 px-2.5 py-2 dark:border-white/10',
|
||||
'hidden' => ! count($getToolbarButtons()),
|
||||
])
|
||||
>
|
||||
<div class="flex gap-x-3 overflow-x-auto">
|
||||
@if ($hasToolbarButton(['bold', 'italic', 'underline', 'strike', 'link']))
|
||||
<x-filament-forms::rich-editor.toolbar.group
|
||||
data-trix-button-group="text-tools"
|
||||
>
|
||||
@if ($hasToolbarButton('bold'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="bold"
|
||||
data-trix-key="b"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.bold') }}"
|
||||
tabindex="-1"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.bold') }}"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="bold"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 384 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M321.1 242.4C340.1 220.1 352 191.6 352 160c0-70.59-57.42-128-128-128L32 32.01c-17.67 0-32 14.31-32 32s14.33 32 32 32h16v320H32c-17.67 0-32 14.31-32 32s14.33 32 32 32h224c70.58 0 128-57.41 128-128C384 305.3 358.6 264.8 321.1 242.4zM112 96.01H224c35.3 0 64 28.72 64 64s-28.7 64-64 64H112V96.01zM256 416H112v-128H256c35.3 0 64 28.71 64 63.1S291.3 416 256 416z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('italic'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="italic"
|
||||
data-trix-key="i"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.italic') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="italic"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 384 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M384 64.01c0 17.69-14.31 32-32 32h-58.67l-133.3 320H224c17.69 0 32 14.31 32 32s-14.31 32-32 32H32c-17.69 0-32-14.31-32-32s14.31-32 32-32h58.67l133.3-320H160c-17.69 0-32-14.31-32-32s14.31-32 32-32h192C369.7 32.01 384 46.33 384 64.01z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('underline'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="underline"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.underline') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="underline"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M16 64c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32h-16v128c0 53 43 96 96 96s96-43 96-96V96h-16c-17.7 0-32-14.3-32-32s14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32h-16v128c0 88.4-71.6 160-160 160S64 312.4 64 224V96H48c-17.7 0-32-14.3-32-32zM0 448c0-17.7 14.3-32 32-32h384c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32z"
|
||||
/>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('strike'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="strike"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.strike') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="strikethrough"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M332.2 319.9c17.22 12.17 22.33 26.51 18.61 48.21c-3.031 17.59-10.88 29.34-24.72 36.99c-35.44 19.75-108.5 11.96-186-19.68c-16.34-6.686-35.03 1.156-41.72 17.53s1.188 35.05 17.53 41.71c31.75 12.93 95.69 35.37 157.6 35.37c29.62 0 58.81-5.156 83.72-18.96c30.81-17.09 50.44-45.46 56.72-82.11c3.998-23.27 2.168-42.58-3.488-59.05H332.2zM488 239.9l-176.5-.0309c-15.85-5.613-31.83-10.34-46.7-14.62c-85.47-24.62-110.9-39.05-103.7-81.33c2.5-14.53 10.16-25.96 22.72-34.03c20.47-13.15 64.06-23.84 155.4 .3438c17.09 4.531 34.59-5.654 39.13-22.74c4.531-17.09-5.656-34.59-22.75-39.12c-91.31-24.18-160.7-21.62-206.3 7.654C121.8 73.72 103.6 101.1 98.09 133.1C89.26 184.5 107.9 217.3 137.2 239.9L24 239.9c-13.25 0-24 10.75-24 23.1c0 13.25 10.75 23.1 24 23.1h464c13.25 0 24-10.75 24-23.1C512 250.7 501.3 239.9 488 239.9z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('link'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="href"
|
||||
data-trix-action="link"
|
||||
data-trix-key="k"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.link') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="link"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M598.6 41.41C570.1 13.8 534.8 0 498.6 0s-72.36 13.8-99.96 41.41l-43.36 43.36c15.11 8.012 29.47 17.58 41.91 30.02c3.146 3.146 5.898 6.518 8.742 9.838l37.96-37.96C458.5 72.05 477.1 64 498.6 64c20.67 0 40.1 8.047 54.71 22.66c14.61 14.61 22.66 34.04 22.66 54.71s-8.049 40.1-22.66 54.71l-133.3 133.3C405.5 343.1 386 352 365.4 352s-40.1-8.048-54.71-22.66C296 314.7 287.1 295.3 287.1 274.6s8.047-40.1 22.66-54.71L314.2 216.4C312.1 212.5 309.9 208.5 306.7 205.3C298.1 196.7 286.8 192 274.6 192c-11.93 0-23.1 4.664-31.61 12.97c-30.71 53.96-23.63 123.6 22.39 169.6C293 402.2 329.2 416 365.4 416c36.18 0 72.36-13.8 99.96-41.41L598.6 241.3c28.45-28.45 42.24-66.01 41.37-103.3C639.1 102.1 625.4 68.16 598.6 41.41zM234 387.4L196.1 425.3C181.5 439.1 162 448 141.4 448c-20.67 0-40.1-8.047-54.71-22.66c-14.61-14.61-22.66-34.04-22.66-54.71s8.049-40.1 22.66-54.71l133.3-133.3C234.5 168 253.1 160 274.6 160s40.1 8.048 54.71 22.66c14.62 14.61 22.66 34.04 22.66 54.71s-8.047 40.1-22.66 54.71L325.8 295.6c2.094 3.939 4.219 7.895 7.465 11.15C341.9 315.3 353.3 320 365.4 320c11.93 0 23.1-4.664 31.61-12.97c30.71-53.96 23.63-123.6-22.39-169.6C346.1 109.8 310.8 96 274.6 96C238.4 96 202.3 109.8 174.7 137.4L41.41 270.7c-27.6 27.6-41.41 63.78-41.41 99.96c-.0001 36.18 13.8 72.36 41.41 99.97C69.01 498.2 105.2 512 141.4 512c36.18 0 72.36-13.8 99.96-41.41l43.36-43.36c-15.11-8.012-29.47-17.58-41.91-30.02C239.6 394.1 236.9 390.7 234 387.4z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
</x-filament-forms::rich-editor.toolbar.group>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton(['h1', 'h2', 'h3']))
|
||||
<x-filament-forms::rich-editor.toolbar.group
|
||||
data-trix-button-group="heading-tools"
|
||||
>
|
||||
@if ($hasToolbarButton('h1'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="heading1"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.h1') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
{{ __('filament-forms::components.rich_editor.toolbar_buttons.h1') }}
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('h2'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="heading"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.h2') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
{{ __('filament-forms::components.rich_editor.toolbar_buttons.h2') }}
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('h3'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="subHeading"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.h3') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
{{ __('filament-forms::components.rich_editor.toolbar_buttons.h3') }}
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
</x-filament-forms::rich-editor.toolbar.group>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton(['blockquote', 'codeBlock', 'bulletList', 'orderedList']))
|
||||
<x-filament-forms::rich-editor.toolbar.group
|
||||
data-trix-button-group="block-tools"
|
||||
>
|
||||
@if ($hasToolbarButton('blockquote'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="quote"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.blockquote') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="quote-left"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M96 224C84.72 224 74.05 226.3 64 229.9V224c0-35.3 28.7-64 64-64c17.67 0 32-14.33 32-32S145.7 96 128 96C57.42 96 0 153.4 0 224v96c0 53.02 42.98 96 96 96s96-42.98 96-96S149 224 96 224zM352 224c-11.28 0-21.95 2.305-32 5.879V224c0-35.3 28.7-64 64-64c17.67 0 32-14.33 32-32s-14.33-32-32-32c-70.58 0-128 57.42-128 128v96c0 53.02 42.98 96 96 96s96-42.98 96-96S405 224 352 224z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('codeBlock'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="code"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.code_block') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="code"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M416 31.94C416 21.75 408.1 0 384.1 0c-13.98 0-26.87 9.072-30.89 23.18l-128 448c-.8404 2.935-1.241 5.892-1.241 8.801C223.1 490.3 232 512 256 512c13.92 0 26.73-9.157 30.75-23.22l128-448C415.6 37.81 416 34.85 416 31.94zM176 143.1c0-18.28-14.95-32-32-32c-8.188 0-16.38 3.125-22.62 9.376l-112 112C3.125 239.6 0 247.8 0 255.1S3.125 272.4 9.375 278.6l112 112C127.6 396.9 135.8 399.1 144 399.1c17.05 0 32-13.73 32-32c0-8.188-3.125-16.38-9.375-22.63L77.25 255.1l89.38-89.38C172.9 160.3 176 152.2 176 143.1zM640 255.1c0-8.188-3.125-16.38-9.375-22.63l-112-112C512.4 115.1 504.2 111.1 496 111.1c-17.05 0-32 13.73-32 32c0 8.188 3.125 16.38 9.375 22.63l89.38 89.38l-89.38 89.38C467.1 351.6 464 359.8 464 367.1c0 18.28 14.95 32 32 32c8.188 0 16.38-3.125 22.62-9.376l112-112C636.9 272.4 640 264.2 640 255.1z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('bulletList'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="bullet"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.bullet_list') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="list-ul"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M16 96C16 69.49 37.49 48 64 48C90.51 48 112 69.49 112 96C112 122.5 90.51 144 64 144C37.49 144 16 122.5 16 96zM480 64C497.7 64 512 78.33 512 96C512 113.7 497.7 128 480 128H192C174.3 128 160 113.7 160 96C160 78.33 174.3 64 192 64H480zM480 224C497.7 224 512 238.3 512 256C512 273.7 497.7 288 480 288H192C174.3 288 160 273.7 160 256C160 238.3 174.3 224 192 224H480zM480 384C497.7 384 512 398.3 512 416C512 433.7 497.7 448 480 448H192C174.3 448 160 433.7 160 416C160 398.3 174.3 384 192 384H480zM16 416C16 389.5 37.49 368 64 368C90.51 368 112 389.5 112 416C112 442.5 90.51 464 64 464C37.49 464 16 442.5 16 416zM112 256C112 282.5 90.51 304 64 304C37.49 304 16 282.5 16 256C16 229.5 37.49 208 64 208C90.51 208 112 229.5 112 256z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('orderedList'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-attribute="number"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.ordered_list') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="list-ol"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M55.1 56.04C55.1 42.78 66.74 32.04 79.1 32.04H111.1C125.3 32.04 135.1 42.78 135.1 56.04V176H151.1C165.3 176 175.1 186.8 175.1 200C175.1 213.3 165.3 224 151.1 224H71.1C58.74 224 47.1 213.3 47.1 200C47.1 186.8 58.74 176 71.1 176H87.1V80.04H79.1C66.74 80.04 55.1 69.29 55.1 56.04V56.04zM118.7 341.2C112.1 333.8 100.4 334.3 94.65 342.4L83.53 357.9C75.83 368.7 60.84 371.2 50.05 363.5C39.26 355.8 36.77 340.8 44.47 330.1L55.59 314.5C79.33 281.2 127.9 278.8 154.8 309.6C176.1 333.1 175.6 370.5 153.7 394.3L118.8 432H152C165.3 432 176 442.7 176 456C176 469.3 165.3 480 152 480H64C54.47 480 45.84 474.4 42.02 465.6C38.19 456.9 39.9 446.7 46.36 439.7L118.4 361.7C123.7 355.9 123.8 347.1 118.7 341.2L118.7 341.2zM512 64C529.7 64 544 78.33 544 96C544 113.7 529.7 128 512 128H256C238.3 128 224 113.7 224 96C224 78.33 238.3 64 256 64H512zM512 224C529.7 224 544 238.3 544 256C544 273.7 529.7 288 512 288H256C238.3 288 224 273.7 224 256C224 238.3 238.3 224 256 224H512zM512 384C529.7 384 544 398.3 544 416C544 433.7 529.7 448 512 448H256C238.3 448 224 433.7 224 416C224 398.3 238.3 384 256 384H512z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
</x-filament-forms::rich-editor.toolbar.group>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('attachFiles'))
|
||||
<x-filament-forms::rich-editor.toolbar.group
|
||||
data-trix-button-group="file-tools"
|
||||
>
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-action="attachFiles"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.attach_files') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="image"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M447.1 32h-484C28.64 32-.0091 60.65-.0091 96v320c0 35.35 28.65 64 63.1 64h384c35.35 0 64-28.65 64-64V96C511.1 60.65 483.3 32 447.1 32zM111.1 96c26.51 0 48 21.49 48 48S138.5 192 111.1 192s-48-21.49-48-48S85.48 96 111.1 96zM446.1 407.6C443.3 412.8 437.9 416 432 416H82.01c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C142.1 290.4 146.9 288 152 288s9.916 2.441 12.93 6.574l32.46 44.51l93.3-139.1C293.7 194.7 298.7 192 304 192s10.35 2.672 13.31 7.125l128 192C448.6 396 448.9 402.3 446.1 407.6z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
</x-filament-forms::rich-editor.toolbar.group>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton(['undo', 'redo']))
|
||||
<x-filament-forms::rich-editor.toolbar.group
|
||||
data-trix-button-group="history-tools"
|
||||
>
|
||||
@if ($hasToolbarButton('undo'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-action="undo"
|
||||
data-trix-key="z"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.undo') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="rotate-left"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M480 256c0 123.4-100.5 223.9-223.9 223.9c-48.84 0-95.17-15.58-134.2-44.86c-14.12-10.59-16.97-30.66-6.375-44.81c10.59-14.12 30.62-16.94 44.81-6.375c27.84 20.91 61 31.94 95.88 31.94C344.3 415.8 416 344.1 416 256s-71.69-159.8-159.8-159.8c-37.46 0-73.09 13.49-101.3 36.64l45.12 45.14c17.01 17.02 4.955 46.1-19.1 46.1H35.17C24.58 224.1 16 215.5 16 204.9V59.04c0-24.04 29.07-36.08 46.07-19.07l47.6 47.63C149.9 52.71 201.5 32.11 256.1 32.11C379.5 32.11 480 132.6 480 256z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
|
||||
@if ($hasToolbarButton('redo'))
|
||||
<x-filament-forms::rich-editor.toolbar.button
|
||||
data-trix-action="redo"
|
||||
data-trix-key="shift+z"
|
||||
title="{{ __('filament-forms::components.rich_editor.toolbar_buttons.redo') }}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
class="-mx-4 h-4 dark:fill-current"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="rotate-right"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M468.9 32.11c13.87 0 27.18 10.77 27.18 27.04v145.9c0 10.59-8.584 19.17-19.17 19.17h-145.7c-16.28 0-27.06-13.32-27.06-27.2c0-6.634 2.461-13.4 7.96-18.9l45.12-45.14c-28.22-23.14-63.85-36.64-101.3-36.64c-88.09 0-159.8 71.69-159.8 159.8S167.8 415.9 255.9 415.9c73.14 0 89.44-38.31 115.1-38.31c18.48 0 31.97 15.04 31.97 31.96c0 35.04-81.59 70.41-147 70.41c-123.4 0-223.9-100.5-223.9-223.9S132.6 32.44 256 32.44c54.6 0 106.2 20.39 146.4 55.26l47.6-47.63C455.5 34.57 462.3 32.11 468.9 32.11z"
|
||||
></path>
|
||||
</svg>
|
||||
</x-filament-forms::rich-editor.toolbar.button>
|
||||
@endif
|
||||
</x-filament-forms::rich-editor.toolbar.group>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div x-cloak data-trix-dialogs class="trix-dialogs">
|
||||
<div
|
||||
data-trix-dialog="href"
|
||||
data-trix-dialog-attribute="href"
|
||||
class="trix-dialog trix-dialog--link"
|
||||
>
|
||||
<div class="trix-dialog__link-fields">
|
||||
<input
|
||||
aria-label="{{ __('filament-forms::components.rich_editor.dialogs.link.label') }}"
|
||||
data-trix-input
|
||||
disabled
|
||||
name="href"
|
||||
placeholder="{{ __('filament-forms::components.rich_editor.dialogs.link.placeholder') }}"
|
||||
required
|
||||
type="text"
|
||||
inputmode="url"
|
||||
class="trix-input trix-input--dialog"
|
||||
/>
|
||||
|
||||
<div class="trix-button-group">
|
||||
<input
|
||||
data-trix-method="setAttribute"
|
||||
type="button"
|
||||
value="{{ __('filament-forms::components.rich_editor.dialogs.link.actions.link') }}"
|
||||
class="trix-button trix-button--dialog"
|
||||
/>
|
||||
|
||||
<input
|
||||
data-trix-method="removeAttribute"
|
||||
type="button"
|
||||
value="{{ __('filament-forms::components.rich_editor.dialogs.link.actions.unlink') }}"
|
||||
class="trix-button trix-button--dialog"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</trix-toolbar>
|
||||
|
||||
<trix-editor
|
||||
@if ($isAutofocused())
|
||||
autofocus
|
||||
@endif
|
||||
id="{{ $id }}"
|
||||
input="trix-value-{{ $id }}"
|
||||
placeholder="{{ $getPlaceholder() }}"
|
||||
toolbar="trix-toolbar-{{ $id }}"
|
||||
@if ($isLiveOnBlur())
|
||||
x-on:blur="$wire.call('$refresh')"
|
||||
@endif
|
||||
x-ref="trix"
|
||||
wire:ignore
|
||||
{{
|
||||
$getExtraInputAttributeBag()->class([
|
||||
'prose min-h-[theme(spacing.48)] max-w-none !border-none px-3 py-1.5 text-base text-gray-950 dark:prose-invert focus-visible:outline-none dark:text-white sm:text-sm sm:leading-6',
|
||||
])
|
||||
}}
|
||||
></trix-editor>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
11
vendor/filament/forms/resources/views/components/rich-editor/toolbar/button.blade.php
vendored
Normal file
11
vendor/filament/forms/resources/views/components/rich-editor/toolbar/button.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<button
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'type' => 'button',
|
||||
], escape: false)
|
||||
->class(['fi-fo-rich-editor-toolbar-btn flex h-8 min-w-[theme(spacing.8)] cursor-pointer items-center justify-center rounded-lg px-2 text-sm font-semibold text-gray-700 transition duration-75 hover:bg-gray-50 focus-visible:bg-gray-50 dark:text-gray-200 dark:hover:bg-white/5 dark:focus-visible:bg-white/5 [&.trix-active]:bg-gray-50 [&.trix-active]:text-primary-600 dark:[&.trix-active]:bg-white/5 dark:[&.trix-active]:text-primary-400'])
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</button>
|
||||
3
vendor/filament/forms/resources/views/components/rich-editor/toolbar/group.blade.php
vendored
Normal file
3
vendor/filament/forms/resources/views/components/rich-editor/toolbar/group.blade.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<div {{ $attributes->class(['flex gap-x-1']) }}>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
30
vendor/filament/forms/resources/views/components/section.blade.php
vendored
Normal file
30
vendor/filament/forms/resources/views/components/section.blade.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
@php
|
||||
$isAside = $isAside();
|
||||
@endphp
|
||||
|
||||
<x-filament::section
|
||||
:aside="$isAside"
|
||||
:collapsed="$isCollapsed()"
|
||||
:collapsible="$isCollapsible() && (! $isAside)"
|
||||
:compact="$isCompact()"
|
||||
:content-before="$isFormBefore()"
|
||||
:description="$getDescription()"
|
||||
:footer-actions="$getFooterActions()"
|
||||
:footer-actions-alignment="$getFooterActionsAlignment()"
|
||||
:header-actions="$getHeaderActions()"
|
||||
:heading="$getHeading()"
|
||||
:icon="$getIcon()"
|
||||
:icon-color="$getIconColor()"
|
||||
:icon-size="$getIconSize()"
|
||||
:persist-collapsed="$shouldPersistCollapsed()"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
"
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</x-filament::section>
|
||||
169
vendor/filament/forms/resources/views/components/select.blade.php
vendored
Normal file
169
vendor/filament/forms/resources/views/components/select.blade.php
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$canSelectPlaceholder = $canSelectPlaceholder();
|
||||
$isDisabled = $isDisabled();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
: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="$getPrefixIconColor()"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$getSuffixIconColor()"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-select'])
|
||||
"
|
||||
>
|
||||
@if ((! ($isSearchable() || $isMultiple()) && $isNative()))
|
||||
<x-filament::input.select
|
||||
:autofocus="$isAutofocused()"
|
||||
:disabled="$isDisabled"
|
||||
:id="$getId()"
|
||||
:inline-prefix="$isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel))"
|
||||
:inline-suffix="$isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel))"
|
||||
:required="$isRequired() && (! $isConcealed())"
|
||||
:attributes="
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
], escape: false)
|
||||
"
|
||||
>
|
||||
@php
|
||||
$isHtmlAllowed = $isHtmlAllowed();
|
||||
@endphp
|
||||
|
||||
@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
|
||||
</x-filament::input.select>
|
||||
@else
|
||||
<div
|
||||
x-ignore
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('select', 'filament/forms') }}"
|
||||
x-data="selectFormComponent({
|
||||
canSelectPlaceholder: @js($canSelectPlaceholder),
|
||||
isHtmlAllowed: @js($isHtmlAllowed()),
|
||||
getOptionLabelUsing: async () => {
|
||||
return await $wire.getFormSelectOptionLabel(@js($statePath))
|
||||
},
|
||||
getOptionLabelsUsing: async () => {
|
||||
return await $wire.getFormSelectOptionLabels(@js($statePath))
|
||||
},
|
||||
getOptionsUsing: async () => {
|
||||
return await $wire.getFormSelectOptions(@js($statePath))
|
||||
},
|
||||
getSearchResultsUsing: async (search) => {
|
||||
return await $wire.getFormSelectSearchResults(@js($statePath), search)
|
||||
},
|
||||
isAutofocused: @js($isAutofocused()),
|
||||
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
|
||||
x-on:keydown.esc="select.dropdown.isActive && $event.stopPropagation()"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'[&_.choices\_\_inner]:ps-0' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
|
||||
])
|
||||
}}
|
||||
>
|
||||
<select
|
||||
x-ref="input"
|
||||
{{
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $getId(),
|
||||
'multiple' => $isMultiple(),
|
||||
], escape: false)
|
||||
->class([
|
||||
'h-9 w-full rounded-lg border-none bg-transparent !bg-none',
|
||||
])
|
||||
}}
|
||||
></select>
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
63
vendor/filament/forms/resources/views/components/split.blade.php
vendored
Normal file
63
vendor/filament/forms/resources/views/components/split.blade.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
|
||||
$verticalAlignment = $getVerticalAlignment();
|
||||
|
||||
if (! $verticalAlignment instanceof VerticalAlignment) {
|
||||
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-split flex gap-6',
|
||||
match ($getFromBreakpoint()) {
|
||||
'sm' => 'flex-col sm:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'sm:items-center',
|
||||
VerticalAlignment::End => 'sm:items-end',
|
||||
default => 'sm:items-start',
|
||||
},
|
||||
'md' => 'flex-col md:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'md:items-center',
|
||||
VerticalAlignment::End => 'md:items-end',
|
||||
default => 'md:items-start',
|
||||
},
|
||||
'lg' => 'flex-col lg:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'lg:items-center',
|
||||
VerticalAlignment::End => 'lg:items-end',
|
||||
default => 'lg:items-start',
|
||||
},
|
||||
'xl' => 'flex-col xl:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'xl:items-center',
|
||||
VerticalAlignment::End => 'xl:items-end',
|
||||
default => 'xl:items-start',
|
||||
},
|
||||
'2xl' => 'flex-col 2xl:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => '2xl:items-center',
|
||||
VerticalAlignment::End => '2xl:items-end',
|
||||
default => '2xl:items-start',
|
||||
},
|
||||
default => match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'items-center',
|
||||
VerticalAlignment::End => 'items-end',
|
||||
default => 'items-start',
|
||||
},
|
||||
},
|
||||
])
|
||||
}}
|
||||
>
|
||||
@foreach ($getChildComponentContainers() as $container)
|
||||
@foreach ($container->getComponents() as $component)
|
||||
<div
|
||||
@class([
|
||||
'w-full flex-1' => $component->canGrow(),
|
||||
])
|
||||
>
|
||||
{{ $component }}
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
107
vendor/filament/forms/resources/views/components/tabs.blade.php
vendored
Normal file
107
vendor/filament/forms/resources/views/components/tabs.blade.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
@php
|
||||
use Filament\Forms\Components\Tabs\Tab;
|
||||
|
||||
$isContained = $isContained();
|
||||
@endphp
|
||||
|
||||
<div
|
||||
wire:ignore.self
|
||||
x-cloak
|
||||
x-data="{
|
||||
tab: @if ($isTabPersisted() && filled($persistenceId = $getId())) $persist(null).as('tabs-{{ $persistenceId }}') @else null @endif,
|
||||
|
||||
getTabs: function () {
|
||||
if (! this.$refs.tabsData) {
|
||||
return []
|
||||
}
|
||||
|
||||
return JSON.parse(this.$refs.tabsData.value)
|
||||
},
|
||||
|
||||
updateQueryString: function () {
|
||||
if (! @js($isTabPersistedInQueryString())) {
|
||||
return
|
||||
}
|
||||
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.set(@js($getTabQueryStringKey()), this.tab)
|
||||
|
||||
history.pushState(null, document.title, url.toString())
|
||||
},
|
||||
}"
|
||||
x-init="
|
||||
$watch('tab', () => updateQueryString())
|
||||
|
||||
const tabs = getTabs()
|
||||
|
||||
if (! tab || ! tabs.includes(tab)) {
|
||||
tab = tabs[@js($getActiveTab()) - 1]
|
||||
}
|
||||
|
||||
Livewire.hook('commit', ({ component, commit, succeed, fail, respond }) => {
|
||||
succeed(({ snapshot, effect }) => {
|
||||
$nextTick(() => {
|
||||
if (component.id !== @js($this->getId())) {
|
||||
return
|
||||
}
|
||||
|
||||
const tabs = getTabs()
|
||||
|
||||
if (! tabs.includes(tab)) {
|
||||
tab = tabs[@js($getActiveTab()) - 1] ?? tab
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
'wire:key' => "{$this->getId()}.{$getStatePath()}." . \Filament\Forms\Components\Tabs::class . '.container',
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-tabs flex flex-col',
|
||||
'fi-contained rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10' => $isContained,
|
||||
])
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
value="{{
|
||||
collect($getChildComponentContainer()->getComponents())
|
||||
->filter(static fn (Tab $tab): bool => $tab->isVisible())
|
||||
->map(static fn (Tab $tab) => $tab->getId())
|
||||
->values()
|
||||
->toJson()
|
||||
}}"
|
||||
x-ref="tabsData"
|
||||
/>
|
||||
|
||||
<x-filament::tabs :contained="$isContained" :label="$getLabel()">
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $tab)
|
||||
@php
|
||||
$tabId = $tab->getId();
|
||||
@endphp
|
||||
|
||||
<x-filament::tabs.item
|
||||
:alpine-active="'tab === \'' . $tabId . '\''"
|
||||
:badge="$tab->getBadge()"
|
||||
:badge-color="$tab->getBadgeColor()"
|
||||
:badge-icon="$tab->getBadgeIcon()"
|
||||
:badge-icon-position="$tab->getBadgeIconPosition()"
|
||||
:icon="$tab->getIcon()"
|
||||
:icon-position="$tab->getIconPosition()"
|
||||
:x-on:click="'tab = \'' . $tabId . '\''"
|
||||
>
|
||||
{{ $tab->getLabel() }}
|
||||
</x-filament::tabs.item>
|
||||
@endforeach
|
||||
</x-filament::tabs>
|
||||
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $tab)
|
||||
{{ $tab }}
|
||||
@endforeach
|
||||
</div>
|
||||
34
vendor/filament/forms/resources/views/components/tabs/tab.blade.php
vendored
Normal file
34
vendor/filament/forms/resources/views/components/tabs/tab.blade.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
@php
|
||||
$id = $getId();
|
||||
$isContained = $getContainer()->getParentComponent()->isContained();
|
||||
|
||||
$activeTabClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-active',
|
||||
'p-6' => $isContained,
|
||||
'mt-6' => ! $isContained,
|
||||
]);
|
||||
|
||||
$inactiveTabClasses = 'invisible absolute h-0 overflow-hidden p-0';
|
||||
@endphp
|
||||
|
||||
<div
|
||||
x-bind:class="{
|
||||
@js($activeTabClasses): tab === @js($id),
|
||||
@js($inactiveTabClasses): tab !== @js($id),
|
||||
}"
|
||||
x-on:expand="tab = @js($id)"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'aria-labelledby' => $id,
|
||||
'id' => $id,
|
||||
'role' => 'tabpanel',
|
||||
'tabindex' => '0',
|
||||
'wire:key' => "{$this->getId()}.{$getStatePath()}." . \Filament\Forms\Components\Tabs\Tab::class . ".tabs.{$id}",
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-tabs-tab outline-none'])
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
144
vendor/filament/forms/resources/views/components/tags-input.blade.php
vendored
Normal file
144
vendor/filament/forms/resources/views/components/tags-input.blade.php
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$color = $getColor() ?? 'primary';
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isReorderable = $isReorderable();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$statePath = $getStatePath();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:inline-prefix="$isPrefixInline"
|
||||
:inline-suffix="$isSuffixInline"
|
||||
:prefix="$prefixLabel"
|
||||
:prefix-actions="$prefixActions"
|
||||
:prefix-icon="$prefixIcon"
|
||||
:prefix-icon-color="$getPrefixIconColor()"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$getSuffixIconColor()"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-tags-input'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('tags-input', 'filament/forms') }}"
|
||||
x-data="tagsInputFormComponent({
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
splitKeys: @js($getSplitKeys()),
|
||||
})"
|
||||
x-ignore
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<x-filament::input
|
||||
autocomplete="off"
|
||||
:autofocus="$isAutofocused()"
|
||||
:disabled="$isDisabled"
|
||||
:id="$id"
|
||||
:inline-prefix="$isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel))"
|
||||
:inline-suffix="$isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel))"
|
||||
:list="$id . '-suggestions'"
|
||||
:placeholder="$getPlaceholder()"
|
||||
type="text"
|
||||
x-bind="input"
|
||||
:attributes="\Filament\Support\prepare_inherited_attributes($getExtraInputAttributeBag())"
|
||||
/>
|
||||
|
||||
<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
|
||||
@class([
|
||||
'[&_.fi-badge-delete-button]:hidden' => $isDisabled,
|
||||
])
|
||||
>
|
||||
<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([
|
||||
'flex w-full flex-wrap gap-1.5 p-2',
|
||||
'border-t border-t-gray-200 dark:border-t-white/10',
|
||||
])
|
||||
>
|
||||
<template
|
||||
x-for="(tag, index) in state"
|
||||
x-bind:key="`${tag}-${index}`"
|
||||
class="hidden"
|
||||
>
|
||||
<x-filament::badge
|
||||
:color="$color"
|
||||
:x-bind:x-sortable-item="$isReorderable ? 'index' : null"
|
||||
:x-sortable-handle="$isReorderable ? '' : null"
|
||||
@class([
|
||||
'cursor-move' => $isReorderable,
|
||||
])
|
||||
>
|
||||
{{ $getTagPrefix() }}
|
||||
|
||||
<span
|
||||
x-text="tag"
|
||||
class="select-none text-start"
|
||||
></span>
|
||||
|
||||
{{ $getTagSuffix() }}
|
||||
|
||||
<x-slot
|
||||
name="deleteButton"
|
||||
x-on:click="deleteTag(tag)"
|
||||
></x-slot>
|
||||
</x-filament::badge>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
114
vendor/filament/forms/resources/views/components/text-input.blade.php
vendored
Normal file
114
vendor/filament/forms/resources/views/components/text-input.blade.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
@php
|
||||
use Filament\Forms\Components\TextInput\Actions\HidePasswordAction;
|
||||
use Filament\Forms\Components\TextInput\Actions\ShowPasswordAction;
|
||||
|
||||
$datalistOptions = $getDatalistOptions();
|
||||
$extraAlpineAttributes = $getExtraAlpineAttributes();
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$id = $getId();
|
||||
$isConcealed = $isConcealed();
|
||||
$isDisabled = $isDisabled();
|
||||
$isPasswordRevealable = $isPasswordRevealable();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$mask = $getMask();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
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();
|
||||
}
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:inline-prefix="$isPrefixInline"
|
||||
:inline-suffix="$isSuffixInline"
|
||||
:prefix="$prefixLabel"
|
||||
:prefix-actions="$prefixActions"
|
||||
:prefix-icon="$prefixIcon"
|
||||
:prefix-icon-color="$getPrefixIconColor()"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$getSuffixIconColor()"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:x-data="$xData"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-text-input overflow-hidden'])
|
||||
"
|
||||
>
|
||||
<x-filament::input
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($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' => $getPlaceholder(),
|
||||
'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([
|
||||
'[&::-ms-reveal]:hidden' => $isPasswordRevealable,
|
||||
])
|
||||
"
|
||||
/>
|
||||
</x-filament::input.wrapper>
|
||||
|
||||
@if ($datalistOptions)
|
||||
<datalist id="{{ $id }}-list">
|
||||
@foreach ($datalistOptions as $option)
|
||||
<option value="{{ $option }}" />
|
||||
@endforeach
|
||||
</datalist>
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
78
vendor/filament/forms/resources/views/components/textarea.blade.php
vendored
Normal file
78
vendor/filament/forms/resources/views/components/textarea.blade.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
@php
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$isConcealed = $isConcealed();
|
||||
$isDisabled = $isDisabled();
|
||||
$rows = $getRows();
|
||||
$shouldAutosize = $shouldAutosize();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
$initialHeight = (($rows ?? 2) * 1.5) + 0.75;
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-textarea overflow-hidden'])
|
||||
"
|
||||
>
|
||||
<textarea
|
||||
@if ($shouldAutosize)
|
||||
@if (FilamentView::hasSpaMode())
|
||||
ax-load="visible"
|
||||
@else
|
||||
ax-load
|
||||
@endif
|
||||
ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('textarea', 'filament/forms') }}"
|
||||
x-data="textareaFormComponent({ initialHeight: @js($initialHeight) })"
|
||||
x-intersect.once="render()"
|
||||
x-on:input="render()"
|
||||
x-on:resize.window="render()"
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
@endif
|
||||
x-ignore
|
||||
wire:ignore.style.height
|
||||
{{
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
'autocomplete' => $getAutocomplete(),
|
||||
'autofocus' => $isAutofocused(),
|
||||
'cols' => $getCols(),
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $getId(),
|
||||
'maxlength' => (! $isConcealed) ? $getMaxLength() : null,
|
||||
'minlength' => (! $isConcealed) ? $getMinLength() : null,
|
||||
'placeholder' => $getPlaceholder(),
|
||||
'readonly' => $isReadOnly(),
|
||||
'required' => $isRequired() && (! $isConcealed),
|
||||
'rows' => $rows,
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
], escape: false)
|
||||
->class([
|
||||
'block w-full border-none bg-transparent px-3 py-1.5 text-base text-gray-950 placeholder:text-gray-400 focus:ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray.500)] disabled:placeholder:[-webkit-text-fill-color:theme(colors.gray.400)] dark:text-white dark:placeholder:text-gray-500 dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray.400)] dark:disabled:placeholder:[-webkit-text-fill-color:theme(colors.gray.500)] sm:text-sm sm:leading-6',
|
||||
'resize-none' => $shouldAutosize,
|
||||
])
|
||||
->style([
|
||||
"height: {$initialHeight}rem" => $shouldAutosize,
|
||||
])
|
||||
}}
|
||||
></textarea>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
61
vendor/filament/forms/resources/views/components/toggle-buttons/grouped.blade.php
vendored
Normal file
61
vendor/filament/forms/resources/views/components/toggle-buttons/grouped.blade.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
@php
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isMultiple = $isMultiple();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::button.group
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['w-max'])
|
||||
"
|
||||
>
|
||||
@foreach ($getOptions() as $value => $label)
|
||||
@php
|
||||
$inputId = "{$id}-{$value}";
|
||||
$shouldOptionBeDisabled = $isDisabled || $isOptionDisabled($value, $label);
|
||||
@endphp
|
||||
|
||||
<input
|
||||
@disabled($shouldOptionBeDisabled)
|
||||
id="{{ $inputId }}"
|
||||
@if (! $isMultiple)
|
||||
name="{{ $id }}"
|
||||
@endif
|
||||
type="{{ $isMultiple ? 'checkbox' : 'radio' }}"
|
||||
value="{{ $value }}"
|
||||
wire:loading.attr="disabled"
|
||||
{{ $applyStateBindingModifiers('wire:model') }}="{{ $statePath }}"
|
||||
{{ $getExtraInputAttributeBag()->class(['peer pointer-events-none absolute opacity-0']) }}
|
||||
/>
|
||||
|
||||
<x-filament::button
|
||||
:color="$getColor($value)"
|
||||
:disabled="$shouldOptionBeDisabled"
|
||||
:for="$inputId"
|
||||
grouped
|
||||
:icon="$getIcon($value)"
|
||||
tag="label"
|
||||
>
|
||||
{{ $label }}
|
||||
</x-filament::button>
|
||||
@endforeach
|
||||
</x-filament::button.group>
|
||||
</x-dynamic-component>
|
||||
80
vendor/filament/forms/resources/views/components/toggle-buttons/index.blade.php
vendored
Normal file
80
vendor/filament/forms/resources/views/components/toggle-buttons/index.blade.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
@php
|
||||
$gridDirection = $getGridDirection() ?? 'column';
|
||||
$hasInlineLabel = $hasInlineLabel();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isInline = $isInline();
|
||||
$isMultiple = $isMultiple();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:has-inline-label="$hasInlineLabel"
|
||||
>
|
||||
<x-slot
|
||||
name="label"
|
||||
@class([
|
||||
'sm:pt-1.5' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $getLabel() }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::grid
|
||||
:default="$getColumns('default')"
|
||||
:sm="$getColumns('sm')"
|
||||
:md="$getColumns('md')"
|
||||
:lg="$getColumns('lg')"
|
||||
:xl="$getColumns('xl')"
|
||||
:two-xl="$getColumns('2xl')"
|
||||
:is-grid="! $isInline"
|
||||
:direction="$gridDirection"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-radio gap-3',
|
||||
'-mt-3' => (! $isInline) && ($gridDirection === 'column'),
|
||||
'flex flex-wrap' => $isInline,
|
||||
])
|
||||
"
|
||||
>
|
||||
@foreach ($getOptions() as $value => $label)
|
||||
@php
|
||||
$inputId = "{$id}-{$value}";
|
||||
$shouldOptionBeDisabled = $isDisabled || $isOptionDisabled($value, $label);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
@class([
|
||||
'break-inside-avoid pt-3' => (! $isInline) && ($gridDirection === 'column'),
|
||||
])
|
||||
>
|
||||
<input
|
||||
@disabled($shouldOptionBeDisabled)
|
||||
id="{{ $inputId }}"
|
||||
@if (! $isMultiple)
|
||||
name="{{ $id }}"
|
||||
@endif
|
||||
type="{{ $isMultiple ? 'checkbox' : 'radio' }}"
|
||||
value="{{ $value }}"
|
||||
wire:loading.attr="disabled"
|
||||
{{ $applyStateBindingModifiers('wire:model') }}="{{ $statePath }}"
|
||||
{{ $getExtraInputAttributeBag()->class(['peer pointer-events-none absolute opacity-0']) }}
|
||||
/>
|
||||
|
||||
<x-filament::button
|
||||
:color="$getColor($value)"
|
||||
:disabled="$shouldOptionBeDisabled"
|
||||
:for="$inputId"
|
||||
:icon="$getIcon($value)"
|
||||
tag="label"
|
||||
>
|
||||
{{ $label }}
|
||||
</x-filament::button>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</x-dynamic-component>
|
||||
136
vendor/filament/forms/resources/views/components/toggle.blade.php
vendored
Normal file
136
vendor/filament/forms/resources/views/components/toggle.blade.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
@php
|
||||
$offColor = $getOffColor() ?? 'gray';
|
||||
$onColor = $getOnColor() ?? 'primary';
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
|
||||
>
|
||||
@capture($content)
|
||||
<button
|
||||
x-data="{
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
}"
|
||||
x-bind:aria-checked="state?.toString()"
|
||||
x-on:click="state = ! state"
|
||||
x-bind:class="
|
||||
state
|
||||
? '{{
|
||||
\Illuminate\Support\Arr::toCssClasses([
|
||||
match ($onColor) {
|
||||
'gray' => 'bg-gray-200 dark:bg-gray-700',
|
||||
default => 'fi-color-custom bg-custom-600',
|
||||
},
|
||||
is_string($onColor) ? "fi-color-{$onColor}" : null,
|
||||
])
|
||||
}}'
|
||||
: '{{
|
||||
\Illuminate\Support\Arr::toCssClasses([
|
||||
match ($offColor) {
|
||||
'gray' => 'bg-gray-200 dark:bg-gray-700',
|
||||
default => 'fi-color-custom bg-custom-600',
|
||||
},
|
||||
is_string($offColor) ? "fi-color-{$offColor}" : null,
|
||||
])
|
||||
}}'
|
||||
"
|
||||
x-bind:style="
|
||||
state
|
||||
? '{{
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$onColor,
|
||||
shades: [600],
|
||||
alias: 'forms::components.toggle.on',
|
||||
)
|
||||
}}'
|
||||
: '{{
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$offColor,
|
||||
shades: [600],
|
||||
alias: 'forms::components.toggle.off',
|
||||
)
|
||||
}}'
|
||||
"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'aria-checked' => 'false',
|
||||
'autofocus' => $isAutofocused(),
|
||||
'disabled' => $isDisabled(),
|
||||
'id' => $getId(),
|
||||
'role' => 'switch',
|
||||
'type' => 'button',
|
||||
'wire:loading.attr' => 'disabled',
|
||||
'wire:target' => $statePath,
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class(['fi-fo-toggle relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent outline-none transition-colors duration-200 ease-in-out disabled:pointer-events-none disabled:opacity-70'])
|
||||
}}
|
||||
>
|
||||
<span
|
||||
class="pointer-events-none relative inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"
|
||||
x-bind:class="{
|
||||
'translate-x-5 rtl:-translate-x-5': state,
|
||||
'translate-x-0': ! state,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
class="absolute inset-0 flex h-full w-full items-center justify-center transition-opacity"
|
||||
aria-hidden="true"
|
||||
x-bind:class="{
|
||||
'opacity-0 ease-out duration-100': state,
|
||||
'opacity-100 ease-in duration-200': ! state,
|
||||
}"
|
||||
>
|
||||
@if ($hasOffIcon())
|
||||
<x-filament::icon
|
||||
:icon="$getOffIcon()"
|
||||
@class([
|
||||
'fi-fo-toggle-off-icon h-3 w-3',
|
||||
match ($offColor) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-700',
|
||||
default => 'text-custom-600',
|
||||
},
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="absolute inset-0 flex h-full w-full items-center justify-center transition-opacity"
|
||||
aria-hidden="true"
|
||||
x-bind:class="{
|
||||
'opacity-100 ease-in duration-200': state,
|
||||
'opacity-0 ease-out duration-100': ! state,
|
||||
}"
|
||||
>
|
||||
@if ($hasOnIcon())
|
||||
<x-filament::icon
|
||||
:icon="$getOnIcon()"
|
||||
x-cloak="x-cloak"
|
||||
@class([
|
||||
'fi-fo-toggle-on-icon h-3 w-3',
|
||||
match ($onColor) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-700',
|
||||
default => 'text-custom-600',
|
||||
},
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
@endcapture
|
||||
|
||||
@if ($isInline())
|
||||
<x-slot name="labelPrefix">
|
||||
{{ $content() }}
|
||||
</x-slot>
|
||||
@else
|
||||
{{ $content() }}
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
291
vendor/filament/forms/resources/views/components/wizard.blade.php
vendored
Normal file
291
vendor/filament/forms/resources/views/components/wizard.blade.php
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
@php
|
||||
$isContained = $isContained();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<div
|
||||
wire:ignore.self
|
||||
x-cloak
|
||||
x-data="{
|
||||
step: null,
|
||||
|
||||
nextStep: function () {
|
||||
let nextStepIndex = this.getStepIndex(this.step) + 1
|
||||
|
||||
if (nextStepIndex >= this.getSteps().length) {
|
||||
return
|
||||
}
|
||||
|
||||
this.step = this.getSteps()[nextStepIndex]
|
||||
|
||||
this.autofocusFields()
|
||||
this.scrollToTop()
|
||||
},
|
||||
|
||||
previousStep: function () {
|
||||
let previousStepIndex = this.getStepIndex(this.step) - 1
|
||||
|
||||
if (previousStepIndex < 0) {
|
||||
return
|
||||
}
|
||||
|
||||
this.step = this.getSteps()[previousStepIndex]
|
||||
|
||||
this.autofocusFields()
|
||||
this.scrollToTop()
|
||||
},
|
||||
|
||||
scrollToTop: function () {
|
||||
this.$nextTick(() =>
|
||||
this.$root.scrollIntoView({ behavior: 'smooth', block: 'start' }),
|
||||
)
|
||||
},
|
||||
|
||||
autofocusFields: function () {
|
||||
$nextTick(() =>
|
||||
this.$refs[`step-${this.step}`]
|
||||
.querySelector('[autofocus]')
|
||||
?.focus(),
|
||||
)
|
||||
},
|
||||
|
||||
getStepIndex: function (step) {
|
||||
let index = this.getSteps().findIndex(
|
||||
(indexedStep) => indexedStep === step,
|
||||
)
|
||||
|
||||
if (index === -1) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return index
|
||||
},
|
||||
|
||||
getSteps: function () {
|
||||
return JSON.parse(this.$refs.stepsData.value)
|
||||
},
|
||||
|
||||
isFirstStep: function () {
|
||||
return this.getStepIndex(this.step) <= 0
|
||||
},
|
||||
|
||||
isLastStep: function () {
|
||||
return this.getStepIndex(this.step) + 1 >= this.getSteps().length
|
||||
},
|
||||
|
||||
isStepAccessible: function (stepId) {
|
||||
return (
|
||||
@js($isSkippable()) || this.getStepIndex(this.step) > this.getStepIndex(stepId)
|
||||
)
|
||||
},
|
||||
|
||||
updateQueryString: function () {
|
||||
if (! @js($isStepPersistedInQueryString())) {
|
||||
return
|
||||
}
|
||||
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.set(@js($getStepQueryStringKey()), this.step)
|
||||
|
||||
history.pushState(null, document.title, url.toString())
|
||||
},
|
||||
}"
|
||||
x-init="
|
||||
$watch('step', () => updateQueryString())
|
||||
|
||||
step = getSteps().at({{ $getStartStep() - 1 }})
|
||||
|
||||
autofocusFields()
|
||||
"
|
||||
x-on:next-wizard-step.window="if ($event.detail.statePath === '{{ $statePath }}') nextStep()"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-wizard',
|
||||
'fi-contained rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10' => $isContained,
|
||||
])
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
value="{{
|
||||
collect($getChildComponentContainer()->getComponents())
|
||||
->filter(static fn (\Filament\Forms\Components\Wizard\Step $step): bool => $step->isVisible())
|
||||
->map(static fn (\Filament\Forms\Components\Wizard\Step $step) => $step->getId())
|
||||
->values()
|
||||
->toJson()
|
||||
}}"
|
||||
x-ref="stepsData"
|
||||
/>
|
||||
|
||||
<ol
|
||||
@if (filled($label = $getLabel()))
|
||||
aria-label="{{ $label }}"
|
||||
@endif
|
||||
role="list"
|
||||
@class([
|
||||
'fi-fo-wizard-header grid divide-y divide-gray-200 dark:divide-white/5 md:grid-flow-col md:divide-y-0 md:overflow-x-auto',
|
||||
'border-b border-gray-200 dark:border-white/10' => $isContained,
|
||||
'rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10' => ! $isContained,
|
||||
])
|
||||
>
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $step)
|
||||
<li
|
||||
class="fi-fo-wizard-header-step relative flex"
|
||||
x-bind:class="{
|
||||
'fi-active': getStepIndex(step) === {{ $loop->index }},
|
||||
'fi-completed': getStepIndex(step) > {{ $loop->index }},
|
||||
}"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
x-bind:aria-current="getStepIndex(step) === {{ $loop->index }} ? 'step' : null"
|
||||
x-on:click="step = @js($step->getId())"
|
||||
x-bind:disabled="! isStepAccessible(@js($step->getId()))"
|
||||
role="step"
|
||||
class="fi-fo-wizard-header-step-button flex h-full items-center gap-x-4 px-6 py-4 text-start"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-wizard-header-step-icon-ctn flex h-10 w-10 shrink-0 items-center justify-center rounded-full"
|
||||
x-bind:class="{
|
||||
'bg-primary-600 dark:bg-primary-500':
|
||||
getStepIndex(step) > {{ $loop->index }},
|
||||
'border-2': getStepIndex(step) <= {{ $loop->index }},
|
||||
'border-primary-600 dark:border-primary-500':
|
||||
getStepIndex(step) === {{ $loop->index }},
|
||||
'border-gray-300 dark:border-gray-600':
|
||||
getStepIndex(step) < {{ $loop->index }},
|
||||
}"
|
||||
>
|
||||
@php
|
||||
$completedIcon = $step->getCompletedIcon();
|
||||
@endphp
|
||||
|
||||
<x-filament::icon
|
||||
:alias="filled($completedIcon) ? null : 'forms::components.wizard.completed-step'"
|
||||
:icon="$completedIcon ?? 'heroicon-o-check'"
|
||||
x-cloak="x-cloak"
|
||||
x-show="getStepIndex(step) > {{ $loop->index }}"
|
||||
class="fi-fo-wizard-header-step-icon h-6 w-6 text-white"
|
||||
/>
|
||||
|
||||
@if (filled($icon = $step->getIcon()))
|
||||
<x-filament::icon
|
||||
:icon="$icon"
|
||||
x-cloak="x-cloak"
|
||||
x-show="getStepIndex(step) <= {{ $loop->index }}"
|
||||
class="fi-fo-wizard-header-step-icon h-6 w-6"
|
||||
x-bind:class="{
|
||||
'text-gray-500 dark:text-gray-400': getStepIndex(step) !== {{ $loop->index }},
|
||||
'text-primary-600 dark:text-primary-500': getStepIndex(step) === {{ $loop->index }},
|
||||
}"
|
||||
/>
|
||||
@else
|
||||
<span
|
||||
x-show="getStepIndex(step) <= {{ $loop->index }}"
|
||||
class="fi-fo-wizard-header-step-indicator text-sm font-medium"
|
||||
x-bind:class="{
|
||||
'text-gray-500 dark:text-gray-400':
|
||||
getStepIndex(step) !== {{ $loop->index }},
|
||||
'text-primary-600 dark:text-primary-500':
|
||||
getStepIndex(step) === {{ $loop->index }},
|
||||
}"
|
||||
>
|
||||
{{ str_pad($loop->index + 1, 2, '0', STR_PAD_LEFT) }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="grid justify-items-start md:w-max md:max-w-60">
|
||||
@if (! $step->isLabelHidden())
|
||||
<span
|
||||
class="fi-fo-wizard-header-step-label text-sm font-medium"
|
||||
x-bind:class="{
|
||||
'text-gray-500 dark:text-gray-400':
|
||||
getStepIndex(step) < {{ $loop->index }},
|
||||
'text-primary-600 dark:text-primary-400':
|
||||
getStepIndex(step) === {{ $loop->index }},
|
||||
'text-gray-950 dark:text-white': getStepIndex(step) > {{ $loop->index }},
|
||||
}"
|
||||
>
|
||||
{{ $step->getLabel() }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if (filled($description = $step->getDescription()))
|
||||
<span
|
||||
class="fi-fo-wizard-header-step-description text-start text-sm text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
{{ $description }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@if (! $loop->last)
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fi-fo-wizard-header-step-separator absolute end-0 hidden h-full w-5 md:block"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
preserveAspectRatio="none"
|
||||
viewBox="0 0 22 80"
|
||||
class="h-full w-full text-gray-200 dark:text-white/5 rtl:rotate-180"
|
||||
>
|
||||
<path
|
||||
d="M0 -2L20 40L0 82"
|
||||
stroke-linejoin="round"
|
||||
stroke="currentcolor"
|
||||
vector-effect="non-scaling-stroke"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $step)
|
||||
{{ $step }}
|
||||
@endforeach
|
||||
|
||||
<div
|
||||
@class([
|
||||
'flex items-center justify-between gap-x-3',
|
||||
'px-6 pb-6' => $isContained,
|
||||
'mt-6' => ! $isContained,
|
||||
])
|
||||
>
|
||||
<span x-cloak x-on:click="previousStep" x-show="! isFirstStep()">
|
||||
{{ $getAction('previous') }}
|
||||
</span>
|
||||
|
||||
<span x-show="isFirstStep()">
|
||||
{{ $getCancelAction() }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
x-cloak
|
||||
x-on:click="
|
||||
$wire.dispatchFormEvent(
|
||||
'wizard::nextStep',
|
||||
'{{ $statePath }}',
|
||||
getStepIndex(step),
|
||||
)
|
||||
"
|
||||
x-show="! isLastStep()"
|
||||
>
|
||||
{{ $getAction('next') }}
|
||||
</span>
|
||||
|
||||
<span x-show="isLastStep()">
|
||||
{{ $getSubmitAction() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
40
vendor/filament/forms/resources/views/components/wizard/step.blade.php
vendored
Normal file
40
vendor/filament/forms/resources/views/components/wizard/step.blade.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
@php
|
||||
$id = $getId();
|
||||
$isContained = $getContainer()->getParentComponent()->isContained();
|
||||
|
||||
$activeStepClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-active',
|
||||
'p-6' => $isContained,
|
||||
'mt-6' => ! $isContained,
|
||||
]);
|
||||
|
||||
$inactiveStepClasses = 'invisible absolute h-0 overflow-hidden p-0';
|
||||
@endphp
|
||||
|
||||
<div
|
||||
x-bind:class="{
|
||||
@js($activeStepClasses): step === @js($id),
|
||||
@js($inactiveStepClasses): step !== @js($id),
|
||||
}"
|
||||
x-on:expand="
|
||||
if (! isStepAccessible(@js($id))) {
|
||||
return
|
||||
}
|
||||
|
||||
step = @js($id)
|
||||
"
|
||||
x-ref="step-{{ $id }}"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'aria-labelledby' => $id,
|
||||
'id' => $id,
|
||||
'role' => 'tabpanel',
|
||||
'tabindex' => '0',
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-wizard-step outline-none'])
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
Reference in New Issue
Block a user