Flux UI

website·Indexed 34 days ago

https://fluxui.dev

A robust, hand-crafted UI component library for Livewire applications built using Tailwind CSS. Flux provides a comprehensive system of Blade components, including layout options like headers and sidebars, and a wide array of UI elements such as modals, dropdowns, and data inputs. The library offers both a standard version and a Pro version featuring advanced components like charts, kanban boards, and rich text editors.

Tokens
76.1K
Snippets
452
Records
502
Agent score
70%

What's inside Flux

  1. Overview of the Flux Chart component

    The Flux Chart component is a lightweight, zero-dependency tool for building charts in Livewire applications. It allows developers to assemble and style charts using a set of declarative Blade components. It is available exclusively in the Pro version of Flux.
  2. Implement an analytics dashboard with Flux UI and Livewire

    Create a data-driven analytics overview by combining Flux UI components with a Livewire component. This implementation uses #[Computed] properties to manage dashboard data such as visitor counts, statistics, top pages, and geographic data, and integrates a DateRange object for time-based filtering.
    <?php
    
    use Carbon
    use Flux\DateRange;
    use Livewire\Attributes\Computed;
    
    new class extends \Livewire\Component {
        public string $chartType = 'bar';
        public DateRange $dateRange;
    
        public function mount(): void
        {
            $this->dateRange = DateRange::last7Days();
        }
    
        #[Computed]
        public function stats(): array
        {
            return [
                ['label' => 'Visitors', 'value' => '128.6K', 'change' => '24.7%', 'trend' => 'up'],
                ['label' => 'Page views', 'value' => '389.1K', 'change' => '2.4%', 'trend' => 'down'],
                // ...
            ];
        }
    
        #[Computed]
        public function visitorData(): array
        {
            // Logic to generate date-series data for charts
            return $visitorData;
        }
    }
    ?>
    
    <div>
        <flux:main container>
            <div class="flex flex-wrap items-center gap-x-2 gap-y-4">
                <flux:date-picker mode="range" size="sm" with-presets wire:model="dateRange" />
                <flux:button size="sm" icon="arrow-up-tray">Export</flux:button>
            </div>
    
            <flux:carousel arrows:position="overlap" track:class="gap-5" fade>
                @foreach ($this->stats as $stat)
                    <flux:carousel.slide class="min-w-56 grow basis-0">
                        <flux:card data-trend="{{ $stat['trend'] }}" variant="soft">
                            <flux:text class="truncate font-medium">{{ $stat['label'] }}</flux:text>
                            <flux:heading size="xl" class="mt-1">{{ $stat['value'] }}</flux:heading>
                        </flux:card>
                    </flux:carousel.slide>
                @endforeach
            </flux:carousel>
        </flux:main>
    </div>
  3. Implement a searchable account overview with Livewire and Flux UI

    Create a responsive account overview page using Flux UI components. This implementation uses a Livewire component to manage the state of a search input and filter a collection of transactions in real-time. The UI utilizes flux:header for the top navigation, flux:sidebar for mobile/desktop navigation, and flux:card to group account details and transaction history.
    <?php
    
    use Illuminate
    Support
    Collection;
    use Livewire
    Attributes
    Computed;
    use Livewire
    Component;
    
    new class extends Component {
        public string $search = '';
    
        #[Computed]
        public function transactions(): Collection
        {
            $search = strtolower(trim($this->search));
    
            return collect([
                ['id' => 1, 'name' => 'Blue Bottle Coffee', 'category' => 'Dining', 'amount' => -6.75, 'icon' => 'building-storefront', 'pending' => true],
                ['id' => 14, 'name' => 'Apple Store', 'category' => 'Shopping', 'amount' => -129.00, 'icon' => 'shopping-bag', 'logo' => 'apple.svg'],
                // ... other transactions
            ])->filter(fn ($transaction) => str_contains(strtolower($transaction['name'].' '.$transaction['category']), $search));
        }
    
        #[Computed]
        public function monthlySpending(): array
        {
            return [
                ['month' => 'Apr', 'past' => 4200, 'current' => 0, 'amount' => 4200],
                // ... other months
            ];
        }
    
        #[Computed]
        public function upcomingPayments(): array
        {
            return [
                ['day' => 8, 'name' => 'Oakwood Property', 'category' => 'Rent', 'amount' => 1850.00],
                // ... other payments
            ];
        }
    };
    ?>
    
    <div>
        <flux:header container class="border-b border-zinc-200 bg-white lg:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900">
            <flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left" aria-label="Open navigation" />
            <flux:brand href="#" logo="https://fluxui.dev/img/demo/logo.png" name="Acme Bank" class="max-lg:hidden dark:hidden" />
            <flux:navbar class="max-lg:hidden">
                <flux:navbar.item href="#" current>Accounts</flux:navbar.item>
                <flux:navbar.item href="#">Transfers</flux:navbar.item>
            </flux:navbar>
            <flux:spacer />
            <flux:dropdown position="bottom" align="end">
                <flux:profile avatar="https://fluxui.dev/img/demo/user.png" aria-label="Account menu" />
                <flux:menu>
                    <flux:menu.item icon="arrow-right-start-on-rectangle">Logout</flux:menu.item>
                </flux:menu>
            </flux:dropdown>
        </flux:header>
    
        <flux:main container>
            <flux:card class="dark bg-zinc-900 [--color-accent:white] [--color-accent-content:white] [--color-accent-foreground:var(--color-zinc-800)]">
                <flux:heading level="1" size="lg">Everyday Checking</flux:heading>
                <flux:heading size="2xl" class="tabular-nums">$8,432.10</flux:heading>
                <div class="flex gap-2">
                    <flux:button size="sm" variant="primary" icon="arrow-right">Send money</flux:button>
                    <flux:button size="sm" icon="plus">Add money</flux:button>
                </div>
            </flux:card>
        </flux:main>
    </div>
  4. Understand Flux props vs attributes

    Flux distinguishes between "props" (internal properties used to customize component behavior or styling) and "attributes" (bespoke HTML attributes that are forwarded directly to the underlying HTML element). For example, a variant prop is used internally to apply CSS classes, while an attribute like x-on:change.prevent is passed directly to the rendered HTML element.
    <!-- 'variant' is a prop; 'x-on:change.prevent' is an attribute -->
    <flux:button variant="primary" x-on:change.prevent="...">
  5. Use the flux:badge component

    The <flux:badge> component is used to highlight information such as status, categories, or counts. It supports various colors, sizes, and variants to convey different levels of importance or meaning.
    <flux:badge color="lime">New</flux:badge>
  6. Use the flux:profile component

    The <flux:profile> component displays a user's profile with an avatar and an optional name. It is commonly used as a trigger for dropdown menus or profile switchers.
    <flux:profile avatar="https://unavatar.io/x/calebporzio" />
  7. Configure a responsive mobile sidebar for navigation

    Use <flux:sidebar> with the collapsible="mobile" attribute and lg:hidden class to create a navigation menu that only appears on smaller screens. The sidebar should be paired with a <flux:sidebar.toggle> inside the <flux:header> to allow users to open and close the menu.
    <flux:sidebar sticky collapsible="mobile" class="lg:hidden bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700">
        <flux:sidebar.header>
            <flux:sidebar.brand href="#" name="Acme Inc." />
            <flux:sidebar.collapse />
        </flux:sidebar.header>
    
        <flux:sidebar.nav>
            <flux:sidebar.item icon="home" href="#">Home</flux:sidebar.item>
            <flux:sidebar.group expandable heading="Favorites">
                <flux:sidebar.item href="#">Link 1</flux:sidebar.item>
            </flux:sidebar.group>
        </flux:sidebar.nav>
    </flux:sidebar>
  8. Use simple pagination for large datasets

    For large datasets where counting the total number of results is computationally expensive, use a simple paginator. This configuration provides only 'Previous' and 'Next' buttons and omits the total page or record count.
    <!-- $orders = Order::simplePaginate() -->
    <flux:pagination :paginator="$orders" />
  9. Capture international phone numbers with flux:phone

    The flux:phone component (available in Flux Pro) allows users to enter international phone numbers. It provides a country picker and automatically normalizes valid phone numbers to the international E.164 format (e.g., +12015550123) while displaying a local format to the user.

    Note: Incomplete or unparseable entries are preserved as typed. Formatting does not validate if a number is active or can receive calls; server-side validation is required.

    <flux:phone wire:model="phone" country="US" label="Phone number" />
  10. Configure Axis Ticks and Marks

    Use <flux:chart.axis.mark> for the small tick lines and <flux:chart.axis.tick> for the text labels. Both are wrappers around SVG elements (<line> and <text> respectively) and can be styled via CSS and SVG attributes.
    <flux:chart.axis axis="x">
        <!-- Tick mark line: 10px long, 2px wide -->
        <flux:chart.axis.mark class="text-zinc-300" stroke-width="2" y1="0" y2="10" />
    
        <!-- Tick label -->
        <flux:chart.axis.tick />
    </flux:chart.axis>
  11. Implement a Popover using flux:dropdown

    The flux:popover component is used to show extra content in a popup. It must be wrapped in a flux:dropdown component, which provides the trigger mechanism. Use flux:popover for generic content; for simple menus, the Dropdown menu component is preferred. Note: This component is only available in the Pro version of Flux.
    <flux:dropdown>
        <flux:button>Options</flux:button>
    
        <flux:popover class="flex flex-col gap-4">
            <!-- Popover content here -->
            <flux:radio.group wire:model="sort" label="Sort by">
                <flux:radio value="active" label="Recently active" />
                <flux:radio value="posted" label="Date posted" checked />
            </flux:radio.group>
        </flux:popover>
    </flux:dropdown>