Overview: The Developer's Design Problem Most developers suffer from a common affliction: we are functional experts but design amateurs. We rely on random fonts like Roboto or Open%20Sans and default to massive text sizes for headings, missing the subtle nuances that professional designers like Hugo use to create polished interfaces. The Flux UI library bridges this gap by providing a comprehensive set of Blade components specifically tailored for the Laravel and Livewire ecosystem. Flux isn't just a collection of styled divs; it is an official toolkit that enforces design constraints and accessibility standards out of the box. It simplifies the creation of complex UI elements—like command palettes, searchable selects, and responsive layouts—using a "hand-done" approach that prioritizes performance. By using Flux, you inherit the opinions of seasoned designers, ensuring your application looks professional without requiring you to manually tweak every pixel. Prerequisites To get the most out of this tutorial, you should have a solid foundation in the following: * **PHP & Laravel**: Familiarity with the Laravel framework and its Blade templating engine. * **Livewire**: Basic knowledge of how Livewire handles state and component lifecycle. * **Tailwind CSS**: Understanding utility-first CSS, as Flux uses Tailwind%20CSS for all internal styling. * **Alpine.js**: A grasp of Alpine.js syntax helps, as it powers the underlying interactivity of the components. Key Libraries & Tools * Flux: The primary UI library featuring Blade components and a JavaScript core. * Livewire: The full-stack framework that handles the dynamic logic for Flux components. * Heroicons: The default icon set used throughout the library (specifically the Micro, Mini, and Solid variants). * Floating%20UI: The sole external dependency, used for intelligent anchor positioning of popovers and dropdowns. * Tailwind%20CSS: The engine for all visual treatments and responsive design. Code Walkthrough: Building Modern Forms Flux approaches forms with a philosophy of composability. Instead of a monolithic input component with dozens of props, it breaks the field down into logical parts. This allows you to customize the "treatment" of each field without fighting the library. ```blade <flux:field> <flux:label>Username</flux:label> <flux:description>Choose a unique name for your profile.</flux:description> <flux:input wire:model="username" placeholder="e.g. dev_harper" /> <flux:error name="username" /> </flux:field> ``` In this example, the `<flux:field>` wrapper handles the relationship between the label and the input. If you decide to move the description below the input, Flux uses CSS sibling selectors to automatically adjust margins. This prevents the awkward spacing issues that plague manual implementations. For repetitive tasks, Flux provides a clean shortcut. You can pass the label and description as props directly to the input, and it will wrap itself internally: ```blade <flux:input label="Email" description="We will never share your email." wire:model="email" /> ``` Advanced Input Features Beyond simple text, Flux handles complex patterns like input masking and clearable fields. Input masking is built directly into the Alpine.js core, keeping the bundle size tiny compared to massive third-party libraries. ```blade <flux:input mask="(999) 999-9999" label="Phone Number" /> <flux:input type="password" viewable label="Password" /> <flux:input clearable icon="magnifying-glass" label="Search" /> ``` Layouts and the Unified Field Theory Layouts are often the most fragile part of a web application. Flux introduces a declarative way to handle sidebars, headers, and footers using CSS%20Grid. The library detects the order of your Blade components to determine the layout structure. ```blade <flux:page> <flux:sidebar sticky stashable> <flux:brand logo="/logo.svg" name="Acme Corp" /> <flux:navlist> <flux:navlist.item icon="home" href="#" current>Dashboard</flux:navlist.item> <flux:navlist.item icon="users" href="#">Team</flux:navlist.item> </flux:navlist> </flux:sidebar> <flux:header> <flux:sidebar.toggle class="lg:hidden" /> <flux:spacer /> <flux:profile name="Dev Harper" /> </flux:header> <flux:main> <!-- Your Content Here --> </flux:main> </flux:page> ``` One notable feature is the `sticky` prop. Normally, `position: sticky` requires manual calculation of offsets. Flux automatically calculates the height of the header or sidebar to ensure elements stick exactly where they should. Furthermore, the `stashable` attribute enables a mobile-ready sidebar that hides automatically, with larger touch targets for mobile accessibility. The Power of the Popover API Building dropdowns is notoriously difficult due to `overflow: hidden` and `position: relative` clipping. Flux solves this by utilizing the native Browser%20Popover%20API. This renders the dropdown in the "top layer" of the browser—above the entire DOM tree—meaning it can never be cut off by a parent container. ```blade <flux:dropdown> <flux:button icon-trailing="chevron-down">Options</flux:button> <flux:menu> <flux:menu.item icon="pencil">Edit</flux:menu.item> <flux:menu.item icon="trash" variant="danger">Delete</flux:menu.item> </flux:menu> </flux:dropdown> ``` Flux also implements "safe areas" for submenus. If a user moves their mouse diagonally toward a submenu, the menu stays open rather than closing immediately. This small UX detail is what separates a developer-built menu from a professional-grade interface. Syntax Notes: Attributes and Naming * **T-Shirt Sizing**: Flux uses standard Tailwind%20CSS sizing conventions (`xs`, `sm`, `base`, `lg`). * **Directional Naming**: The library prefers `leading` and `trailing` over `left` and `right`. This aligns with modern CSS logical properties and prepares your app for RTL (Right-to-Left) support. * **Custom Web Elements**: Under the hood, Flux renders custom elements like `<ui-checkbox-group>`. These are framework-agnostic and handle complex ARIA roles, roving tab indexes, and keyboard navigation automatically. * **Inset Property**: For ghost buttons or badges that need to align with a visual edge, the `inset` prop compensates for internal padding, ensuring perfect optical alignment. Practical Examples: Command Palettes One of the most impressive components in the Flux arsenal is the command palette. It combines a modal, an input, and a searchable list into a high-performance tool. ```blade <flux:command.palette> <flux:command.input placeholder="Search commands..." /> <flux:command.items> <flux:command.item icon="plus">New Project</flux:command.item> <flux:command.item icon="cog">Settings</flux:command.item> </flux:command.items> </flux:command.palette> ``` This palette is fully keyboard-accessible and integrates seamlessly with Livewire for server-side searching. Tips & Gotchas * **Primary Button Fatigue**: Avoid making every button `variant="primary"`. Professional design usually features only one primary action per view; the rest should use the default muted style. * **Optical Alignment**: If a component looks slightly "off" visually even though the pixels match, try using the `inset` prop or Flux's built-in optical alignment features to fix the visual balance. * **Bundle Size**: Do not worry about the JavaScript overhead. The entire Flux core is only 16KB minified, as it avoids bulky third-party dependencies in favor of hand-written web components. * **Livewire Integration**: Remember that you can use `wire:model` directly on groups (like `<flux:radio.group>` or `<flux:checkbox.group>`) rather than binding to individual items. Flux handles the array syncing for you.
Hugo
People
TL;DR
Lance Hedrick (2 mentions) references the name during coffee tutorials like "DOES BREW TEMPERATURE ACTUALLY MATTER?", while Laravel (1 mention) highlights it during the Flux UI library presentation at Laracon US 2024.
- Sep 3, 2024
- Aug 30, 2023
- Feb 6, 2023