@refrakt-md/behaviors 0.14.2 → 0.14.4
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/dist/behaviors/mobile-menu.d.ts +4 -2
- package/dist/behaviors/mobile-menu.d.ts.map +1 -1
- package/dist/behaviors/mobile-menu.js +38 -13
- package/dist/behaviors/mobile-menu.js.map +1 -1
- package/dist/behaviors/nav-collapsible.d.ts.map +1 -1
- package/dist/behaviors/nav-collapsible.js +5 -1
- package/dist/behaviors/nav-collapsible.js.map +1 -1
- package/dist/elements/nav.d.ts +8 -7
- package/dist/elements/nav.d.ts.map +1 -1
- package/dist/elements/nav.js +9 -42
- package/dist/elements/nav.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,13 +4,15 @@ import type { CleanupFn } from '../types.js';
|
|
|
4
4
|
*
|
|
5
5
|
* Replaces Svelte reactive state ($state menuOpen/navOpen) with DOM-based toggling.
|
|
6
6
|
* Discovers elements by data attributes and wires up:
|
|
7
|
-
* - [data-mobile-menu-
|
|
7
|
+
* - [data-mobile-menu-toggle] — toggles the header menu panel (open ↔ close)
|
|
8
|
+
* - [data-mobile-menu-open] — opens the header menu panel (legacy)
|
|
8
9
|
* - [data-mobile-menu-close] — closes all panels
|
|
9
10
|
* - [data-mobile-nav-toggle] — toggles the nav panel
|
|
10
11
|
* - Escape key dismisses all open panels
|
|
11
12
|
* - Body scroll lock when a panel is open
|
|
12
13
|
*
|
|
13
|
-
* Panels are toggled via [data-open] attribute.
|
|
14
|
+
* Panels are toggled via [data-open] attribute. Triggers reflect state via
|
|
15
|
+
* `aria-expanded` and a matching `aria-label`. CSS should use:
|
|
14
16
|
* .rf-mobile-panel { display: none; }
|
|
15
17
|
* .rf-mobile-panel[data-open] { display: block; }
|
|
16
18
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-menu.d.ts","sourceRoot":"","sources":["../../src/behaviors/mobile-menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"mobile-menu.d.ts","sourceRoot":"","sources":["../../src/behaviors/mobile-menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAuF/E"}
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Replaces Svelte reactive state ($state menuOpen/navOpen) with DOM-based toggling.
|
|
5
5
|
* Discovers elements by data attributes and wires up:
|
|
6
|
-
* - [data-mobile-menu-
|
|
6
|
+
* - [data-mobile-menu-toggle] — toggles the header menu panel (open ↔ close)
|
|
7
|
+
* - [data-mobile-menu-open] — opens the header menu panel (legacy)
|
|
7
8
|
* - [data-mobile-menu-close] — closes all panels
|
|
8
9
|
* - [data-mobile-nav-toggle] — toggles the nav panel
|
|
9
10
|
* - Escape key dismisses all open panels
|
|
10
11
|
* - Body scroll lock when a panel is open
|
|
11
12
|
*
|
|
12
|
-
* Panels are toggled via [data-open] attribute.
|
|
13
|
+
* Panels are toggled via [data-open] attribute. Triggers reflect state via
|
|
14
|
+
* `aria-expanded` and a matching `aria-label`. CSS should use:
|
|
13
15
|
* .rf-mobile-panel { display: none; }
|
|
14
16
|
* .rf-mobile-panel[data-open] { display: block; }
|
|
15
17
|
*/
|
|
@@ -19,37 +21,59 @@ export function mobileMenuBehavior(container) {
|
|
|
19
21
|
const panels = root.querySelectorAll('.rf-mobile-panel');
|
|
20
22
|
if (panels.length === 0)
|
|
21
23
|
return () => { };
|
|
24
|
+
const mainPanel = root.querySelector('.rf-mobile-panel:not(.rf-mobile-panel--nav)');
|
|
25
|
+
const navPanel = root.querySelector('.rf-mobile-panel--nav');
|
|
26
|
+
const menuToggles = root.querySelectorAll('[data-mobile-menu-toggle], [data-mobile-menu-open]');
|
|
27
|
+
const navToggles = root.querySelectorAll('[data-mobile-nav-toggle]');
|
|
28
|
+
function syncTriggers() {
|
|
29
|
+
const mainOpen = !!mainPanel?.hasAttribute('data-open');
|
|
30
|
+
menuToggles.forEach(btn => {
|
|
31
|
+
btn.setAttribute('aria-expanded', mainOpen ? 'true' : 'false');
|
|
32
|
+
btn.setAttribute('aria-label', mainOpen ? 'Close menu' : 'Open menu');
|
|
33
|
+
});
|
|
34
|
+
const navOpen = !!navPanel?.hasAttribute('data-open');
|
|
35
|
+
navToggles.forEach(btn => {
|
|
36
|
+
btn.setAttribute('aria-expanded', navOpen ? 'true' : 'false');
|
|
37
|
+
});
|
|
38
|
+
}
|
|
22
39
|
function closeAll() {
|
|
23
40
|
panels.forEach(p => p.removeAttribute('data-open'));
|
|
24
41
|
document.body.style.overflow = '';
|
|
42
|
+
syncTriggers();
|
|
25
43
|
}
|
|
26
44
|
function openPanel(panel) {
|
|
27
|
-
|
|
45
|
+
panels.forEach(p => {
|
|
46
|
+
if (p !== panel)
|
|
47
|
+
p.removeAttribute('data-open');
|
|
48
|
+
});
|
|
28
49
|
panel.setAttribute('data-open', '');
|
|
29
50
|
document.body.style.overflow = 'hidden';
|
|
51
|
+
syncTriggers();
|
|
30
52
|
}
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
-
for (const btn of openBtns) {
|
|
53
|
+
// Header menu toggle — same button opens and closes
|
|
54
|
+
for (const btn of menuToggles) {
|
|
34
55
|
const handler = () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
if (!mainPanel)
|
|
57
|
+
return;
|
|
58
|
+
if (mainPanel.hasAttribute('data-open')) {
|
|
59
|
+
closeAll();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
openPanel(mainPanel);
|
|
63
|
+
}
|
|
38
64
|
};
|
|
39
65
|
btn.addEventListener('click', handler);
|
|
40
66
|
cleanups.push(() => btn.removeEventListener('click', handler));
|
|
41
67
|
}
|
|
42
|
-
//
|
|
68
|
+
// Explicit close buttons (kept for themes that still wire them)
|
|
43
69
|
const closeBtns = root.querySelectorAll('[data-mobile-menu-close]');
|
|
44
70
|
for (const btn of closeBtns) {
|
|
45
71
|
btn.addEventListener('click', closeAll);
|
|
46
72
|
cleanups.push(() => btn.removeEventListener('click', closeAll));
|
|
47
73
|
}
|
|
48
|
-
// Nav panel toggle
|
|
49
|
-
const navToggles = root.querySelectorAll('[data-mobile-nav-toggle]');
|
|
74
|
+
// Nav panel toggle (e.g. docs toolbar hamburger)
|
|
50
75
|
for (const btn of navToggles) {
|
|
51
76
|
const handler = () => {
|
|
52
|
-
const navPanel = root.querySelector('.rf-mobile-panel--nav');
|
|
53
77
|
if (!navPanel)
|
|
54
78
|
return;
|
|
55
79
|
if (navPanel.hasAttribute('data-open')) {
|
|
@@ -69,6 +93,7 @@ export function mobileMenuBehavior(container) {
|
|
|
69
93
|
};
|
|
70
94
|
document.addEventListener('keydown', onKeydown);
|
|
71
95
|
cleanups.push(() => document.removeEventListener('keydown', onKeydown));
|
|
96
|
+
syncTriggers();
|
|
72
97
|
return () => {
|
|
73
98
|
closeAll();
|
|
74
99
|
cleanups.forEach(fn => fn());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-menu.js","sourceRoot":"","sources":["../../src/behaviors/mobile-menu.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"mobile-menu.js","sourceRoot":"","sources":["../../src/behaviors/mobile-menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-collapsible.d.ts","sourceRoot":"","sources":["../../src/behaviors/nav-collapsible.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"nav-collapsible.d.ts","sourceRoot":"","sources":["../../src/behaviors/nav-collapsible.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,SAAS,CAuFjE"}
|
|
@@ -18,7 +18,11 @@ export function navCollapsibleBehavior(el) {
|
|
|
18
18
|
const heading = group.querySelector('[data-field="title"], h1, h2, h3, h4, h5, h6');
|
|
19
19
|
if (!heading)
|
|
20
20
|
continue;
|
|
21
|
-
|
|
21
|
+
// SPEC-054 wraps each nav-group's body content (lists, nested navs,
|
|
22
|
+
// intro/footer slots) in a `<div data-name="panel">`. Animate that
|
|
23
|
+
// wrapper; for older trees that don't have it, fall back to the
|
|
24
|
+
// direct <ul>/<ol>.
|
|
25
|
+
const panel = group.querySelector(':scope > [data-name="panel"], :scope > ul, :scope > ol');
|
|
22
26
|
if (!panel)
|
|
23
27
|
continue;
|
|
24
28
|
const triggerId = heading.id || uniqueId('rf-nav-trigger');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-collapsible.js","sourceRoot":"","sources":["../../src/behaviors/nav-collapsible.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAe;IACrD,IAAI,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,KAAK,MAAM;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CACxB,EAAE,CAAC,gBAAgB,CAAc,yBAAyB,CAAC,CAC3D,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAsB,EAAE,CAAC;IAEvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAClC,8CAA8C,CAC9C,CAAC;QACF,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"nav-collapsible.js","sourceRoot":"","sources":["../../src/behaviors/nav-collapsible.ts"],"names":[],"mappings":"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"}
|
package/dist/elements/nav.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { SafeHTMLElement } from './ssr-safe.js';
|
|
2
2
|
/**
|
|
3
|
-
* <rf-nav> —
|
|
3
|
+
* <rf-nav> — interactive-behavior anchor for the nav rune.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* As of SPEC-055, slug → href resolution and active-state marking are both
|
|
6
|
+
* performed at build time during the cross-page pipeline's postProcess phase.
|
|
7
|
+
* The SSR HTML carries resolved `<a href>` values with `aria-current="page"` /
|
|
8
|
+
* `data-active="ancestor"` attributes already in place.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* This element therefore has no runtime resolution responsibilities. It remains
|
|
11
|
+
* registered as a custom element so other behaviors (collapsible toggling,
|
|
12
|
+
* menubar dropdown open/close, mega panel open/close) can attach to it.
|
|
11
13
|
*/
|
|
12
14
|
export declare class RfNav extends SafeHTMLElement {
|
|
13
15
|
connectedCallback(): void;
|
|
14
|
-
private resolveNavItems;
|
|
15
16
|
}
|
|
16
17
|
//# sourceMappingURL=nav.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../src/elements/nav.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../src/elements/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,qBAAa,KAAM,SAAQ,eAAe;IACzC,iBAAiB;CAGjB"}
|
package/dist/elements/nav.js
CHANGED
|
@@ -1,52 +1,19 @@
|
|
|
1
|
-
import { RfContext } from './context.js';
|
|
2
1
|
import { SafeHTMLElement } from './ssr-safe.js';
|
|
3
2
|
/**
|
|
4
|
-
* <rf-nav> —
|
|
3
|
+
* <rf-nav> — interactive-behavior anchor for the nav rune.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* As of SPEC-055, slug → href resolution and active-state marking are both
|
|
6
|
+
* performed at build time during the cross-page pipeline's postProcess phase.
|
|
7
|
+
* The SSR HTML carries resolved `<a href>` values with `aria-current="page"` /
|
|
8
|
+
* `data-active="ancestor"` attributes already in place.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* This element therefore has no runtime resolution responsibilities. It remains
|
|
11
|
+
* registered as a custom element so other behaviors (collapsible toggling,
|
|
12
|
+
* menubar dropdown open/close, mega panel open/close) can attach to it.
|
|
12
13
|
*/
|
|
13
14
|
export class RfNav extends SafeHTMLElement {
|
|
14
15
|
connectedCallback() {
|
|
15
|
-
|
|
16
|
+
// Reserved for interactive-behavior hooks. No work to do for SSR-resolved navs.
|
|
16
17
|
}
|
|
17
|
-
resolveNavItems() {
|
|
18
|
-
const pages = RfContext.pages;
|
|
19
|
-
const currentUrl = RfContext.currentUrl;
|
|
20
|
-
if (!pages || pages.length === 0)
|
|
21
|
-
return;
|
|
22
|
-
// Find all NavItem elements within this nav
|
|
23
|
-
const items = this.querySelectorAll('[data-rune="nav-item"]');
|
|
24
|
-
for (const item of items) {
|
|
25
|
-
const slug = item.dataset.slug;
|
|
26
|
-
if (!slug)
|
|
27
|
-
continue;
|
|
28
|
-
const candidates = pages.filter(p => p.url.endsWith('/' + slug) || p.url === '/' + slug);
|
|
29
|
-
const page = candidates.length <= 1
|
|
30
|
-
? candidates[0]
|
|
31
|
-
: candidates.sort((a, b) => sharedPrefixLength(b.url, currentUrl) - sharedPrefixLength(a.url, currentUrl))[0];
|
|
32
|
-
if (!page)
|
|
33
|
-
continue;
|
|
34
|
-
// Replace content with a link
|
|
35
|
-
const link = document.createElement('a');
|
|
36
|
-
link.href = page.url;
|
|
37
|
-
link.className = 'rf-nav-item__link';
|
|
38
|
-
link.textContent = page.title;
|
|
39
|
-
if (currentUrl === page.url) {
|
|
40
|
-
link.classList.add('rf-nav-item__link--active');
|
|
41
|
-
}
|
|
42
|
-
item.replaceChildren(link);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function sharedPrefixLength(a, b) {
|
|
47
|
-
let i = 0;
|
|
48
|
-
while (i < a.length && i < b.length && a[i] === b[i])
|
|
49
|
-
i++;
|
|
50
|
-
return i;
|
|
51
18
|
}
|
|
52
19
|
//# sourceMappingURL=nav.js.map
|
package/dist/elements/nav.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav.js","sourceRoot":"","sources":["../../src/elements/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"nav.js","sourceRoot":"","sources":["../../src/elements/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,KAAM,SAAQ,eAAe;IACzC,iBAAiB;QAChB,gFAAgF;IACjF,CAAC;CACD"}
|
package/package.json
CHANGED