@@ -8,6 +8,7 @@ type Props = HTMLAttributes<'div'> & {
88 controlCenterHref? : string ;
99 profileHref? : string ;
1010 signOutHref? : string ;
11+ inline? : boolean ;
1112};
1213
1314const {
@@ -18,6 +19,8 @@ const {
1819 // Arbitrary subpaths of /docs are blocked on the server side, returning to /docs is the best we can do
1920 signOutHref = ' https://octopus.com/signout?ReturnUrl=/docs' ,
2021
22+ inline = false ,
23+
2124 class : className,
2225 ... rest
2326} = Astro .props satisfies Props ;
@@ -30,32 +33,63 @@ const leaving = {
3033};
3134
3235const items: MenuItem [] = [
33- {
34- // Details start out empty, signed-in-user.ts fills things in through Menu's hooks
35- kind: ' detail' ,
36- label: ' ' ,
37- description: ' ' ,
38- data: { ' data-user-details' : ' ' },
39- },
36+ // Omit name/email when inline, as they're used as the row you press to expand the menu
37+ ... (inline
38+ ? []
39+ : [
40+ {
41+ // Details start out empty, signed-in-user.ts fills things in through Menu's hooks
42+ kind: ' detail' as const ,
43+ label: ' ' ,
44+ description: ' ' ,
45+ data: { ' data-user-details' : ' ' },
46+ },
47+ ]),
4048 { label: ' Control Center' , href: controlCenterHref , ... leaving },
4149 { label: ' Profile' , href: profileHref , ... leaving },
42- { kind: ' divider' } ,
50+ ... ( inline ? [] : [ { kind: ' divider' as const }]) ,
4351 { label: ' Sign out' , href: signOutHref },
4452];
4553---
4654
47- <div class:list ={ [' profile-menu' , className ]} {... rest }>
48- <Menu label ={ label } items ={ items } align =" end" width =" 16rem" >
49- <summary
50- slot =" trigger"
51- class =" profile-menu__trigger"
52- aria-label ={ label }
53- aria-haspopup =" menu"
54- >
55- <Avatar size =" medium" shape =" circle" alt =" " data-user-avatar >
56- <span data-user-initials ></span >
57- </Avatar >
58- </summary >
55+ <div
56+ class:list ={ [' profile-menu' , inline && ' profile-menu--inline' , className ]}
57+ {... rest }
58+ >
59+ <Menu
60+ label ={ label }
61+ items ={ items }
62+ align =" end"
63+ width =" 16rem"
64+ inline ={ inline }
65+ density ={ inline ? ' compact' : ' default' }
66+ >
67+ {
68+ inline ? (
69+ <summary
70+ slot = " trigger"
71+ class = " profile-menu__row"
72+ aria-haspopup = " menu"
73+ data-user-details
74+ >
75+ <span class = " profile-menu__labels" >
76+ <span class = " profile-menu__name" data-menu-label />
77+ <span class = " profile-menu__email" data-menu-description />
78+ </span >
79+ </summary >
80+ ) : (
81+ <summary
82+ slot = " trigger"
83+ class = " profile-menu__trigger"
84+ aria-label = { label }
85+ aria-haspopup = " menu"
86+ >
87+ <Avatar size = " medium" shape = " circle" alt = " " data-user-avatar >
88+ <span data-user-initials />
89+ </Avatar >
90+ </summary >
91+ )
92+ }
5993 </Menu >
6094</div >
6195
@@ -93,4 +127,67 @@ const items: MenuItem[] = [
93127 background-color: currentColor;
94128 mask: url('../assets/icons/external-link.svg') center / 80% no-repeat;
95129 }
130+
131+ .profile-menu--inline {
132+ display: block;
133+ }
134+
135+ .profile-menu__row {
136+ display: flex;
137+ align-items: center;
138+ gap: var(--space8);
139+ padding-block: var(--space6);
140+ list-style: none;
141+ color: var(--colorTextPrimary);
142+ text-decoration: none;
143+ cursor: pointer;
144+ }
145+
146+ .profile-menu__row::-webkit-details-marker {
147+ display: none;
148+ }
149+
150+ .profile-menu__row:focus-visible {
151+ outline: var(--borderWidth2) solid var(--colorBorderSelected);
152+ outline-offset: var(--borderWidth2);
153+ }
154+
155+ .profile-menu__labels {
156+ display: flex;
157+ flex: 1 1 auto;
158+ flex-direction: column;
159+ min-width: 0;
160+ color: var(--colorTextPrimary);
161+ text-decoration: none;
162+ }
163+
164+ .profile-menu__name {
165+ font: var(--textBodyRegularLarge);
166+ overflow-wrap: anywhere;
167+ }
168+
169+ .profile-menu__email {
170+ color: var(--colorTextSecondary);
171+ font: var(--textBodyRegularSmall);
172+ overflow-wrap: anywhere;
173+ }
174+
175+ .profile-menu__row::after {
176+ content: '';
177+ flex: none;
178+ width: 1.25rem;
179+ height: 1.25rem;
180+ background-color: var(--colorIconTertiary);
181+ mask: url('../assets/icons/chevron-right.svg') center / contain no-repeat;
182+ }
183+
184+ :global([open]) > .profile-menu__row::after {
185+ mask-image: url('../assets/icons/chevron-down.svg');
186+ }
187+
188+ .profile-menu--inline :global(.menu__item) {
189+ padding-inline: 0;
190+ padding-block: var(--space6);
191+ font: var(--textBodyRegularLarge);
192+ }
96193</style >
0 commit comments