Skip to main content

Actions

Button code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/button.blade.php

@props([
    'variant' => 'primary',
    'size' => 'base',
    'href' => null,
    'icon' => null,
    'iconTrailing' => null,
    'iconWeight' => 'bold',
    'loading' => false,
    'block' => false,
    'type' => 'submit',
])

@php
    /*
    | Polymorphic button. Renders an <a> when `href` is set, otherwise a <button>.
    |
    | Variants: primary, secondary, outline, ghost, danger, success, link
    | Sizes:    xs, sm, base, lg, xl
    |
    | Usage:
    |   <x-ui.button>Save</x-ui.button>
    |   <x-ui.button variant="outline" icon="plus">New</x-ui.button>
    |   <x-ui.button href="/pricing" variant="ghost" icon-trailing="arrow-right">Pricing</x-ui.button>
    */
    $base = 'inline-flex items-center justify-center gap-2 font-semibold rounded-lg transition-[box-shadow,border-color,color,transform] ease-in-out duration-150 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:pointer-events-none cursor-pointer whitespace-nowrap';

    $variants = [
        'primary' => 'bg-brand-600 text-white shadow-sm hover:bg-brand-500 active:bg-brand-700 focus:ring-brand-500',
        'secondary' => 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-700 focus:ring-gray-400',
        'outline' => 'bg-transparent border border-brand-300 text-brand-700 hover:bg-brand-50 focus:ring-brand-500 dark:border-brand-700 dark:text-brand-300 dark:hover:bg-brand-950/40',
        'ghost' => 'bg-transparent text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:ring-gray-400',
        'danger' => 'bg-red-600 text-white shadow-sm hover:bg-red-500 active:bg-red-700 focus:ring-red-500',
        'success' => 'bg-green-600 text-white shadow-sm hover:bg-green-500 active:bg-green-700 focus:ring-green-500',
        'accent' => 'bg-accent-600 text-white shadow-sm hover:bg-accent-500 active:bg-accent-700 focus:ring-accent-500',
        'link' => 'bg-transparent text-brand-600 dark:text-brand-400 hover:text-brand-500 hover:underline underline-offset-4 focus:ring-brand-500 !p-0',
    ];

    $sizes = [
        'xs' => 'text-xs px-2.5 py-1.5',
        'sm' => 'text-sm px-3 py-2',
        'base' => 'text-sm px-4 py-2.5',
        'lg' => 'text-base px-5 py-3',
        'xl' => 'text-base px-6 py-3.5',
    ];

    $iconSize = [
        'xs' => 'sm', 'sm' => 'sm', 'base' => 'base', 'lg' => 'lg', 'xl' => 'lg',
    ][$size] ?? 'base';

    $classes = implode(' ', [
        $base,
        $variants[$variant] ?? $variants['primary'],
        $sizes[$size] ?? $sizes['base'],
        $block ? 'w-full' : '',
    ]);
@endphp

@if ($href)
    <a href="{{ $href }}" {{ $attributes->merge(['class' => $classes]) }}>
        @if ($loading)
            <x-ui.icon name="spinner-gap" :size="$iconSize" class="animate-spin" />
        @elseif ($icon)
            <x-ui.icon :name="$icon" :weight="$iconWeight" :size="$iconSize" />
        @endif
        {{ $slot }}
        @if ($iconTrailing)
            <x-ui.icon :name="$iconTrailing" :weight="$iconWeight" :size="$iconSize" />
        @endif
    </a>
@else
    <button type="{{ $type }}" @disabled($loading) {{ $attributes->merge(['class' => $classes]) }}>
        @if ($loading)
            <x-ui.icon name="spinner-gap" :size="$iconSize" class="animate-spin" />
        @elseif ($icon)
            <x-ui.icon :name="$icon" :weight="$iconWeight" :size="$iconSize" />
        @endif
        {{ $slot }}
        @if ($iconTrailing)
            <x-ui.icon :name="$iconTrailing" :weight="$iconWeight" :size="$iconSize" />
        @endif
    </button>
@endif

resources/views/components/ui/button/cancel.blade.php

@props([
    'variant' => 'ghost',
    'icon' => 'x',
    'type' => 'button',
])

@php
    /*
    | CRUD action button: Cancel. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.cancel :href="route('posts.index')" />
    |   <x-ui.button.cancel>Discard</x-ui.button.cancel>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Cancel' : $slot }}
</x-ui.button>

resources/views/components/ui/button/create.blade.php

@props([
    'variant' => 'primary',
    'icon' => 'plus',
    'type' => 'submit',
])

@php
    /*
    | CRUD action button: Create. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.create />
    |   <x-ui.button.create :href="route('posts.create')">New post</x-ui.button.create>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Create' : $slot }}
</x-ui.button>

resources/views/components/ui/button/delete.blade.php

@props([
    'variant' => 'danger',
    'icon' => 'trash',
    'type' => 'submit',
])

@php
    /*
    | CRUD action button: Delete. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.delete />
    |   <x-ui.button.delete size="sm">Delete post</x-ui.button.delete>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Delete' : $slot }}
</x-ui.button>

resources/views/components/ui/button/edit.blade.php

@props([
    'variant' => 'outline',
    'icon' => 'pencil-simple',
    'type' => 'button',
])

@php
    /*
    | CRUD action button: Edit. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.edit :href="route('posts.edit', $post)" />
    |   <x-ui.button.edit size="sm">Edit post</x-ui.button.edit>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Edit' : $slot }}
</x-ui.button>

resources/views/components/ui/button/save.blade.php

@props([
    'variant' => 'primary',
    'icon' => 'floppy-disk',
    'type' => 'submit',
])

@php
    /*
    | CRUD action button: Save. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.save />
    |   <x-ui.button.save :loading="$saving">Save changes</x-ui.button.save>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Save' : $slot }}
</x-ui.button>

resources/views/components/ui/button/update.blade.php

@props([
    'variant' => 'primary',
    'icon' => 'arrows-clockwise',
    'type' => 'submit',
])

@php
    /*
    | CRUD action button: Update. Thin wrapper over <x-ui.button> with sensible
    | defaults. Any prop (size, loading, href, variant, icon...) can be
    | overridden and is forwarded to the underlying button.
    |
    | Usage:
    |   <x-ui.button.update />
    |   <x-ui.button.update :loading="$saving">Update post</x-ui.button.update>
    */
@endphp

<x-ui.button :variant="$variant" :icon="$icon" :type="$type" {{ $attributes }}>
    {{ $slot->isEmpty() ? 'Update' : $slot }}
</x-ui.button>