Skip to content

Commit a2f6157

Browse files
authored
Optimize large form rendering (#19550)
* Optimize large form rendering * fixes * fix * fix * fixes * fixes * fixes * fixes * fixes * Update ViewComponent.php * Update ViewComponent.php * Update ViewComponentTest.php * cleanup * Update Builder.php * Update ModalTableSelect.php * Update Builder.php * cleanup * rename * Update FileUpload.php * fixes * Update Slider.php * fixes * fixes * fixes --------- Signed-off-by: Dan Harrin <git@danharrin.com>
1 parent 246674e commit a2f6157

98 files changed

Lines changed: 6589 additions & 4822 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/forms/resources/views/components/builder.blade.php

Lines changed: 1 addition & 328 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,151 +1 @@
1-
@php
2-
use Filament\Support\Enums\GridDirection;
3-
4-
$fieldWrapperView = $getFieldWrapperView();
5-
$extraInputAttributeBag = $getExtraInputAttributeBag();
6-
$isHtmlAllowed = $isHtmlAllowed();
7-
$gridDirection = $getGridDirection() ?? GridDirection::Column;
8-
$isBulkToggleable = $isBulkToggleable();
9-
$isDisabled = $isDisabled();
10-
$isSearchable = $isSearchable();
11-
$statePath = $getStatePath();
12-
$options = $getOptions();
13-
$livewireKey = $getLivewireKey();
14-
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
15-
@endphp
16-
17-
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
18-
<div
19-
x-load
20-
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('checkbox-list', 'filament/forms') }}"
21-
x-data="checkboxListFormComponent({
22-
livewireId: @js($this->getId()),
23-
})"
24-
{{ $getExtraAlpineAttributeBag()->class(['fi-fo-checkbox-list']) }}
25-
>
26-
@if (! $isDisabled)
27-
@if ($isSearchable)
28-
<x-filament::input.wrapper
29-
inline-prefix
30-
:prefix-icon="\Filament\Support\Icons\Heroicon::MagnifyingGlass"
31-
:prefix-icon-alias="\Filament\Forms\View\FormsIconAlias::COMPONENTS_CHECKBOX_LIST_SEARCH_FIELD"
32-
class="fi-fo-checkbox-list-search-input-wrp"
33-
>
34-
<input
35-
placeholder="{{ $getSearchPrompt() }}"
36-
type="search"
37-
x-model.debounce.{{ $getSearchDebounce() }}="search"
38-
class="fi-input fi-input-has-inline-prefix"
39-
/>
40-
</x-filament::input.wrapper>
41-
@endif
42-
43-
@if ($isBulkToggleable && count($options))
44-
<div
45-
x-cloak
46-
class="fi-fo-checkbox-list-actions"
47-
wire:key="{{ $livewireKey }}.actions"
48-
>
49-
<span
50-
x-show="! areAllCheckboxesChecked"
51-
x-on:click="toggleAllCheckboxes()"
52-
wire:key="{{ $livewireKey }}.actions.select-all"
53-
>
54-
{{ $getAction('selectAll') }}
55-
</span>
56-
57-
<span
58-
x-show="areAllCheckboxesChecked"
59-
x-on:click="toggleAllCheckboxes()"
60-
wire:key="{{ $livewireKey }}.actions.deselect-all"
61-
>
62-
{{ $getAction('deselectAll') }}
63-
</span>
64-
</div>
65-
@endif
66-
@endif
67-
68-
<div
69-
{{
70-
$getExtraAttributeBag()
71-
->grid($getColumns(), $gridDirection)
72-
->merge([
73-
'x-show' => $isSearchable ? 'visibleCheckboxListOptions.length' : null,
74-
], escape: false)
75-
->class([
76-
'fi-fo-checkbox-list-options',
77-
])
78-
}}
79-
>
80-
@forelse ($options as $value => $label)
81-
<div
82-
wire:key="{{ $livewireKey }}.options.{{ $value }}"
83-
@if ($isSearchable)
84-
x-show="
85-
$el
86-
.querySelector('.fi-fo-checkbox-list-option-label')
87-
?.innerText.toLowerCase()
88-
.includes(search.toLowerCase()) ||
89-
$el
90-
.querySelector('.fi-fo-checkbox-list-option-description')
91-
?.innerText.toLowerCase()
92-
.includes(search.toLowerCase())
93-
"
94-
@endif
95-
class="fi-fo-checkbox-list-option-ctn"
96-
>
97-
<label class="fi-fo-checkbox-list-option">
98-
<input
99-
type="checkbox"
100-
{{
101-
$extraInputAttributeBag
102-
->merge([
103-
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
104-
'value' => $value,
105-
'wire:loading.attr' => 'disabled',
106-
$wireModelAttribute => $statePath,
107-
'x-on:change' => $isBulkToggleable ? 'checkIfAllCheckboxesAreChecked()' : null,
108-
], escape: false)
109-
->class([
110-
'fi-checkbox-input',
111-
'fi-valid' => ! $errors->has($statePath),
112-
'fi-invalid' => $errors->has($statePath),
113-
])
114-
}}
115-
/>
116-
117-
<div class="fi-fo-checkbox-list-option-text">
118-
<span class="fi-fo-checkbox-list-option-label">
119-
@if ($isHtmlAllowed)
120-
{!! $label !!}
121-
@else
122-
{{ $label }}
123-
@endif
124-
</span>
125-
126-
@if ($hasDescription($value))
127-
<p
128-
class="fi-fo-checkbox-list-option-description"
129-
>
130-
{{ $getDescription($value) }}
131-
</p>
132-
@endif
133-
</div>
134-
</label>
135-
</div>
136-
@empty
137-
<div wire:key="{{ $livewireKey }}.empty"></div>
138-
@endforelse
139-
</div>
140-
141-
@if ($isSearchable)
142-
<div
143-
x-cloak
144-
x-show="search && ! visibleCheckboxListOptions.length"
145-
class="fi-fo-checkbox-list-no-search-results-message"
146-
>
147-
{{ $getNoSearchResultsMessage() }}
148-
</div>
149-
@endif
150-
</div>
151-
</x-dynamic-component>
1+
{!! $field->toEmbeddedHtml() !!}
Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1 @@
1-
@php
2-
$fieldWrapperView = $getFieldWrapperView();
3-
$statePath = $getStatePath();
4-
$attributes = $attributes
5-
->merge([
6-
'autofocus' => $isAutofocused(),
7-
'disabled' => $isDisabled(),
8-
'id' => $getId(),
9-
'required' => $isRequired() && (! $isConcealed()),
10-
'wire:loading.attr' => 'disabled',
11-
$applyStateBindingModifiers('wire:model') => $statePath,
12-
], escape: false)
13-
->merge($getExtraAttributes(), escape: false)
14-
->merge($getExtraInputAttributes(), escape: false)
15-
->class([
16-
'fi-checkbox-input',
17-
'fi-valid' => ! $errors->has($statePath),
18-
'fi-invalid' => $errors->has($statePath),
19-
]);
20-
@endphp
21-
22-
<x-dynamic-component
23-
:component="$fieldWrapperView"
24-
:field="$field"
25-
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
26-
>
27-
@if ($isInline())
28-
<x-slot name="labelPrefix">
29-
<input type="checkbox" {{ $attributes }} />
30-
</x-slot>
31-
@else
32-
<input type="checkbox" {{ $attributes }} />
33-
@endif
34-
</x-dynamic-component>
1+
{!! $field->toEmbeddedHtml() !!}
Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1 @@
1-
@php
2-
$fieldWrapperView = $getFieldWrapperView();
3-
$extraAttributeBag = $getExtraAttributeBag();
4-
$isDisabled = $isDisabled();
5-
$isLive = $isLive();
6-
$isLiveOnBlur = $isLiveOnBlur();
7-
$isLiveDebounced = $isLiveDebounced();
8-
$liveDebounce = $getLiveDebounce();
9-
$key = $getKey();
10-
$language = $getLanguage();
11-
$statePath = $getStatePath();
12-
$livewireKey = $getLivewireKey();
13-
@endphp
14-
15-
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
16-
<x-filament::input.wrapper
17-
:disabled="$isDisabled"
18-
:valid="! $errors->has($statePath)"
19-
:attributes="
20-
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
21-
->class(['fi-fo-code-editor'])
22-
"
23-
>
24-
<div
25-
x-load
26-
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('code-editor', 'filament/forms') }}"
27-
x-data="codeEditorFormComponent({
28-
canWrap: @js($canWrap()),
29-
isDisabled: @js($isDisabled),
30-
isLive: @js($isLive),
31-
isLiveDebounced: @js($isLiveDebounced),
32-
isLiveOnBlur: @js($isLiveOnBlur),
33-
liveDebounce: @js($liveDebounce),
34-
language: @js($language?->value),
35-
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')", isOptimisticallyLive: false) }},
36-
})"
37-
wire:ignore
38-
wire:key="{{ $livewireKey }}.{{
39-
substr(md5(serialize([
40-
$isDisabled,
41-
$language?->value,
42-
])), 0, 64)
43-
}}"
44-
{{ $getExtraAlpineAttributeBag() }}
45-
>
46-
<div x-ref="editor" x-cloak></div>
47-
</div>
48-
</x-filament::input.wrapper>
49-
</x-dynamic-component>
1+
{!! $field->toEmbeddedHtml() !!}
Lines changed: 1 addition & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1 @@
1-
@php
2-
$fieldWrapperView = $getFieldWrapperView();
3-
$extraAttributeBag = $getExtraAttributeBag();
4-
$isDisabled = $isDisabled();
5-
$isLive = $isLive();
6-
$isLiveOnBlur = $isLiveOnBlur();
7-
$isLiveDebounced = $isLiveDebounced();
8-
$isPrefixInline = $isPrefixInline();
9-
$isSuffixInline = $isSuffixInline();
10-
$liveDebounce = $getLiveDebounce();
11-
$prefixActions = $getPrefixActions();
12-
$prefixIcon = $getPrefixIcon();
13-
$prefixIconColor = $getPrefixIconColor();
14-
$prefixLabel = $getPrefixLabel();
15-
$suffixActions = $getSuffixActions();
16-
$suffixIcon = $getSuffixIcon();
17-
$suffixIconColor = $getSuffixIconColor();
18-
$suffixLabel = $getSuffixLabel();
19-
$statePath = $getStatePath();
20-
$placeholder = $getPlaceholder();
21-
@endphp
22-
23-
<x-dynamic-component
24-
:component="$fieldWrapperView"
25-
:field="$field"
26-
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
27-
>
28-
<x-filament::input.wrapper
29-
:disabled="$isDisabled"
30-
:inline-prefix="$isPrefixInline"
31-
:inline-suffix="$isSuffixInline"
32-
:prefix="$prefixLabel"
33-
:prefix-actions="$prefixActions"
34-
:prefix-icon="$prefixIcon"
35-
:prefix-icon-color="$prefixIconColor"
36-
:suffix="$suffixLabel"
37-
:suffix-actions="$suffixActions"
38-
:suffix-icon="$suffixIcon"
39-
:suffix-icon-color="$suffixIconColor"
40-
:valid="! $errors->has($statePath)"
41-
x-on:focus-input.stop="$el.querySelector('input')?.focus()"
42-
:attributes="
43-
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
44-
->class('fi-fo-color-picker')
45-
"
46-
>
47-
<div
48-
x-load
49-
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('color-picker', 'filament/forms') }}"
50-
x-data="colorPickerFormComponent({
51-
isAutofocused: @js($isAutofocused()),
52-
isDisabled: @js($isDisabled),
53-
isLive: @js($isLive),
54-
isLiveDebounced: @js($isLiveDebounced),
55-
isLiveOnBlur: @js($isLiveOnBlur),
56-
liveDebounce: @js($liveDebounce),
57-
state: $wire.$entangle('{{ $statePath }}'),
58-
})"
59-
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
60-
x-on:focusout="if (isOpen() && ! $el.contains($event.relatedTarget)) $refs.panel.close()"
61-
{{ $getExtraAlpineAttributeBag()->class(['fi-input-wrp-content']) }}
62-
>
63-
<input
64-
x-on:focus="$refs.panel.open($refs.input)"
65-
x-on:keydown.enter.prevent.stop="togglePanelVisibility()"
66-
x-ref="input"
67-
{{
68-
$getExtraInputAttributeBag()
69-
->merge([
70-
'autocomplete' => 'off',
71-
'disabled' => $isDisabled,
72-
'id' => $getId(),
73-
'placeholder' => filled($placeholder) ? e($placeholder) : null,
74-
'required' => $isRequired() && (! $isConcealed()),
75-
'type' => 'text',
76-
'x-model' . ($isLiveDebounced ? '.debounce.' . $liveDebounce : null) => 'state',
77-
'x-on:blur' => $isLiveOnBlur ? 'isOpen() ? null : commitState()' : null,
78-
], escape: false)
79-
->class([
80-
'fi-input',
81-
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
82-
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
83-
])
84-
}}
85-
/>
86-
87-
<div
88-
class="fi-fo-color-picker-preview my-auto me-3 size-5 shrink-0 rounded-full select-none"
89-
x-on:click="togglePanelVisibility()"
90-
x-bind:class="{
91-
'fi-empty': ! state,
92-
}"
93-
x-bind:style="{ 'background-color': state }"
94-
></div>
95-
96-
<div
97-
wire:ignore.self
98-
wire:key="{{ $getLivewireKey() }}.panel"
99-
x-cloak
100-
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
101-
x-ref="panel"
102-
class="fi-fo-color-picker-panel"
103-
>
104-
@php
105-
$tag = match ($getFormat()) {
106-
'hsl' => 'hsl-string',
107-
'rgb' => 'rgb-string',
108-
'rgba' => 'rgba-string',
109-
default => 'hex',
110-
} . '-color-picker';
111-
@endphp
112-
113-
<{{ $tag }} x-ref="picker" color="{{ $getState() }}" />
114-
</div>
115-
</div>
116-
</x-filament::input.wrapper>
117-
</x-dynamic-component>
1+
{!! $field->toEmbeddedHtml() !!}

0 commit comments

Comments
 (0)