@waggylabs/yumekit 0.4.0-beta.34 → 0.4.0-beta.35

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.
@@ -41,7 +41,7 @@ export class YumeAppbar extends HTMLElement {
41
41
  toggle(): void;
42
42
  render(): void;
43
43
  _buildCollapseButton(cfg: any, isCollapsed: any): HTMLElement;
44
- _buildHeader(cfg: any): HTMLDivElement;
44
+ _buildHeader(): HTMLDivElement;
45
45
  _buildNavItem(item: any, cfg: any, isVertical: any, isCollapsed: any, menuDir: any): HTMLDivElement;
46
46
  _getBreakpointPx(): number;
47
47
  _initRender(): void;
@@ -1274,7 +1274,7 @@ class YumeAppbar extends HTMLElement {
1274
1274
  return btn;
1275
1275
  }
1276
1276
 
1277
- _buildHeader(cfg) {
1277
+ _buildHeader() {
1278
1278
  const header = document.createElement("div");
1279
1279
  header.className = "appbar-header";
1280
1280
  header.setAttribute("part", "header");
@@ -1666,7 +1666,7 @@ class YumeAppbar extends HTMLElement {
1666
1666
  `calc(${cfg.collapsedWidth} - 2 * var(--_appbar-padding) - 2 * var(--component-appbar-border-width, var(--component-sidebar-border-width, 2px)) - 2 * var(--component-button-border-width, 1px))`,
1667
1667
  );
1668
1668
 
1669
- bar.appendChild(this._buildHeader(cfg));
1669
+ bar.appendChild(this._buildHeader());
1670
1670
 
1671
1671
  const body = document.createElement("div");
1672
1672
  body.className = "appbar-body";
@@ -1,10 +1,19 @@
1
1
  class YumePanelBar extends HTMLElement {
2
+
3
+ // -------------------------------------------------------------------------
4
+ // Lifecycle
5
+ // -------------------------------------------------------------------------
6
+
2
7
  constructor() {
3
8
  super();
4
9
  this.attachShadow({ mode: "open" });
5
10
  this.render();
6
11
  }
7
12
 
13
+ // -------------------------------------------------------------------------
14
+ // Public
15
+ // -------------------------------------------------------------------------
16
+
8
17
  render() {
9
18
  const sheet = new CSSStyleSheet();
10
19
  sheet.replaceSync(`
@@ -174,7 +174,7 @@ class YumeRadio extends HTMLElement {
174
174
 
175
175
  _handleKey(e, index, radios) {
176
176
  const len = radios.length;
177
- let newIndex = index;
177
+ let newIndex;
178
178
 
179
179
  if (e.key === "ArrowDown" || e.key === "ArrowRight") {
180
180
  e.preventDefault();
@@ -12,17 +12,18 @@ export class YumeTable extends HTMLElement {
12
12
  set data(val: string);
13
13
  /** Row data as a JSON string or array of objects keyed by column field names. */
14
14
  get data(): string;
15
+ set size(val: string);
16
+ /** Cell padding size: "small" | "medium" | "large" (default "medium"). */
17
+ get size(): string;
15
18
  set striped(val: boolean);
16
19
  /** Whether to show alternating row backgrounds. */
17
20
  get striped(): boolean;
18
- set size(val: string);
19
- /**
20
- * Cell padding size: "small" | "medium" | "large" (default "medium").
21
- */
22
- get size(): string;
23
- _parseAttributes(): void;
24
- _onHeaderClick(field: any): void;
21
+ render(): void;
22
+ _buildBody(columns: any, rows: any): HTMLTableSectionElement;
23
+ _buildHeader(columns: any): HTMLTableSectionElement;
24
+ _buildStyles(): string;
25
25
  _getSortedData(): any[];
26
+ _onHeaderClick(field: any): void;
27
+ _parseAttributes(): void;
26
28
  _sortIcon(field: any): any;
27
- render(): void;
28
29
  }
@@ -7,6 +7,10 @@ class YumeTable extends HTMLElement {
7
7
  return ["columns", "data", "striped", "size"];
8
8
  }
9
9
 
10
+ // -------------------------------------------------------------------------
11
+ // Lifecycle
12
+ // -------------------------------------------------------------------------
13
+
10
14
  constructor() {
11
15
  super();
12
16
  this.attachShadow({ mode: "open" });
@@ -27,127 +31,136 @@ class YumeTable extends HTMLElement {
27
31
  this.render();
28
32
  }
29
33
 
34
+ // -------------------------------------------------------------------------
35
+ // Getters / Setters
36
+ // -------------------------------------------------------------------------
37
+
30
38
  /** Column definitions as a JSON string or array of { field, header?, sortable? } objects. */
31
- get columns() {
32
- return this.getAttribute("columns");
33
- }
39
+ get columns() { return this.getAttribute("columns"); }
34
40
  set columns(val) {
35
- this.setAttribute(
36
- "columns",
37
- typeof val === "string" ? val : JSON.stringify(val),
38
- );
41
+ this.setAttribute("columns", typeof val === "string" ? val : JSON.stringify(val));
39
42
  }
40
43
 
41
44
  /** Row data as a JSON string or array of objects keyed by column field names. */
42
- get data() {
43
- return this.getAttribute("data");
44
- }
45
+ get data() { return this.getAttribute("data"); }
45
46
  set data(val) {
46
- this.setAttribute(
47
- "data",
48
- typeof val === "string" ? val : JSON.stringify(val),
49
- );
47
+ this.setAttribute("data", typeof val === "string" ? val : JSON.stringify(val));
50
48
  }
51
49
 
50
+ /** Cell padding size: "small" | "medium" | "large" (default "medium"). */
51
+ get size() { return this.getAttribute("size") || "medium"; }
52
+ set size(val) { this.setAttribute("size", val); }
53
+
52
54
  /** Whether to show alternating row backgrounds. */
53
- get striped() {
54
- return this.hasAttribute("striped");
55
- }
55
+ get striped() { return this.hasAttribute("striped"); }
56
56
  set striped(val) {
57
57
  if (val) this.setAttribute("striped", "");
58
58
  else this.removeAttribute("striped");
59
59
  }
60
60
 
61
- /**
62
- * Cell padding size: "small" | "medium" | "large" (default "medium").
63
- */
64
- get size() {
65
- return this.getAttribute("size") || "medium";
66
- }
67
- set size(val) {
68
- this.setAttribute("size", val);
69
- }
61
+ // -------------------------------------------------------------------------
62
+ // Public
63
+ // -------------------------------------------------------------------------
70
64
 
71
- _parseAttributes() {
72
- try {
73
- this._parsedColumns = JSON.parse(this.columns || "[]");
74
- } catch {
75
- this._parsedColumns = [];
76
- }
77
- try {
78
- this._parsedData = JSON.parse(this.data || "[]");
79
- } catch {
80
- this._parsedData = [];
81
- }
82
- }
65
+ render() {
66
+ const columns = this._parsedColumns;
67
+ const rows = this._getSortedData();
83
68
 
84
- _onHeaderClick(field) {
85
- if (this._sortField === field) {
86
- this._sortDir =
87
- this._sortDir === "asc"
88
- ? "desc"
89
- : this._sortDir === "desc"
90
- ? "none"
91
- : "asc";
92
- if (this._sortDir === "none") this._sortField = null;
93
- } else {
94
- this._sortField = field;
95
- this._sortDir = "asc";
96
- }
69
+ this.shadowRoot.innerHTML = "";
97
70
 
98
- this.dispatchEvent(
99
- new CustomEvent("sort", {
100
- detail: { field: this._sortField, direction: this._sortDir },
101
- bubbles: true,
102
- composed: true,
103
- }),
104
- );
71
+ const style = document.createElement("style");
72
+ style.textContent = this._buildStyles();
73
+ this.shadowRoot.appendChild(style);
105
74
 
106
- this.render();
107
- }
75
+ const wrapper = document.createElement("div");
76
+ wrapper.className = "table-wrapper";
108
77
 
109
- _getSortedData() {
110
- const data = [...this._parsedData];
111
- if (!this._sortField || this._sortDir === "none") return data;
78
+ const table = document.createElement("table");
79
+ table.setAttribute("role", "grid");
80
+ table.setAttribute("part", "table");
112
81
 
113
- const dir = this._sortDir === "asc" ? 1 : -1;
114
- const field = this._sortField;
82
+ table.appendChild(this._buildHeader(columns));
83
+ table.appendChild(this._buildBody(columns, rows));
115
84
 
116
- return data.sort((a, b) => {
117
- const aVal = a[field];
118
- const bVal = b[field];
85
+ wrapper.appendChild(table);
86
+ this.shadowRoot.appendChild(wrapper);
87
+ }
119
88
 
120
- if (aVal == null && bVal == null) return 0;
121
- if (aVal == null) return 1;
122
- if (bVal == null) return -1;
89
+ // -------------------------------------------------------------------------
90
+ // Private
91
+ // -------------------------------------------------------------------------
123
92
 
124
- if (typeof aVal === "number" && typeof bVal === "number") {
125
- return (aVal - bVal) * dir;
126
- }
93
+ _buildBody(columns, rows) {
94
+ const tbody = document.createElement("tbody");
127
95
 
128
- return String(aVal).localeCompare(String(bVal)) * dir;
96
+ rows.forEach((row) => {
97
+ const tr = document.createElement("tr");
98
+ tr.setAttribute("part", "row");
99
+ columns.forEach((col, colIdx) => {
100
+ const td = document.createElement("td");
101
+ td.setAttribute("part", "cell");
102
+ if (col.rowHeader || colIdx === 0) {
103
+ td.classList.add("row-header");
104
+ }
105
+ td.textContent = row[col.field] ?? "";
106
+ tr.appendChild(td);
107
+ });
108
+ tbody.appendChild(tr);
129
109
  });
130
- }
131
110
 
132
- _sortIcon(field) {
133
- const active = this._sortField === field;
134
- const dir = active ? this._sortDir : "none";
135
- if (dir === "none") return "";
136
- return dir === "asc" ? arrowUp : arrowDown;
111
+ return tbody;
137
112
  }
138
113
 
139
- render() {
140
- const columns = this._parsedColumns;
141
- const rows = this._getSortedData();
142
- const size = this.size;
143
- const striped = this.striped;
114
+ _buildHeader(columns) {
115
+ const thead = document.createElement("thead");
116
+ thead.setAttribute("part", "header");
117
+ const headerRow = document.createElement("tr");
144
118
 
145
- const paddingVar = `var(--component-table-padding-${size}, 8px)`;
119
+ columns.forEach((col) => {
120
+ const th = document.createElement("th");
121
+ th.setAttribute("scope", "col");
146
122
 
147
- this.shadowRoot.innerHTML = "";
123
+ const sortable = col.sortable !== false;
124
+ if (sortable) {
125
+ th.classList.add("sortable");
126
+ th.setAttribute(
127
+ "aria-sort",
128
+ this._sortField === col.field
129
+ ? this._sortDir === "asc"
130
+ ? "ascending"
131
+ : this._sortDir === "desc"
132
+ ? "descending"
133
+ : "none"
134
+ : "none",
135
+ );
136
+ th.addEventListener("click", () => this._onHeaderClick(col.field));
137
+ }
148
138
 
149
- const style = document.createElement("style");
150
- style.textContent = `
139
+ const inner = document.createElement("span");
140
+ inner.className = "th-content";
141
+ inner.textContent = col.header || col.field;
142
+
143
+ if (sortable) {
144
+ const icon = this._sortIcon(col.field);
145
+ if (icon) {
146
+ const iconSpan = document.createElement("span");
147
+ iconSpan.className = "sort-icon";
148
+ iconSpan.innerHTML = icon;
149
+ inner.appendChild(iconSpan);
150
+ }
151
+ }
152
+
153
+ th.appendChild(inner);
154
+ headerRow.appendChild(th);
155
+ });
156
+
157
+ thead.appendChild(headerRow);
158
+ return thead;
159
+ }
160
+
161
+ _buildStyles() {
162
+ const paddingVar = `var(--component-table-padding-${this.size}, 8px)`;
163
+ return `
151
164
  :host {
152
165
  display: block;
153
166
  font-family: var(--font-family-body, sans-serif);
@@ -209,94 +222,82 @@ class YumeTable extends HTMLElement {
209
222
  font-weight: 400;
210
223
  }
211
224
 
212
- ${
213
- striped
214
- ? `tbody tr:nth-child(even) {
215
- background: var(--component-table-hover-background, #292a2b);
216
- }`
217
- : ""
218
- }
225
+ ${this.striped
226
+ ? `tbody tr:nth-child(even) {
227
+ background: var(--component-table-hover-background, #292a2b);
228
+ }`
229
+ : ""}
219
230
 
220
231
  tbody tr:hover {
221
232
  background: var(--component-table-active-background, #46474a);
222
233
  }
223
234
  `;
224
- this.shadowRoot.appendChild(style);
225
-
226
- const wrapper = document.createElement("div");
227
- wrapper.className = "table-wrapper";
228
-
229
- const table = document.createElement("table");
230
- table.setAttribute("role", "grid");
231
- table.setAttribute("part", "table");
235
+ }
232
236
 
233
- const thead = document.createElement("thead");
234
- thead.setAttribute("part", "header");
235
- const headerRow = document.createElement("tr");
237
+ _getSortedData() {
238
+ const data = [...this._parsedData];
239
+ if (!this._sortField || this._sortDir === "none") return data;
236
240
 
237
- columns.forEach((col) => {
238
- const th = document.createElement("th");
239
- th.setAttribute("scope", "col");
241
+ const dir = this._sortDir === "asc" ? 1 : -1;
242
+ const field = this._sortField;
240
243
 
241
- const sortable = col.sortable !== false;
242
- if (sortable) {
243
- th.classList.add("sortable");
244
- th.setAttribute(
245
- "aria-sort",
246
- this._sortField === col.field
247
- ? this._sortDir === "asc"
248
- ? "ascending"
249
- : this._sortDir === "desc"
250
- ? "descending"
251
- : "none"
252
- : "none",
253
- );
254
- th.addEventListener("click", () =>
255
- this._onHeaderClick(col.field),
256
- );
257
- }
244
+ return data.sort((a, b) => {
245
+ const aVal = a[field];
246
+ const bVal = b[field];
258
247
 
259
- const inner = document.createElement("span");
260
- inner.className = "th-content";
261
- inner.textContent = col.header || col.field;
248
+ if (aVal == null && bVal == null) return 0;
249
+ if (aVal == null) return 1;
250
+ if (bVal == null) return -1;
262
251
 
263
- if (sortable) {
264
- const icon = this._sortIcon(col.field);
265
- if (icon) {
266
- const iconSpan = document.createElement("span");
267
- iconSpan.className = "sort-icon";
268
- iconSpan.innerHTML = icon;
269
- inner.appendChild(iconSpan);
270
- }
252
+ if (typeof aVal === "number" && typeof bVal === "number") {
253
+ return (aVal - bVal) * dir;
271
254
  }
272
255
 
273
- th.appendChild(inner);
274
- headerRow.appendChild(th);
256
+ return String(aVal).localeCompare(String(bVal)) * dir;
275
257
  });
258
+ }
276
259
 
277
- thead.appendChild(headerRow);
278
- table.appendChild(thead);
260
+ _onHeaderClick(field) {
261
+ if (this._sortField === field) {
262
+ this._sortDir =
263
+ this._sortDir === "asc"
264
+ ? "desc"
265
+ : this._sortDir === "desc"
266
+ ? "none"
267
+ : "asc";
268
+ if (this._sortDir === "none") this._sortField = null;
269
+ } else {
270
+ this._sortField = field;
271
+ this._sortDir = "asc";
272
+ }
279
273
 
280
- const tbody = document.createElement("tbody");
274
+ this.dispatchEvent(new CustomEvent("sort", {
275
+ detail: { field: this._sortField, direction: this._sortDir },
276
+ bubbles: true,
277
+ composed: true,
278
+ }));
281
279
 
282
- rows.forEach((row) => {
283
- const tr = document.createElement("tr");
284
- tr.setAttribute("part", "row");
285
- columns.forEach((col, colIdx) => {
286
- const td = document.createElement("td");
287
- td.setAttribute("part", "cell");
288
- if (col.rowHeader || colIdx === 0) {
289
- td.classList.add("row-header");
290
- }
291
- td.textContent = row[col.field] ?? "";
292
- tr.appendChild(td);
293
- });
294
- tbody.appendChild(tr);
295
- });
280
+ this.render();
281
+ }
296
282
 
297
- table.appendChild(tbody);
298
- wrapper.appendChild(table);
299
- this.shadowRoot.appendChild(wrapper);
283
+ _parseAttributes() {
284
+ try {
285
+ this._parsedColumns = JSON.parse(this.columns || "[]");
286
+ } catch {
287
+ this._parsedColumns = [];
288
+ }
289
+ try {
290
+ this._parsedData = JSON.parse(this.data || "[]");
291
+ } catch {
292
+ this._parsedData = [];
293
+ }
294
+ }
295
+
296
+ _sortIcon(field) {
297
+ const active = this._sortField === field;
298
+ const dir = active ? this._sortDir : "none";
299
+ if (dir === "none") return "";
300
+ return dir === "asc" ? arrowUp : arrowDown;
300
301
  }
301
302
  }
302
303
 
@@ -102,13 +102,13 @@ class YumeTag extends HTMLElement {
102
102
  const { color, styleType, shape, size } = this;
103
103
 
104
104
  const vars = {
105
- primary: ["--primary-content--", "--primary-content-hover", "--primary-background-component", "--primary-content-inverse", "--primary-background-app"],
106
- secondary: ["--secondary-content--", "--secondary-content-hover", "--secondary-background-component", "--secondary-content-inverse", "--secondary-background-app"],
107
- base: ["--base-content--", "--base-content-lighter", "--base-background-component", "--base-content-inverse", "--base-background-app"],
108
- success: ["--success-content--", "--success-content-hover", "--success-background-component", "--success-content-inverse", "--success-background-app"],
109
- error: ["--error-content--", "--error-content-hover", "--error-background-component", "--error-content-inverse", "--error-background-app"],
110
- warning: ["--warning-content--", "--warning-content-hover", "--warning-background-component", "--warning-content-inverse", "--warning-background-app"],
111
- help: ["--help-content--", "--help-content-hover", "--help-background-component", "--help-content-inverse", "--help-background-app"],
105
+ primary: ["--primary-content--", "--primary-content-inverse", "--primary-background-app"],
106
+ secondary: ["--secondary-content--", "--secondary-content-inverse", "--secondary-background-app"],
107
+ base: ["--base-content--", "--base-content-inverse", "--base-background-app"],
108
+ success: ["--success-content--", "--success-content-inverse", "--success-background-app"],
109
+ error: ["--error-content--", "--error-content-inverse", "--error-background-app"],
110
+ warning: ["--warning-content--", "--warning-content-inverse", "--warning-background-app"],
111
+ help: ["--help-content--", "--help-content-inverse", "--help-background-app"],
112
112
  };
113
113
 
114
114
  const varEntry = vars[color];
@@ -155,7 +155,7 @@ class YumeTag extends HTMLElement {
155
155
 
156
156
  if (isCustomColor) return baseStyle + this._getCustomColorVariant(color, styleType);
157
157
 
158
- const [content, , background, inverse, flatBackground] = varEntry || vars.base;
158
+ const [content, inverse, flatBackground] = varEntry || vars.base;
159
159
 
160
160
  const styleVariants = {
161
161
  filled: `