@codbex/harmonia 1.11.1 → 1.12.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.
@@ -6770,13 +6770,13 @@ function list_default(Alpine) {
6770
6770
  // src/components/menu.js
6771
6771
  function menu_default(Alpine) {
6772
6772
  Alpine.directive("h-menu-trigger", (el, { modifiers }) => {
6773
- el._menu_trigger = {
6773
+ el._h_menu_trigger = {
6774
6774
  isDropdown: modifiers.includes("dropdown"),
6775
6775
  setOpen(open) {
6776
6776
  el.setAttribute("aria-expanded", open);
6777
6777
  }
6778
6778
  };
6779
- if (el._menu_trigger.isDropdown) {
6779
+ if (el._h_menu_trigger.isDropdown) {
6780
6780
  el.setAttribute("aria-haspopup", "true");
6781
6781
  el.setAttribute("aria-expanded", "false");
6782
6782
  if (!el.hasAttribute("id")) {
@@ -6818,10 +6818,10 @@ function menu_default(Alpine) {
6818
6818
  const menuTrigger = (() => {
6819
6819
  if (isSubmenu) return;
6820
6820
  let sibling = el.previousElementSibling;
6821
- while (sibling && !Object.prototype.hasOwnProperty.call(sibling, "_menu_trigger")) {
6821
+ while (sibling && !Object.prototype.hasOwnProperty.call(sibling, "_h_menu_trigger")) {
6822
6822
  sibling = sibling.previousElementSibling;
6823
6823
  }
6824
- if (!Object.prototype.hasOwnProperty.call(sibling, "_menu_trigger")) {
6824
+ if (!Object.prototype.hasOwnProperty.call(sibling, "_h_menu_trigger")) {
6825
6825
  throw new Error(`${original} menu must be placed after a menu trigger element`);
6826
6826
  }
6827
6827
  return sibling;
@@ -6843,16 +6843,22 @@ function menu_default(Alpine) {
6843
6843
  }
6844
6844
  setAriaAttrubutes(menuSubItem);
6845
6845
  } else if (menuTrigger) {
6846
- setAriaAttrubutes(menuTrigger._menu_trigger.isDropdown ? menuTrigger : void 0);
6846
+ if (menuTrigger._h_menu_trigger.isDropdown) {
6847
+ if (!el.hasAttribute("id")) {
6848
+ el.setAttribute("id", `m${uuid_default()}`);
6849
+ }
6850
+ menuTrigger.setAttribute("aria-controls", el.getAttribute("id"));
6851
+ setAriaAttrubutes(menuTrigger);
6852
+ } else setAriaAttrubutes();
6847
6853
  } else {
6848
6854
  setAriaAttrubutes();
6849
6855
  }
6850
6856
  function listenForTrigger(listen) {
6851
6857
  if (listen) {
6852
- if (menuTrigger._menu_trigger.isDropdown) menuTrigger.addEventListener("click", openDropdown);
6858
+ if (menuTrigger._h_menu_trigger.isDropdown) menuTrigger.addEventListener("click", openDropdown);
6853
6859
  else menuTrigger.addEventListener("contextmenu", onContextmenu);
6854
6860
  } else {
6855
- if (menuTrigger._menu_trigger.isDropdown) menuTrigger.removeEventListener("click", openDropdown);
6861
+ if (menuTrigger._h_menu_trigger.isDropdown) menuTrigger.removeEventListener("click", openDropdown);
6856
6862
  else menuTrigger.removeEventListener("contextmenu", onContextmenu);
6857
6863
  }
6858
6864
  }
@@ -6881,8 +6887,8 @@ function menu_default(Alpine) {
6881
6887
  } else {
6882
6888
  listenForTrigger(true);
6883
6889
  if (focusTrigger) menuTrigger.focus();
6884
- if (menuTrigger._menu_trigger.isDropdown) {
6885
- menuTrigger._menu_trigger.setOpen(false);
6890
+ if (menuTrigger._h_menu_trigger.isDropdown) {
6891
+ menuTrigger._h_menu_trigger.setOpen(false);
6886
6892
  }
6887
6893
  }
6888
6894
  }
@@ -6997,7 +7003,7 @@ function menu_default(Alpine) {
6997
7003
  let getPlacement = function() {
6998
7004
  if (isSubmenu) {
6999
7005
  return "right-start";
7000
- } else if (menuTrigger._menu_trigger.isDropdown) {
7006
+ } else if (menuTrigger._h_menu_trigger.isDropdown) {
7001
7007
  return el.getAttribute("data-align") || "bottom-start";
7002
7008
  }
7003
7009
  return "right-start";
@@ -7042,7 +7048,7 @@ function menu_default(Alpine) {
7042
7048
  el.classList.remove("hidden");
7043
7049
  el.pauseKeyEvents = false;
7044
7050
  let firstOpen = true;
7045
- if (!isSubmenu && menuTrigger._menu_trigger.isDropdown) {
7051
+ if (!isSubmenu && menuTrigger._h_menu_trigger.isDropdown) {
7046
7052
  autoUpdateCleanup = autoUpdate(parent, el, updatePosition);
7047
7053
  } else {
7048
7054
  updatePosition();
@@ -7050,8 +7056,8 @@ function menu_default(Alpine) {
7050
7056
  }
7051
7057
  }
7052
7058
  function openDropdown() {
7053
- if (menuTrigger._menu_trigger.isDropdown) {
7054
- menuTrigger._menu_trigger.setOpen(true);
7059
+ if (menuTrigger._h_menu_trigger.isDropdown) {
7060
+ menuTrigger._h_menu_trigger.setOpen(true);
7055
7061
  }
7056
7062
  open(menuTrigger);
7057
7063
  }
@@ -7077,6 +7083,10 @@ function menu_default(Alpine) {
7077
7083
  menuSubItem._menu_sub.open = open;
7078
7084
  menuSubItem._menu_sub.close = close;
7079
7085
  } else {
7086
+ if (menuTrigger._h_menu_trigger.navItem) {
7087
+ menuTrigger._h_menu_trigger.openMenu = openDropdown;
7088
+ menuTrigger._h_menu_trigger.closeMenu = close;
7089
+ }
7080
7090
  listenForTrigger(true);
7081
7091
  }
7082
7092
  function onTransitionEnd(event) {
@@ -7445,6 +7455,154 @@ function menu_default(Alpine) {
7445
7455
  });
7446
7456
  }
7447
7457
 
7458
+ // src/components/navigation-menu.js
7459
+ var navItemTriggerClasses = [
7460
+ "inline-flex",
7461
+ "h-9",
7462
+ "w-max",
7463
+ "items-center",
7464
+ "justify-center",
7465
+ "rounded-control",
7466
+ "px-3",
7467
+ "py-2",
7468
+ "text-sm",
7469
+ "font-medium",
7470
+ "whitespace-nowrap",
7471
+ "gap-1.5",
7472
+ "transition-colors",
7473
+ "duration-100",
7474
+ "motion-reduce:transition-none",
7475
+ "hover:bg-secondary-hover",
7476
+ "hover:text-secondary-foreground",
7477
+ "focus:bg-secondary-hover",
7478
+ "focus:text-secondary-foreground",
7479
+ "outline-ring/50",
7480
+ "focus-visible:outline-[calc(var(--spacing)*0.75)]",
7481
+ "focus-visible:outline",
7482
+ "cursor-pointer",
7483
+ "shrink-0",
7484
+ "[&_svg]:shrink-0",
7485
+ "[&_svg:not([class*='size-'])]:size-4",
7486
+ "has-[>svg]:px-2.5"
7487
+ ];
7488
+ function navigation_menu_default(Alpine) {
7489
+ Alpine.directive("h-nav", (el, { original }) => {
7490
+ if (el.tagName !== "NAV") {
7491
+ throw new Error(`${original} must be a nav element`);
7492
+ }
7493
+ if (!el.hasAttribute("aria-label")) {
7494
+ throw new Error(`${original} must have an "aria-label" attribute`);
7495
+ }
7496
+ el.classList.add("relative", "z-10", "flex", "items-center");
7497
+ el.setAttribute("data-slot", "nav");
7498
+ });
7499
+ Alpine.directive("h-nav-list", (el, { original }, { Alpine: Alpine2 }) => {
7500
+ if (el.tagName !== "UL") {
7501
+ throw new Error(`${original} must be a ul element`);
7502
+ }
7503
+ const nav = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "nav");
7504
+ if (!nav) {
7505
+ throw new Error(`${original} must be inside a ${Alpine2.prefixed("h-nav")} element`);
7506
+ }
7507
+ el.classList.add("flex", "flex-1", "list-none", "items-center", "gap-1");
7508
+ el.setAttribute("data-slot", "nav-list");
7509
+ });
7510
+ Alpine.directive("h-nav-item", (el, { original }) => {
7511
+ if (el.tagName !== "LI") {
7512
+ throw new Error(`${original} must be a li element`);
7513
+ }
7514
+ if (el.parentElement?.getAttribute("data-slot") !== "nav-list") {
7515
+ throw new Error(`${original} must be a direct child of a x-h-nav-list element`);
7516
+ }
7517
+ el.classList.add("relative");
7518
+ el.setAttribute("data-slot", "nav-item");
7519
+ });
7520
+ Alpine.directive("h-nav-trigger", (el, { original }, { cleanup, Alpine: Alpine2 }) => {
7521
+ if (el.tagName !== "BUTTON") {
7522
+ throw new Error(`${original} must be a button element`);
7523
+ }
7524
+ const navItem = Alpine2.findClosest(el.parentElement, (parent) => parent.getAttribute("data-slot") === "nav-item");
7525
+ if (!navItem) {
7526
+ throw new Error(`${original} must be inside a ${Alpine2.prefixed("h-nav-item")} element`);
7527
+ }
7528
+ if (!el.hasAttribute("id")) {
7529
+ el.setAttribute("id", `nnt${uuid_default()}`);
7530
+ }
7531
+ const chevron = createSvg({
7532
+ icon: ChevronDown,
7533
+ classes: "size-4 shrink-0 transition-transform duration-200 motion-reduce:transition-none [[data-state=open]_&]:rotate-180",
7534
+ attrs: { "aria-hidden": "true", role: "presentation" }
7535
+ });
7536
+ el._h_menu_trigger = {
7537
+ isDropdown: true,
7538
+ navItem: true,
7539
+ openMenu: void 0,
7540
+ closeMenu: void 0,
7541
+ setOpen(open) {
7542
+ el.setAttribute("aria-expanded", String(open));
7543
+ el.setAttribute("data-state", open ? "open" : "closed");
7544
+ }
7545
+ };
7546
+ el.setAttribute("aria-haspopup", "menu");
7547
+ el.setAttribute("aria-expanded", "false");
7548
+ el.setAttribute("data-state", "closed");
7549
+ el.classList.add("bg-transparent", "data-[state=open]:bg-secondary-hover", "disabled:opacity-50", "disabled:pointer-events-none", ...navItemTriggerClasses);
7550
+ el.appendChild(chevron);
7551
+ el.setAttribute("data-slot", "nav-trigger");
7552
+ const nav = Alpine2.findClosest(el.parentElement, (p) => p.getAttribute("data-slot") === "nav");
7553
+ let cancelHoverCleanup = null;
7554
+ if (nav?.hasAttribute("data-open-on-hover")) {
7555
+ let scheduleClose = function() {
7556
+ closeTimer = setTimeout(() => {
7557
+ el._h_menu_trigger.closeMenu?.();
7558
+ closeTimer = null;
7559
+ }, 100);
7560
+ }, cancelClose = function() {
7561
+ if (closeTimer) {
7562
+ clearTimeout(closeTimer);
7563
+ closeTimer = null;
7564
+ }
7565
+ }, onNavItemEnter = function() {
7566
+ cancelClose();
7567
+ el._h_menu_trigger.openMenu?.();
7568
+ };
7569
+ el.classList.remove("cursor-pointer");
7570
+ let closeTimer = null;
7571
+ navItem.addEventListener("mouseenter", onNavItemEnter);
7572
+ navItem.addEventListener("mouseleave", scheduleClose);
7573
+ cancelHoverCleanup = () => {
7574
+ cancelClose();
7575
+ navItem.removeEventListener("mouseenter", onNavItemEnter);
7576
+ navItem.removeEventListener("mouseleave", scheduleClose);
7577
+ };
7578
+ }
7579
+ cleanup(() => {
7580
+ if (cancelHoverCleanup) cancelHoverCleanup();
7581
+ if (chevron.parentElement === el) el.removeChild(chevron);
7582
+ });
7583
+ });
7584
+ Alpine.directive("h-nav-link", (el, { original }, { cleanup }) => {
7585
+ if (el.tagName !== "A" && el.tagName !== "BUTTON") {
7586
+ throw new Error(`${original} must be an anchor or button element`);
7587
+ } else if (el.tagName === "BUTTON") {
7588
+ el.setAttribute("type", "button");
7589
+ }
7590
+ el.classList.add(...navItemTriggerClasses, "no-underline", "text-inherit", "data-[active]:bg-secondary-hover", "data-[active]:font-semibold");
7591
+ function syncActive() {
7592
+ if (el.hasAttribute("data-active")) {
7593
+ el.setAttribute("aria-current", "page");
7594
+ } else {
7595
+ el.removeAttribute("aria-current");
7596
+ }
7597
+ }
7598
+ syncActive();
7599
+ const observer = new MutationObserver(syncActive);
7600
+ observer.observe(el, { attributes: true, attributeFilter: ["data-active"] });
7601
+ el.setAttribute("data-slot", "nav-link");
7602
+ cleanup(() => observer.disconnect());
7603
+ });
7604
+ }
7605
+
7448
7606
  // src/utils/breakpoint-listener.js
7449
7607
  function getBreakpointListener(handler, breakpoint = 768, frame = false) {
7450
7608
  let bps = Number.isFinite(breakpoint) ? `${breakpoint}px` : breakpoint;
@@ -11628,7 +11786,7 @@ function tree_default(Alpine) {
11628
11786
  }
11629
11787
 
11630
11788
  // package.json
11631
- var version = "1.11.1";
11789
+ var version = "1.12.0";
11632
11790
 
11633
11791
  // src/utils/theme.js
11634
11792
  var colorSchemeKey = "codbex.harmonia.colorMode";
@@ -11838,6 +11996,7 @@ var registerComponents = (registerPlugin) => {
11838
11996
  registerPlugin(label_default);
11839
11997
  registerPlugin(list_default);
11840
11998
  registerPlugin(menu_default);
11999
+ registerPlugin(navigation_menu_default);
11841
12000
  registerPlugin(notifications_default);
11842
12001
  registerPlugin(pagination_default);
11843
12002
  registerPlugin(popover_default);
@@ -11888,6 +12047,7 @@ export {
11888
12047
  label_default as Label,
11889
12048
  list_default as List,
11890
12049
  menu_default as Menu,
12050
+ navigation_menu_default as NavigationMenu,
11891
12051
  notifications_default as Notifications,
11892
12052
  pagination_default as Pagination,
11893
12053
  popover_default as Popover,