@campminder/components 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/{property-B5JHHBCF.js → shell-tokens-BjECzZvL.js} +47 -43
- package/dist/shell-tokens.d.ts +39 -0
- package/dist/shell-tokens.test.d.ts +1 -0
- package/dist/side-nav/MegaMenu.d.ts +9 -1
- package/dist/side-nav/MegaMenuMobile.d.ts +46 -0
- package/dist/side-nav/MegaMenuMobile.styles.d.ts +11 -0
- package/dist/side-nav/SideNav.d.ts +111 -3
- package/dist/side-nav/SideNav.styles.d.ts +9 -0
- package/dist/side-nav/Utils/render-leaf.d.ts +3 -0
- package/dist/side-nav/mega-menu-focus.test.d.ts +1 -0
- package/dist/side-nav/mega-menu-isolation.test.d.ts +1 -0
- package/dist/side-nav/mega-menu-layout.d.ts +11 -0
- package/dist/side-nav/mega-menu-mobile-focus.test.d.ts +1 -0
- package/dist/side-nav/mega-menu-mobile.test.d.ts +1 -0
- package/dist/side-nav/side-nav-styles-cascade.test.d.ts +1 -0
- package/dist/side-nav.js +880 -326
- package/dist/{state-Ns9O6R8g.js → state-BvQoY71J.js} +1 -1
- package/dist/super-user-banner.js +16 -10
- package/dist/top-bar.js +85 -79
- package/package.json +1 -1
package/dist/side-nav.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { r as
|
|
1
|
+
import { A, b as n, S as C, i as b, n as h, a as w, t as y } from "./shell-tokens-BjECzZvL.js";
|
|
2
|
+
import { r as m } from "./state-BvQoY71J.js";
|
|
3
3
|
/**
|
|
4
4
|
* @license
|
|
5
5
|
* Copyright 2018 Google LLC
|
|
6
6
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
7
7
|
*/
|
|
8
|
-
const
|
|
8
|
+
const v = (e) => e ?? A, R = n` <svg
|
|
9
9
|
width="20"
|
|
10
10
|
height="20"
|
|
11
11
|
viewBox="0 0 20 20"
|
|
@@ -16,7 +16,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
16
16
|
d="M15 1.6665H5.00001C4.08334 1.6665 3.33334 2.4165 3.33334 3.33317V16.6665C3.33334 17.5832 4.08334 18.3332 5.00001 18.3332H15C15.9167 18.3332 16.6667 17.5832 16.6667 16.6665V3.33317C16.6667 2.4165 15.9167 1.6665 15 1.6665ZM5.00001 3.33317H9.16668V9.99984L7.08334 8.74984L5.00001 9.99984V3.33317Z"
|
|
17
17
|
fill="white"
|
|
18
18
|
/>
|
|
19
|
-
</svg>`,
|
|
19
|
+
</svg>`, D = n`<svg
|
|
20
20
|
width="20"
|
|
21
21
|
height="20"
|
|
22
22
|
viewBox="0 0 20 20"
|
|
@@ -27,7 +27,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
27
27
|
d="M15.95 10.7833C15.9833 10.5333 16 10.275 16 10C16 9.73333 15.9833 9.46667 15.9417 9.21667L17.6333 7.9C17.7833 7.78333 17.825 7.55833 17.7333 7.39167L16.1333 4.625C16.0333 4.44167 15.825 4.38333 15.6417 4.44167L13.65 5.24167C13.2333 4.925 12.7917 4.65833 12.3 4.45833L12 2.34167C11.9667 2.14167 11.8 2 11.6 2H8.39999C8.19999 2 8.04166 2.14167 8.00832 2.34167L7.70832 4.45833C7.21666 4.65833 6.76666 4.93333 6.35832 5.24167L4.36666 4.44167C4.18332 4.375 3.97499 4.44167 3.87499 4.625L2.28332 7.39167C2.18332 7.56667 2.21666 7.78333 2.38332 7.9L4.07499 9.21667C4.03332 9.46667 3.99999 9.74167 3.99999 10C3.99999 10.2583 4.01666 10.5333 4.05832 10.7833L2.36666 12.1C2.21666 12.2167 2.17499 12.4417 2.26666 12.6083L3.86666 15.375C3.96666 15.5583 4.17499 15.6167 4.35832 15.5583L6.34999 14.7583C6.76666 15.075 7.20832 15.3417 7.69999 15.5417L7.99999 17.6583C8.04166 17.8583 8.19999 18 8.39999 18H11.6C11.8 18 11.9667 17.8583 11.9917 17.6583L12.2917 15.5417C12.7833 15.3417 13.2333 15.075 13.6417 14.7583L15.6333 15.5583C15.8167 15.625 16.025 15.5583 16.125 15.375L17.725 12.6083C17.825 12.425 17.7833 12.2167 17.625 12.1L15.95 10.7833ZM9.99999 13C8.34999 13 6.99999 11.65 6.99999 10C6.99999 8.35 8.34999 7 9.99999 7C11.65 7 13 8.35 13 10C13 11.65 11.65 13 9.99999 13Z"
|
|
28
28
|
fill="white"
|
|
29
29
|
/>
|
|
30
|
-
</svg> `,
|
|
30
|
+
</svg> `, _ = n`<svg
|
|
31
31
|
width="20"
|
|
32
32
|
height="20"
|
|
33
33
|
viewBox="0 0 20 20"
|
|
@@ -38,7 +38,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
38
38
|
d="M4.16668 10.9833V14.3167L10 17.5L15.8333 14.3167V10.9833L10 14.1667L4.16668 10.9833ZM10 2.5L0.833344 7.5L10 12.5L17.5 8.40833V14.1667H19.1667V7.5L10 2.5Z"
|
|
39
39
|
fill="white"
|
|
40
40
|
/>
|
|
41
|
-
</svg> `,
|
|
41
|
+
</svg> `, F = n`<svg
|
|
42
42
|
width="20"
|
|
43
43
|
height="20"
|
|
44
44
|
viewBox="0 0 20 20"
|
|
@@ -49,7 +49,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
49
49
|
d="M9.99999 1.6665C5.39999 1.6665 1.66666 5.39984 1.66666 9.99984C1.66666 14.5998 5.39999 18.3332 9.99999 18.3332C14.6 18.3332 18.3333 14.5998 18.3333 9.99984C18.3333 5.39984 14.6 1.6665 9.99999 1.6665ZM9.99999 4.1665C11.3833 4.1665 12.5 5.28317 12.5 6.6665C12.5 8.04984 11.3833 9.1665 9.99999 9.1665C8.61666 9.1665 7.49999 8.04984 7.49999 6.6665C7.49999 5.28317 8.61666 4.1665 9.99999 4.1665ZM9.99999 15.9998C7.91666 15.9998 6.07499 14.9332 4.99999 13.3165C5.02499 11.6582 8.33332 10.7498 9.99999 10.7498C11.6583 10.7498 14.975 11.6582 15 13.3165C13.925 14.9332 12.0833 15.9998 9.99999 15.9998Z"
|
|
50
50
|
fill="white"
|
|
51
51
|
/>
|
|
52
|
-
</svg>`,
|
|
52
|
+
</svg>`, P = n`<svg
|
|
53
53
|
width="20"
|
|
54
54
|
height="20"
|
|
55
55
|
viewBox="0 0 20 20"
|
|
@@ -60,7 +60,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
60
60
|
d="M16.6667 15.4167C17.5833 15.4167 18.325 14.6667 18.325 13.7501L18.3333 4.58341C18.3333 3.66675 17.5833 2.91675 16.6667 2.91675H3.33333C2.41667 2.91675 1.66667 3.66675 1.66667 4.58341V13.7501C1.66667 14.6667 2.41667 15.4167 3.33333 15.4167H0C0 16.3334 0.75 17.0834 1.66667 17.0834H18.3333C19.25 17.0834 20 16.3334 20 15.4167H16.6667ZM3.33333 4.58341H16.6667V13.7501H3.33333V4.58341ZM10 16.2501C9.54167 16.2501 9.16667 15.8751 9.16667 15.4167C9.16667 14.9584 9.54167 14.5834 10 14.5834C10.4583 14.5834 10.8333 14.9584 10.8333 15.4167C10.8333 15.8751 10.4583 16.2501 10 16.2501Z"
|
|
61
61
|
fill="white"
|
|
62
62
|
/>
|
|
63
|
-
</svg>`,
|
|
63
|
+
</svg>`, $ = n`<svg
|
|
64
64
|
width="8"
|
|
65
65
|
height="12"
|
|
66
66
|
viewBox="0 0 8 12"
|
|
@@ -71,7 +71,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
71
71
|
d="M1.70687 0L0.296875 1.41L4.87687 6L0.296875 10.59L1.70687 12L7.70687 6L1.70687 0Z"
|
|
72
72
|
fill="white"
|
|
73
73
|
/>
|
|
74
|
-
</svg>`,
|
|
74
|
+
</svg>`, z = (e = "#505050") => n`<svg
|
|
75
75
|
width="14"
|
|
76
76
|
height="14"
|
|
77
77
|
viewBox="0 0 14 14"
|
|
@@ -82,7 +82,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
82
82
|
d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z"
|
|
83
83
|
fill="${e}"
|
|
84
84
|
/>
|
|
85
|
-
</svg>`,
|
|
85
|
+
</svg>`, G = n`<svg
|
|
86
86
|
width="20"
|
|
87
87
|
height="20"
|
|
88
88
|
viewBox="0 0 20 20"
|
|
@@ -93,7 +93,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
93
93
|
d="M15 9.16683V10.8335H18.3333V9.16683H15ZM13.3333 14.6752C14.1333 15.2668 15.175 16.0502 16 16.6668C16.3333 16.2252 16.6667 15.7752 17 15.3335C16.175 14.7168 15.1333 13.9335 14.3333 13.3335C14 13.7835 13.6667 14.2335 13.3333 14.6752ZM17 4.66683C16.6667 4.22516 16.3333 3.77516 16 3.3335C15.175 3.95016 14.1333 4.7335 13.3333 5.3335C13.6667 5.77516 14 6.22516 14.3333 6.66683C15.1333 6.06683 16.175 5.29183 17 4.66683ZM3.33332 7.50016C2.41666 7.50016 1.66666 8.25016 1.66666 9.16683V10.8335C1.66666 11.7502 2.41666 12.5002 3.33332 12.5002H4.16666V15.8335H5.83332V12.5002H6.66666L10.8333 15.0002V5.00016L6.66666 7.50016H3.33332ZM12.9167 10.0002C12.9167 8.89183 12.4333 7.89183 11.6667 7.2085V12.7835C12.4333 12.1085 12.9167 11.1085 12.9167 10.0002Z"
|
|
94
94
|
fill="white"
|
|
95
95
|
/>
|
|
96
|
-
</svg> `,
|
|
96
|
+
</svg> `, H = n`<svg
|
|
97
97
|
width="20"
|
|
98
98
|
height="20"
|
|
99
99
|
viewBox="0 0 20 20"
|
|
@@ -104,7 +104,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
104
104
|
d="M15.95 10.7833C15.9833 10.5333 16 10.275 16 10C16 9.73333 15.9833 9.46667 15.9417 9.21667L17.6333 7.9C17.7833 7.78333 17.825 7.55833 17.7333 7.39167L16.1333 4.625C16.0333 4.44167 15.825 4.38333 15.6417 4.44167L13.65 5.24167C13.2333 4.925 12.7917 4.65833 12.3 4.45833L12 2.34167C11.9667 2.14167 11.8 2 11.6 2H8.39999C8.19999 2 8.04166 2.14167 8.00832 2.34167L7.70832 4.45833C7.21666 4.65833 6.76666 4.93333 6.35832 5.24167L4.36666 4.44167C4.18332 4.375 3.97499 4.44167 3.87499 4.625L2.28332 7.39167C2.18332 7.56667 2.21666 7.78333 2.38332 7.9L4.07499 9.21667C4.03332 9.46667 3.99999 9.74167 3.99999 10C3.99999 10.2583 4.01666 10.5333 4.05832 10.7833L2.36666 12.1C2.21666 12.2167 2.17499 12.4417 2.26666 12.6083L3.86666 15.375C3.96666 15.5583 4.17499 15.6167 4.35832 15.5583L6.34999 14.7583C6.76666 15.075 7.20832 15.3417 7.69999 15.5417L7.99999 17.6583C8.04166 17.8583 8.19999 18 8.39999 18H11.6C11.8 18 11.9667 17.8583 11.9917 17.6583L12.2917 15.5417C12.7833 15.3417 13.2333 15.075 13.6417 14.7583L15.6333 15.5583C15.8167 15.625 16.025 15.5583 16.125 15.375L17.725 12.6083C17.825 12.425 17.7833 12.2167 17.625 12.1L15.95 10.7833ZM9.99999 13C8.34999 13 6.99999 11.65 6.99999 10C6.99999 8.35 8.34999 7 9.99999 7C11.65 7 13 8.35 13 10C13 11.65 11.65 13 9.99999 13Z"
|
|
105
105
|
fill="white"
|
|
106
106
|
/>
|
|
107
|
-
</svg> `,
|
|
107
|
+
</svg> `, U = n`<svg
|
|
108
108
|
width="20"
|
|
109
109
|
height="20"
|
|
110
110
|
viewBox="0 0 20 20"
|
|
@@ -115,7 +115,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
115
115
|
d="M9.99999 1.6665C5.39999 1.6665 1.66666 5.39984 1.66666 9.99984C1.66666 14.5998 5.39999 18.3332 9.99999 18.3332C14.6 18.3332 18.3333 14.5998 18.3333 9.99984C18.3333 5.39984 14.6 1.6665 9.99999 1.6665ZM10.7333 14.7998V15.8332H9.27499V14.7582C8.65832 14.6082 7.28332 14.1165 6.75832 12.2915L8.13332 11.7332C8.18332 11.9165 8.61666 13.4748 10.1333 13.4748C10.9083 13.4748 11.7833 13.0748 11.7833 12.1332C11.7833 11.3332 11.2 10.9165 9.88332 10.4415C8.96666 10.1165 7.09166 9.58317 7.09166 7.68317C7.09166 7.59984 7.09999 5.68317 9.27499 5.2165V4.1665H10.7333V5.19984C12.2667 5.4665 12.825 6.6915 12.95 7.05817L11.6333 7.6165C11.5417 7.32484 11.1417 6.49984 10.05 6.49984C9.46666 6.49984 8.54166 6.80817 8.54166 7.65817C8.54166 8.44984 9.25832 8.74984 10.7417 9.2415C12.7417 9.93317 13.25 10.9498 13.25 12.1165C13.25 14.3082 11.1667 14.7248 10.7333 14.7998Z"
|
|
116
116
|
fill="white"
|
|
117
117
|
/>
|
|
118
|
-
</svg>`,
|
|
118
|
+
</svg>`, Z = n`<svg
|
|
119
119
|
width="20"
|
|
120
120
|
height="20"
|
|
121
121
|
viewBox="0 0 20 20"
|
|
@@ -126,7 +126,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
126
126
|
d="M8.33332 17.0832V12.0832H11.6667V17.0832H15.8333V10.4165H18.3333L9.99999 2.9165L1.66666 10.4165H4.16666V17.0832H8.33332Z"
|
|
127
127
|
fill="white"
|
|
128
128
|
/>
|
|
129
|
-
</svg>`,
|
|
129
|
+
</svg>`, K = n`<svg
|
|
130
130
|
width="20"
|
|
131
131
|
height="20"
|
|
132
132
|
viewBox="0 0 20 20"
|
|
@@ -137,7 +137,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
137
137
|
d="M16.6667 4.99984H13.3333V3.33317C13.3333 2.4165 12.5833 1.6665 11.6667 1.6665H8.33332C7.41666 1.6665 6.66666 2.4165 6.66666 3.33317V4.99984H3.33332C2.41666 4.99984 1.66666 5.74984 1.66666 6.6665V16.6665C1.66666 17.5832 2.41666 18.3332 3.33332 18.3332H16.6667C17.5833 18.3332 18.3333 17.5832 18.3333 16.6665V6.6665C18.3333 5.74984 17.5833 4.99984 16.6667 4.99984ZM8.33332 3.33317H11.6667V4.99984H8.33332V3.33317ZM13.3333 12.4998H10.8333V14.9998H9.16666V12.4998H6.66666V10.8332H9.16666V8.33317H10.8333V10.8332H13.3333V12.4998Z"
|
|
138
138
|
fill="white"
|
|
139
139
|
/>
|
|
140
|
-
</svg> `,
|
|
140
|
+
</svg> `, j = n` <svg
|
|
141
141
|
width="24"
|
|
142
142
|
height="24"
|
|
143
143
|
viewBox="0 0 24 24"
|
|
@@ -148,7 +148,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
148
148
|
d="M3 18H16V16H3V18ZM3 13H13V11H3V13ZM3 6V8H16V6H3ZM21 15.59L17.42 12L21 8.41L19.59 7L14.59 12L19.59 17L21 15.59Z"
|
|
149
149
|
fill="white"
|
|
150
150
|
/>
|
|
151
|
-
</svg>`,
|
|
151
|
+
</svg>`, L = n`<svg
|
|
152
152
|
width="24"
|
|
153
153
|
height="24"
|
|
154
154
|
viewBox="0 0 24 24"
|
|
@@ -156,7 +156,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
156
156
|
xmlns="http://www.w3.org/2000/svg"
|
|
157
157
|
>
|
|
158
158
|
<path d="M3 18H21V16H3V18ZM3 13H21V11H3V13ZM3 6V8H21V6H3Z" fill="white" />
|
|
159
|
-
</svg>`,
|
|
159
|
+
</svg>`, q = n`<svg
|
|
160
160
|
width="20"
|
|
161
161
|
height="20"
|
|
162
162
|
viewBox="0 0 20 20"
|
|
@@ -167,7 +167,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
167
167
|
d="M12.5 2.5H4.16667C3.25 2.5 2.50833 3.25 2.50833 4.16667L2.5 15.8333C2.5 16.75 3.24167 17.5 4.15833 17.5H15.8333C16.75 17.5 17.5 16.75 17.5 15.8333V7.5L12.5 2.5ZM6.66667 14.1667C6.20833 14.1667 5.83333 13.7917 5.83333 13.3333C5.83333 12.875 6.20833 12.5 6.66667 12.5C7.125 12.5 7.5 12.875 7.5 13.3333C7.5 13.7917 7.125 14.1667 6.66667 14.1667ZM6.66667 10.8333C6.20833 10.8333 5.83333 10.4583 5.83333 10C5.83333 9.54167 6.20833 9.16667 6.66667 9.16667C7.125 9.16667 7.5 9.54167 7.5 10C7.5 10.4583 7.125 10.8333 6.66667 10.8333ZM6.66667 7.5C6.20833 7.5 5.83333 7.125 5.83333 6.66667C5.83333 6.20833 6.20833 5.83333 6.66667 5.83333C7.125 5.83333 7.5 6.20833 7.5 6.66667C7.5 7.125 7.125 7.5 6.66667 7.5ZM11.6667 8.33333V3.75L16.25 8.33333H11.6667Z"
|
|
168
168
|
fill="white"
|
|
169
169
|
/>
|
|
170
|
-
</svg>`,
|
|
170
|
+
</svg>`, Y = n`<svg
|
|
171
171
|
width="20"
|
|
172
172
|
height="20"
|
|
173
173
|
viewBox="0 0 20 20"
|
|
@@ -178,7 +178,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
178
178
|
d="M14.1667 10.8332H10V14.9998H14.1667V10.8332ZM13.3333 1.6665V3.33317H6.66667V1.6665H5V3.33317H4.16667C3.24167 3.33317 2.50833 4.08317 2.50833 4.99984L2.5 16.6665C2.5 17.5832 3.24167 18.3332 4.16667 18.3332H15.8333C16.75 18.3332 17.5 17.5832 17.5 16.6665V4.99984C17.5 4.08317 16.75 3.33317 15.8333 3.33317H15V1.6665H13.3333ZM15.8333 16.6665H4.16667V7.49984H15.8333V16.6665Z"
|
|
179
179
|
fill="white"
|
|
180
180
|
/>
|
|
181
|
-
</svg> `,
|
|
181
|
+
</svg> `, Q = n`<svg
|
|
182
182
|
width="20"
|
|
183
183
|
height="20"
|
|
184
184
|
viewBox="0 0 20 20"
|
|
@@ -189,7 +189,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
189
189
|
d="M16.6667 5.83317H12.5V3.33317C12.5 2.4165 11.75 1.6665 10.8333 1.6665H9.16666C8.24999 1.6665 7.49999 2.4165 7.49999 3.33317V5.83317H3.33332C2.41666 5.83317 1.66666 6.58317 1.66666 7.49984V16.6665C1.66666 17.5832 2.41666 18.3332 3.33332 18.3332H16.6667C17.5833 18.3332 18.3333 17.5832 18.3333 16.6665V7.49984C18.3333 6.58317 17.5833 5.83317 16.6667 5.83317ZM7.49999 9.99984C8.19166 9.99984 8.74999 10.5582 8.74999 11.2498C8.74999 11.9415 8.19166 12.4998 7.49999 12.4998C6.80832 12.4998 6.24999 11.9415 6.24999 11.2498C6.24999 10.5582 6.80832 9.99984 7.49999 9.99984ZM9.99999 14.9998H4.99999V14.3748C4.99999 13.5415 6.66666 13.1248 7.49999 13.1248C8.33332 13.1248 9.99999 13.5415 9.99999 14.3748V14.9998ZM10.8333 7.49984H9.16666V3.33317H10.8333V7.49984ZM15 13.7498H11.6667V12.4998H15V13.7498ZM15 11.2498H11.6667V9.99984H15V11.2498Z"
|
|
190
190
|
fill="white"
|
|
191
191
|
/>
|
|
192
|
-
</svg> `,
|
|
192
|
+
</svg> `, W = n`<svg
|
|
193
193
|
width="20"
|
|
194
194
|
height="20"
|
|
195
195
|
viewBox="0 0 20 20"
|
|
@@ -200,7 +200,183 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
200
200
|
d="M10 2.0835C6.66668 2.0835 3.33334 2.50016 3.33334 5.41683V13.3335C3.33334 14.1252 3.65001 14.8418 4.16668 15.3668V17.0835C4.16668 17.5418 4.54168 17.9168 5.00001 17.9168H5.83334C6.29168 17.9168 6.66668 17.5418 6.66668 17.0835V16.2502H13.3333V17.0835C13.3333 17.5418 13.7083 17.9168 14.1667 17.9168H15C15.4583 17.9168 15.8333 17.5418 15.8333 17.0835V15.3668C16.35 14.8418 16.6667 14.1252 16.6667 13.3335V5.41683C16.6667 2.50016 13.6833 2.0835 10 2.0835ZM7.08334 13.7502C6.39168 13.7502 5.83334 13.1918 5.83334 12.5002C5.83334 11.8085 6.39168 11.2502 7.08334 11.2502C7.77501 11.2502 8.33334 11.8085 8.33334 12.5002C8.33334 13.1918 7.77501 13.7502 7.08334 13.7502ZM12.9167 13.7502C12.225 13.7502 11.6667 13.1918 11.6667 12.5002C11.6667 11.8085 12.225 11.2502 12.9167 11.2502C13.6083 11.2502 14.1667 11.8085 14.1667 12.5002C14.1667 13.1918 13.6083 13.7502 12.9167 13.7502ZM15 8.75016H5.00001V6.25016H15V8.75016Z"
|
|
201
201
|
fill="white"
|
|
202
202
|
/>
|
|
203
|
-
</svg> `,
|
|
203
|
+
</svg> `, E = 248, T = 16, f = 530, X = b`
|
|
204
|
+
/* ===== HOST-LEVEL CUSTOM PROPERTIES ===== */
|
|
205
|
+
:host {
|
|
206
|
+
/* '--cm-side-nav-width' is set on 'campminder-app-shell''s ':host'
|
|
207
|
+
* (packages/campminder/src/layout.ts is the source of truth) and
|
|
208
|
+
* pierces the shadow boundary, so it's readable here even though this
|
|
209
|
+
* package is portal-agnostic. It also switches to the collapsed
|
|
210
|
+
* width, which a literal '168px' can't — the fallback below is only
|
|
211
|
+
* for standalone rendering with no shell present.
|
|
212
|
+
* '100vw' is correct for production, where the shell fills the
|
|
213
|
+
* viewport and the nav starts at x=0; it reads over-wide in this
|
|
214
|
+
* harness only because the harness page has a 24px inset the shell
|
|
215
|
+
* doesn't have — a harness-geometry artifact, not a formula bug. */
|
|
216
|
+
--cm-mega-menu-max-width: calc(100vw - var(--cm-side-nav-width, 168px));
|
|
217
|
+
|
|
218
|
+
/* Redeclared even though it would be inherited anyway. Unlike the top bar
|
|
219
|
+
* and the banner, '<cm-mega-menu>' is NOT a sibling shadow root: 'SideNav.ts'
|
|
220
|
+
* renders it inside the side nav's own shadow root (deliberately, rather than
|
|
221
|
+
* through a slot — see the note at that call site), so it is a descendant in
|
|
222
|
+
* the flattened tree and custom properties already reach it.
|
|
223
|
+
*
|
|
224
|
+
* Declaring it regardless keeps the flyout's typeface a property of the
|
|
225
|
+
* flyout, so it survives being reparented or slotted later, and means all
|
|
226
|
+
* four chrome stylesheets read the same way. It cannot drift from the side
|
|
227
|
+
* nav's value because both resolve the one 'SHELL_FONT_FAMILY' constant;
|
|
228
|
+
* an inherited-only version would quietly start differing the moment either
|
|
229
|
+
* file stopped doing that. Rationale for the chain: '../shell-tokens.ts'. */
|
|
230
|
+
--font-family: ${C};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* ===== CSS RESET ===== */
|
|
234
|
+
* {
|
|
235
|
+
margin: 0;
|
|
236
|
+
padding: 0;
|
|
237
|
+
box-sizing: border-box;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ===== ANIMATIONS ===== */
|
|
241
|
+
@keyframes fadeIn {
|
|
242
|
+
from {
|
|
243
|
+
opacity: 0;
|
|
244
|
+
}
|
|
245
|
+
to {
|
|
246
|
+
opacity: 1;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* ===== MEGA MENU CONTAINER ===== */
|
|
251
|
+
.mega-menu {
|
|
252
|
+
position: absolute;
|
|
253
|
+
left: 100%;
|
|
254
|
+
top: 0;
|
|
255
|
+
max-width: var(--cm-mega-menu-max-width);
|
|
256
|
+
height: 100%;
|
|
257
|
+
border-radius: 4px;
|
|
258
|
+
background: #fff;
|
|
259
|
+
box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.12);
|
|
260
|
+
animation: fadeIn 0.5s ease;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* ===== HEADER SECTION ===== */
|
|
264
|
+
.header {
|
|
265
|
+
display: flex;
|
|
266
|
+
align-items: center;
|
|
267
|
+
justify-content: space-between;
|
|
268
|
+
color: #505050;
|
|
269
|
+
border-bottom: 1px solid rgba(160, 160, 160, 1);
|
|
270
|
+
margin: 0 16px;
|
|
271
|
+
height: 56px;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.header-left {
|
|
275
|
+
display: flex;
|
|
276
|
+
align-items: center;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.header-title {
|
|
280
|
+
display: grid;
|
|
281
|
+
place-content: center;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.header-icon {
|
|
285
|
+
margin-right: 8px;
|
|
286
|
+
display: flex;
|
|
287
|
+
justify-content: center;
|
|
288
|
+
align-items: center;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* ===== CLOSE BUTTON ===== */
|
|
292
|
+
.close-button {
|
|
293
|
+
display: flex;
|
|
294
|
+
width: 24px;
|
|
295
|
+
height: 24px;
|
|
296
|
+
justify-content: center;
|
|
297
|
+
align-items: center;
|
|
298
|
+
border-radius: 4px;
|
|
299
|
+
cursor: pointer;
|
|
300
|
+
transition: background 0.2s ease;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.close-button:hover {
|
|
304
|
+
background: rgba(119, 61, 189, 0.12);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* ===== TYPOGRAPHY ===== */
|
|
308
|
+
.title-text {
|
|
309
|
+
color: #505050;
|
|
310
|
+
font-family: var(--font-family);
|
|
311
|
+
font-size: 16px;
|
|
312
|
+
font-weight: 600;
|
|
313
|
+
line-height: 24px;
|
|
314
|
+
letter-spacing: 0.0025em;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* ===== MENU ITEMS CONTAINER ===== */
|
|
318
|
+
.menu-items {
|
|
319
|
+
height: calc(100% - 56px);
|
|
320
|
+
max-width: var(--cm-mega-menu-max-width);
|
|
321
|
+
display: flex;
|
|
322
|
+
flex-flow: column wrap;
|
|
323
|
+
padding: 10px 16px 10px 0px;
|
|
324
|
+
overflow: auto;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* ===== MENU ITEM ===== */
|
|
328
|
+
.menu-item {
|
|
329
|
+
width: ${E}px;
|
|
330
|
+
margin-left: ${T}px;
|
|
331
|
+
margin-bottom: 12px;
|
|
332
|
+
font-family: var(--font-family);
|
|
333
|
+
font-size: 14px;
|
|
334
|
+
font-weight: 400;
|
|
335
|
+
line-height: 20px;
|
|
336
|
+
letter-spacing: -0.001em;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.menu-title {
|
|
340
|
+
display: flex;
|
|
341
|
+
width: 248px;
|
|
342
|
+
padding: 4px 12px;
|
|
343
|
+
align-items: center;
|
|
344
|
+
gap: 8px;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* ===== MENU LINKS ===== */
|
|
348
|
+
.menu-url {
|
|
349
|
+
display: flex;
|
|
350
|
+
align-items: center;
|
|
351
|
+
width: 248px;
|
|
352
|
+
min-height: 32px;
|
|
353
|
+
padding: 6px 12px;
|
|
354
|
+
border-radius: 4px;
|
|
355
|
+
text-decoration: none;
|
|
356
|
+
color: #380f8c;
|
|
357
|
+
transition: background 0.2s ease;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.menu-url:hover,
|
|
361
|
+
.menu-url:focus {
|
|
362
|
+
background: rgba(119, 61, 189, 0.12);
|
|
363
|
+
outline: none;
|
|
364
|
+
cursor: pointer;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.new-tab-icon {
|
|
368
|
+
margin-left: 4px;
|
|
369
|
+
display: grid;
|
|
370
|
+
place-content: center;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* ===== RESPONSIVE ===== */
|
|
374
|
+
@media (max-width: 1150px) {
|
|
375
|
+
.menu-items {
|
|
376
|
+
flex-wrap: nowrap;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
`, J = n`<svg
|
|
204
380
|
width="24"
|
|
205
381
|
height="24"
|
|
206
382
|
viewBox="0 0 24 24"
|
|
@@ -211,7 +387,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
211
387
|
d="M18 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V4C20 2.9 19.1 2 18 2ZM6 4H11V12L8.5 10.5L6 12V4Z"
|
|
212
388
|
fill="#505050"
|
|
213
389
|
/>
|
|
214
|
-
</svg>`,
|
|
390
|
+
</svg>`, ee = n`<svg
|
|
215
391
|
width="24"
|
|
216
392
|
height="24"
|
|
217
393
|
viewBox="0 0 24 24"
|
|
@@ -222,7 +398,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
222
398
|
d="M19.1401 12.9399C19.1801 12.6399 19.2001 12.3299 19.2001 11.9999C19.2001 11.6799 19.1801 11.3599 19.1301 11.0599L21.1601 9.4799C21.3401 9.3399 21.3901 9.0699 21.2801 8.8699L19.3601 5.5499C19.2401 5.3299 18.9901 5.2599 18.7701 5.3299L16.3801 6.2899C15.8801 5.9099 15.3501 5.5899 14.7601 5.3499L14.4001 2.8099C14.3601 2.5699 14.1601 2.3999 13.9201 2.3999H10.0801C9.84011 2.3999 9.65011 2.5699 9.61011 2.8099L9.25011 5.3499C8.66011 5.5899 8.12011 5.9199 7.63011 6.2899L5.24011 5.3299C5.02011 5.2499 4.77011 5.3299 4.65011 5.5499L2.74011 8.8699C2.62011 9.0799 2.66011 9.3399 2.86011 9.4799L4.89011 11.0599C4.84011 11.3599 4.80011 11.6899 4.80011 11.9999C4.80011 12.3099 4.82011 12.6399 4.87011 12.9399L2.84011 14.5199C2.66011 14.6599 2.61011 14.9299 2.72011 15.1299L4.64011 18.4499C4.76011 18.6699 5.01011 18.7399 5.23011 18.6699L7.62011 17.7099C8.12011 18.0899 8.65011 18.4099 9.24011 18.6499L9.60011 21.1899C9.65011 21.4299 9.84011 21.5999 10.0801 21.5999H13.9201C14.1601 21.5999 14.3601 21.4299 14.3901 21.1899L14.7501 18.6499C15.3401 18.4099 15.8801 18.0899 16.3701 17.7099L18.7601 18.6699C18.9801 18.7499 19.2301 18.6699 19.3501 18.4499L21.2701 15.1299C21.3901 14.9099 21.3401 14.6599 21.1501 14.5199L19.1401 12.9399ZM12.0001 15.5999C10.0201 15.5999 8.40011 13.9799 8.40011 11.9999C8.40011 10.0199 10.0201 8.3999 12.0001 8.3999C13.9801 8.3999 15.6001 10.0199 15.6001 11.9999C15.6001 13.9799 13.9801 15.5999 12.0001 15.5999Z"
|
|
223
399
|
fill="#505050"
|
|
224
400
|
/>
|
|
225
|
-
</svg>`,
|
|
401
|
+
</svg>`, te = n`<svg
|
|
226
402
|
width="24"
|
|
227
403
|
height="24"
|
|
228
404
|
viewBox="0 0 24 24"
|
|
@@ -233,7 +409,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
233
409
|
d="M5 13.18V17.18L12 21L19 17.18V13.18L12 17L5 13.18ZM12 3L1 9L12 15L21 10.09V17H23V9L12 3Z"
|
|
234
410
|
fill="#505050"
|
|
235
411
|
/>
|
|
236
|
-
</svg>`,
|
|
412
|
+
</svg>`, oe = n`<svg
|
|
237
413
|
width="24"
|
|
238
414
|
height="24"
|
|
239
415
|
viewBox="0 0 24 24"
|
|
@@ -244,7 +420,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
244
420
|
d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 5C13.66 5 15 6.34 15 8C15 9.66 13.66 11 12 11C10.34 11 9 9.66 9 8C9 6.34 10.34 5 12 5ZM12 19.2C9.5 19.2 7.29 17.92 6 15.98C6.03 13.99 10 12.9 12 12.9C13.99 12.9 17.97 13.99 18 15.98C16.71 17.92 14.5 19.2 12 19.2Z"
|
|
245
421
|
fill="#505050"
|
|
246
422
|
/>
|
|
247
|
-
</svg>`,
|
|
423
|
+
</svg>`, ie = n`<svg
|
|
248
424
|
width="20"
|
|
249
425
|
height="20"
|
|
250
426
|
viewBox="0 0 20 20"
|
|
@@ -255,7 +431,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
255
431
|
d="M16.6667 15.4167C17.5833 15.4167 18.325 14.6667 18.325 13.7501L18.3333 4.58341C18.3333 3.66675 17.5833 2.91675 16.6667 2.91675H3.33333C2.41667 2.91675 1.66667 3.66675 1.66667 4.58341V13.7501C1.66667 14.6667 2.41667 15.4167 3.33333 15.4167H0C0 16.3334 0.75 17.0834 1.66667 17.0834H18.3333C19.25 17.0834 20 16.3334 20 15.4167H16.6667ZM3.33333 4.58341H16.6667V13.7501H3.33333V4.58341ZM10 16.2501C9.54167 16.2501 9.16667 15.8751 9.16667 15.4167C9.16667 14.9584 9.54167 14.5834 10 14.5834C10.4583 14.5834 10.8333 14.9584 10.8333 15.4167C10.8333 15.8751 10.4583 16.2501 10 16.2501Z"
|
|
256
432
|
fill="#505050"
|
|
257
433
|
/>
|
|
258
|
-
</svg>`,
|
|
434
|
+
</svg>`, ne = n`<svg
|
|
259
435
|
width="24"
|
|
260
436
|
height="24"
|
|
261
437
|
viewBox="0 0 24 24"
|
|
@@ -266,7 +442,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
266
442
|
d="M18 11V13H22V11H18ZM16 17.61C16.96 18.32 18.21 19.26 19.2 20C19.6 19.47 20 18.93 20.4 18.4C19.41 17.66 18.16 16.72 17.2 16C16.8 16.54 16.4 17.08 16 17.61ZM20.4 5.6C20 5.07 19.6 4.53 19.2 4C18.21 4.74 16.96 5.68 16 6.4C16.4 6.93 16.8 7.47 17.2 8C18.16 7.28 19.41 6.35 20.4 5.6ZM4 9C2.9 9 2 9.9 2 11V13C2 14.1 2.9 15 4 15H5V19H7V15H8L13 18V6L8 9H4ZM15.5 12C15.5 10.67 14.92 9.47 14 8.65V15.34C14.92 14.53 15.5 13.33 15.5 12Z"
|
|
267
443
|
fill="#505050"
|
|
268
444
|
/>
|
|
269
|
-
</svg> `,
|
|
445
|
+
</svg> `, V = n`<svg
|
|
270
446
|
width="24"
|
|
271
447
|
height="24"
|
|
272
448
|
viewBox="0 0 24 24"
|
|
@@ -277,7 +453,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
277
453
|
d="M19.1401 12.9399C19.1801 12.6399 19.2001 12.3299 19.2001 11.9999C19.2001 11.6799 19.1801 11.3599 19.1301 11.0599L21.1601 9.4799C21.3401 9.3399 21.3901 9.0699 21.2801 8.8699L19.3601 5.5499C19.2401 5.3299 18.9901 5.2599 18.7701 5.3299L16.3801 6.2899C15.8801 5.9099 15.3501 5.5899 14.7601 5.3499L14.4001 2.8099C14.3601 2.5699 14.1601 2.3999 13.9201 2.3999H10.0801C9.84011 2.3999 9.65011 2.5699 9.61011 2.8099L9.25011 5.3499C8.66011 5.5899 8.12011 5.9199 7.63011 6.2899L5.24011 5.3299C5.02011 5.2499 4.77011 5.3299 4.65011 5.5499L2.74011 8.8699C2.62011 9.0799 2.66011 9.3399 2.86011 9.4799L4.89011 11.0599C4.84011 11.3599 4.80011 11.6899 4.80011 11.9999C4.80011 12.3099 4.82011 12.6399 4.87011 12.9399L2.84011 14.5199C2.66011 14.6599 2.61011 14.9299 2.72011 15.1299L4.64011 18.4499C4.76011 18.6699 5.01011 18.7399 5.23011 18.6699L7.62011 17.7099C8.12011 18.0899 8.65011 18.4099 9.24011 18.6499L9.60011 21.1899C9.65011 21.4299 9.84011 21.5999 10.0801 21.5999H13.9201C14.1601 21.5999 14.3601 21.4299 14.3901 21.1899L14.7501 18.6499C15.3401 18.4099 15.8801 18.0899 16.3701 17.7099L18.7601 18.6699C18.9801 18.7499 19.2301 18.6699 19.3501 18.4499L21.2701 15.1299C21.3901 14.9099 21.3401 14.6599 21.1501 14.5199L19.1401 12.9399ZM12.0001 15.5999C10.0201 15.5999 8.40011 13.9799 8.40011 11.9999C8.40011 10.0199 10.0201 8.3999 12.0001 8.3999C13.9801 8.3999 15.6001 10.0199 15.6001 11.9999C15.6001 13.9799 13.9801 15.5999 12.0001 15.5999Z"
|
|
278
454
|
fill="#505050"
|
|
279
455
|
/>
|
|
280
|
-
</svg>`,
|
|
456
|
+
</svg>`, ae = n`<svg
|
|
281
457
|
width="24"
|
|
282
458
|
height="24"
|
|
283
459
|
viewBox="0 0 24 24"
|
|
@@ -288,7 +464,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
288
464
|
d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12.88 17.76V19H11.13V17.71C10.39 17.53 8.74 16.94 8.11 14.75L9.76 14.08C9.82 14.3 10.34 16.17 12.16 16.17C13.09 16.17 14.14 15.69 14.14 14.56C14.14 13.6 13.44 13.1 11.86 12.53C10.76 12.14 8.51 11.5 8.51 9.22C8.51 9.12 8.52 6.82 11.13 6.26V5H12.88V6.24C14.72 6.56 15.39 8.03 15.54 8.47L13.96 9.14C13.85 8.79 13.37 7.8 12.06 7.8C11.36 7.8 10.25 8.17 10.25 9.19C10.25 10.14 11.11 10.5 12.89 11.09C15.29 11.92 15.9 13.14 15.9 14.54C15.9 17.17 13.4 17.67 12.88 17.76Z"
|
|
289
465
|
fill="#505050"
|
|
290
466
|
/>
|
|
291
|
-
</svg> `,
|
|
467
|
+
</svg> `, se = n`<svg
|
|
292
468
|
width="24"
|
|
293
469
|
height="24"
|
|
294
470
|
viewBox="0 0 24 24"
|
|
@@ -299,7 +475,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
299
475
|
d="M20 6H16V4C16 2.9 15.1 2 14 2H10C8.9 2 8 2.9 8 4V6H4C2.9 6 2 6.9 2 8V20C2 21.1 2.9 22 4 22H20C21.1 22 22 21.1 22 20V8C22 6.9 21.1 6 20 6ZM10 4H14V6H10V4ZM16 15H13V18H11V15H8V13H11V10H13V13H16V15Z"
|
|
300
476
|
fill="#505050"
|
|
301
477
|
/>
|
|
302
|
-
</svg> `,
|
|
478
|
+
</svg> `, I = n`<svg
|
|
303
479
|
width="16"
|
|
304
480
|
height="16"
|
|
305
481
|
viewBox="0 0 16 16"
|
|
@@ -310,7 +486,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
310
486
|
d="M12.6667 12.6667H3.33333V3.33333H8V2H3.33333C2.59333 2 2 2.6 2 3.33333V12.6667C2 13.4 2.59333 14 3.33333 14H12.6667C13.4 14 14 13.4 14 12.6667V8H12.6667V12.6667ZM9.33333 2V3.33333H11.7267L5.17333 9.88667L6.11333 10.8267L12.6667 4.27333V6.66667H14V2H9.33333Z"
|
|
311
487
|
fill="#282828"
|
|
312
488
|
/>
|
|
313
|
-
</svg> `,
|
|
489
|
+
</svg> `, re = n`<svg
|
|
314
490
|
width="24"
|
|
315
491
|
height="24"
|
|
316
492
|
viewBox="0 0 24 24"
|
|
@@ -321,7 +497,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
321
497
|
d="M15 3H5C3.9 3 3.01 3.9 3.01 5L3 19C3 20.1 3.89 21 4.99 21H19C20.1 21 21 20.1 21 19V9L15 3ZM8 17C7.45 17 7 16.55 7 16C7 15.45 7.45 15 8 15C8.55 15 9 15.45 9 16C9 16.55 8.55 17 8 17ZM8 13C7.45 13 7 12.55 7 12C7 11.45 7.45 11 8 11C8.55 11 9 11.45 9 12C9 12.55 8.55 13 8 13ZM8 9C7.45 9 7 8.55 7 8C7 7.45 7.45 7 8 7C8.55 7 9 7.45 9 8C9 8.55 8.55 9 8 9ZM14 10V4.5L19.5 10H14Z"
|
|
322
498
|
fill="#505050"
|
|
323
499
|
/>
|
|
324
|
-
</svg> `,
|
|
500
|
+
</svg> `, le = n`<svg
|
|
325
501
|
width="24"
|
|
326
502
|
height="24"
|
|
327
503
|
viewBox="0 0 24 24"
|
|
@@ -332,7 +508,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
332
508
|
d="M17 13H12V18H17V13ZM16 2V4H8V2H6V4H5C3.89 4 3.01 4.9 3.01 6L3 20C3 21.1 3.89 22 5 22H19C20.1 22 21 21.1 21 20V6C21 4.9 20.1 4 19 4H18V2H16ZM19 20H5V9H19V20Z"
|
|
333
509
|
fill="#505050"
|
|
334
510
|
/>
|
|
335
|
-
</svg> `,
|
|
511
|
+
</svg> `, ce = n`<svg
|
|
336
512
|
width="24"
|
|
337
513
|
height="24"
|
|
338
514
|
viewBox="0 0 24 24"
|
|
@@ -343,7 +519,7 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
343
519
|
d="M20 7H15V4C15 2.9 14.1 2 13 2H11C9.9 2 9 2.9 9 4V7H4C2.9 7 2 7.9 2 9V20C2 21.1 2.9 22 4 22H20C21.1 22 22 21.1 22 20V9C22 7.9 21.1 7 20 7ZM9 12C9.83 12 10.5 12.67 10.5 13.5C10.5 14.33 9.83 15 9 15C8.17 15 7.5 14.33 7.5 13.5C7.5 12.67 8.17 12 9 12ZM12 18H6V17.25C6 16.25 8 15.75 9 15.75C10 15.75 12 16.25 12 17.25V18ZM13 9H11V4H13V9ZM18 16.5H14V15H18V16.5ZM18 13.5H14V12H18V13.5Z"
|
|
344
520
|
fill="#505050"
|
|
345
521
|
/>
|
|
346
|
-
</svg> `,
|
|
522
|
+
</svg> `, he = n`<svg
|
|
347
523
|
width="24"
|
|
348
524
|
height="24"
|
|
349
525
|
viewBox="0 0 24 24"
|
|
@@ -354,122 +530,275 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
354
530
|
d="M12 2.5C8 2.5 4 3 4 6.5V16C4 16.95 4.38 17.81 5 18.44V20.5C5 21.05 5.45 21.5 6 21.5H7C7.55 21.5 8 21.05 8 20.5V19.5H16V20.5C16 21.05 16.45 21.5 17 21.5H18C18.55 21.5 19 21.05 19 20.5V18.44C19.62 17.81 20 16.95 20 16V6.5C20 3 16.42 2.5 12 2.5ZM8.5 16.5C7.67 16.5 7 15.83 7 15C7 14.17 7.67 13.5 8.5 13.5C9.33 13.5 10 14.17 10 15C10 15.83 9.33 16.5 8.5 16.5ZM15.5 16.5C14.67 16.5 14 15.83 14 15C14 14.17 14.67 13.5 15.5 13.5C16.33 13.5 17 14.17 17 15C17 15.83 16.33 16.5 15.5 16.5ZM18 10.5H6V7.5H18V10.5Z"
|
|
355
531
|
fill="#505050"
|
|
356
532
|
/>
|
|
357
|
-
</svg>`,
|
|
358
|
-
|
|
533
|
+
</svg>`, O = {
|
|
534
|
+
AccountsSvgIcon: J,
|
|
535
|
+
AdminSvgIcon: ee,
|
|
536
|
+
AlumniSvgIcon: te,
|
|
537
|
+
CamperSvgIcon: oe,
|
|
538
|
+
CommunicationSvgIcon: ne,
|
|
539
|
+
CampInTouchSvgIcon: ie,
|
|
540
|
+
FinancialSvgIcon: ae,
|
|
541
|
+
MedicalSvgIcon: se,
|
|
542
|
+
ReportingSvgIcon: re,
|
|
543
|
+
SchedulingSvgIcon: le,
|
|
544
|
+
StaffSvgIcon: ce,
|
|
545
|
+
TravelSvgIcon: he
|
|
546
|
+
};
|
|
547
|
+
function de(e) {
|
|
548
|
+
return e ? e.id === "home" ? Z : O[`${e.label}SvgIcon`] ?? V : V;
|
|
549
|
+
}
|
|
550
|
+
function Le(e) {
|
|
551
|
+
return e ? e.id === "home" ? !0 : `${e.label}SvgIcon` in O : !1;
|
|
552
|
+
}
|
|
553
|
+
function p(e) {
|
|
554
|
+
return e.startsWith("http") ? new URL(e).pathname + new URL(e).search : e;
|
|
555
|
+
}
|
|
556
|
+
function ge(e, t) {
|
|
557
|
+
const i = p(t);
|
|
558
|
+
for (const o of e) {
|
|
559
|
+
if (o.href && p(o.href) === i)
|
|
560
|
+
return o.id;
|
|
561
|
+
for (const a of o.subCategories)
|
|
562
|
+
if (a.href && p(a.href) === i || a.items.find((r) => p(r.href) === i)) return o.id;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
function ue(e) {
|
|
566
|
+
return e.items.length > 0 || !!e.href;
|
|
567
|
+
}
|
|
568
|
+
function d(e) {
|
|
569
|
+
return e.subCategories.filter(ue);
|
|
570
|
+
}
|
|
571
|
+
function S(e, t) {
|
|
572
|
+
const i = e.find((o) => o.id === t);
|
|
573
|
+
return !!i && d(i).length > 0;
|
|
574
|
+
}
|
|
575
|
+
function pe(e, t) {
|
|
576
|
+
return t === "/" ? "home" : ge(e, t) ?? "";
|
|
577
|
+
}
|
|
578
|
+
function B(e) {
|
|
579
|
+
return e.popup ? n`
|
|
580
|
+
<a
|
|
581
|
+
class="menu-url"
|
|
582
|
+
href="#nowhere"
|
|
583
|
+
@click=${() => {
|
|
584
|
+
const t = window.open(e.href, "", e.popupProperties);
|
|
585
|
+
return t && (t.opener = null), !1;
|
|
586
|
+
}}
|
|
587
|
+
target="_top"
|
|
588
|
+
>
|
|
589
|
+
${e.label}
|
|
590
|
+
<span class="new-tab-icon">${I}</span>
|
|
591
|
+
</a>
|
|
592
|
+
` : n`
|
|
593
|
+
<a
|
|
594
|
+
class="menu-url"
|
|
595
|
+
href="${e.href}"
|
|
596
|
+
target=${e.newTab ? "_blank" : "_self"}
|
|
597
|
+
rel=${v(e.newTab ? "noopener noreferrer" : void 0)}
|
|
598
|
+
>
|
|
599
|
+
${e.label} ${e.newTab ? n`<span class="new-tab-icon">${I}</span>` : null}
|
|
600
|
+
</a>
|
|
601
|
+
`;
|
|
602
|
+
}
|
|
603
|
+
var me = Object.defineProperty, ve = Object.getOwnPropertyDescriptor, x = (e, t, i, o) => {
|
|
604
|
+
for (var a = o > 1 ? void 0 : o ? ve(t, i) : t, s = e.length - 1, r; s >= 0; s--)
|
|
605
|
+
(r = e[s]) && (a = (o ? r(t, i, a) : r(a)) || a);
|
|
606
|
+
return o && a && me(t, i, a), a;
|
|
607
|
+
};
|
|
608
|
+
let g = class extends w {
|
|
609
|
+
constructor() {
|
|
610
|
+
super(...arguments), this.tree = [], this.categoryId = "", this.handleKeyDown = (e) => {
|
|
611
|
+
var t, i;
|
|
612
|
+
if (e.key === "Escape")
|
|
613
|
+
this.handleCloseMegaMenu(!0);
|
|
614
|
+
else if (e.key === "Tab") {
|
|
615
|
+
const o = (t = this.shadowRoot) == null ? void 0 : t.querySelectorAll("a.menu-title, .menu-url");
|
|
616
|
+
if (!o || o.length === 0) return;
|
|
617
|
+
const a = (i = this.shadowRoot) == null ? void 0 : i.activeElement;
|
|
618
|
+
e.shiftKey && a === o[0] ? (e.preventDefault(), this.handleCloseMegaMenu(!0)) : !e.shiftKey && a === o[o.length - 1] && (e.preventDefault(), o[0].focus());
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
connectedCallback() {
|
|
623
|
+
super.connectedCallback(), this.addEventListener("keydown", this.handleKeyDown);
|
|
624
|
+
}
|
|
625
|
+
disconnectedCallback() {
|
|
626
|
+
super.disconnectedCallback(), this.removeEventListener("keydown", this.handleKeyDown);
|
|
627
|
+
}
|
|
628
|
+
get categoryData() {
|
|
629
|
+
return this.tree.find((e) => e.id === this.categoryId);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* The close event keeps its name, `bubbles` and `composed` flags; `detail` is
|
|
633
|
+
* new and carries the caller's focus intent onward to `<cm-side-nav>`'s
|
|
634
|
+
* `dismissFlyout()`, which is the one place the focus rule is applied. Both
|
|
635
|
+
* keyboard paths ask for restoration — they are the paths where focus is inside
|
|
636
|
+
* the flyout and would otherwise be dropped on the document body. The close
|
|
637
|
+
* button asks too; it is harmless when focus is not inside, because
|
|
638
|
+
* `dismissFlyout` only moves focus that actually sits in the flyout.
|
|
639
|
+
*/
|
|
640
|
+
handleCloseMegaMenu(e = !0) {
|
|
641
|
+
this.dispatchEvent(
|
|
642
|
+
new CustomEvent("cm-mega-menu-close", {
|
|
643
|
+
detail: { restoreFocus: e },
|
|
644
|
+
bubbles: !0,
|
|
645
|
+
composed: !0,
|
|
646
|
+
cancelable: !0
|
|
647
|
+
})
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Packs menu items into as many 248px columns as the container's own
|
|
652
|
+
* measured height allows. The `getBoundingClientRect()` calls below are
|
|
653
|
+
* this component measuring its own shadow root, not a sibling, so they
|
|
654
|
+
* don't trip the one rule. The `window.innerWidth <= 1150` gate is a
|
|
655
|
+
* different thing and does not get the same pass: it's a page-viewport
|
|
656
|
+
* read uncorrelated with this component's actual available width, kept
|
|
657
|
+
* only because it's what upstream gated on. `window.innerWidth` is 1024
|
|
658
|
+
* under jsdom, so this early return fires on every test run and the
|
|
659
|
+
* packing logic below it was, until the test added for this floor,
|
|
660
|
+
* unexercised by the suite.
|
|
661
|
+
*/
|
|
662
|
+
setMenuItemsContainerWidth() {
|
|
663
|
+
var a;
|
|
664
|
+
const e = (a = this.shadowRoot) == null ? void 0 : a.querySelector(".menu-items");
|
|
665
|
+
if (!e || window.innerWidth <= 1150) return;
|
|
666
|
+
const t = e.getBoundingClientRect().height - 20;
|
|
667
|
+
let i = 1, o = 0;
|
|
668
|
+
for (const s of e.children)
|
|
669
|
+
o + s.getBoundingClientRect().height + 12 > // 12 for bottom margin on item
|
|
670
|
+
t && (i += 1, o = 0), o += s.getBoundingClientRect().height + 12;
|
|
671
|
+
e.style.width = `${i * E + (i + 1) * T}px`;
|
|
672
|
+
}
|
|
673
|
+
updated(e) {
|
|
674
|
+
super.updated(e), this.setMenuItemsContainerWidth();
|
|
675
|
+
}
|
|
676
|
+
render() {
|
|
677
|
+
const e = this.categoryData, t = e ? d(e) : [];
|
|
678
|
+
return !e || t.length === 0 ? null : n`
|
|
679
|
+
<section class="mega-menu">
|
|
680
|
+
<div class="header">
|
|
681
|
+
<div class="header-left">
|
|
682
|
+
<div class="header-icon">${de(e)}</div>
|
|
683
|
+
<p class="header-title title-text">${e.label}</p>
|
|
684
|
+
</div>
|
|
685
|
+
<p class="close-button" @click=${() => this.handleCloseMegaMenu(!0)}>
|
|
686
|
+
${z()}
|
|
687
|
+
</p>
|
|
688
|
+
</div>
|
|
689
|
+
<div class="menu-items">
|
|
690
|
+
${t.map(
|
|
691
|
+
(i) => n`
|
|
692
|
+
<div class="menu-item">
|
|
693
|
+
${// Deliberate addition, not upstream parity — core-js's
|
|
694
|
+
// `sub_categories[]` never carried a `url`, so there's no parity to
|
|
695
|
+
// break. `MenuSubCategory.href?` lets a sub-category be a direct
|
|
696
|
+
// link, and `isRenderableSubCategory` (`Utils/helpers.ts`) already
|
|
697
|
+
// keeps such a node alive when it has no items. Rendering only
|
|
698
|
+
// `sub.items` left that node's header going nowhere — no live case
|
|
699
|
+
// in `campminder.json` today, but Floor 6's visibility filter can
|
|
700
|
+
// produce one: an `href`-bearing sub-category whose every leaf is
|
|
701
|
+
// gated off for the viewer.
|
|
702
|
+
i.href ? n`<a class="title-text menu-title" href="${i.href}">${i.label}</a>` : n`<p class="title-text menu-title">${i.label}</p>`}
|
|
703
|
+
${i.items.map((o) => B(o))}
|
|
704
|
+
</div>
|
|
705
|
+
`
|
|
706
|
+
)}
|
|
707
|
+
</div>
|
|
708
|
+
</section>
|
|
709
|
+
`;
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
g.styles = [X];
|
|
713
|
+
x([
|
|
714
|
+
h({ attribute: !1 })
|
|
715
|
+
], g.prototype, "tree", 2);
|
|
716
|
+
x([
|
|
717
|
+
h({ type: String, attribute: "category-id" })
|
|
718
|
+
], g.prototype, "categoryId", 2);
|
|
719
|
+
g = x([
|
|
720
|
+
y("cm-mega-menu")
|
|
721
|
+
], g);
|
|
722
|
+
const fe = b`
|
|
359
723
|
:host {
|
|
360
|
-
/*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
|
|
366
|
-
* '100vw' is correct for production, where the shell fills the
|
|
367
|
-
* viewport and the nav starts at x=0; it reads over-wide in this
|
|
368
|
-
* harness only because the harness page has a 24px inset the shell
|
|
369
|
-
* doesn't have — a harness-geometry artifact, not a formula bug. */
|
|
370
|
-
--cm-mega-menu-max-width: calc(100vw - var(--cm-side-nav-width, 168px));
|
|
724
|
+
/* The mobile drill-down is rendered inside '<cm-side-nav>'s shadow root, so
|
|
725
|
+
* it would inherit this anyway. Declaring it keeps the panel's typeface a
|
|
726
|
+
* property of the panel — it survives being reparented or slotted later —
|
|
727
|
+
* and cannot drift from the side nav's value, because both resolve the one
|
|
728
|
+
* 'SHELL_FONT_FAMILY' constant. Rationale: '../shell-tokens.ts'. */
|
|
729
|
+
--font-family: ${C};
|
|
371
730
|
}
|
|
372
731
|
|
|
373
|
-
/* ===== CSS RESET ===== */
|
|
374
732
|
* {
|
|
375
733
|
margin: 0;
|
|
376
734
|
padding: 0;
|
|
377
735
|
box-sizing: border-box;
|
|
378
736
|
}
|
|
379
737
|
|
|
380
|
-
|
|
381
|
-
@keyframes fadeIn {
|
|
382
|
-
from {
|
|
383
|
-
opacity: 0;
|
|
384
|
-
}
|
|
385
|
-
to {
|
|
386
|
-
opacity: 1;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/* ===== MEGA MENU CONTAINER ===== */
|
|
391
|
-
.mega-menu {
|
|
392
|
-
position: absolute;
|
|
393
|
-
left: 100%;
|
|
394
|
-
top: 0;
|
|
395
|
-
max-width: var(--cm-mega-menu-max-width);
|
|
738
|
+
.mega-menu-mobile {
|
|
396
739
|
height: 100%;
|
|
397
|
-
|
|
740
|
+
display: flex;
|
|
741
|
+
flex-direction: column;
|
|
398
742
|
background: #fff;
|
|
399
|
-
box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.12);
|
|
400
|
-
animation: fadeIn 0.5s ease;
|
|
401
743
|
}
|
|
402
744
|
|
|
403
|
-
/* ===== HEADER SECTION ===== */
|
|
404
745
|
.header {
|
|
405
746
|
display: flex;
|
|
406
747
|
align-items: center;
|
|
407
|
-
|
|
748
|
+
gap: 8px;
|
|
408
749
|
color: #505050;
|
|
409
750
|
border-bottom: 1px solid rgba(160, 160, 160, 1);
|
|
410
|
-
|
|
751
|
+
padding: 0 16px;
|
|
411
752
|
height: 56px;
|
|
753
|
+
flex-shrink: 0;
|
|
412
754
|
}
|
|
413
755
|
|
|
414
|
-
.
|
|
415
|
-
display: flex;
|
|
416
|
-
align-items: center;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
.header-title {
|
|
420
|
-
display: grid;
|
|
421
|
-
place-content: center;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
.header-icon {
|
|
425
|
-
margin-right: 8px;
|
|
426
|
-
display: flex;
|
|
427
|
-
justify-content: center;
|
|
428
|
-
align-items: center;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
/* ===== CLOSE BUTTON ===== */
|
|
432
|
-
.close-button {
|
|
756
|
+
.back-button {
|
|
433
757
|
display: flex;
|
|
434
758
|
width: 24px;
|
|
435
759
|
height: 24px;
|
|
436
760
|
justify-content: center;
|
|
437
761
|
align-items: center;
|
|
762
|
+
border: none;
|
|
763
|
+
background: transparent;
|
|
438
764
|
border-radius: 4px;
|
|
439
765
|
cursor: pointer;
|
|
440
766
|
transition: background 0.2s ease;
|
|
441
767
|
}
|
|
442
768
|
|
|
443
|
-
.
|
|
769
|
+
.back-button:hover,
|
|
770
|
+
.back-button:focus-visible {
|
|
444
771
|
background: rgba(119, 61, 189, 0.12);
|
|
445
772
|
}
|
|
446
773
|
|
|
447
|
-
|
|
774
|
+
.back-icon {
|
|
775
|
+
display: flex;
|
|
776
|
+
transform: rotate(180deg);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.header-title {
|
|
780
|
+
display: grid;
|
|
781
|
+
place-content: center;
|
|
782
|
+
}
|
|
783
|
+
|
|
448
784
|
.title-text {
|
|
449
785
|
color: #505050;
|
|
450
|
-
font-family:
|
|
786
|
+
font-family: var(--font-family);
|
|
451
787
|
font-size: 16px;
|
|
452
788
|
font-weight: 600;
|
|
453
789
|
line-height: 24px;
|
|
454
790
|
letter-spacing: 0.0025em;
|
|
455
791
|
}
|
|
456
792
|
|
|
457
|
-
/* ===== MENU ITEMS CONTAINER ===== */
|
|
458
793
|
.menu-items {
|
|
459
|
-
|
|
460
|
-
max-width: var(--cm-mega-menu-max-width);
|
|
461
|
-
display: flex;
|
|
462
|
-
flex-flow: column wrap;
|
|
463
|
-
padding: 10px 16px 10px 0px;
|
|
794
|
+
flex: 1;
|
|
464
795
|
overflow: auto;
|
|
796
|
+
padding: 10px 16px;
|
|
465
797
|
}
|
|
466
798
|
|
|
467
|
-
/* ===== MENU ITEM ===== */
|
|
468
799
|
.menu-item {
|
|
469
|
-
width: ${M}px;
|
|
470
|
-
margin-left: ${V}px;
|
|
471
800
|
margin-bottom: 12px;
|
|
472
|
-
font-family:
|
|
801
|
+
font-family: var(--font-family);
|
|
473
802
|
font-size: 14px;
|
|
474
803
|
font-weight: 400;
|
|
475
804
|
line-height: 20px;
|
|
@@ -478,17 +807,19 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
478
807
|
|
|
479
808
|
.menu-title {
|
|
480
809
|
display: flex;
|
|
481
|
-
width:
|
|
482
|
-
padding:
|
|
810
|
+
width: 100%;
|
|
811
|
+
padding: 8px 12px;
|
|
483
812
|
align-items: center;
|
|
484
813
|
gap: 8px;
|
|
814
|
+
background: var(--color-section-bg, rgba(0, 0, 0, 0.04));
|
|
815
|
+
border-radius: 4px;
|
|
816
|
+
margin-bottom: 4px;
|
|
485
817
|
}
|
|
486
818
|
|
|
487
|
-
/* ===== MENU LINKS ===== */
|
|
488
819
|
.menu-url {
|
|
489
820
|
display: flex;
|
|
490
821
|
align-items: center;
|
|
491
|
-
width:
|
|
822
|
+
width: 100%;
|
|
492
823
|
min-height: 32px;
|
|
493
824
|
padding: 6px 12px;
|
|
494
825
|
border-radius: 4px;
|
|
@@ -509,74 +840,23 @@ const b = (e) => e ?? I, S = t` <svg
|
|
|
509
840
|
display: grid;
|
|
510
841
|
place-content: center;
|
|
511
842
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
`, y = {
|
|
520
|
-
AccountsSvgIcon: j,
|
|
521
|
-
AdminSvgIcon: F,
|
|
522
|
-
AlumniSvgIcon: K,
|
|
523
|
-
CamperSvgIcon: Y,
|
|
524
|
-
CommunicationSvgIcon: q,
|
|
525
|
-
CampInTouchSvgIcon: W,
|
|
526
|
-
FinancialSvgIcon: X,
|
|
527
|
-
MedicalSvgIcon: J,
|
|
528
|
-
ReportingSvgIcon: Q,
|
|
529
|
-
SchedulingSvgIcon: e1,
|
|
530
|
-
StaffSvgIcon: t1,
|
|
531
|
-
TravelSvgIcon: o1
|
|
843
|
+
`;
|
|
844
|
+
var Ce = Object.defineProperty, be = Object.getOwnPropertyDescriptor, M = (e, t, i, o) => {
|
|
845
|
+
for (var a = o > 1 ? void 0 : o ? be(t, i) : t, s = e.length - 1, r; s >= 0; s--)
|
|
846
|
+
(r = e[s]) && (a = (o ? r(t, i, a) : r(a)) || a);
|
|
847
|
+
return o && a && Ce(t, i, a), a;
|
|
532
848
|
};
|
|
533
|
-
|
|
534
|
-
return e ? e.id === "home" ? H : y[`${e.label}SvgIcon`] ?? u : u;
|
|
535
|
-
}
|
|
536
|
-
function w1(e) {
|
|
537
|
-
return e ? e.id === "home" ? !0 : `${e.label}SvgIcon` in y : !1;
|
|
538
|
-
}
|
|
539
|
-
function d(e) {
|
|
540
|
-
return e.startsWith("http") ? new URL(e).pathname + new URL(e).search : e;
|
|
541
|
-
}
|
|
542
|
-
function s1(e, o) {
|
|
543
|
-
const n = d(o);
|
|
544
|
-
for (const i of e) {
|
|
545
|
-
if (i.href && d(i.href) === n)
|
|
546
|
-
return i.id;
|
|
547
|
-
for (const s of i.subCategories)
|
|
548
|
-
if (s.href && d(s.href) === n || s.items.find((a) => d(a.href) === n)) return i.id;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
function r1(e) {
|
|
552
|
-
return e.items.length > 0 || !!e.href;
|
|
553
|
-
}
|
|
554
|
-
function C(e) {
|
|
555
|
-
return e.subCategories.filter(r1);
|
|
556
|
-
}
|
|
557
|
-
function a1(e, o) {
|
|
558
|
-
const n = e.find((i) => i.id === o);
|
|
559
|
-
return !!n && C(n).length > 0;
|
|
560
|
-
}
|
|
561
|
-
function l1(e, o) {
|
|
562
|
-
return o === "/" ? "home" : s1(e, o) ?? "";
|
|
563
|
-
}
|
|
564
|
-
var h1 = Object.defineProperty, c1 = Object.getOwnPropertyDescriptor, v = (e, o, n, i) => {
|
|
565
|
-
for (var s = i > 1 ? void 0 : i ? c1(o, n) : o, r = e.length - 1, a; r >= 0; r--)
|
|
566
|
-
(a = e[r]) && (s = (i ? a(o, n, s) : a(s)) || s);
|
|
567
|
-
return i && s && h1(o, n, s), s;
|
|
568
|
-
};
|
|
569
|
-
let h = class extends m {
|
|
849
|
+
let u = class extends w {
|
|
570
850
|
constructor() {
|
|
571
851
|
super(...arguments), this.tree = [], this.categoryId = "", this.handleKeyDown = (e) => {
|
|
572
|
-
var
|
|
852
|
+
var t, i;
|
|
573
853
|
if (e.key === "Escape")
|
|
574
|
-
this.
|
|
854
|
+
e.stopPropagation(), this.handleBack();
|
|
575
855
|
else if (e.key === "Tab") {
|
|
576
|
-
const
|
|
577
|
-
if (!
|
|
578
|
-
const
|
|
579
|
-
e.shiftKey &&
|
|
856
|
+
const o = (t = this.shadowRoot) == null ? void 0 : t.querySelectorAll(".back-button, a.menu-title, .menu-url");
|
|
857
|
+
if (!o || o.length === 0) return;
|
|
858
|
+
const a = (i = this.shadowRoot) == null ? void 0 : i.activeElement;
|
|
859
|
+
e.shiftKey && a === o[0] ? (e.preventDefault(), e.stopPropagation(), this.handleBack()) : !e.shiftKey && a === o[o.length - 1] && (e.preventDefault(), e.stopPropagation(), o[0].focus());
|
|
580
860
|
}
|
|
581
861
|
};
|
|
582
862
|
}
|
|
@@ -589,97 +869,44 @@ let h = class extends m {
|
|
|
589
869
|
get categoryData() {
|
|
590
870
|
return this.tree.find((e) => e.id === this.categoryId);
|
|
591
871
|
}
|
|
592
|
-
|
|
872
|
+
/**
|
|
873
|
+
* Requests the host go back to the main mobile menu list. Named `-back`, not
|
|
874
|
+
* `-close`, because it does not dismiss the mobile overlay itself — only
|
|
875
|
+
* `<cm-side-nav>`'s own toggle/backdrop does that (see its doc comment).
|
|
876
|
+
*/
|
|
877
|
+
handleBack() {
|
|
593
878
|
this.dispatchEvent(
|
|
594
|
-
new CustomEvent("cm-mega-menu-
|
|
879
|
+
new CustomEvent("cm-mega-menu-mobile-back", {
|
|
595
880
|
bubbles: !0,
|
|
596
|
-
composed: !0
|
|
597
|
-
cancelable: !0
|
|
881
|
+
composed: !0
|
|
598
882
|
})
|
|
599
883
|
);
|
|
600
884
|
}
|
|
601
885
|
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
* this
|
|
605
|
-
* don't trip the one rule. The `window.innerWidth <= 1150` gate is a
|
|
606
|
-
* different thing and does not get the same pass: it's a page-viewport
|
|
607
|
-
* read uncorrelated with this component's actual available width, kept
|
|
608
|
-
* only because it's what upstream gated on. `window.innerWidth` is 1024
|
|
609
|
-
* under jsdom, so this early return fires on every test run and the
|
|
610
|
-
* packing logic below it was, until the test added for this floor,
|
|
611
|
-
* unexercised by the suite.
|
|
886
|
+
* Required, not decorative: drilling in removes the category button focus
|
|
887
|
+
* was on from the DOM (it belonged to the main list, now unmounted), so
|
|
888
|
+
* without this, focus is dropped onto the document body.
|
|
612
889
|
*/
|
|
613
|
-
|
|
614
|
-
var
|
|
615
|
-
|
|
616
|
-
if (!e || window.innerWidth <= 1150) return;
|
|
617
|
-
const o = e.getBoundingClientRect().height - 20;
|
|
618
|
-
let n = 1, i = 0;
|
|
619
|
-
for (const r of e.children)
|
|
620
|
-
i + r.getBoundingClientRect().height + 12 > // 12 for bottom margin on item
|
|
621
|
-
o && (n += 1, i = 0), i += r.getBoundingClientRect().height + 12;
|
|
622
|
-
e.style.width = `${n * M + (n + 1) * V}px`;
|
|
623
|
-
}
|
|
624
|
-
updated(e) {
|
|
625
|
-
super.updated(e), this.setMenuItemsContainerWidth();
|
|
626
|
-
}
|
|
627
|
-
// 2026-09-04: `label` may carry an unresolved `{{Bunk:Proper:Default}}`-style
|
|
628
|
-
// terminology token, on both a sub-category header and a leaf. Rendered
|
|
629
|
-
// verbatim below on purpose — see AGENTS.md's "Never resolve a terminology
|
|
630
|
-
// token."
|
|
631
|
-
renderLeaf(e) {
|
|
632
|
-
return e.popup ? t`
|
|
633
|
-
<a
|
|
634
|
-
class="menu-url"
|
|
635
|
-
href="#nowhere"
|
|
636
|
-
@click=${() => {
|
|
637
|
-
const o = window.open(e.href, "", e.popupProperties);
|
|
638
|
-
return o && (o.opener = null), !1;
|
|
639
|
-
}}
|
|
640
|
-
target="_top"
|
|
641
|
-
>
|
|
642
|
-
${e.label}
|
|
643
|
-
<span class="new-tab-icon">${w}</span>
|
|
644
|
-
</a>
|
|
645
|
-
` : t`
|
|
646
|
-
<a
|
|
647
|
-
class="menu-url"
|
|
648
|
-
href="${e.href}"
|
|
649
|
-
target=${e.newTab ? "_blank" : "_self"}
|
|
650
|
-
rel=${b(e.newTab ? "noopener noreferrer" : void 0)}
|
|
651
|
-
>
|
|
652
|
-
${e.label}
|
|
653
|
-
${e.newTab ? t`<span class="new-tab-icon">${w}</span>` : null}
|
|
654
|
-
</a>
|
|
655
|
-
`;
|
|
890
|
+
firstUpdated() {
|
|
891
|
+
var e, t;
|
|
892
|
+
(t = (e = this.shadowRoot) == null ? void 0 : e.querySelector(".back-button")) == null || t.focus();
|
|
656
893
|
}
|
|
657
894
|
render() {
|
|
658
|
-
const e = this.categoryData,
|
|
659
|
-
return !e ||
|
|
660
|
-
<section class="mega-menu">
|
|
895
|
+
const e = this.categoryData, t = e ? d(e) : [];
|
|
896
|
+
return !e || t.length === 0 ? null : n`
|
|
897
|
+
<section class="mega-menu-mobile">
|
|
661
898
|
<div class="header">
|
|
662
|
-
<
|
|
663
|
-
<
|
|
664
|
-
|
|
665
|
-
</
|
|
666
|
-
<p class="close-button" @click=${this.handleCloseMegaMenu}>${k()}</p>
|
|
899
|
+
<button class="back-button" @click=${() => this.handleBack()} aria-label="Back">
|
|
900
|
+
<span class="back-icon">${$}</span>
|
|
901
|
+
</button>
|
|
902
|
+
<p class="header-title title-text">${e.label}</p>
|
|
667
903
|
</div>
|
|
668
904
|
<div class="menu-items">
|
|
669
|
-
${
|
|
670
|
-
(
|
|
905
|
+
${t.map(
|
|
906
|
+
(i) => n`
|
|
671
907
|
<div class="menu-item">
|
|
672
|
-
${
|
|
673
|
-
|
|
674
|
-
// break. `MenuSubCategory.href?` lets a sub-category be a direct
|
|
675
|
-
// link, and `isRenderableSubCategory` (`Utils/helpers.ts`) already
|
|
676
|
-
// keeps such a node alive when it has no items. Rendering only
|
|
677
|
-
// `sub.items` left that node's header going nowhere — no live case
|
|
678
|
-
// in `campminder.json` today, but Floor 6's visibility filter can
|
|
679
|
-
// produce one: an `href`-bearing sub-category whose every leaf is
|
|
680
|
-
// gated off for the viewer.
|
|
681
|
-
n.href ? t`<a class="title-text menu-title" href="${n.href}">${n.label}</a>` : t`<p class="title-text menu-title">${n.label}</p>`}
|
|
682
|
-
${n.items.map((i) => this.renderLeaf(i))}
|
|
908
|
+
${i.href ? n`<a class="title-text menu-title" href="${i.href}">${i.label}</a>` : n`<p class="title-text menu-title">${i.label}</p>`}
|
|
909
|
+
${i.items.map((o) => B(o))}
|
|
683
910
|
</div>
|
|
684
911
|
`
|
|
685
912
|
)}
|
|
@@ -688,17 +915,17 @@ let h = class extends m {
|
|
|
688
915
|
`;
|
|
689
916
|
}
|
|
690
917
|
};
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
],
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
],
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
],
|
|
701
|
-
const
|
|
918
|
+
u.styles = [fe];
|
|
919
|
+
M([
|
|
920
|
+
h({ attribute: !1 })
|
|
921
|
+
], u.prototype, "tree", 2);
|
|
922
|
+
M([
|
|
923
|
+
h({ type: String, attribute: "category-id" })
|
|
924
|
+
], u.prototype, "categoryId", 2);
|
|
925
|
+
u = M([
|
|
926
|
+
y("cm-mega-menu-mobile")
|
|
927
|
+
], u);
|
|
928
|
+
const we = b`
|
|
702
929
|
/* ===== CSS CUSTOM PROPERTIES (DESIGN TOKENS) ===== */
|
|
703
930
|
:host {
|
|
704
931
|
display: block;
|
|
@@ -732,7 +959,12 @@ const g1 = f`
|
|
|
732
959
|
--easing-exit: cubic-bezier(0.4, 0, 0.2, 1);
|
|
733
960
|
|
|
734
961
|
/* Typography tokens */
|
|
735
|
-
|
|
962
|
+
/* Every text rule below reads this. The shell hardcoded 'Inter' until
|
|
963
|
+
* AB#27079 while nothing in this repo ever loaded Inter, so the chrome
|
|
964
|
+
* silently rendered in the browser's default sans-serif next to a host
|
|
965
|
+
* showing General Sans. The fallback chain and why it must stay a read-only
|
|
966
|
+
* var() live on 'SHELL_FONT_FAMILY' in '../shell-tokens.ts'. */
|
|
967
|
+
--font-family: ${C};
|
|
736
968
|
--font-size-base: 14px;
|
|
737
969
|
--font-size-medium: 15px;
|
|
738
970
|
--font-size-large: 16px;
|
|
@@ -764,13 +996,13 @@ const g1 = f`
|
|
|
764
996
|
box-sizing: border-box;
|
|
765
997
|
}
|
|
766
998
|
|
|
767
|
-
/* ===== MENU TOGGLE BUTTON (mobile
|
|
999
|
+
/* ===== MENU TOGGLE BUTTON (mobile) ===== */
|
|
768
1000
|
.menu-toggle {
|
|
769
1001
|
width: var(--sidebar-header-height);
|
|
770
1002
|
height: var(--sidebar-header-height);
|
|
771
1003
|
cursor: pointer;
|
|
772
1004
|
display: none;
|
|
773
|
-
background:
|
|
1005
|
+
background: var(--color-bg-gradient);
|
|
774
1006
|
border: none;
|
|
775
1007
|
border-bottom: 1px solid var(--color-border-gray);
|
|
776
1008
|
justify-content: center;
|
|
@@ -782,6 +1014,74 @@ const g1 = f`
|
|
|
782
1014
|
height: var(--icon-size-base);
|
|
783
1015
|
}
|
|
784
1016
|
|
|
1017
|
+
/* ===== MOBILE NAV (Floor 5D) ===== */
|
|
1018
|
+
.mobile-nav {
|
|
1019
|
+
display: none;
|
|
1020
|
+
position: relative;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.mobile-overlay-backdrop {
|
|
1024
|
+
position: fixed;
|
|
1025
|
+
inset: 0;
|
|
1026
|
+
background: var(--color-backdrop);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.mobile-overlay-menu {
|
|
1030
|
+
position: fixed;
|
|
1031
|
+
top: 0;
|
|
1032
|
+
left: 0;
|
|
1033
|
+
width: var(--overlay-menu-width);
|
|
1034
|
+
max-width: var(--overlay-menu-max-width);
|
|
1035
|
+
height: 100%;
|
|
1036
|
+
background: var(--color-bg-gradient);
|
|
1037
|
+
color: var(--color-text);
|
|
1038
|
+
/* Deliberately not a scroll-lock on document.body (banned, see AGENTS.md's
|
|
1039
|
+
* one rule) — this is the panel's own scroll boundary staying put under
|
|
1040
|
+
* background touch-scroll, the plan's declared, narrower substitute. */
|
|
1041
|
+
overscroll-behavior: contain;
|
|
1042
|
+
overflow: auto;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
.mobile-categories-container,
|
|
1046
|
+
.mobile-categories-list {
|
|
1047
|
+
list-style: none;
|
|
1048
|
+
margin: 0;
|
|
1049
|
+
padding: 0;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.mobile-categories-list li {
|
|
1053
|
+
display: contents;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
.mobile-category {
|
|
1057
|
+
width: 100%;
|
|
1058
|
+
height: var(--category-height);
|
|
1059
|
+
display: flex;
|
|
1060
|
+
align-items: center;
|
|
1061
|
+
border: none;
|
|
1062
|
+
border-bottom: 1px solid var(--color-border);
|
|
1063
|
+
background: transparent;
|
|
1064
|
+
text-decoration: none;
|
|
1065
|
+
padding: var(--spacing-md);
|
|
1066
|
+
color: var(--color-text);
|
|
1067
|
+
cursor: pointer;
|
|
1068
|
+
font-family: var(--font-family);
|
|
1069
|
+
font-size: var(--font-size-base);
|
|
1070
|
+
font-weight: 400;
|
|
1071
|
+
line-height: var(--line-height-base);
|
|
1072
|
+
letter-spacing: -0.001em;
|
|
1073
|
+
text-align: left;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
.mobile-category.selected {
|
|
1077
|
+
background: var(--color-selected);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
.mobile-category:hover,
|
|
1081
|
+
.mobile-category:focus {
|
|
1082
|
+
background: var(--color-hover);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
785
1085
|
/* ===== NAVIGATION CONTAINER ===== */
|
|
786
1086
|
.nav-container {
|
|
787
1087
|
display: flex;
|
|
@@ -976,6 +1276,10 @@ const g1 = f`
|
|
|
976
1276
|
text-align: left;
|
|
977
1277
|
}
|
|
978
1278
|
|
|
1279
|
+
/* Rendered only by the mobile category list (Floor 5D, AB#26231) — the
|
|
1280
|
+
desktop .category button never emits this markup (see side-nav.test.ts's
|
|
1281
|
+
"no chevron on desktop" regression); the desktop indicator stays
|
|
1282
|
+
.category-hovered::after. */
|
|
979
1283
|
.chevron-right {
|
|
980
1284
|
margin-left: auto;
|
|
981
1285
|
display: flex;
|
|
@@ -991,35 +1295,62 @@ const g1 = f`
|
|
|
991
1295
|
animation-iteration-count: 1 !important;
|
|
992
1296
|
}
|
|
993
1297
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1298
|
+
|
|
1299
|
+
/* ===== MOBILE / DESKTOP VARIANT SWITCH (Floor 5D) =====
|
|
1300
|
+
* Deliberately LAST in this stylesheet. A media query adds no specificity —
|
|
1301
|
+
* it only groups rules that still compete on source order at equal
|
|
1302
|
+
* specificity with anything outside it. This block was originally placed
|
|
1303
|
+
* right after the mobile-only rules it complements (before ".nav-container"'s
|
|
1304
|
+
* own base rule), which put it BEFORE that base rule in source order; the
|
|
1305
|
+
* base rule then won the cascade for ".nav-container" at every viewport,
|
|
1306
|
+
* silently no-opping this block's "display: none" for it. Caught by live
|
|
1307
|
+
* browser measurement 2026-09-17 — see the evidence doc. Keeping this block
|
|
1308
|
+
* last guarantees it wins the cascade against every base rule above,
|
|
1309
|
+
* including any added later; do not insert a new base rule after this one. */
|
|
1310
|
+
@media (max-width: ${f}px) {
|
|
1311
|
+
.nav-container {
|
|
1312
|
+
display: none;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
.mobile-nav {
|
|
1316
|
+
display: block;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
.menu-toggle {
|
|
1320
|
+
display: flex;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
`, N = {
|
|
1324
|
+
AccountsSvgIcon: R,
|
|
1325
|
+
AdminSvgIcon: D,
|
|
1326
|
+
AlumniSvgIcon: _,
|
|
1327
|
+
CamperSvgIcon: F,
|
|
1328
|
+
CommunicationSvgIcon: G,
|
|
1329
|
+
CampInTouchSvgIcon: P,
|
|
1330
|
+
FinancialSvgIcon: U,
|
|
1331
|
+
HomeSvgIcon: Z,
|
|
1332
|
+
MedicalSvgIcon: K,
|
|
1333
|
+
ReportingSvgIcon: q,
|
|
1334
|
+
SchedulingSvgIcon: Y,
|
|
1335
|
+
StaffSvgIcon: Q,
|
|
1336
|
+
TravelSvgIcon: W
|
|
1008
1337
|
};
|
|
1009
|
-
function
|
|
1010
|
-
return e ?
|
|
1338
|
+
function k(e) {
|
|
1339
|
+
return e ? N[`${e}SvgIcon`] ?? H : H;
|
|
1011
1340
|
}
|
|
1012
|
-
function
|
|
1013
|
-
return !!e && `${e}SvgIcon` in
|
|
1341
|
+
function Ve(e) {
|
|
1342
|
+
return !!e && `${e}SvgIcon` in N;
|
|
1014
1343
|
}
|
|
1015
|
-
var
|
|
1016
|
-
for (var
|
|
1017
|
-
(
|
|
1018
|
-
return
|
|
1344
|
+
var ye = Object.defineProperty, xe = Object.getOwnPropertyDescriptor, c = (e, t, i, o) => {
|
|
1345
|
+
for (var a = o > 1 ? void 0 : o ? xe(t, i) : t, s = e.length - 1, r; s >= 0; s--)
|
|
1346
|
+
(r = e[s]) && (a = (o ? r(t, i, a) : r(a)) || a);
|
|
1347
|
+
return o && a && ye(t, i, a), a;
|
|
1019
1348
|
};
|
|
1020
|
-
let l = class extends
|
|
1349
|
+
let l = class extends w {
|
|
1021
1350
|
constructor() {
|
|
1022
|
-
super(...arguments), this.hoveredCategory = "", this.collapsed = !1, this.currentPath = "", this.tree = [], this.
|
|
1351
|
+
super(...arguments), this.hoveredCategory = "", this.mobileMenuOpen = !1, this.activeMobileCategoryId = "", this.isNarrowViewport = l.readViewportWidthFallback(), this.collapsed = !1, this.currentPath = "", this.tree = [], this.handleMobileMediaChange = (e) => {
|
|
1352
|
+
this.isNarrowViewport = e.matches;
|
|
1353
|
+
}, this.toggleSidenav = () => {
|
|
1023
1354
|
this.dispatchEvent(
|
|
1024
1355
|
new CustomEvent("cm-side-nav-toggle", {
|
|
1025
1356
|
detail: { collapsed: !this.collapsed },
|
|
@@ -1027,6 +1358,18 @@ let l = class extends m {
|
|
|
1027
1358
|
composed: !0
|
|
1028
1359
|
})
|
|
1029
1360
|
);
|
|
1361
|
+
}, this.handleMobileOverlayKeyDown = (e) => {
|
|
1362
|
+
var t, i;
|
|
1363
|
+
if (!this.openMobileCategory) {
|
|
1364
|
+
if (e.key === "Escape")
|
|
1365
|
+
this.dismissMobileMenu(!0);
|
|
1366
|
+
else if (e.key === "Tab") {
|
|
1367
|
+
const o = (t = this.shadowRoot) == null ? void 0 : t.querySelectorAll(".mobile-overlay-menu .mobile-category");
|
|
1368
|
+
if (!o || o.length === 0) return;
|
|
1369
|
+
const a = (i = this.shadowRoot) == null ? void 0 : i.activeElement;
|
|
1370
|
+
e.shiftKey && a === o[0] ? (e.preventDefault(), o[o.length - 1].focus()) : !e.shiftKey && a === o[o.length - 1] && (e.preventDefault(), o[0].focus());
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1030
1373
|
};
|
|
1031
1374
|
}
|
|
1032
1375
|
/**
|
|
@@ -1039,10 +1382,24 @@ let l = class extends m {
|
|
|
1039
1382
|
* getter needs to cache.
|
|
1040
1383
|
*/
|
|
1041
1384
|
get selectedCategory() {
|
|
1042
|
-
return
|
|
1385
|
+
return pe(this.tree, this.currentPath);
|
|
1386
|
+
}
|
|
1387
|
+
connectedCallback() {
|
|
1388
|
+
super.connectedCallback(), this.initMobileMediaQuery();
|
|
1043
1389
|
}
|
|
1044
1390
|
disconnectedCallback() {
|
|
1045
|
-
super.disconnectedCallback(), this.clearHoverTimeout();
|
|
1391
|
+
super.disconnectedCallback(), this.clearHoverTimeout(), this.teardownMobileMediaQuery();
|
|
1392
|
+
}
|
|
1393
|
+
/** The fallback used where `matchMedia` is unavailable — see the class doc comment. */
|
|
1394
|
+
static readViewportWidthFallback() {
|
|
1395
|
+
return window.innerWidth <= f;
|
|
1396
|
+
}
|
|
1397
|
+
initMobileMediaQuery() {
|
|
1398
|
+
typeof window.matchMedia == "function" && (this.mobileMediaQuery = window.matchMedia(`(max-width: ${f}px)`), this.isNarrowViewport = this.mobileMediaQuery.matches, this.mobileMediaQuery.addEventListener("change", this.handleMobileMediaChange));
|
|
1399
|
+
}
|
|
1400
|
+
teardownMobileMediaQuery() {
|
|
1401
|
+
var e;
|
|
1402
|
+
(e = this.mobileMediaQuery) == null || e.removeEventListener("change", this.handleMobileMediaChange), this.mobileMediaQuery = void 0;
|
|
1046
1403
|
}
|
|
1047
1404
|
setSelectedCategory(e) {
|
|
1048
1405
|
this.handleMenuItemHover(e);
|
|
@@ -1061,26 +1418,173 @@ let l = class extends m {
|
|
|
1061
1418
|
handleMouseLeave() {
|
|
1062
1419
|
this.clearHoverTimeout();
|
|
1063
1420
|
}
|
|
1421
|
+
/**
|
|
1422
|
+
* The single dismissal entry point for the flyout — every trigger routes through
|
|
1423
|
+
* here (the flyout's own Escape and shift-Tab paths, the nav's mouseleave, and
|
|
1424
|
+
* the shell's page-level Escape / outside pointer press) so the focus rule is
|
|
1425
|
+
* applied in exactly one place and no trigger can bypass it.
|
|
1426
|
+
*
|
|
1427
|
+
* `restoreFocus` is the caller's *intent*; focus only actually moves when it is
|
|
1428
|
+
* also true that focus is currently inside the flyout. A person typing in a form
|
|
1429
|
+
* field while the flyout is dismissed keeps their cursor where it is, and a
|
|
1430
|
+
* pointer press outside keeps the focus the press itself produces.
|
|
1431
|
+
*
|
|
1432
|
+
* The focus target is read BEFORE `hoveredCategory` is cleared, and that order is
|
|
1433
|
+
* load-bearing: the target is found via the `category-hovered` class, which is
|
|
1434
|
+
* derived from `hoveredCategory` in `buildCategoryClass`. Clearing first would
|
|
1435
|
+
* leave nothing to find and silently drop focus onto the document body — the very
|
|
1436
|
+
* defect this method exists to fix.
|
|
1437
|
+
*/
|
|
1438
|
+
dismissFlyout(e) {
|
|
1439
|
+
if (!this.openCategory) return;
|
|
1440
|
+
const t = e && this.focusIsInsideFlyout() ? this.focusRestoreTarget() : null;
|
|
1441
|
+
this.clearHoverTimeout(), this.hoveredCategory = "", t == null || t.focus();
|
|
1442
|
+
}
|
|
1443
|
+
focusIsInsideFlyout() {
|
|
1444
|
+
var t, i;
|
|
1445
|
+
const e = (t = this.shadowRoot) == null ? void 0 : t.querySelector("cm-mega-menu");
|
|
1446
|
+
return e ? ((i = e.shadowRoot) == null ? void 0 : i.activeElement) != null : !1;
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* The category control the flyout was opened from, or the collapse control when
|
|
1450
|
+
* that category control no longer exists — it always does, so focus can never
|
|
1451
|
+
* land on the document body.
|
|
1452
|
+
*/
|
|
1453
|
+
focusRestoreTarget() {
|
|
1454
|
+
const e = this.shadowRoot;
|
|
1455
|
+
return e ? e.querySelector(".category-hovered") ?? e.querySelector(".sidebar-toggle") : null;
|
|
1456
|
+
}
|
|
1064
1457
|
// Utility Methods
|
|
1065
1458
|
get hamburgerIcon() {
|
|
1066
|
-
return this.collapsed ?
|
|
1459
|
+
return this.collapsed ? L : j;
|
|
1067
1460
|
}
|
|
1068
1461
|
/**
|
|
1069
1462
|
* The category the mega-menu flyout is open for, or `undefined` when none
|
|
1070
1463
|
* is. Guards on `renderableSubCategories(category).length > 0` (the same
|
|
1071
|
-
* predicate `hasSubmenus` uses
|
|
1464
|
+
* predicate `hasSubmenus` uses to render a category as a button) rather than on
|
|
1072
1465
|
* `hoveredCategory` alone — `hoveredCategory` can also be the literal
|
|
1073
1466
|
* string `'sidebar-toggle'` (see `handleMouseEnter` call sites), and a
|
|
1074
1467
|
* category with no renderable sub-categories must not open onto nothing.
|
|
1075
1468
|
*/
|
|
1076
1469
|
get openCategory() {
|
|
1077
|
-
const e = this.tree.find((
|
|
1078
|
-
if (!(!e ||
|
|
1470
|
+
const e = this.tree.find((t) => t.id === this.hoveredCategory);
|
|
1471
|
+
if (!(!e || d(e).length === 0))
|
|
1079
1472
|
return e;
|
|
1080
1473
|
}
|
|
1081
1474
|
buildCategoryClass(e) {
|
|
1082
|
-
const
|
|
1083
|
-
return e.id === this.selectedCategory &&
|
|
1475
|
+
const t = ["category"];
|
|
1476
|
+
return e.id === this.selectedCategory && t.push("selected"), e.id === this.hoveredCategory && t.push("category-hovered"), t.join(" ");
|
|
1477
|
+
}
|
|
1478
|
+
/** The category the mobile drill-down is showing, mirroring `openCategory`. */
|
|
1479
|
+
get openMobileCategory() {
|
|
1480
|
+
const e = this.tree.find((t) => t.id === this.activeMobileCategoryId);
|
|
1481
|
+
if (!(!e || d(e).length === 0))
|
|
1482
|
+
return e;
|
|
1483
|
+
}
|
|
1484
|
+
toggleMobileMenu() {
|
|
1485
|
+
if (this.mobileMenuOpen) {
|
|
1486
|
+
this.dismissMobileMenu(!1);
|
|
1487
|
+
return;
|
|
1488
|
+
}
|
|
1489
|
+
this.mobileMenuOpen = !0;
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* The single dismissal entry point for the mobile overlay — every trigger
|
|
1493
|
+
* (the backdrop click, `.menu-toggle`, the overlay's own Escape) routes
|
|
1494
|
+
* through here, mirroring `dismissFlyout`'s reasoning, so the focus rule is
|
|
1495
|
+
* applied in exactly one place and no trigger can bypass it.
|
|
1496
|
+
*
|
|
1497
|
+
* `restoreFocus` is the caller's intent; focus only actually moves when it is
|
|
1498
|
+
* also true that focus is currently inside the overlay. The target is read
|
|
1499
|
+
* BEFORE state is cleared, same load-bearing order as `dismissFlyout` — the
|
|
1500
|
+
* restore target is `.menu-toggle`, which stays in the DOM regardless of
|
|
1501
|
+
* `mobileMenuOpen`, but focus-inside-overlay is only answerable while the
|
|
1502
|
+
* overlay is still open.
|
|
1503
|
+
*/
|
|
1504
|
+
dismissMobileMenu(e) {
|
|
1505
|
+
var i;
|
|
1506
|
+
if (!this.mobileMenuOpen) return;
|
|
1507
|
+
const t = e && this.focusIsInsideMobileOverlay() ? (i = this.shadowRoot) == null ? void 0 : i.querySelector(".menu-toggle") : null;
|
|
1508
|
+
this.mobileMenuOpen = !1, this.activeMobileCategoryId = "", t == null || t.focus();
|
|
1509
|
+
}
|
|
1510
|
+
focusIsInsideMobileOverlay() {
|
|
1511
|
+
var t, i, o, a;
|
|
1512
|
+
const e = (t = this.shadowRoot) == null ? void 0 : t.querySelector(".mobile-overlay-menu");
|
|
1513
|
+
if (!e) return !1;
|
|
1514
|
+
if (this.openMobileCategory) {
|
|
1515
|
+
const s = (i = this.shadowRoot) == null ? void 0 : i.querySelector("cm-mega-menu-mobile");
|
|
1516
|
+
return ((o = s == null ? void 0 : s.shadowRoot) == null ? void 0 : o.activeElement) != null;
|
|
1517
|
+
}
|
|
1518
|
+
return e.contains(((a = this.shadowRoot) == null ? void 0 : a.activeElement) ?? null);
|
|
1519
|
+
}
|
|
1520
|
+
openMobileSubmenu(e) {
|
|
1521
|
+
this.activeMobileCategoryId = e;
|
|
1522
|
+
}
|
|
1523
|
+
async closeMobileSubmenu() {
|
|
1524
|
+
var o;
|
|
1525
|
+
const e = this.activeMobileCategoryId;
|
|
1526
|
+
if (this.activeMobileCategoryId = "", await this.updateComplete, !this.mobileMenuOpen || this.activeMobileCategoryId !== "") return;
|
|
1527
|
+
const t = (o = this.shadowRoot) == null ? void 0 : o.querySelectorAll(".mobile-category"), i = Array.from(t ?? []).find(
|
|
1528
|
+
(a) => a.dataset.categoryId === e
|
|
1529
|
+
);
|
|
1530
|
+
i == null || i.focus();
|
|
1531
|
+
}
|
|
1532
|
+
buildMobileCategoryClass(e) {
|
|
1533
|
+
const t = ["mobile-category"];
|
|
1534
|
+
return e.id === this.selectedCategory && t.push("selected"), t.join(" ");
|
|
1535
|
+
}
|
|
1536
|
+
// 2026-09-17: `category.label` may carry an unresolved `{{Bunk:Proper:Default}}`-style
|
|
1537
|
+
// terminology token — rendered verbatim, same rule as the desktop list above.
|
|
1538
|
+
getMobileCategoryHtml(e) {
|
|
1539
|
+
const t = this.buildMobileCategoryClass(e), i = S(this.tree, e.id), o = k(e.label);
|
|
1540
|
+
return i ? n`
|
|
1541
|
+
<button
|
|
1542
|
+
class="${t}"
|
|
1543
|
+
data-category-id=${e.id}
|
|
1544
|
+
@click=${() => this.openMobileSubmenu(e.id)}
|
|
1545
|
+
>
|
|
1546
|
+
<div class="category-icon">${o}</div>
|
|
1547
|
+
<div class="category-name">${e.label}</div>
|
|
1548
|
+
<span class="chevron-right">${$}</span>
|
|
1549
|
+
</button>
|
|
1550
|
+
` : n`
|
|
1551
|
+
<a
|
|
1552
|
+
class="${t}"
|
|
1553
|
+
data-category-id=${e.id}
|
|
1554
|
+
href="${v(e.href)}"
|
|
1555
|
+
>
|
|
1556
|
+
<div class="category-icon">${o}</div>
|
|
1557
|
+
<div class="category-name">${e.label}</div>
|
|
1558
|
+
</a>
|
|
1559
|
+
`;
|
|
1560
|
+
}
|
|
1561
|
+
renderMobileMainMenu() {
|
|
1562
|
+
return n`
|
|
1563
|
+
<nav class="mobile-categories-container" role="navigation" aria-label="Main categories">
|
|
1564
|
+
<ul class="mobile-categories-list" role="list">
|
|
1565
|
+
${this.tree.map(
|
|
1566
|
+
(e) => n` <li role="listitem">${this.getMobileCategoryHtml(e)}</li> `
|
|
1567
|
+
)}
|
|
1568
|
+
</ul>
|
|
1569
|
+
</nav>
|
|
1570
|
+
`;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* The mobile overlay's body — either the main category list, or the
|
|
1574
|
+
* drill-down for whichever category is active. `cm-mega-menu-mobile-back`
|
|
1575
|
+
* is the drill-down asking to return to the list; it does not close the
|
|
1576
|
+
* overlay (that's `.menu-toggle` / the backdrop), so it only clears
|
|
1577
|
+
* `activeMobileCategoryId`.
|
|
1578
|
+
*/
|
|
1579
|
+
renderMobileOverlayBody() {
|
|
1580
|
+
const e = this.openMobileCategory;
|
|
1581
|
+
return e ? n`
|
|
1582
|
+
<cm-mega-menu-mobile
|
|
1583
|
+
.tree=${this.tree}
|
|
1584
|
+
category-id=${e.id}
|
|
1585
|
+
@cm-mega-menu-mobile-back=${() => this.closeMobileSubmenu()}
|
|
1586
|
+
></cm-mega-menu-mobile>
|
|
1587
|
+
` : this.renderMobileMainMenu();
|
|
1084
1588
|
}
|
|
1085
1589
|
// 2026-09-02: `category.label` may still carry an unresolved `{{Bunk:Proper:Default}}`-style
|
|
1086
1590
|
// terminology token — per-client substitution is a host concern, deferred by the plan (see
|
|
@@ -1088,50 +1592,50 @@ let l = class extends m {
|
|
|
1088
1592
|
// future truncation, tooltip reformat, or `.trim()`/regex touch-up to `category.label` must
|
|
1089
1593
|
// not assume it is plain text.
|
|
1090
1594
|
getCategoryHtml(e) {
|
|
1091
|
-
const
|
|
1092
|
-
return
|
|
1595
|
+
const t = this.buildCategoryClass(e), i = S(this.tree, e.id), o = k(e.label);
|
|
1596
|
+
return i ? n`
|
|
1093
1597
|
<button
|
|
1094
|
-
class="${
|
|
1598
|
+
class="${t}"
|
|
1095
1599
|
@mouseenter=${() => this.handleMouseEnter(e.id)}
|
|
1096
1600
|
@mouseleave=${() => this.handleMouseLeave()}
|
|
1097
1601
|
@click=${() => this.handleMenuItemHover(e.id)}
|
|
1098
1602
|
>
|
|
1099
|
-
<div class="category-icon">${
|
|
1603
|
+
<div class="category-icon">${o}</div>
|
|
1100
1604
|
<div class="category-name">${e.label}</div>
|
|
1101
|
-
<div class="chevron-right">${N}</div>
|
|
1102
1605
|
</button>
|
|
1103
|
-
` :
|
|
1606
|
+
` : n`
|
|
1104
1607
|
<a
|
|
1105
|
-
class="${
|
|
1608
|
+
class="${t}"
|
|
1106
1609
|
@mouseenter=${() => this.handleMouseEnter(e.id)}
|
|
1107
1610
|
@mouseleave=${() => this.handleMouseLeave()}
|
|
1108
1611
|
@click=${() => this.setSelectedCategory(e.id)}
|
|
1109
|
-
href="${
|
|
1612
|
+
href="${v(e.href)}"
|
|
1110
1613
|
>
|
|
1111
|
-
<div class="category-icon">${
|
|
1614
|
+
<div class="category-icon">${o}</div>
|
|
1112
1615
|
<div class="category-name">${e.label}</div>
|
|
1113
1616
|
</a>
|
|
1114
1617
|
`;
|
|
1115
1618
|
}
|
|
1116
1619
|
renderMainMenu() {
|
|
1117
|
-
return
|
|
1620
|
+
return n`
|
|
1118
1621
|
<nav class="categories-container" role="navigation" aria-label="Main categories">
|
|
1119
1622
|
<ul class="categories-list" role="list">
|
|
1120
1623
|
${this.tree.map(
|
|
1121
|
-
(e) =>
|
|
1624
|
+
(e) => n` <li role="listitem">${this.getCategoryHtml(e)}</li> `
|
|
1122
1625
|
)}
|
|
1123
1626
|
</ul>
|
|
1124
1627
|
</nav>
|
|
1125
1628
|
`;
|
|
1126
1629
|
}
|
|
1127
1630
|
render() {
|
|
1128
|
-
const e = this.openCategory;
|
|
1129
|
-
return
|
|
1631
|
+
const e = this.openCategory, t = this.isNarrowViewport;
|
|
1632
|
+
return n`
|
|
1130
1633
|
<nav
|
|
1131
1634
|
class="nav-container"
|
|
1132
1635
|
role="navigation"
|
|
1133
1636
|
aria-label="Main navigation"
|
|
1134
|
-
|
|
1637
|
+
aria-hidden=${t ? "true" : "false"}
|
|
1638
|
+
@mouseleave=${() => this.dismissFlyout(!1)}
|
|
1135
1639
|
>
|
|
1136
1640
|
<aside
|
|
1137
1641
|
class=${`side-nav ${this.collapsed ? "collapsed-sidebar" : ""}`}
|
|
@@ -1159,40 +1663,90 @@ let l = class extends m {
|
|
|
1159
1663
|
from light DOM would have forced hoveredCategory into public API
|
|
1160
1664
|
and crossed the component's own encapsulation. cm-mega-menu gets
|
|
1161
1665
|
the whole tree plus the open category's id (never a resolved node —
|
|
1162
|
-
see MegaMenu.ts's doc comment). Its close event
|
|
1163
|
-
|
|
1164
|
-
|
|
1666
|
+
see MegaMenu.ts's doc comment). Its close event routes through
|
|
1667
|
+
dismissFlyout(), the one dismissal entry point, carrying whether
|
|
1668
|
+
focus should be restored. That resets hoveredCategory back to ''
|
|
1669
|
+
— it is the derived openCategory getter above, not hoveredCategory
|
|
1670
|
+
itself, that becomes undefined.
|
|
1165
1671
|
-->
|
|
1166
|
-
${e ?
|
|
1672
|
+
${e ? n`
|
|
1167
1673
|
<cm-mega-menu
|
|
1168
1674
|
.tree=${this.tree}
|
|
1169
1675
|
category-id=${e.id}
|
|
1170
|
-
@cm-mega-menu-close=${() =>
|
|
1676
|
+
@cm-mega-menu-close=${(i) => {
|
|
1677
|
+
var o;
|
|
1678
|
+
return this.dismissFlyout(((o = i.detail) == null ? void 0 : o.restoreFocus) ?? !1);
|
|
1679
|
+
}}
|
|
1171
1680
|
></cm-mega-menu>
|
|
1172
1681
|
` : null}
|
|
1173
1682
|
</nav>
|
|
1683
|
+
|
|
1684
|
+
<!--
|
|
1685
|
+
Floor 5D's mobile variant — a second, always-rendered DOM tree, per the
|
|
1686
|
+
plan's ruling: both variants render and SideNavStyles's
|
|
1687
|
+
@media (max-width: 530px) picks which is displayed. aria-hidden above
|
|
1688
|
+
mirrors that same breakpoint so the inactive tree is hidden from
|
|
1689
|
+
assistive technology too, not just visually — see this file's header.
|
|
1690
|
+
-->
|
|
1691
|
+
<div class="mobile-nav" aria-hidden=${t ? "false" : "true"}>
|
|
1692
|
+
<button
|
|
1693
|
+
class="menu-toggle"
|
|
1694
|
+
@click=${() => this.toggleMobileMenu()}
|
|
1695
|
+
aria-label="Toggle menu"
|
|
1696
|
+
aria-expanded=${this.mobileMenuOpen ? "true" : "false"}
|
|
1697
|
+
>
|
|
1698
|
+
<span class="toggle-mobile-btn">${L}</span>
|
|
1699
|
+
</button>
|
|
1700
|
+
|
|
1701
|
+
${this.mobileMenuOpen ? n`
|
|
1702
|
+
<div
|
|
1703
|
+
class="mobile-overlay-backdrop"
|
|
1704
|
+
@click=${() => this.dismissMobileMenu(!1)}
|
|
1705
|
+
></div>
|
|
1706
|
+
<!--
|
|
1707
|
+
Focus is deliberately NOT moved into the overlay here when it
|
|
1708
|
+
first opens. .menu-toggle stays in the DOM and keeps focus,
|
|
1709
|
+
and this overlay renders after the toggle in DOM order, so Tab
|
|
1710
|
+
reaches the list naturally — nothing is lost, so moving focus
|
|
1711
|
+
would be unsolicited. Leaving this note so the next person
|
|
1712
|
+
does not "fix" it.
|
|
1713
|
+
-->
|
|
1714
|
+
<div class="mobile-overlay-menu" @keydown=${this.handleMobileOverlayKeyDown}>
|
|
1715
|
+
${this.renderMobileOverlayBody()}
|
|
1716
|
+
</div>
|
|
1717
|
+
` : null}
|
|
1718
|
+
</div>
|
|
1174
1719
|
`;
|
|
1175
1720
|
}
|
|
1176
1721
|
};
|
|
1177
|
-
l.styles = [
|
|
1178
|
-
|
|
1179
|
-
|
|
1722
|
+
l.styles = [we];
|
|
1723
|
+
c([
|
|
1724
|
+
m()
|
|
1180
1725
|
], l.prototype, "hoveredCategory", 2);
|
|
1181
|
-
|
|
1182
|
-
|
|
1726
|
+
c([
|
|
1727
|
+
m()
|
|
1728
|
+
], l.prototype, "mobileMenuOpen", 2);
|
|
1729
|
+
c([
|
|
1730
|
+
m()
|
|
1731
|
+
], l.prototype, "activeMobileCategoryId", 2);
|
|
1732
|
+
c([
|
|
1733
|
+
m()
|
|
1734
|
+
], l.prototype, "isNarrowViewport", 2);
|
|
1735
|
+
c([
|
|
1736
|
+
h({ type: Boolean, reflect: !0 })
|
|
1183
1737
|
], l.prototype, "collapsed", 2);
|
|
1184
|
-
|
|
1185
|
-
|
|
1738
|
+
c([
|
|
1739
|
+
h({ type: String, attribute: "current-path" })
|
|
1186
1740
|
], l.prototype, "currentPath", 2);
|
|
1187
|
-
|
|
1188
|
-
|
|
1741
|
+
c([
|
|
1742
|
+
h({ attribute: !1 })
|
|
1189
1743
|
], l.prototype, "tree", 2);
|
|
1190
|
-
l =
|
|
1191
|
-
|
|
1744
|
+
l = c([
|
|
1745
|
+
y("cm-side-nav")
|
|
1192
1746
|
], l);
|
|
1193
1747
|
export {
|
|
1194
|
-
|
|
1748
|
+
g as MegaMenu,
|
|
1195
1749
|
l as SideNav,
|
|
1196
|
-
|
|
1197
|
-
|
|
1750
|
+
Ve as hasIconFor,
|
|
1751
|
+
Le as hasMegaMenuIconFor
|
|
1198
1752
|
};
|