@helixui/library 0.3.1 → 0.3.2
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/custom-elements.json +2330 -1860
- package/dist/components/hx-action-bar/hx-action-bar.d.ts +3 -1
- package/dist/components/hx-action-bar/hx-action-bar.d.ts.map +1 -1
- package/dist/components/hx-action-bar/index.js +1 -1
- package/dist/components/hx-badge/hx-badge.d.ts +8 -0
- package/dist/components/hx-badge/hx-badge.d.ts.map +1 -1
- package/dist/components/hx-badge/hx-badge.styles.d.ts.map +1 -1
- package/dist/components/hx-badge/index.d.ts +1 -0
- package/dist/components/hx-badge/index.d.ts.map +1 -1
- package/dist/components/hx-badge/index.js +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts +0 -25
- package/dist/components/hx-breadcrumb/hx-breadcrumb.d.ts.map +1 -1
- package/dist/components/hx-breadcrumb/index.js +1 -1
- package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
- package/dist/components/hx-button/index.js +1 -1
- package/dist/components/hx-button-group/hx-button-group.d.ts +3 -1
- package/dist/components/hx-button-group/hx-button-group.d.ts.map +1 -1
- package/dist/components/hx-button-group/index.js +1 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts +3 -1
- package/dist/components/hx-checkbox-group/hx-checkbox-group.d.ts.map +1 -1
- package/dist/components/hx-checkbox-group/index.js +1 -1
- package/dist/components/hx-container/hx-container.d.ts +12 -0
- package/dist/components/hx-container/hx-container.d.ts.map +1 -1
- package/dist/components/hx-container/hx-container.styles.d.ts.map +1 -1
- package/dist/components/hx-container/index.d.ts +1 -0
- package/dist/components/hx-container/index.d.ts.map +1 -1
- package/dist/components/hx-container/index.js +1 -1
- package/dist/components/hx-copy-button/hx-copy-button.d.ts +7 -0
- package/dist/components/hx-copy-button/hx-copy-button.d.ts.map +1 -1
- package/dist/components/hx-drawer/hx-drawer.d.ts +1 -1
- package/dist/components/hx-drawer/index.js +1 -1
- package/dist/components/hx-icon-button/hx-icon-button.d.ts +87 -0
- package/dist/components/hx-icon-button/hx-icon-button.d.ts.map +1 -0
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts +2 -0
- package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -0
- package/dist/components/hx-icon-button/index.d.ts +2 -0
- package/dist/components/hx-icon-button/index.d.ts.map +1 -0
- package/dist/components/hx-icon-button/index.js +5 -0
- package/dist/components/hx-icon-button/index.js.map +1 -0
- package/dist/components/hx-image/index.js +1 -1
- package/dist/components/hx-number-input/hx-number-input.d.ts +2 -2
- package/dist/components/hx-number-input/hx-number-input.d.ts.map +1 -1
- package/dist/components/hx-pagination/hx-pagination.d.ts +2 -0
- package/dist/components/hx-pagination/hx-pagination.d.ts.map +1 -1
- package/dist/components/hx-pagination/index.d.ts +1 -0
- package/dist/components/hx-pagination/index.d.ts.map +1 -1
- package/dist/components/hx-prose/index.js +1 -1
- package/dist/components/hx-radio-group/hx-radio-group.d.ts +31 -10
- package/dist/components/hx-radio-group/hx-radio-group.d.ts.map +1 -1
- package/dist/components/hx-radio-group/hx-radio.styles.d.ts.map +1 -1
- package/dist/components/hx-radio-group/index.js +1 -1
- package/dist/components/hx-slider/hx-slider.d.ts +6 -4
- package/dist/components/hx-slider/hx-slider.d.ts.map +1 -1
- package/dist/components/hx-slider/index.js +1 -1
- package/dist/components/hx-spinner/hx-spinner.d.ts +12 -6
- package/dist/components/hx-spinner/hx-spinner.d.ts.map +1 -1
- package/dist/components/hx-spinner/index.d.ts +1 -0
- package/dist/components/hx-spinner/index.d.ts.map +1 -1
- package/dist/components/hx-stack/hx-stack.d.ts +20 -0
- package/dist/components/hx-stack/hx-stack.d.ts.map +1 -1
- package/dist/components/hx-stack/index.js +1 -1
- package/dist/components/hx-steps/hx-step.d.ts +8 -0
- package/dist/components/hx-steps/hx-step.d.ts.map +1 -1
- package/dist/components/hx-structured-list/index.js +1 -1
- package/dist/components/hx-switch/hx-switch.d.ts +2 -2
- package/dist/components/hx-switch/hx-switch.d.ts.map +1 -1
- package/dist/components/hx-tag/index.d.ts +3 -0
- package/dist/components/hx-tag/index.d.ts.map +1 -1
- package/dist/components/hx-text/hx-text.d.ts +0 -2
- package/dist/components/hx-text/hx-text.d.ts.map +1 -1
- package/dist/components/hx-textarea/hx-textarea.d.ts +7 -0
- package/dist/components/hx-textarea/hx-textarea.d.ts.map +1 -1
- package/dist/components/hx-textarea/index.js +1 -1
- package/dist/components/hx-theme/hx-theme.d.ts +4 -0
- package/dist/components/hx-theme/hx-theme.d.ts.map +1 -1
- package/dist/components/hx-theme/index.d.ts +3 -1
- package/dist/components/hx-theme/index.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts +2 -2
- package/dist/components/hx-toggle-button/hx-toggle-button.d.ts.map +1 -1
- package/dist/components/hx-toggle-button/index.js +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.d.ts +29 -10
- package/dist/components/hx-tree-view/hx-tree-item.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-item.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.d.ts +22 -2
- package/dist/components/hx-tree-view/hx-tree-view.d.ts.map +1 -1
- package/dist/components/hx-tree-view/hx-tree-view.styles.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.d.ts +6 -1
- package/dist/components/hx-tree-view/index.d.ts.map +1 -1
- package/dist/components/hx-tree-view/index.js +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -105
- package/dist/index.js.map +1 -1
- package/dist/shared/{hx-action-bar-D43v5rA2.js → hx-action-bar-B4i9tBCP.js} +71 -61
- package/dist/shared/hx-action-bar-B4i9tBCP.js.map +1 -0
- package/dist/shared/{hx-badge-DYB1Pnym.js → hx-badge-CjT0d8NK.js} +9 -2
- package/dist/shared/hx-badge-CjT0d8NK.js.map +1 -0
- package/dist/shared/{hx-breadcrumb-item-TKRcrMYc.js → hx-breadcrumb-item-DtSxRZ_W.js} +25 -18
- package/dist/shared/hx-breadcrumb-item-DtSxRZ_W.js.map +1 -0
- package/dist/shared/{hx-button-SAbf4_jC.js → hx-button-CtiJsmOg.js} +31 -29
- package/dist/shared/hx-button-CtiJsmOg.js.map +1 -0
- package/dist/shared/{hx-button-group-DET_Pkxt.js → hx-button-group-BMV5qFs4.js} +19 -13
- package/dist/shared/{hx-button-group-DET_Pkxt.js.map → hx-button-group-BMV5qFs4.js.map} +1 -1
- package/dist/shared/{hx-checkbox-group-CIIijwmc.js → hx-checkbox-group-DTS9iT4b.js} +26 -20
- package/dist/shared/hx-checkbox-group-DTS9iT4b.js.map +1 -0
- package/dist/shared/{hx-container-BXZBaOGG.js → hx-container-DLUKnTi9.js} +9 -8
- package/dist/shared/hx-container-DLUKnTi9.js.map +1 -0
- package/dist/shared/hx-copy-button-BXL1xkxb.js.map +1 -1
- package/dist/shared/{hx-drawer-CenIAGuR.js → hx-drawer-bTF0nbrg.js} +2 -2
- package/dist/shared/hx-drawer-bTF0nbrg.js.map +1 -0
- package/dist/shared/hx-icon-button-C_fsUJW4.js +257 -0
- package/dist/shared/hx-icon-button-C_fsUJW4.js.map +1 -0
- package/dist/shared/{hx-image-CzkOEeO4.js → hx-image-xyb_tHCR.js} +2 -2
- package/dist/shared/hx-image-xyb_tHCR.js.map +1 -0
- package/dist/shared/hx-number-input-CS6_w1lT.js.map +1 -1
- package/dist/shared/hx-pagination-DNFgXQm3.js.map +1 -1
- package/dist/shared/{hx-prose-BUkZ8rB3.js → hx-prose-DZh2KrMb.js} +10 -7
- package/dist/shared/{hx-prose-BUkZ8rB3.js.map → hx-prose-DZh2KrMb.js.map} +1 -1
- package/dist/shared/{hx-radio-reSaVmIB.js → hx-radio-CGtFKls2.js} +42 -14
- package/dist/shared/hx-radio-CGtFKls2.js.map +1 -0
- package/dist/shared/{hx-slider-CzHOl3Ur.js → hx-slider-Duzmuid9.js} +12 -8
- package/dist/shared/hx-slider-Duzmuid9.js.map +1 -0
- package/dist/shared/hx-spinner-BOApJ-g9.js.map +1 -1
- package/dist/shared/{hx-stack-C3xUwi6-.js → hx-stack-CfoW7jU7.js} +21 -1
- package/dist/shared/{hx-stack-C3xUwi6-.js.map → hx-stack-CfoW7jU7.js.map} +1 -1
- package/dist/shared/hx-step-nMT0fHEn.js.map +1 -1
- package/dist/shared/{hx-structured-list-DKborM60.js → hx-structured-list-CMja1VXz.js} +5 -5
- package/dist/shared/{hx-structured-list-DKborM60.js.map → hx-structured-list-CMja1VXz.js.map} +1 -1
- package/dist/shared/hx-switch-BPvIcDpM.js.map +1 -1
- package/dist/shared/hx-text-NjKoQATI.js.map +1 -1
- package/dist/shared/{hx-textarea-BLcReynr.js → hx-textarea-B_nmxzhC.js} +12 -8
- package/dist/shared/hx-textarea-B_nmxzhC.js.map +1 -0
- package/dist/shared/hx-theme-6GDoUG8j.js.map +1 -1
- package/dist/shared/{hx-toggle-button---Z4zvmn.js → hx-toggle-button--xCXWRJW.js} +3 -3
- package/dist/shared/{hx-toggle-button---Z4zvmn.js.map → hx-toggle-button--xCXWRJW.js.map} +1 -1
- package/dist/shared/{hx-tree-item-CIo3ek2M.js → hx-tree-item-Cesh_du5.js} +170 -148
- package/dist/shared/hx-tree-item-Cesh_du5.js.map +1 -0
- package/package.json +7 -1
- package/dist/shared/hx-action-bar-D43v5rA2.js.map +0 -1
- package/dist/shared/hx-badge-DYB1Pnym.js.map +0 -1
- package/dist/shared/hx-breadcrumb-item-TKRcrMYc.js.map +0 -1
- package/dist/shared/hx-button-SAbf4_jC.js.map +0 -1
- package/dist/shared/hx-checkbox-group-CIIijwmc.js.map +0 -1
- package/dist/shared/hx-container-BXZBaOGG.js.map +0 -1
- package/dist/shared/hx-drawer-CenIAGuR.js.map +0 -1
- package/dist/shared/hx-image-CzkOEeO4.js.map +0 -1
- package/dist/shared/hx-radio-reSaVmIB.js.map +0 -1
- package/dist/shared/hx-slider-CzHOl3Ur.js.map +0 -1
- package/dist/shared/hx-textarea-BLcReynr.js.map +0 -1
- package/dist/shared/hx-tree-item-CIo3ek2M.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
import { property as
|
|
3
|
-
import { tokenStyles as
|
|
4
|
-
const
|
|
1
|
+
import { css as b, LitElement as g, nothing as m, html as f } from "lit";
|
|
2
|
+
import { property as p, state as c, customElement as _ } from "lit/decorators.js";
|
|
3
|
+
import { tokenStyles as y } from "@helixui/tokens/lit";
|
|
4
|
+
const w = b`
|
|
5
5
|
:host {
|
|
6
6
|
display: block;
|
|
7
|
+
contain: layout style;
|
|
7
8
|
font-family: var(--hx-tree-font-family, var(--hx-font-family-sans, sans-serif));
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -22,12 +23,12 @@ const y = v`
|
|
|
22
23
|
border-radius: var(--hx-border-radius-sm, 0.25rem);
|
|
23
24
|
}
|
|
24
25
|
`;
|
|
25
|
-
var I = Object.defineProperty, k = Object.getOwnPropertyDescriptor,
|
|
26
|
-
for (var
|
|
27
|
-
(
|
|
28
|
-
return
|
|
26
|
+
var I = Object.defineProperty, k = Object.getOwnPropertyDescriptor, x = (t, e, r, i) => {
|
|
27
|
+
for (var s = i > 1 ? void 0 : i ? k(e, r) : e, n = t.length - 1, o; n >= 0; n--)
|
|
28
|
+
(o = t[n]) && (s = (i ? o(e, r, s) : o(s)) || s);
|
|
29
|
+
return i && s && I(e, r, s), s;
|
|
29
30
|
};
|
|
30
|
-
let
|
|
31
|
+
let h = class extends g {
|
|
31
32
|
constructor() {
|
|
32
33
|
super(...arguments), this.label = "", this.selection = "none", this._currentIndex = 0;
|
|
33
34
|
}
|
|
@@ -39,35 +40,35 @@ let d = class extends b {
|
|
|
39
40
|
_getVisibleItems() {
|
|
40
41
|
return this._collectVisibleItems(this);
|
|
41
42
|
}
|
|
42
|
-
_collectVisibleItems(
|
|
43
|
-
const
|
|
44
|
-
for (const r of Array.from(
|
|
43
|
+
_collectVisibleItems(t) {
|
|
44
|
+
const e = [];
|
|
45
|
+
for (const r of Array.from(t.children))
|
|
45
46
|
if (r.tagName.toLowerCase() === "hx-tree-item") {
|
|
46
|
-
const
|
|
47
|
-
|
|
47
|
+
const i = r;
|
|
48
|
+
e.push(i), i.expanded && e.push(...this._collectVisibleItems(i));
|
|
48
49
|
} else
|
|
49
|
-
|
|
50
|
-
return
|
|
50
|
+
e.push(...this._collectVisibleItems(r));
|
|
51
|
+
return e;
|
|
51
52
|
}
|
|
52
53
|
_getSelectedItems() {
|
|
53
54
|
return Array.from(this.querySelectorAll("hx-tree-item[selected]"));
|
|
54
55
|
}
|
|
55
|
-
_focusItem(
|
|
56
|
-
var
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
const r = Math.max(0, Math.min(
|
|
60
|
-
this._currentIndex = r, (
|
|
56
|
+
_focusItem(t) {
|
|
57
|
+
var i;
|
|
58
|
+
const e = this._getVisibleItems();
|
|
59
|
+
if (e.length === 0) return;
|
|
60
|
+
const r = Math.max(0, Math.min(t, e.length - 1));
|
|
61
|
+
this._currentIndex = r, (i = e[r]) == null || i.focus();
|
|
61
62
|
}
|
|
62
63
|
// ─── Event Handling ───
|
|
63
|
-
_handleTreeItemSelect(
|
|
64
|
-
const r =
|
|
64
|
+
_handleTreeItemSelect(t) {
|
|
65
|
+
const r = t.detail.item;
|
|
65
66
|
if (this.selection !== "none") {
|
|
66
67
|
if (this.selection === "single") {
|
|
67
|
-
const
|
|
68
|
-
this._getSelectedItems().forEach((
|
|
69
|
-
|
|
70
|
-
}), r.selected = !
|
|
68
|
+
const i = r.selected;
|
|
69
|
+
this._getSelectedItems().forEach((s) => {
|
|
70
|
+
s.selected = !1;
|
|
71
|
+
}), r.selected = !i;
|
|
71
72
|
} else this.selection === "multiple" && (r.selected = !r.selected);
|
|
72
73
|
this.dispatchEvent(
|
|
73
74
|
new CustomEvent("hx-select", {
|
|
@@ -78,74 +79,74 @@ let d = class extends b {
|
|
|
78
79
|
);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
|
-
_handleKeyDown(
|
|
82
|
-
var
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
82
|
+
_handleKeyDown(t) {
|
|
83
|
+
var s, n, o;
|
|
84
|
+
const e = this._getVisibleItems();
|
|
85
|
+
if (e.length === 0) return;
|
|
85
86
|
let r = this._currentIndex;
|
|
86
|
-
const
|
|
87
|
-
for (let
|
|
88
|
-
if (
|
|
89
|
-
r =
|
|
87
|
+
const i = document.activeElement;
|
|
88
|
+
for (let a = 0; a < e.length; a++)
|
|
89
|
+
if (e[a] === i || (n = (s = e[a]) == null ? void 0 : s.shadowRoot) != null && n.activeElement) {
|
|
90
|
+
r = a;
|
|
90
91
|
break;
|
|
91
92
|
}
|
|
92
|
-
switch (
|
|
93
|
+
switch (t.key) {
|
|
93
94
|
case "ArrowDown": {
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
this._focusItem(
|
|
95
|
+
t.preventDefault();
|
|
96
|
+
const a = r < e.length - 1 ? r + 1 : 0;
|
|
97
|
+
this._focusItem(a);
|
|
97
98
|
break;
|
|
98
99
|
}
|
|
99
100
|
case "ArrowUp": {
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
this._focusItem(
|
|
101
|
+
t.preventDefault();
|
|
102
|
+
const a = r > 0 ? r - 1 : e.length - 1;
|
|
103
|
+
this._focusItem(a);
|
|
103
104
|
break;
|
|
104
105
|
}
|
|
105
106
|
case "ArrowLeft": {
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
if (!
|
|
109
|
-
if (
|
|
110
|
-
|
|
107
|
+
t.preventDefault();
|
|
108
|
+
const a = e[r];
|
|
109
|
+
if (!a) break;
|
|
110
|
+
if (a.expanded && a.hasChildItems)
|
|
111
|
+
a.expanded = !1;
|
|
111
112
|
else {
|
|
112
|
-
const
|
|
113
|
-
if (
|
|
114
|
-
const
|
|
115
|
-
|
|
113
|
+
const u = (o = a.parentElement) == null ? void 0 : o.closest("hx-tree-item");
|
|
114
|
+
if (u) {
|
|
115
|
+
const v = e.indexOf(u);
|
|
116
|
+
v >= 0 && this._focusItem(v);
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
break;
|
|
119
120
|
}
|
|
120
121
|
case "ArrowRight": {
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
if (!
|
|
124
|
-
|
|
122
|
+
t.preventDefault();
|
|
123
|
+
const a = e[r];
|
|
124
|
+
if (!a) break;
|
|
125
|
+
a.hasChildItems && (a.expanded ? this._focusItem(r + 1) : a.expanded = !0);
|
|
125
126
|
break;
|
|
126
127
|
}
|
|
127
128
|
case "Home": {
|
|
128
|
-
|
|
129
|
+
t.preventDefault(), this._focusItem(0);
|
|
129
130
|
break;
|
|
130
131
|
}
|
|
131
132
|
case "End": {
|
|
132
|
-
|
|
133
|
+
t.preventDefault(), this._focusItem(e.length - 1);
|
|
133
134
|
break;
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
|
-
_handleFocusIn(
|
|
138
|
-
|
|
138
|
+
_handleFocusIn(t) {
|
|
139
|
+
t.target === t.currentTarget && this._focusItem(this._currentIndex);
|
|
139
140
|
}
|
|
140
141
|
// ─── Render ───
|
|
141
142
|
render() {
|
|
142
|
-
return
|
|
143
|
+
return f`
|
|
143
144
|
<div
|
|
144
145
|
part="tree"
|
|
145
146
|
class="tree"
|
|
146
147
|
role="tree"
|
|
147
148
|
tabindex="0"
|
|
148
|
-
aria-label=${this.label ||
|
|
149
|
+
aria-label=${this.label || m}
|
|
149
150
|
aria-multiselectable=${this.selection === "multiple" ? "true" : "false"}
|
|
150
151
|
@hx-tree-item-select=${this._handleTreeItemSelect}
|
|
151
152
|
@keydown=${this._handleKeyDown}
|
|
@@ -156,22 +157,23 @@ let d = class extends b {
|
|
|
156
157
|
`;
|
|
157
158
|
}
|
|
158
159
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
],
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
],
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
],
|
|
169
|
-
|
|
160
|
+
h.styles = [y, w];
|
|
161
|
+
x([
|
|
162
|
+
p({ type: String, reflect: !0 })
|
|
163
|
+
], h.prototype, "label", 2);
|
|
164
|
+
x([
|
|
165
|
+
p({ type: String, reflect: !0 })
|
|
166
|
+
], h.prototype, "selection", 2);
|
|
167
|
+
x([
|
|
168
|
+
c()
|
|
169
|
+
], h.prototype, "_currentIndex", 2);
|
|
170
|
+
h = x([
|
|
170
171
|
_("hx-tree-view")
|
|
171
|
-
],
|
|
172
|
-
const C =
|
|
172
|
+
], h);
|
|
173
|
+
const C = b`
|
|
173
174
|
:host {
|
|
174
175
|
display: block;
|
|
176
|
+
contain: layout style;
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
* {
|
|
@@ -327,6 +329,9 @@ const C = v`
|
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
@media (prefers-reduced-motion: reduce) {
|
|
332
|
+
.item-row,
|
|
333
|
+
.expand-btn,
|
|
334
|
+
.expand-btn svg,
|
|
330
335
|
.children {
|
|
331
336
|
transition: none;
|
|
332
337
|
}
|
|
@@ -336,54 +341,59 @@ const C = v`
|
|
|
336
341
|
overflow: hidden;
|
|
337
342
|
}
|
|
338
343
|
`;
|
|
339
|
-
var S = Object.defineProperty, E = Object.getOwnPropertyDescriptor,
|
|
340
|
-
for (var
|
|
341
|
-
(
|
|
342
|
-
return
|
|
344
|
+
var S = Object.defineProperty, E = Object.getOwnPropertyDescriptor, d = (t, e, r, i) => {
|
|
345
|
+
for (var s = i > 1 ? void 0 : i ? E(e, r) : e, n = t.length - 1, o; n >= 0; n--)
|
|
346
|
+
(o = t[n]) && (s = (i ? o(e, r, s) : o(s)) || s);
|
|
347
|
+
return i && s && S(e, r, s), s;
|
|
343
348
|
};
|
|
344
|
-
let
|
|
349
|
+
let l = class extends g {
|
|
345
350
|
constructor() {
|
|
346
|
-
super(...arguments), this.expanded = !1, this.selected = !1, this.disabled = !1, this._hasChildren = !1;
|
|
351
|
+
super(...arguments), this.expanded = !1, this.selected = !1, this.disabled = !1, this._hasChildren = !1, this._level = 1, this._posInSet = 1, this._setSize = 1, this._selectable = !1;
|
|
347
352
|
}
|
|
348
353
|
// ─── Computed ARIA ───
|
|
349
|
-
/**
|
|
354
|
+
/**
|
|
355
|
+
* Whether this item has slotted children.
|
|
356
|
+
* @returns True if one or more elements are assigned to the children slot.
|
|
357
|
+
*/
|
|
350
358
|
get hasChildItems() {
|
|
351
359
|
return this._hasChildren;
|
|
352
360
|
}
|
|
353
|
-
/**
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
361
|
+
/**
|
|
362
|
+
* Recompute all cached ARIA metadata in a single DOM pass.
|
|
363
|
+
* Called on connect, slotchange, and whenever structural context may change.
|
|
364
|
+
*/
|
|
365
|
+
_updateAriaMetadata() {
|
|
366
|
+
let t = 1, e = this.parentElement;
|
|
367
|
+
for (; e; )
|
|
368
|
+
e.tagName.toLowerCase() === "hx-tree-item" && t++, e = e.parentElement;
|
|
369
|
+
this._level = t;
|
|
370
|
+
const r = this.parentElement;
|
|
371
|
+
if (r) {
|
|
372
|
+
const s = Array.from(r.children).filter(
|
|
373
|
+
(n) => n.tagName.toLowerCase() === "hx-tree-item"
|
|
374
|
+
);
|
|
375
|
+
this._posInSet = s.indexOf(this) + 1, this._setSize = s.length;
|
|
376
|
+
} else
|
|
377
|
+
this._posInSet = 1, this._setSize = 1;
|
|
378
|
+
const i = this.closest("hx-tree-view");
|
|
379
|
+
if (i) {
|
|
380
|
+
const s = i.getAttribute("selection");
|
|
381
|
+
this._selectable = s === "single" || s === "multiple";
|
|
382
|
+
} else
|
|
383
|
+
this._selectable = !1;
|
|
384
|
+
}
|
|
385
|
+
// ─── Lifecycle ───
|
|
386
|
+
connectedCallback() {
|
|
387
|
+
super.connectedCallback(), this._updateAriaMetadata();
|
|
378
388
|
}
|
|
379
389
|
// ─── Children Detection ───
|
|
380
|
-
_handleChildrenSlotChange(
|
|
381
|
-
const
|
|
382
|
-
this._hasChildren =
|
|
390
|
+
_handleChildrenSlotChange(t) {
|
|
391
|
+
const e = t.target;
|
|
392
|
+
this._hasChildren = e.assignedElements().length > 0, this._updateAriaMetadata();
|
|
383
393
|
}
|
|
384
394
|
// ─── Event Handlers ───
|
|
385
|
-
_handleExpandClick(
|
|
386
|
-
|
|
395
|
+
_handleExpandClick(t) {
|
|
396
|
+
t.stopPropagation(), !this.disabled && (this.expanded = !this.expanded);
|
|
387
397
|
}
|
|
388
398
|
_handleRowClick() {
|
|
389
399
|
this.disabled || this.dispatchEvent(
|
|
@@ -394,31 +404,31 @@ let o = class extends b {
|
|
|
394
404
|
})
|
|
395
405
|
);
|
|
396
406
|
}
|
|
397
|
-
_handleKeyDown(
|
|
407
|
+
_handleKeyDown(t) {
|
|
398
408
|
if (!this.disabled)
|
|
399
|
-
switch (
|
|
409
|
+
switch (t.key) {
|
|
400
410
|
case "ArrowRight":
|
|
401
|
-
|
|
411
|
+
t.preventDefault(), this._hasChildren && !this.expanded && (this.expanded = !0);
|
|
402
412
|
break;
|
|
403
413
|
case "ArrowLeft":
|
|
404
|
-
|
|
414
|
+
t.preventDefault(), this._hasChildren && this.expanded && (this.expanded = !1);
|
|
405
415
|
break;
|
|
406
416
|
case "Enter":
|
|
407
417
|
case " ":
|
|
408
|
-
|
|
418
|
+
t.preventDefault(), this._handleRowClick();
|
|
409
419
|
break;
|
|
410
420
|
}
|
|
411
421
|
}
|
|
412
422
|
// ─── Public API ───
|
|
413
423
|
/** Focus this item's interactive row element. */
|
|
414
424
|
focus() {
|
|
415
|
-
var
|
|
416
|
-
const
|
|
417
|
-
|
|
425
|
+
var e;
|
|
426
|
+
const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector(".item-row");
|
|
427
|
+
t == null || t.focus();
|
|
418
428
|
}
|
|
419
429
|
// ─── Render ───
|
|
420
430
|
_renderExpandIcon() {
|
|
421
|
-
return this._hasChildren ?
|
|
431
|
+
return this._hasChildren ? f`
|
|
422
432
|
<button
|
|
423
433
|
part="expand-icon"
|
|
424
434
|
class="expand-btn"
|
|
@@ -430,23 +440,23 @@ let o = class extends b {
|
|
|
430
440
|
<polyline points="6 4 10 8 6 12" />
|
|
431
441
|
</svg>
|
|
432
442
|
</button>
|
|
433
|
-
` :
|
|
443
|
+
` : f`<span class="expand-placeholder" aria-hidden="true"></span>`;
|
|
434
444
|
}
|
|
435
445
|
render() {
|
|
436
|
-
const
|
|
437
|
-
return
|
|
446
|
+
const t = this._hasChildren ? String(this.expanded) : m, e = this._selectable ? String(this.selected) : m;
|
|
447
|
+
return f`
|
|
438
448
|
<div part="item" class="item">
|
|
439
449
|
<div
|
|
440
450
|
part="row"
|
|
441
451
|
class="item-row"
|
|
442
452
|
role="treeitem"
|
|
443
453
|
tabindex="-1"
|
|
444
|
-
aria-expanded=${
|
|
445
|
-
aria-selected=${
|
|
446
|
-
aria-disabled=${this.disabled ? "true" :
|
|
447
|
-
aria-level=${this.
|
|
448
|
-
aria-posinset=${this.
|
|
449
|
-
aria-setsize=${this.
|
|
454
|
+
aria-expanded=${t}
|
|
455
|
+
aria-selected=${e}
|
|
456
|
+
aria-disabled=${this.disabled ? "true" : m}
|
|
457
|
+
aria-level=${this._level}
|
|
458
|
+
aria-posinset=${this._posInSet}
|
|
459
|
+
aria-setsize=${this._setSize}
|
|
450
460
|
@click=${this._handleRowClick}
|
|
451
461
|
@keydown=${this._handleKeyDown}
|
|
452
462
|
>
|
|
@@ -471,24 +481,36 @@ let o = class extends b {
|
|
|
471
481
|
`;
|
|
472
482
|
}
|
|
473
483
|
};
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
],
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
],
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
],
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
],
|
|
487
|
-
|
|
484
|
+
l.styles = [y, C];
|
|
485
|
+
d([
|
|
486
|
+
p({ type: Boolean, reflect: !0 })
|
|
487
|
+
], l.prototype, "expanded", 2);
|
|
488
|
+
d([
|
|
489
|
+
p({ type: Boolean, reflect: !0 })
|
|
490
|
+
], l.prototype, "selected", 2);
|
|
491
|
+
d([
|
|
492
|
+
p({ type: Boolean, reflect: !0 })
|
|
493
|
+
], l.prototype, "disabled", 2);
|
|
494
|
+
d([
|
|
495
|
+
c()
|
|
496
|
+
], l.prototype, "_hasChildren", 2);
|
|
497
|
+
d([
|
|
498
|
+
c()
|
|
499
|
+
], l.prototype, "_level", 2);
|
|
500
|
+
d([
|
|
501
|
+
c()
|
|
502
|
+
], l.prototype, "_posInSet", 2);
|
|
503
|
+
d([
|
|
504
|
+
c()
|
|
505
|
+
], l.prototype, "_setSize", 2);
|
|
506
|
+
d([
|
|
507
|
+
c()
|
|
508
|
+
], l.prototype, "_selectable", 2);
|
|
509
|
+
l = d([
|
|
488
510
|
_("hx-tree-item")
|
|
489
|
-
],
|
|
511
|
+
], l);
|
|
490
512
|
export {
|
|
491
|
-
|
|
492
|
-
|
|
513
|
+
l as H,
|
|
514
|
+
h as a
|
|
493
515
|
};
|
|
494
|
-
//# sourceMappingURL=hx-tree-item-
|
|
516
|
+
//# sourceMappingURL=hx-tree-item-Cesh_du5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hx-tree-item-Cesh_du5.js","sources":["../../src/components/hx-tree-view/hx-tree-view.styles.ts","../../src/components/hx-tree-view/hx-tree-view.ts","../../src/components/hx-tree-view/hx-tree-item.styles.ts","../../src/components/hx-tree-view/hx-tree-item.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixTreeViewStyles = css`\n :host {\n display: block;\n contain: layout style;\n font-family: var(--hx-tree-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n * {\n box-sizing: border-box;\n }\n\n .tree {\n display: block;\n outline: none;\n }\n\n .tree:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTreeViewStyles } from './hx-tree-view.styles.js';\nimport type { HelixTreeItem, HxTreeItemSelectDetail } from './hx-tree-item.js';\n\n/** Selection mode for the tree. */\nexport type TreeSelection = 'none' | 'single' | 'multiple';\n\n/** Detail type for the `hx-select` event. */\nexport interface HxSelectDetail {\n /** The tree item that was selected or deselected. */\n item: HelixTreeItem;\n /** Whether the item is now selected. */\n selected: boolean;\n}\n\n/**\n * A hierarchical tree component for navigating nested data structures.\n * Used in healthcare applications for org charts, ICD-10 code hierarchies, and department navigation.\n *\n * Implements WAI-ARIA tree view pattern with `role=\"tree\"` on the container\n * and `role=\"treeitem\"` on each item. Supports `aria-label` via the `label` property\n * for screen reader identification. Full keyboard navigation: Arrow keys for movement,\n * Enter/Space for selection, Home/End for first/last item.\n *\n * ## Scale Limits\n *\n * This component renders all tree items simultaneously in the DOM. It is suitable for\n * trees with up to ~500 visible items. For large taxonomies (e.g., ICD-10 with 70,000+\n * codes), use async/lazy loading: only render top-level nodes initially and populate\n * child nodes on `hx-select` or expand events. The component exposes the `expanded`\n * property on `hx-tree-item` for programmatic control of subtrees, enabling consumer-level\n * virtualization strategies without requiring changes to this component.\n *\n * @summary Hierarchical tree view with expand/collapse and keyboard navigation.\n *\n * @tag hx-tree-view\n *\n * @slot - Default slot for hx-tree-item elements.\n *\n * @fires {CustomEvent<HxSelectDetail>} hx-select - Dispatched when a tree item is selected or deselected.\n *\n * @csspart tree - The tree container element with role=\"tree\".\n *\n * @cssprop [--hx-tree-font-family=var(--hx-font-family-sans)] - Tree font family.\n */\n@customElement('hx-tree-view')\nexport class HelixTreeView extends LitElement {\n static override styles = [tokenStyles, helixTreeViewStyles];\n\n // ─── Properties ───\n\n /**\n * Accessible label for the tree. Applied as `aria-label` on the tree container.\n * Provides context to screen readers about the tree's purpose.\n * @attr label\n */\n @property({ type: String, reflect: true })\n label = '';\n\n /**\n * Selection mode for the tree.\n * - `none` — items cannot be selected\n * - `single` — only one item can be selected at a time\n * - `multiple` — multiple items can be selected\n * @attr selection\n */\n @property({ type: String, reflect: true })\n selection: TreeSelection = 'none';\n\n // ─── Internal State ───\n\n @state() private _currentIndex = 0;\n\n // ─── Internal Helpers ───\n\n /**\n * Returns a flat ordered list of all visible (not inside a collapsed item) hx-tree-items\n * in depth-first order.\n */\n private _getVisibleItems(): HelixTreeItem[] {\n return this._collectVisibleItems(this);\n }\n\n private _collectVisibleItems(container: Element): HelixTreeItem[] {\n const items: HelixTreeItem[] = [];\n for (const child of Array.from(container.children)) {\n if (child.tagName.toLowerCase() === 'hx-tree-item') {\n const item = child as HelixTreeItem;\n items.push(item);\n if (item.expanded) {\n items.push(...this._collectVisibleItems(item));\n }\n } else {\n items.push(...this._collectVisibleItems(child));\n }\n }\n return items;\n }\n\n private _getSelectedItems(): HelixTreeItem[] {\n return Array.from(this.querySelectorAll<HelixTreeItem>('hx-tree-item[selected]'));\n }\n\n private _focusItem(index: number): void {\n const items = this._getVisibleItems();\n if (items.length === 0) return;\n const clamped = Math.max(0, Math.min(index, items.length - 1));\n this._currentIndex = clamped;\n items[clamped]?.focus();\n }\n\n // ─── Event Handling ───\n\n private _handleTreeItemSelect(e: Event): void {\n const event = e as CustomEvent<HxTreeItemSelectDetail>;\n const item = event.detail.item;\n\n if (this.selection === 'none') return;\n\n if (this.selection === 'single') {\n const wasSelected = item.selected;\n this._getSelectedItems().forEach((i) => {\n i.selected = false;\n });\n item.selected = !wasSelected;\n } else if (this.selection === 'multiple') {\n item.selected = !item.selected;\n }\n\n this.dispatchEvent(\n new CustomEvent<HxSelectDetail>('hx-select', {\n bubbles: true,\n composed: true,\n detail: { item, selected: item.selected },\n }),\n );\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n const items = this._getVisibleItems();\n if (items.length === 0) return;\n\n let currentIndex = this._currentIndex;\n const focused = document.activeElement;\n\n for (let i = 0; i < items.length; i++) {\n if (items[i] === focused || items[i]?.shadowRoot?.activeElement) {\n currentIndex = i;\n break;\n }\n }\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n this._focusItem(next);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n this._focusItem(prev);\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n const currentItem = items[currentIndex];\n if (!currentItem) break;\n if (currentItem.expanded && currentItem.hasChildItems) {\n currentItem.expanded = false;\n } else {\n const parentItem = currentItem.parentElement?.closest('hx-tree-item') as\n | HelixTreeItem\n | undefined;\n if (parentItem) {\n const parentIndex = items.indexOf(parentItem);\n if (parentIndex >= 0) {\n this._focusItem(parentIndex);\n }\n }\n }\n break;\n }\n case 'ArrowRight': {\n e.preventDefault();\n const currentItem = items[currentIndex];\n if (!currentItem) break;\n if (currentItem.hasChildItems) {\n if (!currentItem.expanded) {\n currentItem.expanded = true;\n } else {\n this._focusItem(currentIndex + 1);\n }\n }\n break;\n }\n case 'Home': {\n e.preventDefault();\n this._focusItem(0);\n break;\n }\n case 'End': {\n e.preventDefault();\n this._focusItem(items.length - 1);\n break;\n }\n }\n }\n\n private _handleFocusIn(e: FocusEvent): void {\n if (e.target === e.currentTarget) {\n this._focusItem(this._currentIndex);\n }\n }\n\n // ─── Render ───\n\n override render() {\n return html`\n <div\n part=\"tree\"\n class=\"tree\"\n role=\"tree\"\n tabindex=\"0\"\n aria-label=${this.label || nothing}\n aria-multiselectable=${this.selection === 'multiple' ? 'true' : 'false'}\n @hx-tree-item-select=${this._handleTreeItemSelect}\n @keydown=${this._handleKeyDown}\n @focusin=${this._handleFocusIn}\n >\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tree-view': HelixTreeView;\n }\n}\n\n/** Canonical type alias for HelixTreeView. Use this when typing hx-tree-view element references. */\nexport type HxTreeView = HelixTreeView;\n\n/** @deprecated Use {@link HxTreeView} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcTreeView = HelixTreeView;\n","import { css } from 'lit';\n\nexport const helixTreeItemStyles = css`\n :host {\n display: block;\n contain: layout style;\n }\n\n * {\n box-sizing: border-box;\n }\n\n /* ─── Item Container ─── */\n\n .item {\n display: block;\n }\n\n /* ─── Item Row ─── */\n\n .item-row {\n display: flex;\n align-items: center;\n gap: var(--hx-tree-item-gap, var(--hx-space-2, 0.5rem));\n padding: var(--hx-tree-item-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-tree-item-padding-x, var(--hx-space-2, 0.5rem));\n padding-left: calc(\n var(--hx-tree-item-padding-x, var(--hx-space-2, 0.5rem)) + var(--_indent-level, 0) *\n var(--hx-tree-indent-size, 1.5rem)\n );\n border-radius: var(--hx-tree-item-border-radius, var(--hx-border-radius-sm, 0.25rem));\n cursor: pointer;\n outline: none;\n color: var(--hx-tree-item-color, var(--hx-color-neutral-900, #111827));\n font-family: var(--hx-tree-item-font-family, var(--hx-font-family-sans, sans-serif));\n font-size: var(--hx-tree-item-font-size, var(--hx-font-size-sm, 0.875rem));\n line-height: var(--hx-line-height-normal, 1.5);\n transition: background-color var(--hx-transition-fast, 150ms ease);\n user-select: none;\n }\n\n .item-row:hover {\n background-color: var(--hx-tree-item-hover-bg, var(--hx-color-neutral-100, #f3f4f6));\n }\n\n .item-row:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #2563eb);\n outline-offset: var(--hx-focus-ring-offset, -2px);\n }\n\n /* ─── Selected State ─── */\n\n :host([selected]) .item-row {\n background-color: var(--hx-tree-item-selected-bg, var(--hx-color-primary-100, #dbeafe));\n color: var(--hx-tree-item-selected-color, var(--hx-color-primary-800, #1e40af));\n }\n\n :host([selected]) .item-row:hover {\n background-color: var(--hx-tree-item-selected-hover-bg, var(--hx-color-primary-200, #bfdbfe));\n }\n\n /* ─── Disabled State ─── */\n\n :host([disabled]) .item-row {\n opacity: 0.4;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n /* ─── Expand Icon ─── */\n\n .expand-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n }\n\n .expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--hx-space-4, 1rem);\n height: var(--hx-space-4, 1rem);\n padding: 0;\n border: none;\n background: transparent;\n color: var(--hx-tree-item-expand-icon-color, var(--hx-color-neutral-500, #6b7280));\n cursor: pointer;\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n transition: transform var(--hx-transition-fast, 150ms ease);\n pointer-events: auto;\n }\n\n .expand-btn:hover {\n background-color: var(\n --hx-tree-item-expand-hover-bg,\n var(--hx-overlay-black-6, rgba(0, 0, 0, 0.06))\n );\n }\n\n .expand-btn svg {\n width: var(--hx-space-3, 0.75rem);\n height: var(--hx-space-3, 0.75rem);\n stroke: currentColor;\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n transition: transform var(--hx-transition-fast, 150ms ease);\n }\n\n :host([expanded]) .expand-btn svg {\n transform: rotate(90deg);\n }\n\n .expand-placeholder {\n display: block;\n width: var(--hx-space-4, 1rem);\n flex-shrink: 0;\n }\n\n /* ─── Icon Slot ─── */\n\n .item-icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--hx-tree-item-icon-color, var(--hx-color-neutral-500, #6b7280));\n }\n\n .item-icon:empty {\n display: none;\n }\n\n /* ─── Label ─── */\n\n .item-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* ─── Children (animated) ─── */\n\n .children {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--hx-transition-base, 200ms ease);\n --_indent-level: calc(var(--_indent-level, 0) + 1);\n }\n\n .children--expanded {\n grid-template-rows: 1fr;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item-row,\n .expand-btn,\n .expand-btn svg,\n .children {\n transition: none;\n }\n }\n\n .children-inner {\n overflow: hidden;\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixTreeItemStyles } from './hx-tree-item.styles.js';\n\n/** Detail type for the `hx-tree-item-select` event. */\nexport interface HxTreeItemSelectDetail {\n /** The tree item that was selected or activated. */\n item: HelixTreeItem;\n}\n\n/**\n * A tree item used within an hx-tree-view component.\n * Supports expand/collapse, selection, keyboard navigation, and icon/children slots.\n *\n * @summary Individual item within an hx-tree-view hierarchical tree.\n *\n * @tag hx-tree-item\n *\n * @slot - Default slot for the item label content.\n * @slot icon - Custom icon shown before the label.\n * @slot children - Nested hx-tree-item elements for sub-tree.\n *\n * @csspart item - The outer item container.\n * @csspart row - The interactive item row (contains expand icon, icon slot, and label).\n * @csspart expand-icon - The expand/collapse toggle button.\n * @csspart label - The label text content area.\n * @csspart children - The children container.\n *\n * @cssprop [--hx-tree-item-color=var(--hx-color-neutral-900)] - Item text color.\n * @cssprop [--hx-tree-item-hover-bg=var(--hx-color-neutral-100)] - Hover background color.\n * @cssprop [--hx-tree-item-selected-bg=var(--hx-color-primary-100)] - Selected background color.\n * @cssprop [--hx-tree-item-selected-color=var(--hx-color-primary-800)] - Selected text color.\n * @cssprop [--hx-tree-item-padding-x=var(--hx-space-2)] - Horizontal padding.\n * @cssprop [--hx-tree-item-padding-y=var(--hx-space-1)] - Vertical padding.\n * @cssprop [--hx-tree-indent-size=1.5rem] - Indentation size per level.\n *\n * @fires {CustomEvent<HxTreeItemSelectDetail>} hx-tree-item-select - Dispatched when this item is clicked or activated via keyboard.\n */\n@customElement('hx-tree-item')\nexport class HelixTreeItem extends LitElement {\n static override styles = [tokenStyles, helixTreeItemStyles];\n\n // ─── Properties ───\n\n /**\n * Whether the item is expanded (showing children).\n * @attr expanded\n */\n @property({ type: Boolean, reflect: true })\n expanded = false;\n\n /**\n * Whether the item is selected.\n * @attr selected\n */\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n /**\n * Whether the item is disabled (non-interactive).\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // ─── Internal State ───\n\n @state() private _hasChildren = false;\n\n /**\n * Cached ARIA position metadata. Computed once on connect and on slotchange\n * of the parent container, avoiding repeated DOM traversal on every render.\n */\n @state() private _level = 1;\n @state() private _posInSet = 1;\n @state() private _setSize = 1;\n @state() private _selectable = false;\n\n // ─── Computed ARIA ───\n\n /**\n * Whether this item has slotted children.\n * @returns True if one or more elements are assigned to the children slot.\n */\n get hasChildItems(): boolean {\n return this._hasChildren;\n }\n\n /**\n * Recompute all cached ARIA metadata in a single DOM pass.\n * Called on connect, slotchange, and whenever structural context may change.\n */\n private _updateAriaMetadata(): void {\n // Compute nesting level by counting ancestor hx-tree-item elements.\n let level = 1;\n let el: Element | null = this.parentElement;\n while (el) {\n if (el.tagName.toLowerCase() === 'hx-tree-item') level++;\n el = el.parentElement;\n }\n this._level = level;\n\n // Compute position-in-set and set-size from sibling hx-tree-item elements.\n const parent = this.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (c) => c.tagName.toLowerCase() === 'hx-tree-item',\n );\n this._posInSet = siblings.indexOf(this) + 1;\n this._setSize = siblings.length;\n } else {\n this._posInSet = 1;\n this._setSize = 1;\n }\n\n // Determine if the owning tree supports selection.\n const tree = this.closest('hx-tree-view');\n if (tree) {\n const selection = tree.getAttribute('selection');\n this._selectable = selection === 'single' || selection === 'multiple';\n } else {\n this._selectable = false;\n }\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._updateAriaMetadata();\n }\n\n // ─── Children Detection ───\n\n private _handleChildrenSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasChildren = slot.assignedElements().length > 0;\n this._updateAriaMetadata();\n }\n\n // ─── Event Handlers ───\n\n private _handleExpandClick(e: Event): void {\n e.stopPropagation();\n if (this.disabled) return;\n this.expanded = !this.expanded;\n }\n\n private _handleRowClick(): void {\n if (this.disabled) return;\n this.dispatchEvent(\n new CustomEvent<HxTreeItemSelectDetail>('hx-tree-item-select', {\n bubbles: true,\n composed: true,\n detail: { item: this },\n }),\n );\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (this.disabled) return;\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault();\n if (this._hasChildren && !this.expanded) {\n this.expanded = true;\n }\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (this._hasChildren && this.expanded) {\n this.expanded = false;\n }\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n this._handleRowClick();\n break;\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Home':\n case 'End':\n // Bubble up to hx-tree-view for navigation\n break;\n }\n }\n\n // ─── Public API ───\n\n /** Focus this item's interactive row element. */\n override focus(): void {\n const row = this.shadowRoot?.querySelector<HTMLElement>('.item-row');\n row?.focus();\n }\n\n // ─── Render ───\n\n private _renderExpandIcon() {\n if (!this._hasChildren) {\n return html`<span class=\"expand-placeholder\" aria-hidden=\"true\"></span>`;\n }\n return html`\n <button\n part=\"expand-icon\"\n class=\"expand-btn\"\n tabindex=\"-1\"\n aria-label=\"${this.expanded ? 'Collapse' : 'Expand'}\"\n @click=${this._handleExpandClick}\n >\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <polyline points=\"6 4 10 8 6 12\" />\n </svg>\n </button>\n `;\n }\n\n override render() {\n const ariaExpanded = this._hasChildren ? String(this.expanded) : nothing;\n const ariaSelected = this._selectable ? String(this.selected) : nothing;\n\n return html`\n <div part=\"item\" class=\"item\">\n <div\n part=\"row\"\n class=\"item-row\"\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-expanded=${ariaExpanded}\n aria-selected=${ariaSelected}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-level=${this._level}\n aria-posinset=${this._posInSet}\n aria-setsize=${this._setSize}\n @click=${this._handleRowClick}\n @keydown=${this._handleKeyDown}\n >\n ${this._renderExpandIcon()}\n <span class=\"item-icon\">\n <slot name=\"icon\"></slot>\n </span>\n <span part=\"label\" class=\"item-label\">\n <slot></slot>\n </span>\n </div>\n <div\n part=\"children\"\n class=\"children ${this.expanded ? 'children--expanded' : ''}\"\n role=\"group\"\n >\n <div class=\"children-inner\">\n <slot name=\"children\" @slotchange=${this._handleChildrenSlotChange}></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-tree-item': HelixTreeItem;\n }\n}\n\n/** Canonical type alias for HelixTreeItem. Use this when typing hx-tree-item element references. */\nexport type HxTreeItem = HelixTreeItem;\n\n/** @deprecated Use {@link HxTreeItem} instead. The `Wc` prefix was a legacy naming convention. */\nexport type WcTreeItem = HelixTreeItem;\n"],"names":["helixTreeViewStyles","css","HelixTreeView","LitElement","container","items","child","item","index","clamped","_a","e","wasSelected","i","currentIndex","focused","_b","next","prev","currentItem","parentItem","_c","parentIndex","html","nothing","tokenStyles","__decorateClass","property","state","customElement","helixTreeItemStyles","HelixTreeItem","level","el","parent","siblings","c","tree","selection","slot","row","ariaExpanded","ariaSelected"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helixui/library",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Enterprise Web Component Library built with Lit 3.x",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
"test:coverage": "vitest run --coverage.enabled",
|
|
42
42
|
"test:watch": "vitest",
|
|
43
43
|
"test:ui": "vitest --ui",
|
|
44
|
+
"test:batch:1": "vitest run \"hx-accordion/|hx-action-bar/|hx-alert/|hx-avatar/|hx-badge/|hx-breadcrumb/|hx-button/|hx-button-group/|hx-card/|hx-carousel/|hx-checkbox/|hx-checkbox-group/|hx-code-snippet/|hx-color-picker/|hx-combobox/\" --reporter=verbose",
|
|
45
|
+
"test:batch:2": "vitest run \"hx-container/|hx-copy-button/|hx-data-table/|hx-date-picker/|hx-dialog/|hx-divider/|hx-drawer/|hx-dropdown/|hx-field/|hx-field-label/|hx-file-upload/|hx-form/|hx-format-date/|hx-grid/|hx-help-text/\" --reporter=verbose",
|
|
46
|
+
"test:batch:3": "vitest run \"hx-icon/|hx-icon-button/|hx-image/|hx-link/|hx-list/|hx-menu/|hx-meter/|hx-nav/|hx-number-input/|hx-overflow-menu/|hx-pagination/|hx-popover/|hx-popup/|hx-progress-bar/|hx-progress-ring/\" --reporter=verbose",
|
|
47
|
+
"test:batch:4": "vitest run \"hx-prose/|hx-radio-group/|hx-rating/|hx-select/|hx-side-nav/|hx-skeleton/|hx-slider/|hx-spinner/|hx-split-button/|hx-split-panel/|hx-stack/|hx-status-indicator/|hx-steps/|hx-structured-list/\" --reporter=verbose",
|
|
48
|
+
"test:batch:5": "vitest run \"hx-switch/|hx-tabs/|hx-tag/|hx-text/|hx-text-input/|hx-textarea/|hx-theme/|hx-time-picker/|hx-toast/|hx-toggle-button/|hx-tooltip/|hx-top-nav/|hx-tree-view/|hx-visually-hidden/\" --reporter=verbose",
|
|
49
|
+
"test:component": "vitest run --reporter=verbose",
|
|
44
50
|
"cem": "custom-elements-manifest analyze --litelement --globs \"src/components/**/*.ts\" --exclude \"**/*.stories.ts\" --exclude \"**/*.styles.ts\"",
|
|
45
51
|
"lint": "eslint src/",
|
|
46
52
|
"clean": "rm -rf dist custom-elements.json"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hx-action-bar-D43v5rA2.js","sources":["../../src/components/hx-action-bar/hx-action-bar.styles.ts","../../src/components/hx-action-bar/hx-action-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixActionBarStyles = css`\n :host {\n display: block;\n }\n\n /* ─── Base ─── */\n\n .base {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--hx-action-bar-gap, var(--hx-space-2, 0.5rem));\n padding: var(--hx-action-bar-padding, var(--hx-space-2, 0.5rem) var(--hx-space-3, 0.75rem));\n background: var(--hx-action-bar-bg, transparent);\n border: var(--hx-action-bar-border, none);\n box-sizing: border-box;\n width: 100%;\n }\n\n /* ─── Sticky (top) ─── */\n\n .base--sticky {\n position: sticky;\n top: 0;\n padding-top: max(var(--hx-action-bar-padding-block-start, 0px), env(safe-area-inset-top, 0px));\n z-index: var(--hx-action-bar-z-index, 10);\n /*\n * Consumers: when this bar is sticky, add scroll-padding-top to the scroll container\n * equal to the bar's rendered height so anchor targets are not hidden behind the bar.\n * Example: .scroll-container { scroll-padding-top: 2.5rem; }\n */\n }\n\n /* ─── Bottom sticky ─── */\n\n .base--bottom {\n position: sticky;\n bottom: 0;\n /*\n * Respect iOS home-indicator safe area on devices with notch/home bar.\n * Falls back to 0px on devices that do not support env().\n */\n padding-bottom: max(\n var(--hx-action-bar-padding-block-end, 0px),\n env(safe-area-inset-bottom, 0px)\n );\n z-index: var(--hx-action-bar-z-index, 10);\n }\n\n /* ─── Variant: outlined ─── */\n\n .base--outlined {\n background: var(--hx-action-bar-bg, var(--hx-color-neutral-0, #fff));\n border: var(\n --hx-action-bar-border,\n var(--hx-border-width-thin, 1px) solid var(--hx-color-neutral-200, #e5e7eb)\n );\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n /* ─── Variant: filled ─── */\n\n .base--filled {\n background: var(--hx-action-bar-bg, var(--hx-color-neutral-50, #f9fafb));\n border-radius: var(--hx-border-radius-md, 0.375rem);\n }\n\n /* ─── Size modifiers ─── */\n\n .base--sm {\n padding: var(--hx-action-bar-padding, var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem));\n gap: var(--hx-action-bar-gap, var(--hx-space-1, 0.25rem));\n min-height: var(--hx-size-8, 2rem);\n }\n\n .base--md {\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n .base--lg {\n padding: var(--hx-action-bar-padding, var(--hx-space-3, 0.75rem) var(--hx-space-4, 1rem));\n gap: var(--hx-action-bar-gap, var(--hx-space-3, 0.75rem));\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Sections ─── */\n\n .section {\n display: flex;\n align-items: center;\n gap: inherit;\n }\n\n /*\n * Equal flex-basis on start and end guarantees the center section is visually centered\n * within the full bar width, regardless of how wide start and end content are.\n */\n .section--start {\n flex: 1 1 0;\n justify-content: flex-start;\n }\n\n .section--center {\n flex: 0 0 auto;\n justify-content: center;\n }\n\n .section--end {\n flex: 1 1 0;\n justify-content: flex-end;\n }\n\n /* ─── Slotted content ─── */\n\n ::slotted(*) {\n flex-shrink: 0;\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { tokenStyles } from '@helixui/tokens/lit';\nimport { helixActionBarStyles } from './hx-action-bar.styles.js';\n\n/**\n * A horizontal toolbar container for grouping related action buttons and controls.\n * Implements the ARIA toolbar pattern with roving tabindex keyboard navigation.\n *\n * @summary Horizontal action bar for grouping related controls.\n *\n * @tag hx-action-bar\n *\n * @slot start - Left-aligned actions.\n * @slot - Center content (default slot).\n * @slot end - Right-aligned actions.\n * @slot overflow - Actions revealed when the bar is constrained for space.\n *\n * @csspart base - The root toolbar container element.\n * @csspart start - The start (left) slot wrapper.\n * @csspart center - The center (default) slot wrapper.\n * @csspart end - The end (right) slot wrapper.\n * @csspart overflow - The overflow slot wrapper (hidden when no overflow content).\n *\n * @cssprop [--hx-action-bar-bg=transparent] - Bar background color (default variant).\n * @cssprop [--hx-action-bar-border=none] - Bar border (default variant).\n * @cssprop [--hx-action-bar-padding=var(--hx-space-2,0.5rem) var(--hx-space-3,0.75rem)] - Inner padding.\n * @cssprop [--hx-action-bar-gap=var(--hx-space-2,0.5rem)] - Gap between slotted items.\n * @cssprop [--hx-action-bar-z-index=10] - Z-index when sticky or bottom position.\n *\n * @attr {string} aria-label - Required. Identifies the toolbar to assistive technology.\n * When multiple toolbars appear on the same page, each must have a unique, descriptive label.\n *\n * @example\n * ```html\n * <hx-action-bar aria-label=\"Patient actions\">\n * <hx-button slot=\"start\">Save</hx-button>\n * <hx-button slot=\"end\" variant=\"ghost\">Cancel</hx-button>\n * </hx-action-bar>\n * ```\n */\n@customElement('hx-action-bar')\nexport class HelixActionBar extends LitElement {\n static override styles = [tokenStyles, helixActionBarStyles];\n\n /**\n * Size of the action bar — propagated as a data attribute to slotted children.\n * @attr size\n */\n @property({ type: String, reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Visual variant controlling the bar background.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'default' | 'outlined' | 'filled' = 'default';\n\n /**\n * Position and sticky behavior of the action bar.\n * - `top` — normal flow (default)\n * - `sticky` — sticks to the top of the scroll container; add `scroll-padding-top` to the\n * scroll container equal to the bar height to prevent anchor targets from scrolling behind it\n * - `bottom` — sticks to the bottom of the scroll container with iOS safe-area-inset support\n * @attr position\n */\n @property({ type: String, reflect: true })\n position: 'top' | 'bottom' | 'sticky' = 'top';\n\n /**\n * @deprecated Use `position=\"sticky\"` instead.\n * When true, the bar sticks to the top of its scroll container.\n * @attr sticky\n */\n @property({ type: Boolean, reflect: true })\n sticky = false;\n\n /**\n * Accessible label for the toolbar.\n * Required when multiple toolbars appear on the same page.\n * @attr aria-label\n */\n @property({ attribute: 'aria-label' })\n ariaLabel: string = 'Actions';\n\n /** Cached list of focusable items — invalidated on slot change. */\n private _focusableCache: HTMLElement[] | null = null;\n\n /** Whether the overflow slot has assigned content. */\n @state()\n private _hasOverflow = false;\n\n // ─── Lifecycle ───\n\n /** Arrow function field — stable reference for add/removeEventListener. */\n private _handleKeydown = (e: KeyboardEvent): void => {\n if (e.key === 'ArrowRight') {\n e.preventDefault();\n this._moveFocus('next');\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this._moveFocus('prev');\n } else if (e.key === 'Home') {\n e.preventDefault();\n // Move directly to first item — do NOT call _moveFocus which would visit other items first.\n const items = this._getFocusableItems();\n if (items.length) {\n items.forEach((el, i) => el.setAttribute('tabindex', i === 0 ? '0' : '-1'));\n items[0]?.focus();\n }\n } else if (e.key === 'End') {\n e.preventDefault();\n const items = this._getFocusableItems();\n const last = items.length - 1;\n if (items.length) {\n items.forEach((el, i) => el.setAttribute('tabindex', i === last ? '0' : '-1'));\n items[last]?.focus();\n }\n }\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Prevent dual aria-label announcement: the host carries the consumer's\n // aria-label attribute while the inner div[role=\"toolbar\"] receives the\n // same value. Setting role=\"none\" on the host hides it from the\n // accessibility tree so only the toolbar is announced.\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'none');\n }\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n override firstUpdated(): void {\n // Slot assignments are complete by firstUpdated; initialize roving tabindex\n // immediately rather than waiting for the async slotchange event.\n this._initRovingTabindex();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n // ─── Focusable item discovery ───\n\n private _isFocusable(el: HTMLElement): boolean {\n // Check disabled via DOM attribute (native elements) or property (custom elements)\n if (el.hasAttribute('disabled')) return false;\n const elWithDisabled = el as HTMLElement & { disabled?: boolean };\n if (elWithDisabled.disabled === true) return false;\n\n // Use the IDL tabIndex property — covers both DOM attribute and ElementInternals settings.\n // Custom elements (e.g. hx-button) that set tabIndex via ElementInternals are discoverable.\n if (el.tabIndex >= 0) return true;\n\n const tag = el.tagName.toLowerCase();\n return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';\n }\n\n private _getFocusableItems(): HTMLElement[] {\n if (this._focusableCache) return this._focusableCache;\n\n const slots = this.shadowRoot?.querySelectorAll('slot') ?? [];\n const items: HTMLElement[] = [];\n\n for (const slot of Array.from(slots)) {\n const assigned = (slot as HTMLSlotElement).assignedElements({ flatten: true });\n for (const el of assigned) {\n if (!(el instanceof HTMLElement)) continue;\n if (this._isFocusable(el)) {\n // Element is itself focusable — include it and do NOT also recurse into its children\n // to prevent double-counting compound components (e.g. <a><button>).\n items.push(el);\n } else {\n // Element is a non-focusable wrapper (e.g. <div>, <span>) — find focusable children.\n const descendants = el.querySelectorAll<HTMLElement>('*');\n for (const d of Array.from(descendants)) {\n if (this._isFocusable(d)) {\n items.push(d);\n }\n }\n }\n }\n }\n\n this._focusableCache = items;\n return items;\n }\n\n // ─── Roving tabindex helpers ───\n\n private _initRovingTabindex(): void {\n this._focusableCache = null; // invalidate cache on slot change\n const items = this._getFocusableItems();\n if (!items.length) return;\n const hasActive = items.some((el) => el.getAttribute('tabindex') === '0');\n if (!hasActive) {\n // No item is active yet — make the first item tabbable.\n items.forEach((el, i) => el.setAttribute('tabindex', i === 0 ? '0' : '-1'));\n } else {\n // An item is already active — ensure new items get tabindex=\"-1\"\n // without disturbing the currently active item.\n items.forEach((el) => {\n if (el.getAttribute('tabindex') === null) el.setAttribute('tabindex', '-1');\n });\n }\n }\n\n private _moveFocus(direction: 'next' | 'prev'): void {\n const items = this._getFocusableItems();\n if (!items.length) return;\n\n const focused = document.activeElement as HTMLElement | null;\n const currentIndex = items.indexOf(focused as HTMLElement);\n\n let nextIndex: number;\n if (direction === 'next') {\n nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n } else {\n nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n }\n\n items.forEach((el, i) => {\n el.setAttribute('tabindex', i === nextIndex ? '0' : '-1');\n });\n\n items[nextIndex]?.focus();\n }\n\n // ─── Event Handlers ───\n\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n if (slot.name === 'overflow') {\n this._hasOverflow = slot.assignedElements({ flatten: true }).length > 0;\n }\n this._initRovingTabindex();\n }\n\n // ─── Render ───\n\n override render() {\n const isSticky = this.position === 'sticky' || this.sticky;\n const isBottom = this.position === 'bottom';\n const positionClass = isSticky ? ' base--sticky' : isBottom ? ' base--bottom' : '';\n\n return html`\n <div\n part=\"base\"\n role=\"toolbar\"\n aria-label=${this.ariaLabel}\n aria-orientation=\"horizontal\"\n class=\"base base--${this.size} base--${this.variant}${positionClass}\"\n >\n <div part=\"start\" class=\"section section--start\">\n <slot name=\"start\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"center\" class=\"section section--center\">\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"end\" class=\"section section--end\">\n <slot name=\"end\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n <div part=\"overflow\" class=\"section section--overflow\" ?hidden=${!this._hasOverflow}>\n <slot name=\"overflow\" @slotchange=${this._handleSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-action-bar': HelixActionBar;\n }\n}\n"],"names":["helixActionBarStyles","css","HelixActionBar","LitElement","items","el","i","_a","last","_b","tag","slots","slot","assigned","descendants","d","direction","focused","currentIndex","nextIndex","isSticky","isBottom","positionClass","html","tokenStyles","__decorateClass","property","state","customElement"],"mappings":"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"}
|