🎨 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,58 @@
@aware([ 'placeholder' ])
@props([
'placeholder' => null,
'clearable' => null,
'invalid' => false,
'suffix' => null,
'size' => null,
'max' => 1,
])
@php
// Clearable is not supported on xs size...
if ($size === 'xs') $clearable = null;
$classes = Flux::classes()
->add('group/select-button cursor-default py-2')
->add('overflow-hidden') // Overflow hidden is here to prevent the button from growing when selected text is too long.
->add('flex items-center')
->add('shadow-xs')
->add('bg-white dark:bg-white/10 dark:disabled:bg-white/[7%]')
// Make the placeholder match the text color of standard input placeholders...
->add('disabled:shadow-none')
->add(match ($size) {
default => 'h-10 text-base sm:text-sm rounded-lg px-3 block w-full',
'sm' => 'h-8 text-sm rounded-lg ps-3 pe-2 block w-full',
'xs' => 'h-6 text-xs rounded-lg ps-3 pe-2 block w-full',
})
->add($invalid
? 'border border-red-500'
: 'border border-zinc-200 border-b-zinc-300/80 dark:border-white/10'
)
;
@endphp
<button type="button" {{ $attributes->class($classes) }} @if ($invalid) data-invalid @endif data-flux-group-target data-flux-select-button>
<?php if ($slot->isNotEmpty()): ?>
{{ $slot }}
<?php else: ?>
<flux:select.selected :$placeholder :$max :$suffix />
<?php endif; ?>
<?php if ($clearable): ?>
<flux:button as="div"
class="cursor-pointer ms-2 -me-2 [[data-flux-select-button]:has([data-flux-select-placeholder])_&]:hidden [[data-flux-select][disabled]:has([data-selected])_&]:hidden"
variant="subtle"
:size="$size === 'sm' ? 'xs' : 'sm'"
square
tabindex="-1"
aria-label="Clear selected"
x-on:click.prevent.stop="let select = $el.closest('ui-select'); select.value = select.hasAttribute('multiple') ? [] : null; select.dispatchEvent(new Event('change', { bubbles: false })); select.dispatchEvent(new Event('input', { bubbles: false }))"
>
<flux:icon.x-mark variant="micro" />
</flux:button>
<?php endif; ?>
<flux:icon.chevron-down variant="mini" class="ms-2 -me-1 text-zinc-400/75 [[data-flux-select-button]:hover_&]:text-zinc-800 [[disabled]_&]:text-zinc-200! dark:text-white/60 dark:[[data-flux-select-button]:hover_&]:text-white dark:[[disabled]_&]:text-white/40!" />
</button>

View File

@@ -0,0 +1,4 @@
{{-- This file exists for backwards compatibility... --}}
<x-select.option.empty {{ $attributes }}>
{{ $slot }}
</x-select.option.empty>

View File

@@ -0,0 +1,7 @@
@props([
'variant' => 'default',
])
<flux:with-field :$attributes>
<flux:delegate-component :component="'select.variants.' . $variant">{{ $slot }}</flux:delegate-component>
</flux:with-field>

View File

@@ -0,0 +1,14 @@
@aware([ 'variant' ])
@props([
'variant' => 'check',
])
@php
// This prevents variants picked up by `@aware()` from other wrapping components like flux::modal from being used here...
$variant = $variant !== 'check' && Flux::componentExists('select.indicator.variants.' . $variant)
? $variant
: 'check';
@endphp
<flux:delegate-component :component="'select.indicator.variants.' . $variant">{{ $slot }}</flux:delegate-component>

View File

@@ -0,0 +1,3 @@
@blaze
<flux:icon variant="mini" icon="check" class="hidden [ui-option[data-selected]_&]:block" />

View File

