🎨 Add new Flux icons: implement multiple reusable icon components (e.g., hand-raised, hand-thumb-up, heart, hashtag, home) with variant support for improved UI consistency.

This commit is contained in:
HolgerHatGarKeineNode
2026-01-23 23:00:02 +01:00
parent 578e4f13fc
commit b30fec150c
792 changed files with 307541 additions and 117 deletions

View File

@@ -0,0 +1,5 @@
@blaze
<ui-menu-checkbox-group {{ $attributes }} data-flux-menu-checkbox-group>
{{ $slot }}
</ui-menu-checkbox-group>

View File

@@ -0,0 +1,62 @@
@blaze
@php $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
@php $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
@props([
'iconVariant' => 'mini',
'iconTrailing' => null,
'variant' => 'default',
'indent' => false,
'suffix' => null,
'label' => null,
'kbd' => null,
])
@php
if ($kbd) $suffix = $kbd;
$iconClasses = Flux::classes()
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$iconTrailingClasses = Flux::classes()
->add('ms-auto')
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$classes = Flux::classes()
->add('group/menu-checkbox flex items-center px-2 py-1.5 w-full focus:outline-hidden')
->add('rounded-md')
->add('text-start text-sm font-medium')
->add('[[disabled]_&]:opacity-50 [&[disabled]]:opacity-50')
->add([
'text-zinc-800 data-active:bg-zinc-50 dark:text-white dark:data-active:bg-zinc-600',
'**:data-flux-menu-item-icon:text-zinc-400 dark:**:data-flux-menu-item-icon:text-white/60 [&[data-active]_[data-flux-menu-item-icon]]:text-current',
])
;
@endphp
<ui-menu-checkbox {{ $attributes->class($classes) }} data-flux-menu-item-has-icon data-flux-menu-checkbox>
<div class="w-7">
<div class="hidden group-data-checked/menu-checkbox:block">
<flux:icon :variant="$iconVariant" icon="check" :class="$iconClasses" data-flux-menu-item-icon />
</div>
</div>
{{ $label ?? $slot }}
<?php if ($suffix): ?>
<div class="ms-auto opacity-50 text-xs">
{{ $suffix }}
</div>
<?php endif; ?>
<?php if (is_string($iconTrailing) && $iconTrailing !== ''): ?>
<flux:icon :icon="$iconTrailing" :variant="$iconVariant" :class="$iconTrailingClasses" data-flux-menu-item-icon />
<?php elseif ($iconTrailing): ?>
{{ $iconTrailing }}
<?php endif; ?>
</ui-menu-checkbox>

View File

@@ -0,0 +1,24 @@
@blaze
@props([
'heading' => null,
])
@php
$classes = Flux::classes()
->add('-mx-[.3125rem] px-[.3125rem]')
->add('[&+&>[data-flux-menu-separator-top]]:hidden [&:first-child>[data-flux-menu-separator-top]]:hidden [&:last-child>[data-flux-menu-separator-bottom]]:hidden')
;
@endphp
<div {{ $attributes->class($classes) }} role="group" data-flux-menu-group>
<flux:menu.separator data-flux-menu-separator-top />
<?php if ($heading): ?>
<flux:menu.heading>{{ $heading }}</flux:menu.heading>
<?php endif; ?>
{{ $slot }}
<flux:menu.separator data-flux-menu-separator-bottom />
</div>

View File

@@ -0,0 +1,16 @@
@blaze
@php
$classes = Flux::classes([
'p-2 pb-1 w-full',
'flex items-center',
'text-start text-xs font-medium',
'text-zinc-500 font-medium dark:text-zinc-300',
]);
@endphp
<div {{ $attributes->class($classes) }} data-flux-menu-heading>
<div class="w-7 hidden [[data-flux-menu]:has(>[data-flux-menu-item-has-icon])_&]:block"></div>
<div>{{ $slot }}</div>
</div>

View File

@@ -0,0 +1,19 @@
@blaze
@php
$classes = Flux::classes()
->add('[:where(&)]:min-w-48 p-[.3125rem]')
->add('rounded-lg shadow-lg')
->add('border border-border-default')
->add('bg-bg-elevated')
->add('focus:outline-hidden')
;
@endphp
<ui-menu
{{ $attributes->class($classes) }}
popover="manual"
data-flux-menu
>
{{ $slot }}
</ui-menu>

View File

