@campminder/components 0.1.0 → 0.2.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 CHANGED
@@ -196,3 +196,36 @@ fails loudly rather than silently rendering an empty banner.
196
196
 
197
197
  > Components render themselves; the shell owns layout. No component may touch
198
198
  > `document.body`, `document.head`, or query for a sibling.
199
+
200
+ ## Dismissing the side-nav flyout
201
+
202
+ `<cm-side-nav>` exposes exactly one dismissal entry point:
203
+
204
+ ```ts
205
+ dismissFlyout(restoreFocus: boolean): void
206
+ ```
207
+
208
+ It closes the flyout when one is open and is a no-op when none is. Every trigger
209
+ routes through it — the flyout's own Escape and shift-Tab paths, the navigation's
210
+ mouseleave, the `cm-mega-menu-close` event (which now carries
211
+ `detail.restoreFocus`), and the host shell's page-level Escape and outside pointer
212
+ press — so the focus rule below is applied in one place and no trigger can bypass
213
+ it.
214
+
215
+ **The focus rule.** Focus moves only when `restoreFocus` is true _and_ focus is
216
+ currently inside the flyout; then it goes to the category control that opened the
217
+ flyout, falling back to the navigation's collapse control when that category
218
+ control no longer exists. Focus is never left on the document body, and is never
219
+ pulled into the navigation from somewhere else on the page — a person typing in a
220
+ form field, or pressing a pointer outside the flyout, keeps the focus they have.
221
+
222
+ Two consequences worth keeping in mind when changing this code:
223
+
224
+ - The focus target is read **before** the open-category state is cleared. The
225
+ target is found via the `category-hovered` class, which is derived from that
226
+ state; clearing first leaves nothing to find and silently reintroduces the
227
+ dropped-focus bug.
228
+ - Page-level Escape and outside-pointer listening belongs to the **shell**, which
229
+ calls `dismissFlyout` on each slotted navigation — `true` for Escape, `false`
230
+ for an outside pointer press. This component registers nothing on `document` or
231
+ `window`, per the rule above, and `mega-menu-isolation.test.ts` observes that.
@@ -25,6 +25,15 @@ export declare class MegaMenu extends LitElement {
25
25
  disconnectedCallback(): void;
26
26
  private handleKeyDown;
27
27
  private get categoryData();
28
+ /**
29
+ * The close event keeps its name, `bubbles` and `composed` flags; `detail` is
30
+ * new and carries the caller's focus intent onward to `<cm-side-nav>`'s
31
+ * `dismissFlyout()`, which is the one place the focus rule is applied. Both
32
+ * keyboard paths ask for restoration — they are the paths where focus is inside
33
+ * the flyout and would otherwise be dropped on the document body. The close
34
+ * button asks too; it is harmless when focus is not inside, because
35
+ * `dismissFlyout` only moves focus that actually sits in the flyout.
36
+ */
28
37
  private handleCloseMegaMenu;
29
38
  /**
30
39
  * Packs menu items into as many 248px columns as the container's own
@@ -67,11 +67,36 @@ export declare class SideNav extends LitElement {
67
67
  private clearHoverTimeout;
68
68
  private handleMouseEnter;
69
69
  private handleMouseLeave;
70
+ /**
71
+ * The single dismissal entry point for the flyout — every trigger routes through
72
+ * here (the flyout's own Escape and shift-Tab paths, the nav's mouseleave, and
73
+ * the shell's page-level Escape / outside pointer press) so the focus rule is
74
+ * applied in exactly one place and no trigger can bypass it.
75
+ *
76
+ * `restoreFocus` is the caller's *intent*; focus only actually moves when it is
77
+ * also true that focus is currently inside the flyout. A person typing in a form
78
+ * field while the flyout is dismissed keeps their cursor where it is, and a
79
+ * pointer press outside keeps the focus the press itself produces.
80
+ *
81
+ * The focus target is read BEFORE `hoveredCategory` is cleared, and that order is
82
+ * load-bearing: the target is found via the `category-hovered` class, which is
83
+ * derived from `hoveredCategory` in `buildCategoryClass`. Clearing first would
84
+ * leave nothing to find and silently drop focus onto the document body — the very
85
+ * defect this method exists to fix.
86
+ */
87
+ dismissFlyout(restoreFocus: boolean): void;
88
+ private focusIsInsideFlyout;
89
+ /**
90
+ * The category control the flyout was opened from, or the collapse control when
91
+ * that category control no longer exists — it always does, so focus can never
92
+ * land on the document body.
93
+ */
94
+ private focusRestoreTarget;
70
95
  private get hamburgerIcon();
71
96
  /**
72
97
  * The category the mega-menu flyout is open for, or `undefined` when none
73
98
  * is. Guards on `renderableSubCategories(category).length > 0` (the same
74
- * predicate `hasSubmenus` uses for the chevron above) rather than on
99
+ * predicate `hasSubmenus` uses to render a category as a button) rather than on
75
100
  * `hoveredCategory` alone — `hoveredCategory` can also be the literal
76
101
  * string `'sidebar-toggle'` (see `handleMouseEnter` call sites), and a
77
102
  * category with no renderable sub-categories must not open onto nothing.
package/dist/side-nav.js CHANGED
@@ -1,11 +1,11 @@
1
- import { A as I, b as t, i as f, n as c, a as m, t as x } from "./property-B5JHHBCF.js";
2
- import { r as Z } from "./state-Ns9O6R8g.js";
1
+ import { A as I, b as o, i as f, n as c, a as m, t as b } from "./property-B5JHHBCF.js";
2
+ import { r as S } from "./state-Ns9O6R8g.js";
3
3
  /**
4
4
  * @license
5
5
  * Copyright 2018 Google LLC
6
6
  * SPDX-License-Identifier: BSD-3-Clause
7
7
  */
8
- const b = (e) => e ?? I, S = t` <svg
8
+ const x = (e) => e ?? I, Z = o` <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>`, E = t`<svg
19
+ </svg>`, T = o`<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> `, T = t`<svg
30
+ </svg> `, E = o`<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> `, $ = t`<svg
41
+ </svg> `, $ = o`<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>`, B = t`<svg
52
+ </svg>`, B = o`<svg
53
53
  width="20"
54
54
  height="20"
55
55
  viewBox="0 0 20 20"
@@ -60,7 +60,8 @@ 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>`, N = t`<svg
63
+ </svg>`;
64
+ o`<svg
64
65
  width="8"
65
66
  height="12"
66
67
  viewBox="0 0 8 12"
@@ -71,7 +72,8 @@ const b = (e) => e ?? I, S = t` <svg
71
72
  d="M1.70687 0L0.296875 1.41L4.87687 6L0.296875 10.59L1.70687 12L7.70687 6L1.70687 0Z"
72
73
  fill="white"
73
74
  />
74
- </svg>`, k = (e = "#505050") => t`<svg
75
+ </svg>`;
76
+ const k = (e = "#505050") => o`<svg
75
77
  width="14"
76
78
  height="14"
77
79
  viewBox="0 0 14 14"
@@ -82,7 +84,7 @@ const b = (e) => e ?? I, S = t` <svg
82
84
  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
85
  fill="${e}"
84
86
  />
85
- </svg>`, A = t`<svg
87
+ </svg>`, A = o`<svg
86
88
  width="20"
87
89
  height="20"
88
90
  viewBox="0 0 20 20"
@@ -93,7 +95,7 @@ const b = (e) => e ?? I, S = t` <svg
93
95
  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
96
  fill="white"
95
97
  />
96
- </svg> `, p = t`<svg
98
+ </svg> `, v = o`<svg
97
99
  width="20"
98
100
  height="20"
99
101
  viewBox="0 0 20 20"
@@ -104,7 +106,7 @@ const b = (e) => e ?? I, S = t` <svg
104
106
  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
107
  fill="white"
106
108
  />
107
- </svg> `, O = t`<svg
109
+ </svg> `, N = o`<svg
108
110
  width="20"
109
111
  height="20"
110
112
  viewBox="0 0 20 20"
@@ -115,7 +117,7 @@ const b = (e) => e ?? I, S = t` <svg
115
117
  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
118
  fill="white"
117
119
  />
118
- </svg>`, H = t`<svg
120
+ </svg>`, H = o`<svg
119
121
  width="20"
120
122
  height="20"
121
123
  viewBox="0 0 20 20"
@@ -126,7 +128,7 @@ const b = (e) => e ?? I, S = t` <svg
126
128
  d="M8.33332 17.0832V12.0832H11.6667V17.0832H15.8333V10.4165H18.3333L9.99999 2.9165L1.66666 10.4165H4.16666V17.0832H8.33332Z"
127
129
  fill="white"
128
130
  />
129
- </svg>`, R = t`<svg
131
+ </svg>`, O = o`<svg
130
132
  width="20"
131
133
  height="20"
132
134
  viewBox="0 0 20 20"
@@ -137,7 +139,7 @@ const b = (e) => e ?? I, S = t` <svg
137
139
  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
140
  fill="white"
139
141
  />
140
- </svg> `, z = t` <svg
142
+ </svg> `, R = o` <svg
141
143
  width="24"
142
144
  height="24"
143
145
  viewBox="0 0 24 24"
@@ -148,7 +150,7 @@ const b = (e) => e ?? I, S = t` <svg
148
150
  d="M3 18H16V16H3V18ZM3 13H13V11H3V13ZM3 6V8H16V6H3ZM21 15.59L17.42 12L21 8.41L19.59 7L14.59 12L19.59 17L21 15.59Z"
149
151
  fill="white"
150
152
  />
151
- </svg>`, _ = t`<svg
153
+ </svg>`, z = o`<svg
152
154
  width="24"
153
155
  height="24"
154
156
  viewBox="0 0 24 24"
@@ -156,7 +158,7 @@ const b = (e) => e ?? I, S = t` <svg
156
158
  xmlns="http://www.w3.org/2000/svg"
157
159
  >
158
160
  <path d="M3 18H21V16H3V18ZM3 13H21V11H3V13ZM3 6V8H21V6H3Z" fill="white" />
159
- </svg>`, G = t`<svg
161
+ </svg>`, _ = o`<svg
160
162
  width="20"
161
163
  height="20"
162
164
  viewBox="0 0 20 20"
@@ -167,7 +169,7 @@ const b = (e) => e ?? I, S = t` <svg
167
169
  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
170
  fill="white"
169
171
  />
170
- </svg>`, P = t`<svg
172
+ </svg>`, G = o`<svg
171
173
  width="20"
172
174
  height="20"
173
175
  viewBox="0 0 20 20"
@@ -178,7 +180,7 @@ const b = (e) => e ?? I, S = t` <svg
178
180
  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
181
  fill="white"
180
182
  />
181
- </svg> `, D = t`<svg
183
+ </svg> `, P = o`<svg
182
184
  width="20"
183
185
  height="20"
184
186
  viewBox="0 0 20 20"
@@ -189,7 +191,7 @@ const b = (e) => e ?? I, S = t` <svg
189
191
  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
192
  fill="white"
191
193
  />
192
- </svg> `, U = t`<svg
194
+ </svg> `, D = o`<svg
193
195
  width="20"
194
196
  height="20"
195
197
  viewBox="0 0 20 20"
@@ -200,7 +202,7 @@ const b = (e) => e ?? I, S = t` <svg
200
202
  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
203
  fill="white"
202
204
  />
203
- </svg> `, j = t`<svg
205
+ </svg> `, F = o`<svg
204
206
  width="24"
205
207
  height="24"
206
208
  viewBox="0 0 24 24"
@@ -211,7 +213,7 @@ const b = (e) => e ?? I, S = t` <svg
211
213
  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
214
  fill="#505050"
213
215
  />
214
- </svg>`, F = t`<svg
216
+ </svg>`, U = o`<svg
215
217
  width="24"
216
218
  height="24"
217
219
  viewBox="0 0 24 24"
@@ -222,7 +224,7 @@ const b = (e) => e ?? I, S = t` <svg
222
224
  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
225
  fill="#505050"
224
226
  />
225
- </svg>`, K = t`<svg
227
+ </svg>`, j = o`<svg
226
228
  width="24"
227
229
  height="24"
228
230
  viewBox="0 0 24 24"
@@ -233,7 +235,7 @@ const b = (e) => e ?? I, S = t` <svg
233
235
  d="M5 13.18V17.18L12 21L19 17.18V13.18L12 17L5 13.18ZM12 3L1 9L12 15L21 10.09V17H23V9L12 3Z"
234
236
  fill="#505050"
235
237
  />
236
- </svg>`, Y = t`<svg
238
+ </svg>`, K = o`<svg
237
239
  width="24"
238
240
  height="24"
239
241
  viewBox="0 0 24 24"
@@ -244,7 +246,7 @@ const b = (e) => e ?? I, S = t` <svg
244
246
  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
247
  fill="#505050"
246
248
  />
247
- </svg>`, W = t`<svg
249
+ </svg>`, Y = o`<svg
248
250
  width="20"
249
251
  height="20"
250
252
  viewBox="0 0 20 20"
@@ -255,7 +257,7 @@ const b = (e) => e ?? I, S = t` <svg
255
257
  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
258
  fill="#505050"
257
259
  />
258
- </svg>`, q = t`<svg
260
+ </svg>`, q = o`<svg
259
261
  width="24"
260
262
  height="24"
261
263
  viewBox="0 0 24 24"
@@ -266,7 +268,7 @@ const b = (e) => e ?? I, S = t` <svg
266
268
  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
269
  fill="#505050"
268
270
  />
269
- </svg> `, u = t`<svg
271
+ </svg> `, p = o`<svg
270
272
  width="24"
271
273
  height="24"
272
274
  viewBox="0 0 24 24"
@@ -277,7 +279,7 @@ const b = (e) => e ?? I, S = t` <svg
277
279
  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
280
  fill="#505050"
279
281
  />
280
- </svg>`, X = t`<svg
282
+ </svg>`, W = o`<svg
281
283
  width="24"
282
284
  height="24"
283
285
  viewBox="0 0 24 24"
@@ -288,7 +290,7 @@ const b = (e) => e ?? I, S = t` <svg
288
290
  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
291
  fill="#505050"
290
292
  />
291
- </svg> `, J = t`<svg
293
+ </svg> `, X = o`<svg
292
294
  width="24"
293
295
  height="24"
294
296
  viewBox="0 0 24 24"
@@ -299,7 +301,7 @@ const b = (e) => e ?? I, S = t` <svg
299
301
  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
302
  fill="#505050"
301
303
  />
302
- </svg> `, w = t`<svg
304
+ </svg> `, w = o`<svg
303
305
  width="16"
304
306
  height="16"
305
307
  viewBox="0 0 16 16"
@@ -310,7 +312,7 @@ const b = (e) => e ?? I, S = t` <svg
310
312
  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
313
  fill="#282828"
312
314
  />
313
- </svg> `, Q = t`<svg
315
+ </svg> `, J = o`<svg
314
316
  width="24"
315
317
  height="24"
316
318
  viewBox="0 0 24 24"
@@ -321,7 +323,7 @@ const b = (e) => e ?? I, S = t` <svg
321
323
  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
324
  fill="#505050"
323
325
  />
324
- </svg> `, e1 = t`<svg
326
+ </svg> `, Q = o`<svg
325
327
  width="24"
326
328
  height="24"
327
329
  viewBox="0 0 24 24"
@@ -332,7 +334,7 @@ const b = (e) => e ?? I, S = t` <svg
332
334
  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
335
  fill="#505050"
334
336
  />
335
- </svg> `, t1 = t`<svg
337
+ </svg> `, e1 = o`<svg
336
338
  width="24"
337
339
  height="24"
338
340
  viewBox="0 0 24 24"
@@ -343,7 +345,7 @@ const b = (e) => e ?? I, S = t` <svg
343
345
  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
346
  fill="#505050"
345
347
  />
346
- </svg> `, o1 = t`<svg
348
+ </svg> `, t1 = o`<svg
347
349
  width="24"
348
350
  height="24"
349
351
  viewBox="0 0 24 24"
@@ -354,7 +356,7 @@ const b = (e) => e ?? I, S = t` <svg
354
356
  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
357
  fill="#505050"
356
358
  />
357
- </svg>`, M = 248, V = 16, i1 = f`
359
+ </svg>`, M = 248, y = 16, o1 = f`
358
360
  /* ===== HOST-LEVEL CUSTOM PROPERTIES ===== */
359
361
  :host {
360
362
  /* '--cm-side-nav-width' is set on 'campminder-app-shell''s ':host'
@@ -467,7 +469,7 @@ const b = (e) => e ?? I, S = t` <svg
467
469
  /* ===== MENU ITEM ===== */
468
470
  .menu-item {
469
471
  width: ${M}px;
470
- margin-left: ${V}px;
472
+ margin-left: ${y}px;
471
473
  margin-bottom: 12px;
472
474
  font-family: 'Inter', sans-serif;
473
475
  font-size: 14px;
@@ -516,67 +518,67 @@ const b = (e) => e ?? I, S = t` <svg
516
518
  flex-wrap: nowrap;
517
519
  }
518
520
  }
519
- `, y = {
520
- AccountsSvgIcon: j,
521
- AdminSvgIcon: F,
522
- AlumniSvgIcon: K,
523
- CamperSvgIcon: Y,
521
+ `, V = {
522
+ AccountsSvgIcon: F,
523
+ AdminSvgIcon: U,
524
+ AlumniSvgIcon: j,
525
+ CamperSvgIcon: K,
524
526
  CommunicationSvgIcon: q,
525
- CampInTouchSvgIcon: W,
526
- FinancialSvgIcon: X,
527
- MedicalSvgIcon: J,
528
- ReportingSvgIcon: Q,
529
- SchedulingSvgIcon: e1,
530
- StaffSvgIcon: t1,
531
- TravelSvgIcon: o1
527
+ CampInTouchSvgIcon: Y,
528
+ FinancialSvgIcon: W,
529
+ MedicalSvgIcon: X,
530
+ ReportingSvgIcon: J,
531
+ SchedulingSvgIcon: Q,
532
+ StaffSvgIcon: e1,
533
+ TravelSvgIcon: t1
532
534
  };
533
- function n1(e) {
534
- return e ? e.id === "home" ? H : y[`${e.label}SvgIcon`] ?? u : u;
535
+ function i1(e) {
536
+ return e ? e.id === "home" ? H : V[`${e.label}SvgIcon`] ?? p : p;
535
537
  }
536
- function w1(e) {
537
- return e ? e.id === "home" ? !0 : `${e.label}SvgIcon` in y : !1;
538
+ function p1(e) {
539
+ return e ? e.id === "home" ? !0 : `${e.label}SvgIcon` in V : !1;
538
540
  }
539
541
  function d(e) {
540
542
  return e.startsWith("http") ? new URL(e).pathname + new URL(e).search : e;
541
543
  }
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;
544
+ function n1(e, t) {
545
+ const i = d(t);
546
+ for (const n of e) {
547
+ if (n.href && d(n.href) === i)
548
+ return n.id;
549
+ for (const s of n.subCategories)
550
+ if (s.href && d(s.href) === i || s.items.find((a) => d(a.href) === i)) return n.id;
549
551
  }
550
552
  }
551
- function r1(e) {
553
+ function s1(e) {
552
554
  return e.items.length > 0 || !!e.href;
553
555
  }
554
556
  function C(e) {
555
- return e.subCategories.filter(r1);
557
+ return e.subCategories.filter(s1);
556
558
  }
557
- function a1(e, o) {
558
- const n = e.find((i) => i.id === o);
559
- return !!n && C(n).length > 0;
559
+ function r1(e, t) {
560
+ const i = e.find((n) => n.id === t);
561
+ return !!i && C(i).length > 0;
560
562
  }
561
- function l1(e, o) {
562
- return o === "/" ? "home" : s1(e, o) ?? "";
563
+ function a1(e, t) {
564
+ return t === "/" ? "home" : n1(e, t) ?? "";
563
565
  }
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;
566
+ var l1 = Object.defineProperty, h1 = Object.getOwnPropertyDescriptor, u = (e, t, i, n) => {
567
+ for (var s = n > 1 ? void 0 : n ? h1(t, i) : t, r = e.length - 1, a; r >= 0; r--)
568
+ (a = e[r]) && (s = (n ? a(t, i, s) : a(s)) || s);
569
+ return n && s && l1(t, i, s), s;
568
570
  };
569
571
  let h = class extends m {
570
572
  constructor() {
571
573
  super(...arguments), this.tree = [], this.categoryId = "", this.handleKeyDown = (e) => {
572
- var o, n;
574
+ var t, i;
573
575
  if (e.key === "Escape")
574
- this.handleCloseMegaMenu();
576
+ this.handleCloseMegaMenu(!0);
575
577
  else if (e.key === "Tab") {
576
- const i = (o = this.shadowRoot) == null ? void 0 : o.querySelectorAll("a.menu-title, .menu-url");
577
- if (!i || i.length === 0) return;
578
- const s = (n = this.shadowRoot) == null ? void 0 : n.activeElement;
579
- e.shiftKey && s === i[0] ? (e.preventDefault(), this.handleCloseMegaMenu()) : !e.shiftKey && s === i[i.length - 1] && (e.preventDefault(), i[0].focus());
578
+ const n = (t = this.shadowRoot) == null ? void 0 : t.querySelectorAll("a.menu-title, .menu-url");
579
+ if (!n || n.length === 0) return;
580
+ const s = (i = this.shadowRoot) == null ? void 0 : i.activeElement;
581
+ e.shiftKey && s === n[0] ? (e.preventDefault(), this.handleCloseMegaMenu(!0)) : !e.shiftKey && s === n[n.length - 1] && (e.preventDefault(), n[0].focus());
580
582
  }
581
583
  };
582
584
  }
@@ -589,9 +591,19 @@ let h = class extends m {
589
591
  get categoryData() {
590
592
  return this.tree.find((e) => e.id === this.categoryId);
591
593
  }
592
- handleCloseMegaMenu() {
594
+ /**
595
+ * The close event keeps its name, `bubbles` and `composed` flags; `detail` is
596
+ * new and carries the caller's focus intent onward to `<cm-side-nav>`'s
597
+ * `dismissFlyout()`, which is the one place the focus rule is applied. Both
598
+ * keyboard paths ask for restoration — they are the paths where focus is inside
599
+ * the flyout and would otherwise be dropped on the document body. The close
600
+ * button asks too; it is harmless when focus is not inside, because
601
+ * `dismissFlyout` only moves focus that actually sits in the flyout.
602
+ */
603
+ handleCloseMegaMenu(e = !0) {
593
604
  this.dispatchEvent(
594
605
  new CustomEvent("cm-mega-menu-close", {
606
+ detail: { restoreFocus: e },
595
607
  bubbles: !0,
596
608
  composed: !0,
597
609
  cancelable: !0
@@ -614,12 +626,12 @@ let h = class extends m {
614
626
  var s;
615
627
  const e = (s = this.shadowRoot) == null ? void 0 : s.querySelector(".menu-items");
616
628
  if (!e || window.innerWidth <= 1150) return;
617
- const o = e.getBoundingClientRect().height - 20;
618
- let n = 1, i = 0;
629
+ const t = e.getBoundingClientRect().height - 20;
630
+ let i = 1, n = 0;
619
631
  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`;
632
+ n + r.getBoundingClientRect().height + 12 > // 12 for bottom margin on item
633
+ t && (i += 1, n = 0), n += r.getBoundingClientRect().height + 12;
634
+ e.style.width = `${i * M + (i + 1) * y}px`;
623
635
  }
624
636
  updated(e) {
625
637
  super.updated(e), this.setMenuItemsContainerWidth();
@@ -629,45 +641,47 @@ let h = class extends m {
629
641
  // verbatim below on purpose — see AGENTS.md's "Never resolve a terminology
630
642
  // token."
631
643
  renderLeaf(e) {
632
- return e.popup ? t`
644
+ return e.popup ? o`
633
645
  <a
634
646
  class="menu-url"
635
647
  href="#nowhere"
636
648
  @click=${() => {
637
- const o = window.open(e.href, "", e.popupProperties);
638
- return o && (o.opener = null), !1;
649
+ const t = window.open(e.href, "", e.popupProperties);
650
+ return t && (t.opener = null), !1;
639
651
  }}
640
652
  target="_top"
641
653
  >
642
654
  ${e.label}
643
655
  <span class="new-tab-icon">${w}</span>
644
656
  </a>
645
- ` : t`
657
+ ` : o`
646
658
  <a
647
659
  class="menu-url"
648
660
  href="${e.href}"
649
661
  target=${e.newTab ? "_blank" : "_self"}
650
- rel=${b(e.newTab ? "noopener noreferrer" : void 0)}
662
+ rel=${x(e.newTab ? "noopener noreferrer" : void 0)}
651
663
  >
652
664
  ${e.label}
653
- ${e.newTab ? t`<span class="new-tab-icon">${w}</span>` : null}
665
+ ${e.newTab ? o`<span class="new-tab-icon">${w}</span>` : null}
654
666
  </a>
655
667
  `;
656
668
  }
657
669
  render() {
658
- const e = this.categoryData, o = e ? C(e) : [];
659
- return !e || o.length === 0 ? null : t`
670
+ const e = this.categoryData, t = e ? C(e) : [];
671
+ return !e || t.length === 0 ? null : o`
660
672
  <section class="mega-menu">
661
673
  <div class="header">
662
674
  <div class="header-left">
663
- <div class="header-icon">${n1(e)}</div>
675
+ <div class="header-icon">${i1(e)}</div>
664
676
  <p class="header-title title-text">${e.label}</p>
665
677
  </div>
666
- <p class="close-button" @click=${this.handleCloseMegaMenu}>${k()}</p>
678
+ <p class="close-button" @click=${() => this.handleCloseMegaMenu(!0)}>
679
+ ${k()}
680
+ </p>
667
681
  </div>
668
682
  <div class="menu-items">
669
- ${o.map(
670
- (n) => t`
683
+ ${t.map(
684
+ (i) => o`
671
685
  <div class="menu-item">
672
686
  ${// Deliberate addition, not upstream parity — core-js's
673
687
  // `sub_categories[]` never carried a `url`, so there's no parity to
@@ -678,8 +692,8 @@ let h = class extends m {
678
692
  // in `campminder.json` today, but Floor 6's visibility filter can
679
693
  // produce one: an `href`-bearing sub-category whose every leaf is
680
694
  // 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))}
695
+ i.href ? o`<a class="title-text menu-title" href="${i.href}">${i.label}</a>` : o`<p class="title-text menu-title">${i.label}</p>`}
696
+ ${i.items.map((n) => this.renderLeaf(n))}
683
697
  </div>
684
698
  `
685
699
  )}
@@ -688,17 +702,17 @@ let h = class extends m {
688
702
  `;
689
703
  }
690
704
  };
691
- h.styles = [i1];
692
- v([
705
+ h.styles = [o1];
706
+ u([
693
707
  c({ attribute: !1 })
694
708
  ], h.prototype, "tree", 2);
695
- v([
709
+ u([
696
710
  c({ type: String, attribute: "category-id" })
697
711
  ], h.prototype, "categoryId", 2);
698
- h = v([
699
- x("cm-mega-menu")
712
+ h = u([
713
+ b("cm-mega-menu")
700
714
  ], h);
701
- const g1 = f`
715
+ const c1 = f`
702
716
  /* ===== CSS CUSTOM PROPERTIES (DESIGN TOKENS) ===== */
703
717
  :host {
704
718
  display: block;
@@ -976,6 +990,9 @@ const g1 = f`
976
990
  text-align: left;
977
991
  }
978
992
 
993
+ /* Unused on desktop: upstream gates the chevron behind deviceCSS.isMobile,
994
+ and the mobile menu is deferred to AB#26231 (Floor 5D). Kept so that
995
+ work does not have to re-derive this rule. */
979
996
  .chevron-right {
980
997
  margin-left: auto;
981
998
  display: flex;
@@ -992,30 +1009,30 @@ const g1 = f`
992
1009
  }
993
1010
  }
994
1011
  `, L = {
995
- AccountsSvgIcon: S,
996
- AdminSvgIcon: E,
997
- AlumniSvgIcon: T,
1012
+ AccountsSvgIcon: Z,
1013
+ AdminSvgIcon: T,
1014
+ AlumniSvgIcon: E,
998
1015
  CamperSvgIcon: $,
999
1016
  CommunicationSvgIcon: A,
1000
1017
  CampInTouchSvgIcon: B,
1001
- FinancialSvgIcon: O,
1018
+ FinancialSvgIcon: N,
1002
1019
  HomeSvgIcon: H,
1003
- MedicalSvgIcon: R,
1004
- ReportingSvgIcon: G,
1005
- SchedulingSvgIcon: P,
1006
- StaffSvgIcon: D,
1007
- TravelSvgIcon: U
1020
+ MedicalSvgIcon: O,
1021
+ ReportingSvgIcon: _,
1022
+ SchedulingSvgIcon: G,
1023
+ StaffSvgIcon: P,
1024
+ TravelSvgIcon: D
1008
1025
  };
1009
- function d1(e) {
1010
- return e ? L[`${e}SvgIcon`] ?? p : p;
1026
+ function g1(e) {
1027
+ return e ? L[`${e}SvgIcon`] ?? v : v;
1011
1028
  }
1012
- function f1(e) {
1029
+ function w1(e) {
1013
1030
  return !!e && `${e}SvgIcon` in L;
1014
1031
  }
1015
- var C1 = Object.defineProperty, v1 = Object.getOwnPropertyDescriptor, g = (e, o, n, i) => {
1016
- for (var s = i > 1 ? void 0 : i ? v1(o, n) : o, r = e.length - 1, a; r >= 0; r--)
1017
- (a = e[r]) && (s = (i ? a(o, n, s) : a(s)) || s);
1018
- return i && s && C1(o, n, s), s;
1032
+ var d1 = Object.defineProperty, C1 = Object.getOwnPropertyDescriptor, g = (e, t, i, n) => {
1033
+ for (var s = n > 1 ? void 0 : n ? C1(t, i) : t, r = e.length - 1, a; r >= 0; r--)
1034
+ (a = e[r]) && (s = (n ? a(t, i, s) : a(s)) || s);
1035
+ return n && s && d1(t, i, s), s;
1019
1036
  };
1020
1037
  let l = class extends m {
1021
1038
  constructor() {
@@ -1039,7 +1056,7 @@ let l = class extends m {
1039
1056
  * getter needs to cache.
1040
1057
  */
1041
1058
  get selectedCategory() {
1042
- return l1(this.tree, this.currentPath);
1059
+ return a1(this.tree, this.currentPath);
1043
1060
  }
1044
1061
  disconnectedCallback() {
1045
1062
  super.disconnectedCallback(), this.clearHoverTimeout();
@@ -1061,26 +1078,62 @@ let l = class extends m {
1061
1078
  handleMouseLeave() {
1062
1079
  this.clearHoverTimeout();
1063
1080
  }
1081
+ /**
1082
+ * The single dismissal entry point for the flyout — every trigger routes through
1083
+ * here (the flyout's own Escape and shift-Tab paths, the nav's mouseleave, and
1084
+ * the shell's page-level Escape / outside pointer press) so the focus rule is
1085
+ * applied in exactly one place and no trigger can bypass it.
1086
+ *
1087
+ * `restoreFocus` is the caller's *intent*; focus only actually moves when it is
1088
+ * also true that focus is currently inside the flyout. A person typing in a form
1089
+ * field while the flyout is dismissed keeps their cursor where it is, and a
1090
+ * pointer press outside keeps the focus the press itself produces.
1091
+ *
1092
+ * The focus target is read BEFORE `hoveredCategory` is cleared, and that order is
1093
+ * load-bearing: the target is found via the `category-hovered` class, which is
1094
+ * derived from `hoveredCategory` in `buildCategoryClass`. Clearing first would
1095
+ * leave nothing to find and silently drop focus onto the document body — the very
1096
+ * defect this method exists to fix.
1097
+ */
1098
+ dismissFlyout(e) {
1099
+ if (!this.openCategory) return;
1100
+ const t = e && this.focusIsInsideFlyout() ? this.focusRestoreTarget() : null;
1101
+ this.clearHoverTimeout(), this.hoveredCategory = "", t == null || t.focus();
1102
+ }
1103
+ focusIsInsideFlyout() {
1104
+ var t, i;
1105
+ const e = (t = this.shadowRoot) == null ? void 0 : t.querySelector("cm-mega-menu");
1106
+ return e ? ((i = e.shadowRoot) == null ? void 0 : i.activeElement) != null : !1;
1107
+ }
1108
+ /**
1109
+ * The category control the flyout was opened from, or the collapse control when
1110
+ * that category control no longer exists — it always does, so focus can never
1111
+ * land on the document body.
1112
+ */
1113
+ focusRestoreTarget() {
1114
+ const e = this.shadowRoot;
1115
+ return e ? e.querySelector(".category-hovered") ?? e.querySelector(".sidebar-toggle") : null;
1116
+ }
1064
1117
  // Utility Methods
1065
1118
  get hamburgerIcon() {
1066
- return this.collapsed ? _ : z;
1119
+ return this.collapsed ? z : R;
1067
1120
  }
1068
1121
  /**
1069
1122
  * The category the mega-menu flyout is open for, or `undefined` when none
1070
1123
  * is. Guards on `renderableSubCategories(category).length > 0` (the same
1071
- * predicate `hasSubmenus` uses for the chevron above) rather than on
1124
+ * predicate `hasSubmenus` uses to render a category as a button) rather than on
1072
1125
  * `hoveredCategory` alone — `hoveredCategory` can also be the literal
1073
1126
  * string `'sidebar-toggle'` (see `handleMouseEnter` call sites), and a
1074
1127
  * category with no renderable sub-categories must not open onto nothing.
1075
1128
  */
1076
1129
  get openCategory() {
1077
- const e = this.tree.find((o) => o.id === this.hoveredCategory);
1130
+ const e = this.tree.find((t) => t.id === this.hoveredCategory);
1078
1131
  if (!(!e || C(e).length === 0))
1079
1132
  return e;
1080
1133
  }
1081
1134
  buildCategoryClass(e) {
1082
- const o = ["category"];
1083
- return e.id === this.selectedCategory && o.push("selected"), e.id === this.hoveredCategory && o.push("category-hovered"), o.join(" ");
1135
+ const t = ["category"];
1136
+ return e.id === this.selectedCategory && t.push("selected"), e.id === this.hoveredCategory && t.push("category-hovered"), t.join(" ");
1084
1137
  }
1085
1138
  // 2026-09-02: `category.label` may still carry an unresolved `{{Bunk:Proper:Default}}`-style
1086
1139
  // terminology token — per-client substitution is a host concern, deferred by the plan (see
@@ -1088,37 +1141,36 @@ let l = class extends m {
1088
1141
  // future truncation, tooltip reformat, or `.trim()`/regex touch-up to `category.label` must
1089
1142
  // not assume it is plain text.
1090
1143
  getCategoryHtml(e) {
1091
- const o = this.buildCategoryClass(e), n = a1(this.tree, e.id), i = d1(e.label);
1092
- return n ? t`
1144
+ const t = this.buildCategoryClass(e), i = r1(this.tree, e.id), n = g1(e.label);
1145
+ return i ? o`
1093
1146
  <button
1094
- class="${o}"
1147
+ class="${t}"
1095
1148
  @mouseenter=${() => this.handleMouseEnter(e.id)}
1096
1149
  @mouseleave=${() => this.handleMouseLeave()}
1097
1150
  @click=${() => this.handleMenuItemHover(e.id)}
1098
1151
  >
1099
- <div class="category-icon">${i}</div>
1152
+ <div class="category-icon">${n}</div>
1100
1153
  <div class="category-name">${e.label}</div>
1101
- <div class="chevron-right">${N}</div>
1102
1154
  </button>
1103
- ` : t`
1155
+ ` : o`
1104
1156
  <a
1105
- class="${o}"
1157
+ class="${t}"
1106
1158
  @mouseenter=${() => this.handleMouseEnter(e.id)}
1107
1159
  @mouseleave=${() => this.handleMouseLeave()}
1108
1160
  @click=${() => this.setSelectedCategory(e.id)}
1109
- href="${b(e.href)}"
1161
+ href="${x(e.href)}"
1110
1162
  >
1111
- <div class="category-icon">${i}</div>
1163
+ <div class="category-icon">${n}</div>
1112
1164
  <div class="category-name">${e.label}</div>
1113
1165
  </a>
1114
1166
  `;
1115
1167
  }
1116
1168
  renderMainMenu() {
1117
- return t`
1169
+ return o`
1118
1170
  <nav class="categories-container" role="navigation" aria-label="Main categories">
1119
1171
  <ul class="categories-list" role="list">
1120
1172
  ${this.tree.map(
1121
- (e) => t` <li role="listitem">${this.getCategoryHtml(e)}</li> `
1173
+ (e) => o` <li role="listitem">${this.getCategoryHtml(e)}</li> `
1122
1174
  )}
1123
1175
  </ul>
1124
1176
  </nav>
@@ -1126,12 +1178,12 @@ let l = class extends m {
1126
1178
  }
1127
1179
  render() {
1128
1180
  const e = this.openCategory;
1129
- return t`
1181
+ return o`
1130
1182
  <nav
1131
1183
  class="nav-container"
1132
1184
  role="navigation"
1133
1185
  aria-label="Main navigation"
1134
- @mouseleave=${() => this.hoveredCategory = ""}
1186
+ @mouseleave=${() => this.dismissFlyout(!1)}
1135
1187
  >
1136
1188
  <aside
1137
1189
  class=${`side-nav ${this.collapsed ? "collapsed-sidebar" : ""}`}
@@ -1159,24 +1211,29 @@ let l = class extends m {
1159
1211
  from light DOM would have forced hoveredCategory into public API
1160
1212
  and crossed the component's own encapsulation. cm-mega-menu gets
1161
1213
  the whole tree plus the open category's id (never a resolved node —
1162
- see MegaMenu.ts's doc comment). Its close event resets
1163
- hoveredCategory back to '' — it is the derived openCategory getter
1164
- above, not hoveredCategory itself, that becomes undefined.
1214
+ see MegaMenu.ts's doc comment). Its close event routes through
1215
+ dismissFlyout(), the one dismissal entry point, carrying whether
1216
+ focus should be restored. That resets hoveredCategory back to ''
1217
+ — it is the derived openCategory getter above, not hoveredCategory
1218
+ itself, that becomes undefined.
1165
1219
  -->
1166
- ${e ? t`
1220
+ ${e ? o`
1167
1221
  <cm-mega-menu
1168
1222
  .tree=${this.tree}
1169
1223
  category-id=${e.id}
1170
- @cm-mega-menu-close=${() => this.hoveredCategory = ""}
1224
+ @cm-mega-menu-close=${(t) => {
1225
+ var i;
1226
+ return this.dismissFlyout(((i = t.detail) == null ? void 0 : i.restoreFocus) ?? !1);
1227
+ }}
1171
1228
  ></cm-mega-menu>
1172
1229
  ` : null}
1173
1230
  </nav>
1174
1231
  `;
1175
1232
  }
1176
1233
  };
1177
- l.styles = [g1];
1234
+ l.styles = [c1];
1178
1235
  g([
1179
- Z()
1236
+ S()
1180
1237
  ], l.prototype, "hoveredCategory", 2);
1181
1238
  g([
1182
1239
  c({ type: Boolean, reflect: !0 })
@@ -1188,11 +1245,11 @@ g([
1188
1245
  c({ attribute: !1 })
1189
1246
  ], l.prototype, "tree", 2);
1190
1247
  l = g([
1191
- x("cm-side-nav")
1248
+ b("cm-side-nav")
1192
1249
  ], l);
1193
1250
  export {
1194
1251
  h as MegaMenu,
1195
1252
  l as SideNav,
1196
- f1 as hasIconFor,
1197
- w1 as hasMegaMenuIconFor
1253
+ w1 as hasIconFor,
1254
+ p1 as hasMegaMenuIconFor
1198
1255
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campminder/components",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"