@@ -0,0 +1,28 @@
@blaze
@php
$classes = Flux::classes()
->add('shrink-0 size-[1.125rem] rounded-[.3rem] flex justify-center items-center')
->add('text-sm text-zinc-700 dark:text-zinc-800')
->add('[ui-option[disabled]_&]:opacity-75 [ui-option[data-selected][disabled]_&]:opacity-50 ')
->add('[ui-option[data-selected]_&>svg:first-child]:block')
->add([
'border',
'border-zinc-300 dark:border-white/10',
'[ui-option[disabled]_&]:border-zinc-200 dark:[ui-option[disabled]_&]:border-white/5',
'[ui-option[data-selected]_&]:border-transparent',
'[ui-option[disabled][data-selected]_&]::border-transparent',
])
->add([
'bg-white dark:bg-white/10',
'[ui-option[data-selected]_&]:bg-[var(--color-accent)]',
'hover:[ui-option[data-selected]_&]:bg-(--color-accent)',
'focus:[ui-option[data-selected]_&]:bg-(--color-accent)',
])
;
@endphp
<div {{ $attributes->class($classes) }}>
<flux:icon.check variant="micro" class="hidden text-[var(--color-accent-foreground)]" />
<flux:icon.minus variant="micro" class="hidden text-[var(--color-accent-foreground)]" />
</div>

View File

@@ -0,0 +1,27 @@
@blaze
@php
$classes = Flux::classes()
->add('shrink-0 size-[1.125rem] rounded-full')
->add('text-sm text-zinc-700 dark:text-zinc-800')
->add('[ui-option[disabled]_&]:opacity-75 [ui-option[data-selected][disabled]_&]:opacity-50')
->add('flex justify-center items-center [ui-option[data-selected]_&>div]:block')
->add([
'border',
'border-zinc-300 dark:border-white/10',
'[ui-option[disabled]_&]:border-zinc-200 dark:[ui-option[disabled]_&]:border-white/5',
'[ui-option[data-selected]_&]:border-transparent data-indeterminate:border-transparent',
'[ui-option[data-selected]_&]:[ui-option[disabled]_&]:border-transparent data-indeterminate:border-transparent',
])
->add([
'bg-white dark:bg-white/10',
'[ui-option[data-selected]_&]:bg-[var(--color-accent)]',
'hover:[ui-option[data-selected]_&]:bg-(--color-accent)',
'focus:[ui-option[data-selected]_&]:bg-(--color-accent)',
])
;
@endphp
<div {{ $attributes->class($classes) }}>
<div class="hidden size-2 rounded-full bg-[var(--color-accent-foreground)]"></div>
</div>

View File

@@ -0,0 +1,43 @@
@aware([ 'placeholder' ])
@props([
'placeholder' => null,
'clearable' => null,
'invalid' => null,
'size' => null,
])
@php
$classes = Flux::classes()
->add('data-invalid:text-red-500 dark:data-invalid:text-red-400')
// We don't want to show the red border when invalid, so we need to apply all the default border styles with data-invalid: and important! modifier
->add('data-invalid:shadow-xs! data-invalid:border-zinc-200! data-invalid:border-b-zinc-300/80! data-invalid:disabled:border-b-zinc-200! data-invalid:dark:border-white/10! data-invalid:dark:disabled:border-white/5!');
$loading = $attributes->whereStartsWith('wire:model.live')->isNotEmpty();
if ($loading) {
$attributes = $attributes->merge(['wire:loading.attr' => 'data-flux-loading']);
}
@endphp
<flux:input :$size :$placeholder :$attributes :class:input="$classes">
<x-slot name="iconTrailing">
<?php if ($clearable): ?>
<flux:button as="div"
class="cursor-pointer ms-2 -me-3 [[data-flux-input]:has(input:placeholder-shown)_&]:hidden [[data-flux-select]:has([disabled][data-selected])_&]:hidden"
variant="subtle"
:size="$size === 'sm' ? 'xs' : 'sm'"
square
tabindex="-1"
aria-label="Clear selected"
x-on:click.prevent.stop="let select = $el.closest('ui-select'); select.value = select.hasAttribute('multiple') ? [] : null; select.dispatchEvent(new Event('change', { bubbles: false })); select.dispatchEvent(new Event('input', { bubbles: false }))"
>
<flux:icon.x-mark variant="micro" />
</flux:button>
<?php endif; ?>
<flux:button size="sm" square variant="subtle" tabindex="-1" class="-me-1 [[disabled]_&]:pointer-events-none">
<flux:icon.chevron-up-down variant="mini" class="text-zinc-400/75 [[data-flux-input]:hover_&]:text-zinc-800 [[disabled]_&]:text-zinc-200! dark:text-white/60 dark:[[data-flux-input]:hover_&]:text-white dark:[[disabled]_&]:text-white/40!" />
</flux:button>
</x-slot>
</flux:input>

