@codbex/harmonia 1.2.0 → 1.3.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
@@ -4601,6 +4601,7 @@
4601
4601
  const close = () => {
4602
4602
  el._popover.expanded = false;
4603
4603
  el.addEventListener("click", handler);
4604
+ setAttributes();
4604
4605
  };
4605
4606
  const handler = () => {
4606
4607
  el._popover.expanded = !el._popover.expanded;
@@ -7319,13 +7320,35 @@
7319
7320
  el.classList.add("vbox", "min-h-0", "flex-1", "gap-2", "overflow-auto", "group-data-[collapsed=true]/sidebar:overflow-hidden");
7320
7321
  el.setAttribute("data-slot", "sidebar-content");
7321
7322
  });
7322
- Alpine.directive("h-sidebar-group", (el) => {
7323
+ Alpine.directive("h-sidebar-group", (el, { expression, modifiers }, { effect, evaluate: evaluate2, evaluateLater, Alpine: Alpine2 }) => {
7323
7324
  el.classList.add("relative", "vbox", "w-full", "min-w-0", "p-2");
7324
7325
  el.setAttribute("data-slot", "sidebar-group");
7326
+ el._h_sidebar_group = {
7327
+ collapsable: modifiers.includes("collapsed"),
7328
+ controlId: void 0,
7329
+ controls: void 0,
7330
+ state: Alpine2.reactive({
7331
+ collapsed: evaluate2(expression || "false")
7332
+ })
7333
+ };
7334
+ if (expression) {
7335
+ el._h_sidebar_group.state = Alpine2.reactive({
7336
+ collapsed: evaluate2(expression || "false")
7337
+ });
7338
+ const getCollapsed = evaluateLater(expression);
7339
+ effect(() => {
7340
+ getCollapsed((collapsed) => {
7341
+ el._h_sidebar_group.state.collapsed = collapsed;
7342
+ });
7343
+ });
7344
+ }
7325
7345
  });
7326
- Alpine.directive("h-sidebar-group-label", (el, { modifiers }) => {
7346
+ Alpine.directive("h-sidebar-group-label", (el, { original }, { cleanup }) => {
7347
+ const group = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_sidebar_group"));
7348
+ if (!group) {
7349
+ throw new Error(`${original} must be placed inside a sidebar group`);
7350
+ }
7327
7351
  el.classList.add(
7328
- "text-sidebar-foreground/70",
7329
7352
  "ring-sidebar-ring",
7330
7353
  "flex",
7331
7354
  "h-8",
@@ -7333,7 +7356,6 @@
7333
7356
  "items-center",
7334
7357
  "rounded-md",
7335
7358
  "px-2",
7336
- "text-xs",
7337
7359
  "font-medium",
7338
7360
  "outline-hidden",
7339
7361
  "transition-[margin,opacity]",
@@ -7344,8 +7366,39 @@
7344
7366
  "[&>svg]:shrink-0",
7345
7367
  "group-data-[collapsed=true]/sidebar:!hidden"
7346
7368
  );
7347
- if (modifiers.includes("action")) el.classList.add("hover:bg-secondary-hover", "active:bg-secondary-active");
7348
7369
  el.setAttribute("data-slot", "sidebar-group-label");
7370
+ if (group._h_sidebar_group.collapsable) {
7371
+ el.classList.add("text-sidebar-foreground", "text-sm", "hover:bg-secondary-hover", "active:bg-secondary-active");
7372
+ if (el.hasAttribute("id")) {
7373
+ group._h_sidebar_group.controlId = el.getAttribute("id");
7374
+ } else {
7375
+ group._h_sidebar_group.controlId = `sgl${v4_default()}`;
7376
+ el.setAttribute("id", group._h_sidebar_group.controlId);
7377
+ }
7378
+ group._h_sidebar_group.controls = `sgc${v4_default()}`;
7379
+ el.setAttribute("aria-controls", group._h_sidebar_group.controls);
7380
+ el.setAttribute("aria-expanded", !group._h_sidebar_group.state.collapsed);
7381
+ const handler = () => {
7382
+ group._h_sidebar_group.state.collapsed = !group._h_sidebar_group.state.collapsed;
7383
+ el.setAttribute("aria-expanded", !group._h_sidebar_group.state.collapsed);
7384
+ };
7385
+ el.appendChild(
7386
+ createSvg({
7387
+ icon: ChevronRight,
7388
+ classes: "ml-auto pointer-events-none size-4 shrink-0 transition-transform duration-200 [[aria-expanded=true]>&]:rotate-90",
7389
+ attrs: {
7390
+ "aria-hidden": true,
7391
+ role: "presentation"
7392
+ }
7393
+ })
7394
+ );
7395
+ el.addEventListener("click", handler);
7396
+ cleanup(() => {
7397
+ el.removeEventListener("click", handler);
7398
+ });
7399
+ } else {
7400
+ el.classList.add("text-sidebar-foreground/70", "text-xs");
7401
+ }
7349
7402
  });
7350
7403
  Alpine.directive("h-sidebar-group-action", (el) => {
7351
7404
  el.classList.add(
@@ -7373,36 +7426,92 @@
7373
7426
  "md:after:hidden",
7374
7427
  "group-data-[collapsed=true]/sidebar:hidden"
7375
7428
  );
7429
+ if (el.tagName !== "BUTTON") {
7430
+ el.setAttribute("role", "button");
7431
+ } else {
7432
+ el.setAttribute("type", "button");
7433
+ }
7376
7434
  el.setAttribute("data-slot", "sidebar-group-action");
7377
7435
  });
7378
- Alpine.directive("h-sidebar-group-content", (el) => {
7379
- el.classList.add("w-full", "text-sm");
7436
+ Alpine.directive("h-sidebar-group-content", (el, { original }, { effect }) => {
7437
+ const group = Alpine.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_sidebar_group"));
7438
+ if (!group) {
7439
+ throw new Error(`${original} must be placed inside a sidebar group`);
7440
+ }
7441
+ el.classList.add("w-full", "text-sm", "data-[collapsed=true]:hidden", "group-data-[collapsed=true]/sidebar:!block");
7380
7442
  el.setAttribute("data-slot", "sidebar-group-content");
7443
+ if (group._h_sidebar_group.collapsable) {
7444
+ el.setAttribute("id", group._h_sidebar_group.controls);
7445
+ el.setAttribute("aria-labelledby", group._h_sidebar_group.controlId);
7446
+ el.setAttribute("data-collapsed", group._h_sidebar_group.state.collapsed);
7447
+ effect(() => {
7448
+ el.setAttribute("data-collapsed", group._h_sidebar_group.state.collapsed);
7449
+ });
7450
+ }
7381
7451
  });
7382
- Alpine.directive("h-sidebar-menu", (el) => {
7452
+ Alpine.directive("h-sidebar-menu", (el, { original }) => {
7453
+ if (el.tagName !== "UL") {
7454
+ throw new Error(`${original} must be an ul element`);
7455
+ }
7383
7456
  el.classList.add("vbox", "w-full", "min-w-0", "gap-1");
7384
7457
  el.setAttribute("data-slot", "sidebar-menu");
7385
7458
  });
7386
- Alpine.directive("h-sidebar-menu-item", (el) => {
7387
- el.classList.add("group/menu-item", "relative");
7459
+ Alpine.directive("h-sidebar-menu-item", (el, { original, expression, modifiers }, { effect, evaluate: evaluate2, evaluateLater, Alpine: Alpine2 }) => {
7460
+ if (el.tagName !== "LI") {
7461
+ throw new Error(`${original} must be a li element`);
7462
+ }
7463
+ el._h_sidebar_menu_item = {
7464
+ isSub: false,
7465
+ collapsable: modifiers.includes("collapsed"),
7466
+ controlId: void 0,
7467
+ controls: void 0,
7468
+ state: Alpine2.reactive({
7469
+ collapsed: evaluate2(expression || "false")
7470
+ })
7471
+ };
7472
+ let parent = el.parentElement;
7473
+ while (parent) {
7474
+ if (parent.getAttribute("data-slot") === "sidebar-menu-sub") {
7475
+ el._h_sidebar_menu_item.isSub = true;
7476
+ break;
7477
+ } else if (parent.getAttribute("data-slot") === "sidebar") {
7478
+ break;
7479
+ }
7480
+ parent = parent.parentElement;
7481
+ }
7482
+ if (!el._h_sidebar_menu_item.isSub) {
7483
+ el.classList.add("group/menu-item", "relative");
7484
+ } else {
7485
+ el.classList.add("relative");
7486
+ }
7388
7487
  el.setAttribute("data-slot", "sidebar-menu-item");
7488
+ if (expression) {
7489
+ const getCollapsed = evaluateLater(expression);
7490
+ effect(() => {
7491
+ getCollapsed((collapsed) => {
7492
+ el._h_sidebar_menu_item.state.collapsed = collapsed;
7493
+ });
7494
+ });
7495
+ }
7389
7496
  });
7390
- Alpine.directive("h-sidebar-menu-button", (el) => {
7497
+ Alpine.directive("h-sidebar-menu-button", (el, { original }, { cleanup, Alpine: Alpine2 }) => {
7498
+ if (el.tagName !== "BUTTON" && el.tagName !== "A") {
7499
+ throw new Error(`${original} must be a button or a link`);
7500
+ } else if (el.tagName === "BUTTON") {
7501
+ el.setAttribute("type", "button");
7502
+ }
7503
+ const menuItem = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_sidebar_menu_item"));
7391
7504
  el.classList.add(
7392
- "peer/menu-button",
7393
7505
  "flex",
7394
7506
  "w-full",
7395
7507
  "items-center",
7396
7508
  "gap-2",
7397
7509
  "overflow-hidden",
7398
7510
  "rounded-md",
7399
- "p-2",
7400
- "text-left",
7401
- "text-sm",
7402
7511
  "align-middle",
7512
+ "[&>span]:align-middle",
7403
7513
  "outline-hidden",
7404
7514
  "ring-sidebar-ring",
7405
- "transition-[width,height,padding]",
7406
7515
  "hover:bg-sidebar-secondary",
7407
7516
  "hover:text-sidebar-secondary-foreground",
7408
7517
  "focus-visible:ring-2",
@@ -7410,24 +7519,14 @@
7410
7519
  "active:text-sidebar-primary-foreground",
7411
7520
  "disabled:pointer-events-none",
7412
7521
  "disabled:opacity-50",
7413
- "group-has-data-[sidebar=menu-action]/menu-item:pr-8",
7414
7522
  "aria-disabled:pointer-events-none",
7415
7523
  "aria-disabled:opacity-50",
7416
7524
  "data-[active=true]:bg-sidebar-primary",
7417
- "data-[active=true]:font-medium",
7418
7525
  "data-[active=true]:text-sidebar-primary-foreground",
7419
- "data-[state=open]:hover:bg-sidebar-secondary",
7420
- "data-[state=open]:hover:text-sidebar-secondary-foreground",
7421
- "group-data-[collapsed=true]/sidebar:!size-8",
7422
- "group-data-[collapsed=true]/sidebar:!p-2",
7423
- "group-data-[collapsed=true]/sidebar:[&>*:not(svg:first-child):not([data-slot=menu])]:!hidden",
7424
7526
  "[&>span]:truncate",
7425
- "[&>span]:align-middle",
7426
7527
  "[&>svg]:size-4",
7427
- "[&>svg]:shrink-0",
7428
- "[&>svg:not(:first-child):last-child]:ml-auto"
7528
+ "[&>svg]:shrink-0"
7429
7529
  );
7430
- if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "sidebar-menu-button");
7431
7530
  const sizes = {
7432
7531
  default: ["h-8", "text-sm"],
7433
7532
  sm: ["h-7", "text-xs"],
@@ -7438,22 +7537,77 @@
7438
7537
  el.classList.add(...sizes[size3]);
7439
7538
  }
7440
7539
  }
7441
- if (!el.hasAttribute("data-size")) el.setAttribute("data-size", "default");
7442
- setSize2(el.getAttribute("data-size"));
7540
+ setSize2(el.getAttribute("data-size") || "default");
7541
+ if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "sidebar-menu-button");
7542
+ if (menuItem && menuItem._h_sidebar_menu_item.isSub) {
7543
+ el.classList.add("text-sidebar-foreground", "h-7", "min-w-0", "-translate-x-px", "px-2", "[&>svg:not(:first-child):last-child]:ml-auto", "group-data-[collapsed=true]/sidebar:hidden");
7544
+ if (!el.hasAttribute("data-slot")) el.setAttribute("data-slot", "sidebar-menu-sub-button");
7545
+ } else {
7546
+ el.classList.add(
7547
+ "peer/menu-button",
7548
+ "p-2",
7549
+ "text-left",
7550
+ "text-sm",
7551
+ "duration-200",
7552
+ "transition-[width,height,padding]",
7553
+ "group-has-data-[sidebar=menu-action]/menu-item:pr-8",
7554
+ "data-[active=true]:font-medium",
7555
+ "data-[state=open]:hover:bg-sidebar-secondary",
7556
+ "data-[state=open]:hover:text-sidebar-secondary-foreground",
7557
+ "group-data-[collapsed=true]/sidebar:!size-8",
7558
+ "group-data-[collapsed=true]/sidebar:!p-2",
7559
+ "group-data-[collapsed=true]/sidebar:[&>*:not(svg:first-child):not([data-slot=menu])]:!hidden"
7560
+ );
7561
+ }
7562
+ if (menuItem && menuItem._h_sidebar_menu_item.collapsable) {
7563
+ if (el.hasAttribute("id")) {
7564
+ menuItem._h_sidebar_menu_item.controlId = el.getAttribute("id");
7565
+ } else {
7566
+ menuItem._h_sidebar_menu_item.controlId = `sgl${v4_default()}`;
7567
+ el.setAttribute("id", menuItem._h_sidebar_menu_item.controlId);
7568
+ }
7569
+ menuItem._h_sidebar_menu_item.controls = `sgc${v4_default()}`;
7570
+ el.setAttribute("aria-controls", menuItem._h_sidebar_menu_item.controls);
7571
+ el.setAttribute("aria-expanded", !menuItem._h_sidebar_menu_item.state.collapsed);
7572
+ const handler = () => {
7573
+ menuItem._h_sidebar_menu_item.state.collapsed = !menuItem._h_sidebar_menu_item.state.collapsed;
7574
+ el.setAttribute("aria-expanded", !menuItem._h_sidebar_menu_item.state.collapsed);
7575
+ };
7576
+ el.appendChild(
7577
+ createSvg({
7578
+ icon: ChevronRight,
7579
+ classes: "ml-auto pointer-events-none size-4 shrink-0 transition-transform duration-200 [[aria-expanded=true]>&]:rotate-90",
7580
+ attrs: {
7581
+ "aria-hidden": true,
7582
+ role: "presentation"
7583
+ }
7584
+ })
7585
+ );
7586
+ el.addEventListener("click", handler);
7587
+ cleanup(() => {
7588
+ el.removeEventListener("click", handler);
7589
+ });
7590
+ } else {
7591
+ el.classList.add("[&>svg:not(:first-child):last-child]:ml-auto");
7592
+ }
7443
7593
  });
7444
7594
  Alpine.directive("h-sidebar-menu-action", (el, { modifiers }) => {
7445
7595
  el.classList.add(
7446
7596
  "text-sidebar-foreground",
7447
7597
  "ring-sidebar-ring",
7448
7598
  "hover:bg-sidebar-secondary",
7599
+ "active:bg-sidebar-secondary/70",
7449
7600
  "hover:text-sidebar-secondary-foreground",
7450
7601
  "peer-hover/menu-button:text-sidebar-secondary-foreground",
7602
+ "peer-active/menu-button:text-sidebar-primary-foreground",
7603
+ "peer-data-[active=true]/menu-button:text-sidebar-primary-foreground",
7451
7604
  "absolute",
7452
- "top-1.5",
7453
- "right-1.5",
7605
+ "top-0.5",
7606
+ "right-0.5",
7607
+ "bottom-0.5",
7454
7608
  "flex",
7455
7609
  "aspect-square",
7456
- "w-5",
7610
+ "h-auto",
7457
7611
  "items-center",
7458
7612
  "justify-center",
7459
7613
  "rounded-md",
@@ -7466,40 +7620,23 @@
7466
7620
  "after:absolute",
7467
7621
  "after:-inset-2",
7468
7622
  "md:after:hidden",
7469
- "peer-data-[size=sm]/menu-button:top-1",
7470
- "peer-data-[size=default]/menu-button:top-1.5",
7471
- "peer-data-[size=lg]/menu-button:top-2.5",
7472
7623
  "group-data-[collapsed=true]/sidebar:hidden"
7473
7624
  );
7474
7625
  if (modifiers.includes("autohide")) {
7475
- el.classList.add("peer-data-[active=true]/menu-button:text-sidebar-secondary-foreground", "group-focus-within/menu-item:opacity-100", "group-hover/menu-item:opacity-100", "data-[state=open]:opacity-100", "md:opacity-0");
7626
+ el.classList.add("group-focus-within/menu-item:opacity-100", "group-hover/menu-item:opacity-100", "data-[state=open]:opacity-100", "md:opacity-0");
7627
+ }
7628
+ if (el.tagName !== "BUTTON") {
7629
+ el.setAttribute("role", "button");
7630
+ } else {
7631
+ el.setAttribute("type", "button");
7476
7632
  }
7477
7633
  el.setAttribute("data-slot", "sidebar-menu-action");
7478
7634
  });
7479
- Alpine.directive("h-sidebar-menu-badge", (el) => {
7480
- el.classList.add(
7481
- "text-sidebar-foreground",
7482
- "pointer-events-none",
7483
- "absolute",
7484
- "right-1.5",
7485
- "flex",
7486
- "h-5",
7487
- "min-w-5",
7488
- "items-center",
7489
- "justify-center",
7490
- "rounded-md",
7491
- "px-1",
7492
- "text-xs",
7493
- "font-medium",
7494
- "tabular-nums",
7495
- "select-none",
7496
- "peer-hover/menu-button:text-sidebar-secondary-foreground",
7497
- "peer-data-[active=true]/menu-button:text-sidebar-primary-foreground",
7498
- "peer-data-[size=sm]/menu-button:top-1",
7499
- "peer-data-[size=default]/menu-button:top-1.5",
7500
- "peer-data-[size=lg]/menu-button:top-2.5",
7501
- "group-data-[collapsed=true]/sidebar:hidden"
7502
- );
7635
+ Alpine.directive("h-sidebar-menu-badge", (el, { original }) => {
7636
+ if (el.tagName !== "SPAN") {
7637
+ throw new Error(`${original} must be a span element`);
7638
+ }
7639
+ el.classList.add("flex-1", "pointer-events-none", "flex", "h-full", "min-w-min", "items-center", "justify-end", "text-xs", "font-medium", "tabular-nums", "select-none", "group-data-[collapsed=true]/sidebar:hidden");
7503
7640
  el.setAttribute("data-slot", "sidebar-menu-badge");
7504
7641
  });
7505
7642
  Alpine.directive("h-sidebar-menu-skeleton", (el, { modifiers }) => {
@@ -7520,64 +7657,27 @@
7520
7657
  el.setAttribute("data-slot", "sidebar-separator");
7521
7658
  el.setAttribute("role", "none");
7522
7659
  });
7523
- Alpine.directive("h-sidebar-menu-sub", (el, { modifiers }) => {
7524
- el.classList.add("vbox", "min-w-0", "translate-x-px", "gap-1", "py-0.5", "group-data-[collapsed=true]/sidebar:!hidden");
7525
- if (!modifiers.includes("flat")) {
7526
- el.classList.add("border-sidebar-border", "mx-3.5", "border-l", "px-2.5");
7660
+ Alpine.directive("h-sidebar-menu-sub", (el, { original }, { effect, Alpine: Alpine2 }) => {
7661
+ if (el.tagName !== "UL") {
7662
+ throw new Error(`${original} must be an ul element`);
7663
+ }
7664
+ const menuItem = Alpine2.findClosest(el.parentElement, (parent) => parent.hasOwnProperty("_h_sidebar_menu_item"));
7665
+ if (!menuItem) {
7666
+ throw new Error(`${original} must be placed inside a sidebar menu item`);
7667
+ }
7668
+ el.classList.add("vbox", "min-w-0", "translate-x-px", "gap-1", "pl-2.5", "py-0.5", "ml-3.5", "data-[collapsed=true]:!hidden", "group-data-[collapsed=true]/sidebar:!hidden");
7669
+ if (el.getAttribute("data-line") !== "false") {
7670
+ el.classList.add("border-sidebar-border", "border-l");
7527
7671
  }
7528
7672
  el.setAttribute("data-slot", "sidebar-menu-sub");
7529
- });
7530
- Alpine.directive("h-sidebar-menu-sub-item", (el) => {
7531
- el.classList.add("group/menu-sub-item", "relative");
7532
- el.setAttribute("data-slot", "sidebar-menu-sub-item");
7533
- });
7534
- Alpine.directive("h-sidebar-menu-sub-button", (el) => {
7535
- el.classList.add(
7536
- "text-sidebar-foreground",
7537
- "ring-sidebar-ring",
7538
- "hover:bg-sidebar-secondary",
7539
- "hover:text-sidebar-secondary-foreground",
7540
- "active:bg-primary-secondary",
7541
- "active:text-sidebar-primary-foreground",
7542
- "[&>svg]:text-sidebar-secondary-foreground",
7543
- "flex",
7544
- "h-7",
7545
- "w-full",
7546
- "min-w-0",
7547
- "-translate-x-px",
7548
- "items-center",
7549
- "gap-2",
7550
- "overflow-hidden",
7551
- "rounded-md",
7552
- "px-2",
7553
- "align-middle",
7554
- "outline-hidden",
7555
- "focus-visible:ring-2",
7556
- "disabled:pointer-events-none",
7557
- "disabled:opacity-50",
7558
- "aria-disabled:pointer-events-none",
7559
- "aria-disabled:opacity-50",
7560
- "[&>span]:truncate",
7561
- "[&>span]:align-middle",
7562
- "[&>svg]:size-4",
7563
- "[&>svg]:shrink-0",
7564
- "[&>svg:not(:first-child):last-child]:ml-auto",
7565
- "data-[active=true]:bg-sidebar-primary",
7566
- "data-[active=true]:text-sidebar-primary-foreground",
7567
- "group-data-[collapsed=true]/sidebar:hidden"
7568
- );
7569
- el.setAttribute("data-slot", "sidebar-menu-sub-button");
7570
- const sizes = {
7571
- sm: ["text-xs"],
7572
- md: ["text-sm"]
7573
- };
7574
- function setSize2(size3) {
7575
- if (sizes.hasOwnProperty(size3)) {
7576
- el.classList.add(...sizes[size3]);
7577
- }
7673
+ if (menuItem._h_sidebar_menu_item.collapsable) {
7674
+ el.setAttribute("id", menuItem._h_sidebar_menu_item.controls);
7675
+ el.setAttribute("aria-labelledby", menuItem._h_sidebar_menu_item.controlId);
7676
+ el.setAttribute("data-collapsed", menuItem._h_sidebar_menu_item.state.collapsed);
7677
+ effect(() => {
7678
+ el.setAttribute("data-collapsed", menuItem._h_sidebar_menu_item.state.collapsed);
7679
+ });
7578
7680
  }
7579
- if (!el.hasAttribute("data-size")) el.setAttribute("data-size", "md");
7580
- setSize2(el.getAttribute("data-size"));
7581
7681
  });
7582
7682
  Alpine.directive("h-sidebar-footer", (el) => {
7583
7683
  el.classList.add("vbox", "gap-2", "px-2", "h-12", "justify-center", "border-t");
@@ -9891,7 +9991,7 @@
9891
9991
  }
9892
9992
 
9893
9993
  // package.json
9894
- var version = "1.2.0";
9994
+ var version = "1.3.0";
9895
9995
 
9896
9996
  // src/index.js
9897
9997
  window.Harmonia = { getBreakpointListener, addColorSchemeListener, getColorScheme, removeColorSchemeListener, setColorScheme, version };