icon-button.blade.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. @php
  2. use Filament\Support\Enums\IconSize;
  3. use Filament\Support\Enums\Size;
  4. use Filament\Support\View\Components\BadgeComponent;
  5. use Filament\Support\View\Components\IconButtonComponent;
  6. use Illuminate\View\ComponentAttributeBag;
  7. @endphp
  8. @props([
  9. 'badge' => null,
  10. 'badgeColor' => 'primary',
  11. 'badgeSize' => Size::ExtraSmall,
  12. 'color' => 'primary',
  13. 'disabled' => false,
  14. 'form' => null,
  15. 'formId' => null,
  16. 'href' => null,
  17. 'icon' => null,
  18. 'iconAlias' => null,
  19. 'iconSize' => null,
  20. 'keyBindings' => null,
  21. 'label' => null,
  22. 'loadingIndicator' => true,
  23. 'size' => Size::Medium,
  24. 'spaMode' => null,
  25. 'tag' => 'button',
  26. 'target' => null,
  27. 'tooltip' => null,
  28. 'type' => 'button',
  29. ])
  30. @php
  31. if (! $size instanceof Size) {
  32. $size = filled($size) ? (Size::tryFrom($size) ?? $size) : null;
  33. }
  34. if (! $badgeSize instanceof Size) {
  35. $badgeSize = filled($badgeSize) ? (Size::tryFrom($badgeSize) ?? $badgeSize) : null;
  36. }
  37. if (filled($iconSize) && (! $iconSize instanceof IconSize)) {
  38. $iconSize = IconSize::tryFrom($iconSize) ?? $iconSize;
  39. }
  40. $iconSize ??= match ($size) {
  41. Size::ExtraSmall => IconSize::Small,
  42. Size::Large, Size::ExtraLarge => IconSize::Large,
  43. default => null,
  44. };
  45. $wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
  46. $hasLoadingIndicator = filled($wireTarget) || ($type === 'submit' && filled($form));
  47. if ($hasLoadingIndicator) {
  48. $loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
  49. }
  50. $hasTooltip = $hasTooltip = filled($tooltip);
  51. @endphp
  52. <{{ $tag }}
  53. @if (($tag === 'a') && (! ($disabled && $hasTooltip)))
  54. {{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
  55. @endif
  56. @if ($keyBindings)
  57. x-bind:id="$id('key-bindings')"
  58. x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id)?.click()"
  59. @endif
  60. @if ($hasTooltip)
  61. x-tooltip="{
  62. content: @js($tooltip),
  63. theme: $store.theme,
  64. allowHTML: @js($tooltip instanceof \Illuminate\Contracts\Support\Htmlable),
  65. }"
  66. @endif
  67. {{
  68. $attributes
  69. ->merge([
  70. 'aria-disabled' => $disabled ? 'true' : null,
  71. 'aria-label' => $label,
  72. 'disabled' => $disabled && blank($tooltip),
  73. 'form' => $formId,
  74. 'type' => $tag === 'button' ? $type : null,
  75. 'wire:loading.attr' => $tag === 'button' ? 'disabled' : null,
  76. 'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
  77. ], escape: false)
  78. ->merge([
  79. 'title' => $hasTooltip ? null : $label,
  80. ], escape: true)
  81. ->when(
  82. $disabled && $hasTooltip,
  83. fn (ComponentAttributeBag $attributes) => $attributes->filter(
  84. fn (mixed $value, string $key): bool => ! str($key)->startsWith(['href', 'x-on:', 'wire:click']),
  85. ),
  86. )
  87. ->class([
  88. 'fi-icon-btn',
  89. 'fi-disabled' => $disabled,
  90. ($size instanceof Size) ? "fi-size-{$size->value}" : (is_string($size) ? $size : ''),
  91. ])
  92. ->color(IconButtonComponent::class, $color)
  93. }}
  94. >
  95. {{
  96. \Filament\Support\generate_icon_html($icon, $iconAlias, (new \Illuminate\View\ComponentAttributeBag([
  97. 'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
  98. 'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : false,
  99. ])), size: $iconSize)
  100. }}
  101. @if ($hasLoadingIndicator)
  102. {{
  103. \Filament\Support\generate_loading_indicator_html((new \Illuminate\View\ComponentAttributeBag([
  104. 'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
  105. 'wire:target' => $loadingIndicatorTarget,
  106. ])), size: $iconSize)
  107. }}
  108. @endif
  109. @if (filled($badge))
  110. <div class="fi-icon-btn-badge-ctn">
  111. @if ($badge instanceof \Illuminate\View\ComponentSlot)
  112. {{ $badge }}
  113. @else
  114. <span
  115. {{
  116. (new ComponentAttributeBag)->color(BadgeComponent::class, $badgeColor)->class([
  117. 'fi-badge',
  118. ($badgeSize instanceof Size) ? "fi-size-{$badgeSize->value}" : (is_string($badgeSize) ? $badgeSize : ''),
  119. ])
  120. }}
  121. >
  122. {{ $badge }}
  123. </span>
  124. @endif
  125. </div>
  126. @endif
  127. </{{ $tag }}>