Skip to content

Commit ffe9a20

Browse files
feat: navigation menu (#3706)
* chore: bump zag js * chore: add navigation-menu to all frameworks * chore: wip * chore: wip * refactor: remove viewport context * refactor: basic version * feat: add presence * refactor: remove unnecessary Assign type * feat: add navigation menu for solid * feat: add navigation menu for vue * feat: add navigation menu for svelte * fix: export missing anatomy * refactor: cleanup * refactor: prefer context * chore: update * fix: svelte * refactor: dont export proxy component --------- Co-authored-by: Segun Adebayo <[email protected]>
1 parent 8486e69 commit ffe9a20

File tree

113 files changed

+3942
-282
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+3942
-282
lines changed

.storybook/styles.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
@import url('./styles/json-tree-view.css');
1919
@import url('./styles/listbox.css');
2020
@import url('./styles/menu.css');
21+
@import url('./styles/navigation-menu.css');
2122
@import url('./styles/number-input.css');
2223
@import url('./styles/pagination.css');
2324
@import url('./styles/password-input.css');
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
@keyframes nav-menu-from-right {
2+
from {
3+
transform: translate3d(200px, 0, 0);
4+
opacity: 0;
5+
}
6+
to {
7+
transform: translate3d(0, 0, 0);
8+
opacity: 1;
9+
}
10+
}
11+
12+
@keyframes nav-menu-from-left {
13+
from {
14+
transform: translate3d(-200px, 0, 0);
15+
opacity: 0;
16+
}
17+
to {
18+
transform: translate3d(0, 0, 0);
19+
opacity: 1;
20+
}
21+
}
22+
23+
@keyframes nav-menu-to-right {
24+
from {
25+
transform: translate3d(0, 0, 0);
26+
opacity: 1;
27+
}
28+
to {
29+
transform: translate3d(200px, 0, 0);
30+
opacity: 0;
31+
}
32+
}
33+
34+
@keyframes nav-menu-to-left {
35+
from {
36+
transform: translate3d(0, 0, 0);
37+
opacity: 1;
38+
}
39+
to {
40+
transform: translate3d(-200px, 0, 0);
41+
opacity: 0;
42+
}
43+
}
44+
45+
@keyframes nav-menu-scale-in {
46+
from {
47+
transform: rotateX(-30deg) scale(0.9);
48+
opacity: 0;
49+
}
50+
to {
51+
transform: rotateX(0deg) scale(1);
52+
opacity: 1;
53+
}
54+
}
55+
56+
@keyframes nav-menu-scale-out {
57+
from {
58+
transform: rotateX(0deg) scale(1);
59+
opacity: 1;
60+
}
61+
to {
62+
transform: rotateX(-10deg) scale(0.95);
63+
opacity: 0;
64+
}
65+
}
66+
67+
@keyframes nav-menu-fade-in {
68+
from {
69+
opacity: 0;
70+
}
71+
to {
72+
opacity: 1;
73+
}
74+
}
75+
76+
@keyframes nav-menu-fade-out {
77+
from {
78+
opacity: 1;
79+
}
80+
to {
81+
opacity: 0;
82+
}
83+
}
84+
85+
[data-scope='navigation-menu'][data-part='root'] {
86+
--arrow-size: 20px;
87+
--indicator-size: 10px;
88+
position: relative;
89+
}
90+
91+
[data-scope='navigation-menu'][data-part='list'] {
92+
all: unset;
93+
list-style: none;
94+
display: flex;
95+
}
96+
97+
[data-scope='navigation-menu'][data-part='item'] {
98+
position: relative;
99+
}
100+
101+
.viewport [data-scope='navigation-menu'][data-part='item'] {
102+
position: unset;
103+
}
104+
105+
[data-scope='navigation-menu'][data-part='trigger'] {
106+
padding: 10px 16px;
107+
font-weight: bold;
108+
display: flex;
109+
align-items: center;
110+
border: 0;
111+
background: transparent;
112+
font-size: inherit;
113+
gap: 4px;
114+
}
115+
116+
[data-scope='navigation-menu'][data-part='link'] {
117+
padding: 10px 16px;
118+
font-weight: bold;
119+
display: block;
120+
color: inherit;
121+
text-decoration: none;
122+
123+
&:hover {
124+
text-decoration: underline;
125+
}
126+
}
127+
128+
[data-scope='navigation-menu'][data-part='content'] {
129+
position: absolute;
130+
width: max-content;
131+
left: 0;
132+
margin-top: 5px;
133+
border-radius: 10px;
134+
z-index: 1;
135+
}
136+
137+
[data-scope='navigation-menu'][data-part='root']:not(.viewport) [data-scope='navigation-menu'][data-part='content'] {
138+
top: 100%;
139+
padding: 20px;
140+
background-color: white;
141+
box-shadow:
142+
0 10px 100px -20px rgba(50, 50, 93, 0.25),
143+
0 30px 60px -30px rgba(0, 0, 0, 0.3);
144+
145+
&[data-state='open'] {
146+
animation: nav-menu-scale-in 250ms ease;
147+
}
148+
149+
&[data-state='closed'] {
150+
animation: nav-menu-scale-out 250ms ease;
151+
}
152+
}
153+
154+
[data-scope='navigation-menu'][data-part='root'].viewport [data-scope='navigation-menu'][data-part='content'] {
155+
top: 0;
156+
padding: 40px;
157+
display: grid;
158+
gap: 20px;
159+
will-change: transform, opacity;
160+
161+
background-color: transparent;
162+
box-shadow: none;
163+
164+
&[data-motion='from-start'] {
165+
animation: nav-menu-from-left 250ms ease;
166+
}
167+
168+
&[data-motion='from-end'] {
169+
animation: nav-menu-from-right 250ms ease;
170+
}
171+
172+
&[data-motion='to-start'] {
173+
animation: nav-menu-to-left 250ms ease;
174+
}
175+
176+
&[data-motion='to-end'] {
177+
animation: nav-menu-to-right 250ms ease;
178+
}
179+
}
180+
181+
[data-scope='navigation-menu'][data-part='viewport'] {
182+
position: relative;
183+
top: 0;
184+
left: 0;
185+
background-color: white;
186+
transition:
187+
width 300ms ease,
188+
height 300ms ease;
189+
width: var(--viewport-width);
190+
height: var(--viewport-height);
191+
transform-origin: top center;
192+
overflow: hidden;
193+
border-radius: 8px;
194+
box-shadow:
195+
hsl(206 22% 7% / 35%) 0px 10px 38px -10px,
196+
hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
197+
margin-top: var(--indicator-size);
198+
199+
&[data-state='open'] {
200+
animation: nav-menu-scale-in 200ms ease;
201+
}
202+
203+
&[data-state='closed'] {
204+
animation: nav-menu-scale-out 200ms ease;
205+
}
206+
}
207+
208+
[data-scope='navigation-menu'][data-part='viewport-positioner'] {
209+
position: absolute;
210+
width: max-content;
211+
}
212+
213+
/* Indicator + Arrow */
214+
[data-scope='navigation-menu'][data-part='arrow'] {
215+
position: relative;
216+
top: 4px;
217+
width: var(--arrow-size);
218+
height: var(--arrow-size);
219+
background-color: white;
220+
rotate: 45deg;
221+
border-radius: 3px;
222+
}
223+
224+
[data-scope='navigation-menu'][data-part='indicator'] {
225+
display: flex;
226+
justify-content: center;
227+
height: var(--indicator-size);
228+
z-index: 1;
229+
230+
&[data-orientation='horizontal'] {
231+
left: 0px;
232+
translate: var(--trigger-x) 0;
233+
top: calc(var(--indicator-size) * -1);
234+
width: var(--trigger-width);
235+
}
236+
237+
&[data-state='open'] {
238+
animation: nav-menu-fade-in 250ms ease;
239+
}
240+
241+
&[data-state='closed'] {
242+
animation: nav-menu-fade-out 250ms ease;
243+
}
244+
}
245+
246+
.viewport [data-scope='navigation-menu'][data-part='indicator'] {
247+
top: unset;
248+
bottom: calc(var(--indicator-size) * -1);
249+
transition:
250+
translate 250ms ease,
251+
width 250ms ease;
252+
}

0 commit comments

Comments
 (0)