View File

@@ -0,0 +1,33 @@
@blaze
@props([
'modal' => null,
])
@php
$classes = Flux::classes()
->add('group/option overflow-hidden data-hidden:hidden group flex items-center px-2 py-1.5 w-full focus:outline-hidden')
->add('rounded-md')
->add('text-start text-sm font-medium select-none')
->add('text-zinc-800 data-active:bg-zinc-100 [&[disabled]]:text-zinc-400 dark:text-white dark:data-active:bg-zinc-600 dark:[&[disabled]]:text-zinc-400')
->add('[&[disabled]]:pointer-events-none')
;
if ($modal) {
$attributes = $attributes->merge(['x-on:click' => "\$dispatch('modal-show', { name: '{$modal}' })"]);
}
if ($attributes->whereStartsWith('wire:click')->isNotEmpty()) {
$attributes = $attributes->merge(['wire:loading.attr' => 'data-flux-loading']);
}
@endphp
<ui-option-create {{ $attributes->class($classes) }} action data-flux-option-create>
<div class="w-6 shrink-0">
<flux:icon variant="mini" icon="plus" />
</div>
<span class="overflow-hidden text-nowrap text-ellipsis">{{ $slot }}</span>
<flux:icon.loading class="hidden [[data-flux-loading]>&]:block ms-auto text-zinc-400 [[data-flux-menu-item]:hover_&]:text-current" variant="micro" />
</ui-option-create>

View File

@@ -0,0 +1,14 @@
@blaze
@php
$classes = Flux::classes()
->add('data-hidden:hidden block items-center px-2 py-1.5 w-full')
->add('rounded-md')
->add('text-start text-sm font-medium')
->add('text-zinc-500 data-active:bg-zinc-100 dark:text-zinc-300 dark:data-active:bg-zinc-600')
;
@endphp
<ui-option-empty {{ $attributes->class($classes) }} data-flux-listbox-empty wire:ignore>
{{ $slot }}
</ui-option-empty>

View File

@@ -0,0 +1,14 @@
@aware([ 'variant' ])
@props([
'variant' => 'default',
])
@php
// This prevents variants picked up by `@aware()` from other wrapping components like flux::modal from being used here...
$variant = $variant !== 'default' && Flux::componentExists('select.variants.' . $variant)
? 'custom'
: 'default';
@endphp
<flux:delegate-component :component="'select.option.variants.' . $variant">{{ $slot }}</flux:delegate-component>

View File

@@ -0,0 +1,46 @@
@aware([ 'indicator' ])
@props([
'filterable' => null,
'indicator' => null,
'loading' => null,
'label' => null,
'value' => null,
])
@php
$classes = Flux::classes()
->add('group/option overflow-hidden data-hidden:hidden group flex items-center px-2 py-1.5 w-full focus:outline-hidden')
->add('rounded-md')
->add('text-start text-sm font-medium select-none')
->add('text-zinc-800 data-active:bg-zinc-100 [&[disabled]]:text-zinc-400 dark:text-white dark:data-active:bg-zinc-600 dark:[&[disabled]]:text-zinc-400')
;
$livewireAction = $attributes->whereStartsWith('wire:click')->isNotEmpty();
$alpineAction = $attributes->whereStartsWith('x-on:click')->isNotEmpty();
$loading ??= $loading ?? $livewireAction;
if ($loading) {
$attributes = $attributes->merge(['wire:loading.attr' => 'data-flux-loading']);
}
@endphp
<ui-option
@if ($value !== null) value="{{ $value }}" @endif
@if ($value) wire:key="{{ $value }}" @endif
@if ($filterable === false) filter="manual" @endif
@if ($livewireAction || $alpineAction) action @endif
{{ $attributes->class($classes) }}
data-flux-option
>
<div class="w-6 shrink-0 [ui-selected_&]:hidden">
<flux:select.indicator :variant="$indicator" />
</div>
{{ $label ?? $slot }}
<?php if ($loading): ?>
<flux:icon.loading class="hidden [[data-flux-loading]>&]:block ms-auto text-zinc-400 [[data-flux-menu-item]:hover_&]:text-current" variant="micro" />
<?php endif; ?>
</ui-option>

