Skip to content

Component Library

The starter includes reusable, accessible Blade components that integrate with the Northwestern Laravel UI stack.


A Bootstrap-based breadcrumb navigation component that automatically handles the last item as active and supports both named routes and direct URLs.

#breadcrumbs Required array<string, string>

An associative array where keys are route names (or URLs) and values are the display labels

  • Automatic Active State: The last breadcrumb is automatically marked as active
  • Named Routes & URLs: Accepts both Laravel named routes and direct URLs
  • Cypress Testing Support: Includes data-cy attributes for automated testing
<x-breadcrumbs :breadcrumbs="[
'home' => 'Home',
'dashboard.index' => 'Dashboard',
'users.index' => 'Users',
'users.show' => 'John Doe'
]" />

With Direct URLs:

<x-breadcrumbs :breadcrumbs="[
'home' => 'Home',
'https://example.com/external' => 'External Link',
'users.index' => 'Users'
]" />

A feature-rich copy-to-clipboard component with visual feedback, tooltips, and flexible styling options. Uses ClipboardJS for reliable cross-browser copying functionality.

#text Required string

The text content to copy to the clipboard

#label string | null null

Optional label text to display alongside the icon

#isButton bool true

Render as a button (true) or inline span (false)

#buttonSize string | null null

Bootstrap button size: sm or lg

#buttonVariant string outline-secondary

Bootstrap button variant for the default state

#successVariant string outline-success

Bootstrap button variant for the success state

#icon string fa-copy

Font Awesome icon class for the default state (e.g. fa-copy, fa-rss)

#iconPosition string left

Icon position: left, right, or none

The component accepts any standard Bootstrap 5 button variant:

  • Solid: primary, secondary, success, danger, warning, info, light, dark, link
  • Outline: outline-primary, outline-secondary, outline-success, outline-danger, outline-warning, outline-info, outline-light, outline-dark

Basic Button:

<x-clipboard text="Hello World" />

With Label:

<x-clipboard
text="user@example.com"
label="Email Address"
button-variant="primary"
/>

Small Button:

<x-clipboard
text="{{ $accessToken }}"
label="Copy Token"
button-size="sm"
/>

Inline Span (No Button):

<x-clipboard
:text="$user->id"
label="Copy ID"
:is-button="false"
/>

Icon on Right:

<x-clipboard
text="https://example.com/share/12345"
label="Share Link"
icon-position="right"
button-variant="success"
/>

Custom Icon:

<x-clipboard
:text="$feedUrl"
label="RSS Feed"
icon="fa-rss"
button-size="sm"
/>

No Icon (Label Only):

<x-clipboard
text="{{ $secret }}"
label="Copy Secret"
icon-position="none"
/>

Custom Styling with Classes:

<x-clipboard
text="{{ $code }}"
label="Copy Code"
class="w-100"
/>

A searchable select component built on Tom Select with support for multiple selection, asynchronous search, and plugins. Works with Livewire.

#id Required string

Unique identifier for the select element

#options Required array | Collection

Options for the select (arrays, Collections, or Enums)

#settings array []

Additional Tom Select settings (merged with defaults)

#plugins array []

Tom Select plugins to enable with optional configurations

#searchable bool true

Enable/disable search functionality

#searchUrl string ''

URL for asynchronous search API endpoint

#optionCountSingularNoun string Item

Singular noun for the option count plugin

#optionCountPluralNoun string | null Auto-generated

Plural noun for the option count plugin

#maxOptions int | null 30

Maximum number of options to display

The Select component supports the following Tom Select plugins:

  • caret_position - Adjust caret position in input
  • change_listener - Listen for changes
  • checkbox_options - Add checkboxes to options
  • clear_button - Add a clear all button
  • drag_drop - Drag and drop to reorder
  • dropdown_header - Custom dropdown header
  • dropdown_input - Input field in dropdown
  • input_autogrow - Auto-grow input width
  • no_active_items - Disable active item behavior
  • no_backspace_delete - Disable backspace deletion
  • optgroup_columns - Display optgroups as columns
  • remove_button - Add remove buttons to items
  • restore_on_backspace - Restore item on backspace
  • virtual_scroll - Virtual scrolling for large lists
  • option_count - Display option count (custom plugin)

See the Tom Select Plugins Documentation for detailed plugin options.

  • Multiple Data Formats: Supports arrays, Collections, Enums (both Unit and Backed)
  • Optgroup Support: Nested arrays automatically render as optgroups
  • Async Search: Built-in support for server-side search with automatic throttling (250ms)
  • Enum Integration: Automatic label resolution for enums with label() method
  • Accessibility: Proper ARIA attributes and semantic HTML

Basic Select:

<x-select
id="country"
:options="['us' => 'United States', 'ca' => 'Canada', 'mx' => 'Mexico']"
/>

With Collection:

<x-select
id="users"
:options="$users->pluck('name', 'id')"
placeholder="Select a user"
/>

With Enums:

<x-select
id="affiliation"
:options="App\Enums\Affiliation::cases()"
/>

With Optgroups:

<x-select
id="locations"
:options="[
'North America' => [
'us' => 'United States',
'ca' => 'Canada'
],
'Europe' => [
'uk' => 'United Kingdom',
'de' => 'Germany'
]
]"
/>

Multiple Selection with Plugins:

<x-select
id="tags"
:options="$tags"
:plugins="['checkbox_options', 'remove_button', 'clear_button']"
multiple
/>

Async Search:

<x-select
id="users-search"
:options="[]"
search-url="{{ route('api.users.search') }}"
placeholder="Type to search users..."
/>

With Custom Settings:

<x-select
id="priority"
:options="['low' => 'Low', 'medium' => 'Medium', 'high' => 'High']"
:settings="[
'selectOnTab' => true,
'closeAfterSelect' => true,
'maxItems' => 3
]"
/>

With Option Count Plugin:

<x-select
id="courses"
:options="$courses"
:plugins="['option_count' => true]"
option-count-singular-noun="Course"
option-count-plural-noun="Courses"
/>

Non-Searchable Select:

<x-select
id="status"
:options="['active' => 'Active', 'inactive' => 'Inactive']"
:searchable="false"
/>

Livewire Integration:

<x-select
id="department"
:options="$departments"
wire:model="selectedDepartment"
ignore-livewire-updates
/>

When using search-url, your API endpoint should return JSON in this format:

[
{"value": "1", "text": "Option 1"},
{"value": "2", "text": "Option 2"}
]

The component automatically sends these query parameters:

  • q: The search query string
  • l: The maximum number of options to return

Displays a user’s Wildcard ID photo from Northwestern’s identity system. The component handles photo caching, URL generation with cache busting, and provides lazy loading for performance.

#user Required User | null

The User model instance to display the photo for

  • Cache Busting: Automatically includes a cache-busting parameter based on wildcard_photo_last_synced_at
  • Lazy Loading: Images load lazily to improve page performance
  • Fallback Support: Gracefully handles missing photos with a default route

Basic Usage:

<x-wildcard-photo :user="$user" />

With Custom Classes:

<x-wildcard-photo
:user="$user"
class="border-3"
/>

With Custom Size:

<x-wildcard-photo
:user="$user"
class="img-thumbnail"
style="width: 150px; height: 150px;"
/>