@@ -0,0 +1,81 @@
@blaze
@php $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
@php $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
@props([
'iconTrailing' => null,
'iconVariant' => 'mini',
'variant' => 'default',
'suffix' => null,
'value' => null,
'icon' => null,
'kbd' => null,
])
@php
if ($kbd) $suffix = $kbd;
$iconClasses = Flux::classes()
->add('me-2')
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$trailingIconClasses = Flux::classes()
->add('ms-auto text-text-tertiary [[data-flux-menu-item-icon]:hover_&]:text-current')
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$classes = Flux::classes()
->add('flex items-center px-2 py-1.5 w-full focus:outline-hidden')
->add('rounded-md')
->add('text-start text-sm font-medium')
->add('[&[disabled]]:opacity-50')
->add(match ($variant) {
'danger' => [
'text-text-primary data-active:text-red-400 data-active:bg-red-400/20',
'**:data-flux-menu-item-icon:text-text-tertiary [&[data-active]_[data-flux-menu-item-icon]]:text-current',
],
'default' => [
'text-text-primary data-active:bg-bg-surface',
'**:data-flux-menu-item-icon:text-text-tertiary [&[data-active]_[data-flux-menu-item-icon]]:text-current',
]
})
;
$suffixClasses = Flux::classes()
->add('ms-auto text-xs text-text-tertiary')
;
@endphp
<flux:button-or-link-pure :attributes="$attributes->class($classes)" data-flux-menu-item :data-flux-menu-item-has-icon="!! $icon">
<?php if (is_string($icon) && $icon !== ''): ?>
<flux:icon :$icon :variant="$iconVariant" :class="$iconClasses" data-flux-menu-item-icon />
<?php elseif ($icon): ?>
{{ $icon }}
<?php else: ?>
<div class="w-7 hidden [[data-flux-menu]:has(>[data-flux-menu-item-has-icon])_&]:block"></div>
<?php endif; ?>
{{ $slot }}
<?php if ($suffix): ?>
<?php if (is_string($suffix)): ?>
<div class="{{ $suffixClasses }}">
{{ $suffix }}
</div>
<?php else: ?>
{{ $suffix }}
<?php endif; ?>
<?php endif; ?>
<?php if (is_string($iconTrailing) && $iconTrailing !== ''): ?>
<flux:icon :icon="$iconTrailing" :variant="$iconVariant" :class="$trailingIconClasses" data-flux-menu-item-icon />
<?php elseif ($iconTrailing): ?>
{{ $iconTrailing }}
<?php endif; ?>
{{ $submenu ?? '' }}
</flux:button-or-link-pure>

View File

@@ -0,0 +1,5 @@
@blaze
<ui-menu-radio-group {{ $attributes }} data-flux-menu-radio-group>
{{ $slot }}
</ui-menu-radio-group>

View File

@@ -0,0 +1,62 @@
@blaze
@php $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
@php $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
@props([
'iconVariant' => 'mini',
'iconTrailing' => null,
'variant' => 'default',
'indent' => false,
'suffix' => null,
'label' => null,
'kbd' => null,
])
@php
if ($kbd) $suffix = $kbd;
$iconClasses = Flux::classes()
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$iconTrailingClasses = Flux::classes()
->add('ms-auto')
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : null)
;
$classes = Flux::classes()
->add('group/menu-radio flex items-center px-2 py-1.5 w-full focus:outline-hidden')
->add('rounded-md')
->add('text-start text-sm font-medium')
->add('[[disabled]_&]:opacity-50 [&[disabled]]:opacity-50')
->add([
'text-zinc-800 data-active:bg-zinc-50 dark:text-white dark:data-active:bg-zinc-600',
'**:data-flux-menu-item-icon:text-zinc-400 dark:**:data-flux-menu-item-icon:text-white/60 [&[data-active]_[data-flux-menu-item-icon]]:text-current',
])
;
@endphp
<ui-menu-radio {{ $attributes->class($classes) }} data-flux-menu-item-has-icon data-flux-menu-radio>
<div class="w-7">
<div class="hidden group-data-checked/menu-radio:block">
<flux:icon :variant="$iconVariant" icon="check" :class="$iconClasses" data-flux-menu-item-icon />
</div>
</div>
{{ $label ?? $slot }}
<?php if ($suffix): ?>
<div class="ms-auto opacity-50 text-xs">
{{ $suffix }}
</div>
<?php endif; ?>
<?php if (is_string($iconTrailing) && $iconTrailing !== ''): ?>
<flux:icon :icon="$iconTrailing" :variant="$iconVariant" :class="$iconTrailingClasses" data-flux-menu-item-icon />
<?php elseif ($iconTrailing): ?>
{{ $iconTrailing }}
<?php endif; ?>
</ui-menu-radio>

View File

@@ -0,0 +1,5 @@
@blaze
<div class="-mx-[.3125rem] my-[.3125rem] h-px" {{ $attributes }} data-flux-menu-separator>
<flux:separator class="dark:bg-zinc-600!" />
</div>

View File

@@ -0,0 +1,40 @@
@blaze
@php $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
@php $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
@props([
'iconVariant' => 'mini',
'iconTrailing' => null,
'heading' => '',
'icon' => null,
'keepOpen' => false,
])
@php
$iconClasses = Flux::classes()
->add('ms-auto text-zinc-400 [[data-flux-menu-item]:hover_&]:text-current')
// When using the outline icon variant, we need to size it down to match the default icon sizes...
->add($iconVariant === 'outline' ? 'size-5' : '');
@endphp
<ui-submenu data-flux-menu-submenu>
<flux:menu.item :$icon :$iconVariant>
{{ $heading }}
<x-slot:suffix>
<?php if (is_string($iconTrailing) && $iconTrailing !== ''): ?>
<flux:icon :icon="$iconTrailing" :variant="$iconVariant" :class="$iconClasses" />
<?php elseif ($iconTrailing): ?>
{{ $iconTrailing }}
<?php else: ?>
<flux:icon icon="chevron-right" :variant="$iconVariant" :class="$iconClasses->add('rtl:hidden')" />
<flux:icon icon="chevron-left" :variant="$iconVariant" :class="$iconClasses->add('hidden rtl:inline')" />
<?php endif; ?>
</x-slot:suffix>
</flux:menu.item>
<flux:menu :keep-open="$keepOpen">
{{ $slot }}
</flux:menu>
</ui-submenu>