View File

@@ -0,0 +1,11 @@
@blaze
@props([
'value' => null,
])
<option
{{ $attributes }}
@if (isset($value)) value="{{ $value }}" @endif
@if (isset($value)) wire:key="{{ $value }}" @endif
>{{ $slot }}</option>

View File

@@ -0,0 +1,47 @@
@aware([ 'searchable' ])
@props([
'searchable' => null,
'search' => null,
'empty' => null,
])
@php
$classes = Flux::classes()
->add('[:where(&)]:min-w-48 [:where(&)]:max-h-[20rem] p-[.3125rem] scroll-py-[.3125rem]')
->add('rounded-lg shadow-xs')
->add('border border-zinc-200 dark:border-zinc-600')
->add('bg-white dark:bg-zinc-700')
;
// Searchable can also be a slot...
if (is_object($searchable)) $search = $searchable;
@endphp
<?php if (! $searchable): ?>
<ui-options popover="manual" {{ $attributes->class($classes) }} data-flux-options>
{{ $slot }}
</ui-options>
<?php else: ?>
<div popover="manual" class="[:where(&)]:min-w-48 [&:popover-open]:flex [&:popover-open]:flex-col rounded-lg shadow-xs border border-zinc-200 dark:border-zinc-600 bg-white dark:bg-zinc-700 p-[.3125rem]" data-flux-options>
<?php if ($search): ?> {{ $search }} <?php else: ?>
<flux:select.search />
<?php endif; ?>
<ui-options class="max-h-[20rem] overflow-y-auto -me-[.3125rem] -mt-[.3125rem] pt-[.3125rem] pe-[.3125rem] -mb-[.3125rem] pb-[.3125rem] scroll-py-[.3125rem]">
<?php if ($empty): ?>
<?php if (is_string($empty)): ?>
<flux:select.option.empty>{!! __($empty) !!}</flux:select.option.empty>
<?php else: ?>
{{ $empty }}
<?php endif; ?>
<?php else: ?>
<flux:select.option.empty when-loading="{!! __('Loading...') !!}">
{!! __('No results found') !!}
</flux:select.option.empty>
<?php endif; ?>
{{ $slot }}
</ui-options>
</div>
<?php endif; ?>

View File

@@ -0,0 +1,75 @@
@props([
'clearable' => true,
'closable' => null,
'icon' => null,
])
@php
// Clerable or closable, not both...
if ($closable !== null) $clearable = null;
$classes = Flux::classes()
->add('h-10 w-full flex items-center px-3 py-2')
->add('font-medium text-base sm:text-sm text-zinc-800 dark:text-white')
->add('ps-9') // Make room for magnifying glass icon...
->add('pe-9') // Make room for clear/clos button and loading indicator...
->add('outline-hidden')
->add('border-b border-zinc-200 dark:border-zinc-600')
->add('bg-white dark:bg-zinc-700')
// The below reverts styles added by Tailwind Forms plugin
->add('border-t-0 border-s-0 border-e-0 focus:ring-0 focus:border-zinc-200 dark:focus:border-zinc-600')
->add('data-invalid:text-red-500 dark:data-invalid:text-red-400')
;
$name = $attributes->whereStartsWith('wire:model')->first();
$invalid ??= ($name && $errors->has($name));
$loading = $attributes->whereStartsWith('wire:model.live')->isNotEmpty();
if ($loading) {
$attributes = $attributes->merge(['wire:loading.attr' => 'data-flux-loading']);
}
@endphp
<div class="relative flex grow mx-[-5px] mt-[-5px] mb-[5px]" data-flux-select-search>
<div class="absolute top-0 bottom-0 flex items-center justify-center text-xs text-zinc-400 ps-3.5 start-0">
<?php if (is_string($icon)): ?>
<flux:icon :$icon variant="micro" />
<?php elseif ($icon): ?>
{{ $icon }}
<?php else: ?>
<flux:icon.magnifying-glass variant="micro" />
<?php endif; ?>
</div>
<input
type="text"
@if ($invalid) aria-invalid="true" data-invalid @endif
{{ $attributes->class($classes)->merge(['placeholder' => __('Search...')]) }}
/>
<?php if ($loading): ?>
<div class="opacity-0 [[data-flux-select-search]:has([data-flux-loading])_&]:opacity-100 transition-opacity absolute top-0 bottom-0 flex items-center justify-center pe-2.5 end-0">
<flux:icon.loading class="text-zinc-400 [[data-flux-menu-item]:hover_&]:text-current" variant="mini" />
</div>
<?php endif; ?>
<?php if ($closable): ?>
<div class="[[data-flux-select-search]:has([data-flux-loading])_&]:opacity-0 transition-opacity absolute top-0 bottom-0 flex items-center justify-center pe-1 end-0">
<ui-close>
<flux:button square variant="subtle" size="sm" aria-label="Clear search input">
<flux:icon.x-mark variant="micro" />
</flux:button>
</ui-close>
</div>
<?php elseif ($clearable): ?>
<div class="[[data-flux-select-search]:has([data-flux-loading])_&]:opacity-0 transition-opacity absolute top-0 bottom-0 flex items-center justify-center pe-1 end-0 [[data-flux-select-search]:has(input:placeholder-shown)_&]:hidden">
<flux:button square variant="subtle" size="sm" tabindex="-1" aria-label="Clear command input"
x-on:click="$el.closest('[data-flux-select-search]').querySelector('input').value = ''; $el.closest('[data-flux-select-search]').querySelector('input').dispatchEvent(new Event('input', { bubbles: false })); $el.closest('[data-flux-select-search]').querySelector('input').focus()"
>
<flux:icon.x-mark variant="micro" />
</flux:button>
</div>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,25 @@
@blaze
@props([
'placeholder' => null,
'suffix' => null,
'max' => 1,
])
@php
$classes = Flux::classes()
->add('truncate flex gap-2 text-start flex-1 text-zinc-700')
->add('[[disabled]_&]:text-zinc-500 dark:text-zinc-300 dark:[[disabled]_&]:text-zinc-400');
@endphp
<ui-selected x-ignore wire:ignore {{ $attributes->class($classes) }}>
<template name="placeholder">
<span class="text-zinc-400 [[disabled]_&]:text-zinc-400/70 dark:text-zinc-400 dark:[[disabled]_&]:text-zinc-500" data-flux-select-placeholder>
{{ $placeholder }}
</span>
</template>
<template name="overflow" max="{{ $max }}" >
<div><slot name="count"></slot> {{ $suffix ?? __('selected') }}</div>
</template>
</ui-selected>

View File

@@ -0,0 +1,56 @@
@props([
'placeholder' => null,
'searchable' => null,
'clearable' => null,
'multiple' => null,
'invalid' => null,
'empty' => null,
'input' => null,
'size' => null,
'name' => null,
])
@php
// We only want to show the name attribute on the checkbox if it has been set
// manually, but not if it has been set from the wire:model attribute...
$showName = isset($name);
if (! isset($name)) {
$name = $attributes->whereStartsWith('wire:model')->first();
}
if ($searchable) {
throw new \Exception('Comboboxes do not support the searchable prop.');
}
if ($multiple) {
throw new \Exception('Comboboxes do not support the multiple prop.');
}
$invalid ??= ($name && $errors->has($name));
$class = Flux::classes()
->add('w-full');
@endphp
<ui-select autocomplete="strict" clear="esc" {{ $attributes->class($class)->merge(['filter' => true]) }} @if($showName) name="{{ $name }}" @endif data-flux-control data-flux-select>
<?php if ($input): ?> {{ $input }} <?php else: ?>
<flux:select.input :$placeholder :$invalid :$size :$clearable />
<?php endif; ?>
<flux:select.options>
<?php if ($empty): ?>
<?php if (is_string($empty)): ?>
<flux:select.option.empty>{!! __($empty) !!}</flux:select.option.empty>
<?php else: ?>
{{ $empty }}
<?php endif; ?>
<?php else: ?>
<flux:select.option.empty when-loading="{!! __('Loading...') !!}">
{!! __('No results found') !!}
</flux:select.option.empty>
<?php endif; ?>
{{ $slot }}
</flux:select.options>
</ui-select>

View File

