Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add desktop/mobile navigation #74

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@
"autoload": {
"psr-4": {
"Rapidez\\Statamic\\": "src"
}
},
"files": [
"src/Helpers/UrlHelper.php"
]
},
"config": {
"sort-packages": true,
Expand Down
56 changes: 56 additions & 0 deletions resources/views/components/nav-layer.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@props(['id', 'children', 'title' => __('Menu'), 'hasParent' => false, 'tag' => 'form', 'parentUrl' => ''])
@slots(['headerbutton'])
@php
$baseUrl = \Statamic\Facades\Site::current()->absoluteUrl();
@endphp
<x-rapidez::slideover.mobile
:title="(string) $title"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the casting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise I get this error
image

:$id
:$hasParent
:$tag
>
<x-slot:headerbutton>
JimmyHoenderdaal marked this conversation as resolved.
Show resolved Hide resolved
<div class="absolute left-0 top-1/2 -translate-y-1/2 cursor-pointer text-white">
@include('rapidez-statamic::navigation.header-button')
</div>
</x-slot:headerbutton>
<div class="bg-inactive-100 flex w-full flex-1 flex-col">
<ul class="mt-5 flex flex-col divide-y border-y bg-white">
@if ($hasParent && $parentUrl)
<li>
<a href="{{ $parentUrl }}" class="normal flex items-center justify-between p-5 font-semibold">
@lang('Go to :item', ['item' => strtolower($title)])
</a>
</li>
@endif
@foreach ($children ?: [] as $child)
@php
$url = getItemUrl($child, $baseUrl);
@endphp
<li class="relative">
@if ($child['title'] ?? '')
<a href="{{ $url }}" class="flex items-center justify-between p-5 font-semibold">
{{ $child['title'] }}
@if ($child['children'])
<x-heroicon-o-chevron-right class="size-4" />
@endif
</a>
@endif
@if ($child['children'])
@php($childId = uniqid(Str::snake("{$child['title']}" ?? '')))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This vs unique helpers provide by Laravel? Don't we have a unique ID already which we can use?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is using uniqid but it adds snake case to the title for whenever there are spaces in the title
image

I want to use the title here since it makes it more clear what id's and for's are linked to each other in your browser.
Could of course remove that part and only have uniqid but that would make the id a bit abstract and thus hard to debug if needed

<label class="absolute inset-0 cursor-pointer" for="{{ $childId }}"></label>
<x-rapidez-statamic::nav-layer
:id="$childId"
:children="$child['children'] ?? []"
:title="$child['title'] ?? ''"
:parent-url="$child['url']"
has-parent
tag="div"
></x-rapidez-statamic::nav-layer>
@endif
</li>
@endforeach
</ul>
{{ $slot }}
</div>
</x-rapidez::slideover.mobile>
1 change: 1 addition & 0 deletions resources/views/navigation/header-button.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{-- This is shown on the first slideover of the mobile menu, this is empty by default but can be overridden --}}
60 changes: 60 additions & 0 deletions resources/views/navigation/nav.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@props(['nav' => 'nav:main', 'mobileNav' => 'nav:main'])
@php
// This combines multiple navigations into one for desktop and mobile seperately, only neccessary if you have multiple navigations
$navData = array_merge(...Arr::map(Arr::wrap($nav), fn($item) => Statamic::tag($item)->fetch()));
$mobileNavData = array_merge(...Arr::map(Arr::wrap($mobileNav), fn($item) => Statamic::tag($item)->fetch()));
@endphp
<nav class="lg:hidden">
<x-rapidez-statamic::nav-layer
id="navigation"
is-form
:children="$mobileNavData"
/>
</nav>
@php
$baseUrl = \Statamic\Facades\Site::current()->absoluteUrl();
@endphp
<nav class="relative border-y max-lg:hidden">
<ul class="text-neutral [&>:not(:hover)]:hover:text-inactive flex items-center justify-center gap-8 text-sm font-semibold">
@foreach ($navData as $item)
@php
$itemUrl = getItemUrl($item, $baseUrl);
@endphp
<li class="group">
<a class="relative flex py-5 transition" href="{{ $itemUrl }}">
{{ $item['title'] }}
@if ($item['children'])
<div class="bg-primary absolute inset-x-0 bottom-0 z-50 h-0.5 w-full origin-right translate-y-1/2 scale-x-0 transition group-hover:origin-left group-hover:scale-x-100"></div>
@endif
</a>
@if ($item['children'])
<div class="pointer-events-none absolute inset-x-0 top-full -translate-y-1 border-t bg-white opacity-0 transition group-hover:pointer-events-auto group-hover:translate-y-0 group-hover:opacity-100">
<div class="bg-neutral/50 pointer-events-none absolute inset-x-0 top-full h-screen"></div>
<div class="container relative flex overflow-hidden">
<ul class="w-full columns-3 flex-col gap-x-12 py-10 font-bold xl:columns-4">
@foreach ($item['children'] as $item)
@php
$itemUrl = getItemUrl($item, $baseUrl);
@endphp
<li class="flex break-inside-avoid flex-col gap-1 pb-5">
<a href="{{ $itemUrl }}">{{ $item['title'] }}</a>
<ul class="[&>:not(:hover)]:hover:text-inactive flex flex-col font-medium">
@foreach ($item['children'] as $item)
@php
$itemUrl = getItemUrl($item, $baseUrl);
@endphp
<li class="transition">
<a href="{{ $itemUrl }}">{{ $item['title'] }}</a>
</li>
@endforeach
</ul>
</li>
@endforeach
</ul>
</div>
</div>
@endif
</li>
@endforeach
</ul>
</nav>
16 changes: 16 additions & 0 deletions src/Helpers/UrlHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

if (!function_exists('getItemUrl')) {
function getItemUrl($item, $baseUrl)
{
$types = ['linked_product', 'linked_category', 'linked_brand'];

foreach ($types as $type) {
if (isset($item[$type]) && ($item[$type]?->value()['url_path'] ?? false)) {
return $baseUrl . '/' . $item[$type]->value()['url_path'];
}
}

return $item['url'] ?? '';
}
}