@codbex/harmonia 1.10.1 → 1.11.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/dist/harmonia.js CHANGED
@@ -42,6 +42,7 @@
42
42
  var CircleSuccess = 26;
43
43
  var CircleUnknown = 27;
44
44
  var CircleUser = 28;
45
+ var Home = 29;
45
46
  function setCalendarContent(svg) {
46
47
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
47
48
  path.setAttributeNS(
@@ -384,6 +385,15 @@
384
385
  );
385
386
  svg.appendChild(path2);
386
387
  }
388
+ function setHomeContent(svg) {
389
+ const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
390
+ path.setAttributeNS(
391
+ null,
392
+ "d",
393
+ "m8 0.8252c-0.51124 0-1.0243 0.19615-1.416 0.58789l-4.4316 4.4297c-0.27162 0.2733-0.65234 0.7207-0.65234 1.6055v5.7266c0 1.108 0.892 2 2 2h9c1.108 0 2-0.892 2-2v-5.7266c0-0.88477-0.38073-1.3322-0.65234-1.6055l-4.4316-4.4297c-0.39174-0.39174-0.90478-0.58789-1.416-0.58789zm0 1.4258c0.25431-2.91e-4 0.5101 0.096117 0.70703 0.29297l4.2207 4.2188v0.00195c0.17404 0.1851 0.27111 0.42951 0.27148 0.68359v5.4277c0 0.554-0.446 1-1 1h-1.5078v-4.1289c0-1.108-0.892-2-2-2h-1.3828c-1.108 0-2 0.892-2 2v4.1289h-1.5078c-0.554 0-1-0.446-1-1v-5.4277c3.752e-4 -0.25408 0.09744-0.4985 0.27148-0.68359v-0.00195l4.2207-4.2188c0.19693-0.19685 0.45273-0.29326 0.70703-0.29297zm-0.58984 6.7949h1.1797c0.44244-4.323e-4 0.80121 0.35834 0.80078 0.80078v4.0293h-2.7812v-4.0293c-4.322e-4 -0.44244 0.35834-0.80121 0.80078-0.80078z"
394
+ );
395
+ svg.appendChild(path);
396
+ }
387
397
  function createSvg({ icon, classes = "size-4", attrs } = {}) {
388
398
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
389
399
  svg.setAttributeNS(null, "width", "16");
@@ -484,6 +494,9 @@
484
494
  case CircleUser:
485
495
  setCircleUserContent(svg);
486
496
  break;
497
+ case Home:
498
+ setHomeContent(svg);
499
+ break;
487
500
  default:
488
501
  break;
489
502
  }
@@ -583,6 +596,9 @@
583
596
  case "circle-user":
584
597
  setCircleUserContent(svg);
585
598
  break;
599
+ case "home":
600
+ setHomeContent(svg);
601
+ break;
586
602
  default:
587
603
  break;
588
604
  }
@@ -1017,6 +1033,113 @@
1017
1033
  });
1018
1034
  }
1019
1035
 
1036
+ // src/components/breadcrumb.js
1037
+ function breadcrumb_default(Alpine) {
1038
+ Alpine.directive("h-breadcrumb", (el, _, { Alpine: Alpine2, cleanup }) => {
1039
+ el.classList.add("flex", "items-center", "break-words", "text-sm", "text-muted-foreground", "rounded-control");
1040
+ el.setAttribute("role", "navigation");
1041
+ el.setAttribute("aria-label", "breadcrumb");
1042
+ el.setAttribute("data-slot", "breadcrumb");
1043
+ const variants = {
1044
+ outline: ["border"]
1045
+ };
1046
+ const allVariantClasses = Object.values(variants).flat();
1047
+ const sizes = {
1048
+ default: ["h-9", "px-3"],
1049
+ md: ["h-8", "px-2.5"],
1050
+ sm: ["h-6.5", "px-2"]
1051
+ };
1052
+ const allSizeClasses = Object.values(sizes).flat();
1053
+ function applyClasses() {
1054
+ const variant = el.getAttribute("data-variant");
1055
+ const size3 = el.getAttribute("data-size") ?? "default";
1056
+ el.classList.remove(...allVariantClasses, ...allSizeClasses);
1057
+ if (variant && Object.prototype.hasOwnProperty.call(variants, variant)) {
1058
+ el.classList.add(...variants[variant]);
1059
+ el.classList.add(...sizes[size3] ?? sizes.default);
1060
+ } else {
1061
+ el.classList.add("px-2");
1062
+ }
1063
+ }
1064
+ applyClasses();
1065
+ const observer = new MutationObserver(() => applyClasses());
1066
+ observer.observe(el, { attributes: true, attributeFilter: ["data-variant", "data-size"] });
1067
+ if (el.getAttribute("data-overflow") === "scroll") {
1068
+ el.classList.add("overflow-x-scroll", "scrollbar-none");
1069
+ let preserveScroll = false;
1070
+ const scrollToEnd = () => {
1071
+ el.scrollLeft = el.scrollWidth;
1072
+ };
1073
+ Alpine2.nextTick(scrollToEnd);
1074
+ const handleScroll = () => {
1075
+ preserveScroll = el.scrollLeft < el.scrollWidth - el.clientWidth - 1;
1076
+ };
1077
+ const handleResize = () => {
1078
+ if (!preserveScroll) scrollToEnd();
1079
+ };
1080
+ el.addEventListener("scroll", handleScroll);
1081
+ window.addEventListener("resize", handleResize);
1082
+ cleanup(() => {
1083
+ el.removeEventListener("scroll", handleScroll);
1084
+ window.removeEventListener("resize", handleResize);
1085
+ observer.disconnect();
1086
+ });
1087
+ } else if (el.getAttribute("data-overflow") === "nowrap") {
1088
+ el.classList.add("flex-nowrap");
1089
+ cleanup(() => observer.disconnect());
1090
+ } else {
1091
+ el.classList.add("flex-wrap");
1092
+ cleanup(() => observer.disconnect());
1093
+ }
1094
+ });
1095
+ Alpine.directive("h-breadcrumb-list", (el, _, { Alpine: Alpine2 }) => {
1096
+ el.classList.add("flex", "items-center", "gap-1.5");
1097
+ el.setAttribute("data-slot", "breadcrumb-list");
1098
+ const nav = Alpine2.findClosest(el, (node) => node.getAttribute("data-slot") === "breadcrumb");
1099
+ const overflow = nav?.getAttribute("data-overflow");
1100
+ if (overflow === "scroll" || overflow === "nowrap") {
1101
+ el.classList.add("flex-nowrap");
1102
+ } else {
1103
+ el.classList.add("flex-wrap");
1104
+ }
1105
+ });
1106
+ Alpine.directive("h-breadcrumb-item", (el) => {
1107
+ el.classList.add("group", "inline-flex", "items-center", "gap-1.5");
1108
+ el.setAttribute("data-slot", "breadcrumb-item");
1109
+ const separator = createSvg({
1110
+ icon: ChevronRight,
1111
+ classes: "size-3.5 group-first-of-type:hidden",
1112
+ attrs: { "aria-hidden": "true", role: "presentation" }
1113
+ });
1114
+ el.prepend(separator);
1115
+ });
1116
+ Alpine.directive("h-breadcrumb-link", (el) => {
1117
+ el.classList.add(
1118
+ "cursor-pointer",
1119
+ "hbox",
1120
+ "gap-1.5",
1121
+ "items-center",
1122
+ "whitespace-nowrap",
1123
+ "text-primary",
1124
+ "transition-colors",
1125
+ "underline-offset-4",
1126
+ "hover:underline",
1127
+ "hover:text-primary-hover",
1128
+ "active:text-primary-active",
1129
+ "[&>svg]:size-4",
1130
+ "[&>svg]:text-current"
1131
+ );
1132
+ el.setAttribute("data-slot", "breadcrumb-link");
1133
+ });
1134
+ Alpine.directive("h-breadcrumb-page", (el) => {
1135
+ el.classList.add("hbox", "gap-1.5", "items-center", "whitespace-nowrap", "text-foreground", "font-normal", "[&>svg]:size-4", "[&>svg]:text-current");
1136
+ el.setAttribute("role", "link");
1137
+ el.setAttribute("aria-current", "page");
1138
+ el.setAttribute("aria-disabled", "true");
1139
+ el.setAttribute("data-slot", "breadcrumb-page");
1140
+ });
1141
+ }
1142
+
1020
1143
  // src/components/button.js