@@ -0,0 +1,33 @@
@props([
'invalid' => null,
'clear' => null,
'close' => null,
'size' => null,
'name' => null,
])
@php
// We only want to show the name attribute on the checkbox if it has been set
// manually, but not if it has been set from the wire:model attribute...
$showName = isset($name);
if (! isset($name)) {
$name = $attributes->whereStartsWith('wire:model')->first();
}
$invalid ??= ($name && $errors->has($name));
$class = Flux::classes()
->add('w-full');
@endphp
<ui-select
clear="{{ $clear ?? 'close esc select' }}"
@if ($close) close="{{ $close }}" @endif
{{ $attributes->class($class)->merge(['filter' => true]) }}
@if($showName) name="{{ $name }}" @endif
data-flux-control
data-flux-select
>
{{ $slot}}
</ui-select>

View File

@@ -0,0 +1,50 @@
@blaze
@props([
'name' => $attributes->whereStartsWith('wire:model')->first(),
'placeholder' => null,
'invalid' => null,
'size' => null,
])
@php
$invalid ??= ($name && $errors->has($name));
$classes = Flux::classes()
->add('appearance-none') // Strip the browser's default <select> styles...
->add('[:where(&)]:w-full ps-3 pe-10 block')
->add(match ($size) {
default => 'h-10 py-2 text-base sm:text-sm leading-[1.375rem] rounded-lg',
'sm' => 'h-8 py-1.5 text-sm leading-[1.125rem] rounded-lg',
'xs' => 'h-6 text-xs leading-[1.125rem] rounded-lg',
})
->add('shadow-xs border')
->add('bg-white dark:bg-white/10 dark:disabled:bg-white/[7%]')
->add('text-zinc-700 dark:text-zinc-300 disabled:text-zinc-500 dark:disabled:text-zinc-400')
// Make the placeholder match the text color of standard input placeholders...
->add('has-[option.placeholder:checked]:text-zinc-400 dark:has-[option.placeholder:checked]:text-zinc-400')
// Options on Windows don't inherit dark mode styles, so we need to force them...
->add('dark:[&>option]:bg-zinc-700 dark:[&>option]:text-white')
->add('disabled:shadow-none')
->add($invalid
? 'border border-red-500'
: 'border border-zinc-200 border-b-zinc-300/80 dark:border-white/10'
)
;
@endphp
<select
{{ $attributes->class($classes) }}
@if ($invalid) aria-invalid="true" data-invalid @endif
@isset ($name) name="{{ $name }}" @endisset
@if (is_numeric($size)) size="{{ $size }}" @endif
data-flux-control
data-flux-select-native
data-flux-group-target
>
<?php if ($placeholder): ?>
<option value="" disabled selected class="placeholder">{{ $placeholder }}</option>
<?php endif; ?>
{{ $slot }}
</select>

View File

@@ -0,0 +1,52 @@
@props([
'selectedSuffix' => null,
'placeholder' => null,
'searchable' => null,
'clearable' => null,
'invalid' => null,
'button' => null, // Deprecated...
'trigger' => null,
'search' => null, // Slot forwarding...
'empty' => null, // Slot forwarding...
'clear' => null,
'close' => null,
'name' => null,
'size' => null,
])
@php
// We only want to show the name attribute on the checkbox if it has been set
// manually, but not if it has been set from the wire:model attribute...
$showName = isset($name);
if (! isset($name)) {
$name = $attributes->whereStartsWith('wire:model')->first();
}
$invalid ??= ($name && $errors->has($name));
$class = Flux::classes()
->add('w-full')
// The below reverts styles added by Tailwind Forms plugin
->add('border-0 p-0 bg-transparent')
;
$trigger ??= $button;
@endphp
<ui-select
clear="{{ $clear ?? 'close esc select' }}"
@if ($close) close="{{ $close }}" @endif
{{ $attributes->class($class)->merge(['filter' => true]) }}
@if($showName) name="{{ $name }}" @endif
data-flux-control
data-flux-select
>
<?php if ($trigger): ?> {{ $trigger }} <?php else: ?>
<flux:select.button :$placeholder :$invalid :$size :$clearable :suffix="$selectedSuffix" />
<?php endif; ?>
<flux:select.options :$search :$searchable :$empty>
{{ $slot }}
</flux:select.options>
</ui-select>