File size: 2,258 Bytes
7086abd
 
c5304fa
7086abd
c5304fa
 
 
7086abd
 
 
a1a6daf
 
 
 
 
 
 
7086abd
a1a6daf
 
7086abd
c5304fa
 
 
7086abd
c5304fa
 
 
a1a6daf
7086abd
c5304fa
 
 
 
 
 
a1a6daf
 
 
7086abd
 
7174ecf
06feee8
7174ecf
7086abd
 
d9327c0
a1a6daf
7086abd
 
 
c5304fa
 
 
d9327c0
c5304fa
d9327c0
 
7086abd
 
 
d90f53e
7086abd
 
 
6a0861b
7086abd
 
d9327c0
a1a6daf
7086abd
 
 
 
a1a6daf
7086abd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<script lang="ts">
	import { browser } from "$app/environment";
	import { beforeNavigate } from "$app/navigation";
	import { base } from "$app/paths";
	import { page } from "$app/state";
	import IconNew from "$lib/components/icons/IconNew.svelte";
	import { createEventDispatcher } from "svelte";
	import CarbonClose from "~icons/carbon/close";
	import CarbonTextAlignJustify from "~icons/carbon/text-align-justify";

	interface Props {
		isOpen?: boolean;
		title: string | undefined;
		children?: import("svelte").Snippet;
	}

	let { isOpen = false, title = $bindable(), children }: Props = $props();

	let closeEl: HTMLButtonElement | undefined = $state();
	let openEl: HTMLButtonElement | undefined = $state();

	$effect(() => {
		title ??= "New Chat";
	});

	const dispatch = createEventDispatcher();
	beforeNavigate(() => {
		dispatch("toggle", false);
	});

	let shouldFocusClose = $derived(isOpen && closeEl);
	let shouldRefocusOpen = $derived(!isOpen && browser && document.activeElement === closeEl);
	$effect(() => {
		if (shouldFocusClose) {
			closeEl?.focus();
		} else if (shouldRefocusOpen) {
			openEl?.focus();
		}
	});
</script>

<nav
	class="flex h-12 items-center justify-between border-b bg-gray-50 px-3 dark:border-gray-800 dark:bg-gray-800/70 md:hidden"
>
	<button
		type="button"
		class="-ml-3 flex size-12 shrink-0 items-center justify-center text-lg"
		onclick={() => dispatch("toggle", true)}
		aria-label="Open menu"
		bind:this={openEl}><CarbonTextAlignJustify /></button
	>
	<div class="flex h-full items-center justify-center">
		<span class="truncate px-4" data-testid="chat-title">{title}</span>
	</div>
	<a
		class:invisible={!page.params?.id}
		href="{base}/"
		class="-mr-3 flex size-12 shrink-0 items-center justify-center text-lg"><IconNew /></a
	>
</nav>
<nav
	class="fixed inset-0 z-30 grid max-h-screen grid-cols-1 grid-rows-[auto,auto,1fr,auto] bg-white dark:bg-gray-900 {isOpen
		? 'block'
		: 'hidden'}"
>
	<div class="flex h-12 items-center px-4">
		<button
			type="button"
			class="-mr-3 ml-auto flex size-12 items-center justify-center text-lg"
			onclick={() => dispatch("toggle", false)}
			aria-label="Close menu"
			bind:this={closeEl}><CarbonClose /></button
		>
	</div>
	{@render children?.()}
</nav>