@refrakt-md/behaviors 0.14.2 → 0.14.3

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.
@@ -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-open] — opens the header menu panel
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. CSS should use:
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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CA+D/E"}
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-open] — opens the header menu panel
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. CSS should use:
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
- closeAll();
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
- // Open menu buttonsopen the first non-nav panel
32
- const openBtns = root.querySelectorAll('[data-mobile-menu-open]');
33
- for (const btn of openBtns) {
53
+ // Header menu togglesame button opens and closes
54
+ for (const btn of menuToggles) {
34
55
  const handler = () => {
35
- const panel = root.querySelector('.rf-mobile-panel:not(.rf-mobile-panel--nav)');
36
- if (panel)
37
- openPanel(panel);
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
- // Close buttons
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":"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"}
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,CAiFjE"}
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
- const panel = group.querySelector(':scope > ul, :scope > ol');
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":"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"}
1
+ {"version":3,"file":"nav-collapsible.js","sourceRoot":"","sources":["../../src/behaviors/nav-collapsible.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,17 @@
1
1
  import { SafeHTMLElement } from './ssr-safe.js';
2
2
  /**
3
- * <rf-nav> — resolves page slugs to links with active state.
3
+ * <rf-nav> — interactive-behavior anchor for the nav rune.
4
4
  *
5
- * Reads page data from RfContext.pages and current URL from RfContext.currentUrl.
6
- * Finds NavItem children (via [data-rune="nav-item"]) and resolves their
7
- * data-slug attributes to page URLs.
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
- * Progressive enhancement: without JS, shows plain text from identity transform.
10
- * With JS, replaces text with <a> links and marks the active page.
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":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;GASG;AACH,qBAAa,KAAM,SAAQ,eAAe;IACzC,iBAAiB;IAIjB,OAAO,CAAC,eAAe;CAgCvB"}
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"}
@@ -1,52 +1,19 @@
1
- import { RfContext } from './context.js';
2
1
  import { SafeHTMLElement } from './ssr-safe.js';
3
2
  /**
4
- * <rf-nav> — resolves page slugs to links with active state.
3
+ * <rf-nav> — interactive-behavior anchor for the nav rune.
5
4
  *
6
- * Reads page data from RfContext.pages and current URL from RfContext.currentUrl.
7
- * Finds NavItem children (via [data-rune="nav-item"]) and resolves their
8
- * data-slug attributes to page URLs.
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
- * Progressive enhancement: without JS, shows plain text from identity transform.
11
- * With JS, replaces text with <a> links and marks the active page.
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
- this.resolveNavItems();
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
@@ -1 +1 @@
1
- {"version":3,"file":"nav.js","sourceRoot":"","sources":["../../src/elements/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,OAAO,KAAM,SAAQ,eAAe;IACzC,iBAAiB;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACxB,CAAC;IAEO,eAAe;QACtB,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,4CAA4C;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAc,wBAAwB,CAAC,CAAC;QAC3E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC;gBAClC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACf,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1B,kBAAkB,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,CAC7E,CAAC,CAAC,CAAC,CAAC;YACN,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,8BAA8B;YAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC;YACrB,IAAI,CAAC,SAAS,GAAG,mBAAmB,CAAC;YACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;YAE9B,IAAI,UAAU,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACjD,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;CACD;AAED,SAAS,kBAAkB,CAAC,CAAS,EAAE,CAAS;IAC/C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAC1D,OAAO,CAAC,CAAC;AACV,CAAC"}
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@refrakt-md/behaviors",
3
3
  "description": "Vanilla JS behavior library for refrakt.md runes — tabs, accordions, copy buttons, keyboard navigation",
4
- "version": "0.14.2",
4
+ "version": "0.14.3",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {