this repo has no description
1---
2import type { nav } from "@/content/config";
3import { getEntry } from "astro:content";
4
5import Sidebar from "./Sidebar.astro";
6import Hamburger from "@/assets/hamburger.svg";
7
8const data = (await getEntry("nav", "urls")?.then((x) => x.data)) ?? [];
9---
10
11<nav>
12 <h1>🪤 | vielle.dev</h1>
13 <ul class="desktop">
14 {
15 (() => {
16 const a = (name: string, href: string) => <a {href}>{name}</a>;
17 const render = (
18 name: string,
19 children: nav[],
20 popout: boolean = true,
21 ) => {
22 const list = (
23 <ul>
24 {children.map((x) => (
25 <li>
26 {x.children
27 ? render(x.name, x.children, false)
28 : a(x.name, x.url || "")}
29 </li>
30 ))}
31 </ul>
32 );
33 return popout ? (
34 <details name="nav">
35 <summary>
36 <span>{name}</span>
37 </summary>
38 {list}
39 </details>
40 ) : (
41 <>
42 <span>{name}</span>
43 {list}
44 </>
45 );
46 };
47 return data.map((entry) => (
48 <li>
49 {entry.children
50 ? render(entry.name, entry.children)
51 : a(entry.name, entry.url || "")}
52 </li>
53 ));
54 })()
55 }
56 </ul>
57
58 <button class="mobile" popovertarget="sidebar"><Hamburger /></button>
59
60 <Sidebar />
61</nav>
62
63<style>
64 nav {
65 background-color: white;
66 color: black;
67 border: 5px solid black;
68 border-radius: 0 0 20px 20px;
69 box-shadow: 0 10px;
70 display: flex;
71 flex-direction: row;
72 align-items: center;
73 justify-content: center;
74 padding: 10px 40px;
75 }
76
77 nav > ul {
78 display: flex;
79 flex-direction: row;
80 align-items: center;
81 justify-content: center;
82 gap: 10px;
83
84 & > li {
85 list-style-type: none;
86 display: flex;
87 flex-direction: row;
88 align-items: center;
89 justify-content: center;
90 gap: 10px;
91 &:not(:first-child)::before {
92 content: "";
93 display: block;
94 width: 5px;
95 height: 5px;
96 border-radius: 2.5px;
97 background-color: currentColor;
98 }
99 }
100 }
101
102 details {
103 position: relative;
104
105 summary::marker {
106 content: url(../../assets/arrow-right.svg);
107 + {
108 margin-left: 5px;
109 }
110 }
111 &[open] > summary::marker {
112 content: url(../../assets/arrow-down.svg);
113 }
114 }
115
116 details > ul {
117 background-color: white;
118 border: 5px solid black;
119 border-radius: 20px;
120 box-shadow: 0 10px;
121
122 padding: 10px 20px;
123 width: max-content;
124
125 ul {
126 margin-left: 1em;
127 }
128 }
129
130 /* positioning */
131 details[open] {
132 anchor-name: --detail-anchor;
133 > ul {
134 position: absolute;
135
136 /* fallback for no anchor support */
137 right: -20px;
138
139 /* remove fallback when supported */
140 @supports (anchor-name: --supports-anchor) {
141 position: fixed;
142 right: unset;
143 }
144
145 /* anchor positioning. all properties should progressive enhance */
146 position-anchor: --detail-anchor;
147 position-area: bottom span-right;
148 position-try-fallbacks: flip-inline;
149 position-try: flip-inline;
150 }
151 }
152
153 h1 {
154 margin-right: auto;
155 font-size: 1.5rem;
156 white-space: nowrap;
157 }
158
159 button:has(svg) {
160 padding: 0;
161 border: none;
162 background-color: transparent;
163
164 width: 2em;
165 height: 2em;
166
167 & svg {
168 width: 100%;
169 height: 100%;
170 }
171 }
172
173 .mobile {
174 display: none;
175 }
176
177 @media screen and (max-width: 650px) {
178 .mobile {
179 display: var(--display, block) !important;
180 }
181
182 .desktop {
183 display: none !important;
184 }
185 }
186</style>