Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Headless Ui Laravel Package

schaefersoft/laravel-headless-ui

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require schaefersoft/laravel-headless-ui
    

    No manual service provider registration needed (auto-discovery).

  2. Import Assets:

    • Add CSS to your stylesheet:
      @import '../../vendor/schaefersoft/laravel-headless-ui/resources/css/hui.css';
      
    • Include JS in your entry file (Vite/Laravel Mix):
      import '../../vendor/schaefersoft/laravel-headless-ui/dist/js/hui.js';
      
  3. First Component: Use the x-hui:: prefix in Blade:

    <x-hui::tabs>
        <x-hui::tabs.tablist>
            <x-hui::tabs.tab>Tab 1</x-hui::tabs.tab>
            <x-hui::tabs.tab>Tab 2</x-hui::tabs.tab>
        </x-hui::tabs.tablist>
        <x-hui::tabs.panel>Content 1</x-hui::tabs.panel>
        <x-hui::tabs.panel>Content 2</x-hui::tabs.panel>
    </x-hui::tabs>
    

Where to Look First

  • Documentation: Start with the README and component-specific docs (e.g., docs/tabs.md).
  • Component List: The README table summarizes all available components with previews.
  • Installation: Verify asset imports (CSS/JS) are correct in your build pipeline.

First Use Case

Replace a basic tab system: Replace a jQuery-based or Bootstrap tab implementation with this headless version for better accessibility and no external JS dependencies.


Implementation Patterns

Usage Patterns

  1. Component Composition:

    • Use nested Blade components (e.g., x-hui::tabs + x-hui::tabs.tab).
    • Example for a dropdown:
      <x-hui::dropdown>
          <x-hui::dropdown.trigger>Menu</x-hui::dropdown.trigger>
          <x-hui::dropdown.content>
              <x-hui::dropdown.item>Item 1</x-hui::dropdown.item>
              <x-hui::dropdown.item>Item 2</x-hui::dropdown.item>
          </x-hui::dropdown.content>
      </x-hui::dropdown>
      
  2. State Management:

    • Use props like :initial-index for Tabs or active for Disclosure:
      <x-hui::disclosure :open="true">
          <x-hui::disclosure.button>Click me</x-hui::disclosure.button>
          <x-hui::disclosure.panel>Content</x-hui::disclosure.panel>
      </x-hui::disclosure>
      
  3. Dynamic Content:

    • Loop through collections for dynamic tabs or dropdown items:
      <x-hui::tabs>
          <x-hui::tabs.tablist>
              @foreach ($items as $item)
                  <x-hui::tabs.tab>{{ $item->name }}</x-hui::tabs.tab>
              @endforeach
          </x-hui::tabs.tablist>
          <!-- Panels -->
      </x-hui::tabs>
      
  4. Form Integration:

    • Sync RangeSlider with form inputs:
      <x-hui::range-slider>
          <x-hui::range-slider.track>
              <x-hui::range-slider.thumb role="min" name="price_min" value="{{ old('price_min', 20) }}"/>
              <x-hui::range-slider.thumb role="max" name="price_max" value="{{ old('price_max', 80) }}"/>
          </x-hui::range-slider.track>
      </x-hui::range-slider>
      

Workflows

  1. Accessibility-First Development:

    • Use the package’s built-in ARIA attributes (e.g., aria-disabled, aria-expanded).
    • Test keyboard navigation (e.g., ArrowLeft/Right for Tabs, Space/Enter for Dropdowns).
  2. Tailwind CSS Integration:

    • Append the CSS layer to Tailwind’s base:
      @import '../../vendor/schaefersoft/laravel-headless-ui/resources/css/hui.css' layer(base);
      
    • Use Tailwind classes for styling (e.g., data-[active]:bg-blue-500).
  3. Conditional Rendering:

    • Use Blade @if to toggle components dynamically:
      @if (auth()->user()->can('edit'))
          <x-hui::dropdown>
              <x-hui::dropdown.trigger>Actions</x-hui::dropdown.trigger>
              <x-hui::dropdown.content>
                  <x-hui::dropdown.item>Edit</x-hui::dropdown.item>
                  <x-hui::dropdown.item>Delete</x-hui::dropdown.item>
              </x-hui::dropdown.content>
          </x-hui::dropdown>
      @endif
      
  4. Reusable Components:

    • Create custom Blade components that wrap x-hui::* components:
      <!-- resources/views/components/admin-tabs.blade.php -->
      <x-hui::tabs :vertical="true">
          <x-hui::tabs.tablist>
              <x-hui::tabs.tab active>Overview</x-hui::tabs.tab>
              <x-hui::tabs.tab>Settings</x-hui::tabs.tab>
          </x-hui::tabs.tablist>
          {{ $slot }}
      </x-hui::tabs>
      
    • Use in views:
      <x-admin-tabs>
          <x-hui::tabs.panel>Overview content</x-hui::tabs.panel>
          <x-hui::tabs.panel>Settings content</x-hui::tabs.panel>
      </x-admin-tabs>
      

Integration Tips

  1. Laravel Mix/Vite:

    • For Vite, ensure the JS import path is correct:
      // vite.config.js
      export default defineConfig({
        resolve: {
          alias: {
            'laravel-headless-ui': path.resolve(__dirname, 'vendor/schaefersoft/laravel-headless-ui'),
          },
        },
      });
      
  2. Form Requests:

    • Bind RangeSlider inputs to Form Requests:
      public function rules()
      {
          return [
              'price_min' => 'sometimes|integer|min:0|max:100',
              'price_max' => 'sometimes|integer|min:0|max:100',
          ];
      }
      
  3. Livewire/Alpine.js:

    • Combine with Alpine.js for reactive state:
      <div x-data="{ open: false }">
          <x-hui::disclosure @open.window="open = true">
              <x-hui::disclosure.button>Toggle</x-hui::disclosure.button>
              <x-hui::disclosure.panel x-show="open">Content</x-hui::disclosure.panel>
          </x-hui::disclosure>
      </div>
      
  4. Testing:

    • Use Laravel’s testing helpers for interactions:
      $this->get('/dashboard')
           ->assertSeeInOrder([
               'Tab 1',
               'Tab 2',
           ])
           ->press('Tab 2')
           ->assertSee('Content 2');
      

Gotchas and Tips

Pitfalls

  1. Missing role Attribute:

    • Error: RangeSlider thumbs require role="min" or role="max".
    • Fix: Ensure both thumbs are defined for dual sliders:
      <x-hui::range-slider.thumb role="min" ... />
      <x-hui::range-slider.thumb role="max" ... />
      
  2. CSS Specificity:

    • Issue: Custom styles may not override default styles due to specificity.
    • Fix: Use !important sparingly or increase specificity:
      .custom-slider .hui-range-slider-thumb::-webkit-slider-thumb {
          background: red !important;
      }
      
  3. JavaScript Conflicts:

    • Issue: If using TypeScript source (hui.ts), ensure your bundler supports ES modules.
    • Fix: Stick with the pre-built hui.js for simplicity.
  4. Disabled State:

    • Issue: Disabled tabs/buttons may not visually indicate their state.
    • Fix: Use data-[disabled] attributes in CSS:
      [data-disabled] {
          opacity: 0.5;
          pointer-events: none;
      }
      
  5. Initial State:

    • Issue: :initial-index may not work as expected if tabs are dynamically loaded.
    • Fix: Use JavaScript to set the active tab after DOM load:
      document.querySelector('[data-active]').click();
      

Debugging

  1. Console Errors:
    • Check browser console for missing JS/CSS paths. Verify imports in your build tool
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony