54 lines
2.3 KiB
PHP
54 lines
2.3 KiB
PHP
@props([
|
|
'variant' => 'primary',
|
|
'size' => 'md',
|
|
'type' => 'button',
|
|
'loading' => false,
|
|
// Given an href this renders an anchor instead. A link that looks like a
|
|
// button must still BE a link: middle-click, "open in new tab" and the
|
|
// status bar all come from the element, not from the styling.
|
|
'href' => null,
|
|
])
|
|
@php
|
|
$base = 'inline-flex items-center justify-center gap-2 rounded-[10px] font-semibold leading-none transition select-none disabled:opacity-50 disabled:pointer-events-none';
|
|
|
|
$sizes = [
|
|
'sm' => 'min-h-8 px-3 text-[13px]',
|
|
'md' => 'min-h-10 px-[18px] text-[14px]',
|
|
'lg' => 'min-h-[46px] px-[22px] text-[15px]',
|
|
];
|
|
|
|
// Accent buttons use the AA-safe darker fill (#c2560a) so white text passes
|
|
// WCAG AA; #f97316 alone is only ~2.8:1 (design handoff §6.1).
|
|
$variants = [
|
|
'primary' => 'bg-accent-active text-on-accent hover:bg-accent-press',
|
|
'secondary' => 'border border-line-strong bg-surface text-body hover:bg-surface-hover',
|
|
'ghost' => 'text-body hover:bg-surface-hover',
|
|
'danger' => 'bg-danger text-on-accent hover:opacity-90',
|
|
// The document primary: ink on paper, warming to the accent on hover.
|
|
// Orange is the accent, not the loudest thing on the page — on a sheet
|
|
// full of hairlines a filled orange button is the only thing anyone
|
|
// sees, and it is rarely the most important thing on the page.
|
|
'ink' => 'bg-ink text-bg hover:bg-accent-text',
|
|
];
|
|
|
|
$classes = $base.' '.($sizes[$size] ?? $sizes['md']).' '.($variants[$variant] ?? $variants['primary']);
|
|
@endphp
|
|
@if ($href !== null)
|
|
<a href="{{ $href }}" {{ $attributes->merge(['class' => $classes]) }}>{{ $slot }}</a>
|
|
@else
|
|
<button
|
|
type="{{ $type }}"
|
|
{{ $attributes->merge(['class' => $classes]) }}
|
|
@disabled($loading)
|
|
@if ($loading) aria-busy="true" @endif
|
|
>
|
|
@if ($loading)
|
|
<svg class="size-4 animate-spin" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 0 1 8-8V0C5.4 0 0 5.4 0 12h4z"></path>
|
|
</svg>
|
|
@endif
|
|
{{ $slot }}
|
|
</button>
|
|
@endif
|