Skip to content

Commit

Permalink
feat: modal component (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
ell-ska authored Feb 7, 2025
2 parents 6d0fb72 + ca961f0 commit 7eff6b5
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 1 deletion.
7 changes: 6 additions & 1 deletion resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}
}

@layer utils {
@layer utilities {
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
Expand All @@ -29,4 +29,9 @@
-ms-overflow-style: none;
scrollbar-width: none;
}

/* this is used by alpine.js to properly hide elements on load */
[x-cloak] {
@apply hidden;
}
}
67 changes: 67 additions & 0 deletions resources/views/components/modal/base.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@props([
'name',
'show' => false,
])

<div
x-data="{
show: @js($show),
focusables() {
const selector = 'a, button, input:not([type=\'hidden\']), textarea, select, details, [tabindex]:not([tabindex=\'-1\'])'
return [...$el.querySelectorAll(selector)].filter(element => !element.hasAttribute('disabled'))
},
firstFocusable() {
return this.focusables()[0]
},
lastFocusable() {
return this.focusables().slice(-1)[0]
},
nextFocusable() {
const focusables = this.focusables()
const nextFocusableIndex = (focusables.indexOf(document.activeElement) + 1) % (focusables.length + 1)
return focusables[nextFocusableIndex] || this.firstFocusable()
},
prevFocusable() {
const focusables = this.focusables()
const prevFocusableIndex = Math.max(0, focusables.indexOf(document.activeElement)) -1
return focusables[prevFocusableIndex] || this.lastFocusable()
},
}"
x-show="show"
x-init="
$watch('show', (show) => {
if (show) {
document.body.classList.add('overflow-hidden')
} else {
document.body.classList.remove('overflow-hidden')
}
})
"
x-on:open-modal.window="
if ($event.detail === '{{ $name }}') {
show = true
}
"
x-on:close-modal.window="
if ($event.detail === '{{ $name }}') {
show = false
}
"
x-on:keydown.escape.window="show = false"
x-on:keydown.tab.prevent="$event.shiftKey || nextFocusable().focus()"
x-on:keydown.shift.tab.prevent="prevFocusable().focus()"
x-cloak
@class([
'flex' => $show,
'hidden' => "$show",
'fixed inset-0 flex justify-center overflow-y-scroll',
])
>
<div
@click="show = false"
class="absolute inset-0 bg-slate-800/80 backdrop-blur-sm"
></div>
{{ $slot }}
</div>
8 changes: 8 additions & 0 deletions resources/views/components/modal/input.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div
class="relative flex w-full flex-col gap-2 self-end sm:max-w-xl sm:self-center"
>
<x-modal.title>{{ $title }}</x-modal.title>
<div class="w-full bg-slate-700 px-4 pt-4 pb-8 sm:rounded-2xl sm:p-4">
{{ $slot }}
</div>
</div>
10 changes: 10 additions & 0 deletions resources/views/components/modal/menu.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div
class="relative flex w-full flex-col gap-2 self-end sm:max-w-xl sm:self-center"
>
<x-modal.title>{{ $title }}</x-modal.title>
<div
class="flex w-full flex-col gap-2 divide-y-1 divide-slate-600 bg-slate-700 px-2 pt-4 pb-8 sm:rounded-2xl sm:p-2 [&>*]:pb-2"
>
{{ $slot }}
</div>
</div>
3 changes: 3 additions & 0 deletions resources/views/components/modal/title.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="text-center text-lg font-bold text-slate-50 sm:text-xl">
{{ $slot }}
</div>

0 comments on commit 7eff6b5

Please sign in to comment.