1021
1144
  var buttonVariants = {
1022
1145
  default: [
@@ -3418,7 +3541,9 @@
3418
3541
  "has-[>[data-slot=chip-close]]:pr-0",
3419
3542
  "has-[>[data-slot=spinner]]:px-2",
3420
3543
  "text-secondary-foreground",
3421
- "border"
3544
+ "border",
3545
+ "[&>:is(div,span:not([data-slot=chip-close]),p)]:py-1",
3546
+ "[&>:is(div,span:not([data-slot=chip-close]),p)]:truncate"
3422
3547
  );
3423
3548
  if (!el.hasAttribute("type")) {
3424
3549
  el.setAttribute("type", "button");
@@ -3491,8 +3616,8 @@
3491
3616
  });
3492
3617
  });
3493
3618
  Alpine.directive("h-chip-close", (el, { original }, { effect, cleanup }) => {
3494
- if (el.tagName === "BUTTON") {
3495
- throw new Error(`${original} must NOT be a button element`);
3619
+ if (el.tagName !== "SPAN") {
3620
+ throw new Error(`${original} must be a span element`);
3496
3621
  }
3497
3622
  const chip = Alpine.findClosest(el.parentElement, (parent) => Object.prototype.hasOwnProperty.call(parent, "_h_chip"));
3498
3623
  el.classList.add(
@@ -4827,6 +4952,10 @@
4827
4952
  }
4828
4953
  function close(closeParent = false, focusTrigger = false) {
4829
4954
  el.pauseKeyEvents = false;
4955
+ if (autoUpdateCleanup) {
4956
+ autoUpdateCleanup();
4957
+ autoUpdateCleanup = null;
4958
+ }
4830
4959
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
4831
4960
  el.classList.add("hidden", "scale-95", "opacity-0");
4832
4961
  Object.assign(el.style, {
@@ -4956,6 +5085,7 @@
4956
5085
  }
4957
5086
  }
4958
5087
  }
5088
+ let autoUpdateCleanup;
4959
5089
  function open(parent) {
4960
5090
  if (el.classList.contains("hidden")) {
4961
5091
  let getPlacement = function() {
@@ -4965,41 +5095,52 @@
4965
5095
  return el.getAttribute("data-align") || "bottom-start";
4966
5096
  }
4967
5097
  return "right-start";
5098
+ }, updatePosition = function() {
5099
+ const isFirst = firstOpen;
5100
+ firstOpen = false;
5101
+ computePosition2(parent, el, {
5102
+ placement: getPlacement(),
5103
+ strategy: "fixed",
5104
+ middleware: [
5105
+ offset2(isSubmenu ? 0 : 4),
5106
+ flip2(),
5107
+ shift2({ padding: 4 }),
5108
+ size2({
5109
+ apply({ availableWidth, availableHeight, elements }) {
5110
+ Object.assign(elements.floating.style, {
5111
+ maxWidth: `${Math.max(0, availableWidth) - 4}px`,
5112
+ maxHeight: `${Math.max(0, availableHeight) - 4}px`
5113
+ });
5114
+ }
5115
+ })
5116
+ ]
5117
+ }).then(({ x, y }) => {
5118
+ if (isFirst) {
5119
+ if (!isSubmenu) {
5120
+ Alpine2.nextTick(() => el.focus());
5121
+ listenForTrigger(false);
5122
+ }
5123
+ Alpine2.nextTick(() => {
5124
+ top.addEventListener("contextmenu", onClick);
5125
+ top.addEventListener("click", onClick);
5126
+ el.addEventListener("keydown", onKeyDown);
5127
+ });
5128
+ }
5129
+ Object.assign(el.style, {
5130
+ left: `${x}px`,
5131
+ top: `${y}px`
5132
+ });
5133
+ el.classList.remove("scale-95", "opacity-0");
5134
+ });
4968
5135
  };
4969
5136
  el.classList.remove("hidden");
4970
5137
  el.pauseKeyEvents = false;
4971
- computePosition2(parent, el, {
4972
- placement: getPlacement(),
4973
- strategy: "fixed",
4974
- middleware: [
4975
- offset2(isSubmenu ? 0 : 4),
4976
- flip2(),
4977
- shift2({ padding: 4 }),
4978
- size2({
4979
- apply({ availableWidth, availableHeight, elements }) {
4980
- Object.assign(elements.floating.style, {
4981
- maxWidth: `${Math.max(0, availableWidth) - 4}px`,
4982
- maxHeight: `${Math.max(0, availableHeight) - 4}px`
4983
- });
4984
- }
4985
- })
4986
- ]
4987
- }).then(({ x, y }) => {
4988
- if (!isSubmenu) {
4989
- Alpine2.nextTick(() => el.focus());
4990
- listenForTrigger(false);
4991
- }
4992
- Alpine2.nextTick(() => {
4993
- top.addEventListener("contextmenu", onClick);
4994
- top.addEventListener("click", onClick);
4995
- el.addEventListener("keydown", onKeyDown);
4996
- });
4997
- Object.assign(el.style, {
4998
- left: `${x}px`,
4999
- top: `${y}px`
5000
- });
5001
- el.classList.remove("scale-95", "opacity-0");
5002
- });
5138
+ let firstOpen = true;
5139
+ if (!isSubmenu && menuTrigger._menu_trigger.isDropdown) {
5140
+ autoUpdateCleanup = autoUpdate(parent, el, updatePosition);
5141
+ } else {
5142
+ updatePosition();
5143
+ }
5003
5144
  }
5004
5145
  }
5005
5146
  function openDropdown() {
@@ -5043,6 +5184,7 @@
5043
5184
  }
5044
5185
  el.addEventListener("transitionend", onTransitionEnd);
5045
5186
  cleanup(() => {
5187
+ if (autoUpdateCleanup) autoUpdateCleanup();
5046
5188
  if (menuTrigger) listenForTrigger(false);
5047
5189
  top.removeEventListener("click", onClick);
5048
5190
  top.removeEventListener("contextmenu", onClick);
@@ -5082,7 +5224,10 @@
5082
5224
  "data-[inset=true]:pl-8",
5083
5225
  "[&_svg]:pointer-events-none",
5084
5226
  "[&_svg]:shrink-0",
5085
- "[&_svg:not([class*='size-'])]:size-4"
5227
+ "[&_svg:not([class*='size-'])]:size-4",
5228
+ "[&>a]:no-underline",
5229
+ "[&>a]:text-inherit",
5230
+ "[&>a]:size-full"
5086
5231
  );
5087
5232
  el.setAttribute("role", "menuitem");
5088
5233
  el.setAttribute("tabindex", "-1");
@@ -5496,8 +5641,8 @@
5496
5641
  el.setAttribute("aria-atomic", "false");
5497
5642
  el.setAttribute("data-slot", "notification-overlay");
5498
5643
  const commonListClasses = ["flex", "flex-col", "py-4", "p-10", "gap-4", "overflow-visible", "size-full"];
5499
- const commonTopClasses = ["[mask-image:linear-gradient(to_bottom,black_80%,transparent)]", "row-1"];
5500
- const commonBottomClasses = ["[mask-image:linear-gradient(to_top,black_80%,transparent)]", "row-2"];
5644
+ const commonTopClasses = ["mask-[linear-gradient(to_bottom,black_85%,transparent)]", "row-1"];
5645
+ const commonBottomClasses = ["mask-[linear-gradient(to_top,black_85%,transparent)]", "row-2"];
5501
5646
  const olTopLeft = document.createElement("ol");
5502
5647
  olTopLeft.classList.add(...commonListClasses, ...commonTopClasses, "max-lg:hidden", "items-start");
5503
5648
  olTopLeft.setAttribute("tabindex", "-1");
@@ -11572,7 +11717,7 @@
11572
11717
  }
11573
11718
 
11574
11719
  // package.json
11575
- var version = "1.10.1";
11720
+ var version = "1.11.0";
11576
11721
 
11577
11722
  // src/index.js
11578
11723
  window.Harmonia = { getBreakpointListener, addColorSchemeListener, getColorScheme, removeColorSchemeListener, setColorScheme, getSystemColorScheme, version };
@@ -11581,6 +11726,7 @@
11581
11726
  window.Alpine.plugin(alert_default);
11582
11727
  window.Alpine.plugin(avatar_default);
11583
11728
  window.Alpine.plugin(badge_default);
11729
+ window.Alpine.plugin(breadcrumb_default);
11584
11730
  window.Alpine.plugin(button_default);
11585
11731
  window.Alpine.plugin(calendar_default);
11586
11732
  window.Alpine.plugin(card_default);