generated from boboko/starter
general products page and small rewrite of search and category controllers etc
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
|
||||
{{-- Products (CSS-only hover dropdown) --}}
|
||||
<div class="group relative h-full flex items-center">
|
||||
<a href="{{ url('/'.app()->getLocale().'/products') }}" class="nav-link uppercase inline-flex items-center gap-1 relative font-display font-extrabold italic text-black no-underline py-8">
|
||||
<a href="{{ route('products') }}" class="nav-link uppercase inline-flex items-center gap-1 relative font-display font-extrabold italic text-black no-underline py-8">
|
||||
<span>{{ __('storefront.nav.products') }}</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4 not-italic transition-transform group-hover:rotate-180">
|
||||
<path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
|
||||
@@ -47,10 +47,18 @@
|
||||
</a>
|
||||
|
||||
{{-- Search --}}
|
||||
<button type="button" class="flex items-center justify-center w-10 h-10 hover:opacity-70 transition-opacity" aria-label="Search">
|
||||
<button
|
||||
type="button"
|
||||
popovertarget="search-overlay"
|
||||
popovertargetaction="toggle"
|
||||
class="flex items-center justify-center w-10 h-10 hover:opacity-70 transition-opacity"
|
||||
aria-label="{{ __('storefront.shop.search_label') }}"
|
||||
>
|
||||
<x-ui.icon name="search" :size="40" />
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-search-overlay />
|
||||
</header>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{{--
|
||||
Full-width search bar that covers the header. A [popover] (top layer, so it
|
||||
sits over the sticky header with no z-index juggling; Escape and click-away
|
||||
close come for free). The header's search button opens it via popovertarget.
|
||||
The `nav-search` controller measures the header on open (→ --search-overlay-h,
|
||||
since the header isn't a fixed height below `lg`) and focuses the field.
|
||||
Fade transition lives in app.css (#search-overlay).
|
||||
--}}
|
||||
<div
|
||||
id="search-overlay"
|
||||
popover
|
||||
data-controller="nav-search"
|
||||
class="fixed w-full inset-x-0 top-0 bottom-auto m-0 h-[var(--search-overlay-h)] border-0 bg-brand p-0"
|
||||
>
|
||||
<form
|
||||
method="get"
|
||||
action="{{ route('search') }}"
|
||||
class="flex h-full items-center gap-6 px-10"
|
||||
>
|
||||
<label for="search-overlay-input" class="sr-only">{{ __('storefront.shop.search_label') }}</label>
|
||||
<input
|
||||
id="search-overlay-input"
|
||||
type="search"
|
||||
name="q"
|
||||
required
|
||||
autocomplete="off"
|
||||
data-nav-search-target="input"
|
||||
placeholder="{{ __('storefront.search.placeholder') }}"
|
||||
class="min-w-0 flex-1 appearance-none border-0 border-b border-black bg-transparent pb-2 placeholder:text-black/60 focus:outline-none [&::-webkit-search-cancel-button]:appearance-none"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
popovertarget="search-overlay"
|
||||
popovertargetaction="hide"
|
||||
aria-label="{{ __('storefront.nav.close') }}"
|
||||
class="shrink-0 text-black transition-opacity hover:opacity-70"
|
||||
>
|
||||
<x-ui.icon name="close" :size="44" />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
@props(['paginator'])
|
||||
|
||||
{{-- "Showing 1–12 of 48 products" — takes any LengthAwarePaginator. Shared by
|
||||
the category listing and the search results page. --}}
|
||||
<p {{ $attributes }}>
|
||||
{{ trans_choice('storefront.shop.showing_results', $paginator->total(), [
|
||||
'first' => $paginator->firstItem() ?? 0,
|
||||
'last' => $paginator->lastItem() ?? 0,
|
||||
'total' => $paginator->total(),
|
||||
]) }}
|
||||
</p>
|
||||
@@ -0,0 +1,24 @@
|
||||
@props([
|
||||
'options', // [['label' => string, 'href' => string, 'current' => bool], ...] — build with App\Catalog\ProductSortOptions
|
||||
'id' => 'sort',
|
||||
])
|
||||
|
||||
{{-- Product sort dropdown. Options are plain links (built per page, so each can
|
||||
carry its own state); following one navigates the enclosing turbo-frame and
|
||||
advances the URL. Shared by the category listing and search results. --}}
|
||||
@php
|
||||
$active = collect($options)->firstWhere('current', true) ?? ($options[0] ?? ['label' => '']);
|
||||
@endphp
|
||||
|
||||
<x-ui.dropdown
|
||||
:id="$id"
|
||||
:label="$active['label']"
|
||||
:ariaLabel="__('storefront.shop.sort_label')"
|
||||
triggerClass="min-w-48"
|
||||
>
|
||||
@foreach ($options as $option)
|
||||
<x-ui.dropdown.item :href="$option['href']" :current="$option['current'] ?? false">
|
||||
{{ $option['label'] }}
|
||||
</x-ui.dropdown.item>
|
||||
@endforeach
|
||||
</x-ui.dropdown>
|
||||
Reference in New Issue
Block a user