ezfw-core 1.0.21 → 1.0.23
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/components/EzBaseComponent.ts +100 -5
- package/components/EzComponent.ts +3 -3
- package/components/EzLabel.ts +12 -3
- package/components/avatar/EzAvatar.ts +84 -54
- package/components/badge/EzBadge.ts +43 -24
- package/components/button/EzButton.ts +5 -3
- package/components/button/EzButtonGroup.ts +7 -10
- package/components/card/EzCard.ts +2 -1
- package/components/chart/EzChart.ts +20 -15
- package/components/checkbox/EzCheckbox.ts +47 -43
- package/components/dataview/EzDataView.ts +14 -29
- package/components/dataview/modes/EzDataViewCards.ts +51 -41
- package/components/dataview/modes/EzDataViewGrid.ts +5 -2
- package/components/datepicker/EzDatePicker.ts +2 -2
- package/components/dialog/EzDialog.ts +84 -67
- package/components/dropdown/EzDropdown.ts +72 -58
- package/components/form/EzForm.ts +45 -37
- package/components/kanban/EzKanban.module.scss +221 -0
- package/components/kanban/EzKanban.ts +222 -0
- package/components/kanban/EzKanbanTypes.ts +166 -0
- package/components/kanban/board/EzKanbanBoard.ts +117 -0
- package/components/kanban/card/EzKanbanCard.module.scss +173 -0
- package/components/kanban/card/EzKanbanCard.ts +275 -0
- package/components/kanban/card/EzKanbanCardEditor.ts +209 -0
- package/components/kanban/column/EzKanbanColumn.ts +253 -0
- package/components/kanban/state/EzKanbanController.ts +373 -0
- package/components/kanban/state/EzKanbanDragDrop.ts +226 -0
- package/components/panel/EzPanel.ts +59 -68
- package/components/picker/EzPicker.module.scss +14 -0
- package/components/picker/EzPicker.ts +118 -0
- package/components/radio/EzRadio.ts +55 -47
- package/components/select/EzSelect.ts +48 -44
- package/components/skeleton/EzSkeleton.ts +31 -26
- package/components/switch/EzSwitch.ts +52 -44
- package/components/tabs/EzTabPanel.ts +52 -48
- package/components/textarea/EzTextarea.ts +69 -54
- package/components/timepicker/EzTimePicker.ts +2 -2
- package/components/tooltip/EzTooltip.ts +20 -33
- package/core/ez.ts +7 -0
- package/core/loader.ts +2 -0
- package/core/renderer.ts +80 -4
- package/core/styleShortcuts.ts +418 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { effect } from '@preact/signals';
|
|
2
2
|
import tooltipStyles from './tooltip/EzTooltip.module.scss';
|
|
3
3
|
import { cx } from '../utils/cssModules.js';
|
|
4
|
+
import { extractStyleShortcuts, mergeStyles, EzStyleShortcuts } from '../core/styleShortcuts.js';
|
|
4
5
|
|
|
5
6
|
const tooltipCls = cx(tooltipStyles);
|
|
6
7
|
|
|
@@ -11,6 +12,7 @@ const tooltipCls = cx(tooltipStyles);
|
|
|
11
12
|
declare const ez: {
|
|
12
13
|
_controllers: Record<string, EzController | undefined>;
|
|
13
14
|
getController(name: string): EzController | null;
|
|
15
|
+
getControllerSync(name: string): EzController | null;
|
|
14
16
|
getDeepValue(obj: unknown, path: string[]): unknown;
|
|
15
17
|
setDeepValue(obj: unknown, path: string[], value: unknown): void;
|
|
16
18
|
_createElement(config: EzComponentConfig): Promise<HTMLElement>;
|
|
@@ -19,6 +21,7 @@ declare const ez: {
|
|
|
19
21
|
|
|
20
22
|
interface EzController {
|
|
21
23
|
state: Record<string, unknown>;
|
|
24
|
+
_computed?: Record<string, { value: unknown }>;
|
|
22
25
|
[key: string]: unknown;
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -46,6 +49,8 @@ interface BindConfig {
|
|
|
46
49
|
text?: string | (() => string);
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
type StyleValue = string | number | undefined;
|
|
53
|
+
|
|
49
54
|
export interface EzComponentConfig {
|
|
50
55
|
controller?: string | null;
|
|
51
56
|
bind?: string | BindConfig;
|
|
@@ -58,6 +63,73 @@ export interface EzComponentConfig {
|
|
|
58
63
|
_styleModule?: StyleModule;
|
|
59
64
|
onChange?: string | ((value: unknown) => void);
|
|
60
65
|
itemRender?: (item: unknown, index: number, meta: ItemRenderMeta) => EzComponentConfig | null;
|
|
66
|
+
|
|
67
|
+
// Style shortcuts - Spacing
|
|
68
|
+
p?: StyleValue;
|
|
69
|
+
pt?: StyleValue;
|
|
70
|
+
pr?: StyleValue;
|
|
71
|
+
pb?: StyleValue;
|
|
72
|
+
pl?: StyleValue;
|
|
73
|
+
px?: StyleValue;
|
|
74
|
+
py?: StyleValue;
|
|
75
|
+
m?: StyleValue;
|
|
76
|
+
mt?: StyleValue;
|
|
77
|
+
mr?: StyleValue;
|
|
78
|
+
mb?: StyleValue;
|
|
79
|
+
ml?: StyleValue;
|
|
80
|
+
mx?: StyleValue;
|
|
81
|
+
my?: StyleValue;
|
|
82
|
+
gap?: StyleValue;
|
|
83
|
+
|
|
84
|
+
// Style shortcuts - Sizing
|
|
85
|
+
w?: StyleValue;
|
|
86
|
+
h?: StyleValue;
|
|
87
|
+
minW?: StyleValue;
|
|
88
|
+
maxW?: StyleValue;
|
|
89
|
+
minH?: StyleValue;
|
|
90
|
+
maxH?: StyleValue;
|
|
91
|
+
|
|
92
|
+
// Style shortcuts - Flexbox
|
|
93
|
+
justify?: string;
|
|
94
|
+
align?: string;
|
|
95
|
+
alignSelf?: string;
|
|
96
|
+
wrap?: string | boolean;
|
|
97
|
+
|
|
98
|
+
// Style shortcuts - Typography
|
|
99
|
+
fs?: StyleValue;
|
|
100
|
+
fw?: StyleValue;
|
|
101
|
+
ta?: string;
|
|
102
|
+
lh?: StyleValue;
|
|
103
|
+
|
|
104
|
+
// Style shortcuts - Visual
|
|
105
|
+
bg?: string;
|
|
106
|
+
color?: string;
|
|
107
|
+
rounded?: StyleValue | boolean;
|
|
108
|
+
br?: StyleValue | boolean;
|
|
109
|
+
brt?: StyleValue;
|
|
110
|
+
brb?: StyleValue;
|
|
111
|
+
brl?: StyleValue;
|
|
112
|
+
brr?: StyleValue;
|
|
113
|
+
brtl?: StyleValue;
|
|
114
|
+
brtr?: StyleValue;
|
|
115
|
+
brbl?: StyleValue;
|
|
116
|
+
brbr?: StyleValue;
|
|
117
|
+
shadow?: string;
|
|
118
|
+
opacity?: number;
|
|
119
|
+
|
|
120
|
+
// Style shortcuts - Layout
|
|
121
|
+
d?: string;
|
|
122
|
+
pos?: string;
|
|
123
|
+
z?: number;
|
|
124
|
+
overflow?: string;
|
|
125
|
+
top?: StyleValue;
|
|
126
|
+
right?: StyleValue;
|
|
127
|
+
bottom?: StyleValue;
|
|
128
|
+
left?: StyleValue;
|
|
129
|
+
|
|
130
|
+
// Wrapper for grouping shortcuts
|
|
131
|
+
ezStyle?: EzStyleShortcuts;
|
|
132
|
+
|
|
61
133
|
[key: string]: unknown;
|
|
62
134
|
}
|
|
63
135
|
|
|
@@ -292,10 +364,15 @@ export class EzBaseComponent {
|
|
|
292
364
|
props = bind.data.split('.');
|
|
293
365
|
}
|
|
294
366
|
|
|
367
|
+
// Track render version to cancel stale async renders
|
|
368
|
+
let currentRenderVersion = 0;
|
|
369
|
+
|
|
295
370
|
const stop = effect(() => {
|
|
371
|
+
const renderVersion = ++currentRenderVersion;
|
|
372
|
+
|
|
296
373
|
(async () => {
|
|
297
374
|
const itemFn = this.config.itemRender;
|
|
298
|
-
const controller = ez.
|
|
375
|
+
const controller = ez.getControllerSync(activeCtrl!);
|
|
299
376
|
let data = ez.getDeepValue(controller?.state, props!) as unknown[] | unknown;
|
|
300
377
|
|
|
301
378
|
// If not found in state, check computed properties
|
|
@@ -311,6 +388,9 @@ export class EzBaseComponent {
|
|
|
311
388
|
data = [data];
|
|
312
389
|
}
|
|
313
390
|
|
|
391
|
+
// Check if this render is still current before modifying DOM
|
|
392
|
+
if (renderVersion !== currentRenderVersion) return;
|
|
393
|
+
|
|
314
394
|
el.innerHTML = '';
|
|
315
395
|
|
|
316
396
|
if (Array.isArray(data)) {
|
|
@@ -318,8 +398,10 @@ export class EzBaseComponent {
|
|
|
318
398
|
(el as HTMLElement & { _ezListRendered: boolean })._ezListRendered = true;
|
|
319
399
|
el.setAttribute("data-ez-list", "true");
|
|
320
400
|
|
|
321
|
-
el.innerHTML = '';
|
|
322
401
|
for (let i = 0; i < data.length; i++) {
|
|
402
|
+
// Check if render is still current before each iteration
|
|
403
|
+
if (renderVersion !== currentRenderVersion) return;
|
|
404
|
+
|
|
323
405
|
if (data[i] == null) {
|
|
324
406
|
if (import.meta.env.DEV) {
|
|
325
407
|
console.warn(`[Ez] bind.data: Item at index ${i} is null/undefined. Controller: "${activeCtrl}", path: "${props!.join('.')}". Skipping.`);
|
|
@@ -340,12 +422,16 @@ export class EzBaseComponent {
|
|
|
340
422
|
}
|
|
341
423
|
// Only inherit CSS if child doesn't have its own CSS module
|
|
342
424
|
const childHasOwnCss = childCfg.css ||
|
|
343
|
-
(childCfg.eztype && ez.hasStyles(childCfg.eztype));
|
|
425
|
+
(typeof childCfg.eztype === 'string' && ez.hasStyles(childCfg.eztype));
|
|
344
426
|
if (!childHasOwnCss && this.config.css) {
|
|
345
427
|
childCfg.css = this.config.css;
|
|
346
428
|
childCfg._styleModule = this.config._styleModule;
|
|
347
429
|
}
|
|
348
430
|
const childEl = await ez._createElement(childCfg);
|
|
431
|
+
|
|
432
|
+
// Final check before appending
|
|
433
|
+
if (renderVersion !== currentRenderVersion) return;
|
|
434
|
+
|
|
349
435
|
el.appendChild(childEl);
|
|
350
436
|
}
|
|
351
437
|
}
|
|
@@ -541,8 +627,17 @@ export class EzBaseComponent {
|
|
|
541
627
|
}
|
|
542
628
|
|
|
543
629
|
applyStyles(el: HTMLElement): void {
|
|
544
|
-
|
|
545
|
-
|
|
630
|
+
// Extract style shortcuts from config
|
|
631
|
+
const { styles: shortcutStyles } = extractStyleShortcuts(this.config as Record<string, unknown>);
|
|
632
|
+
|
|
633
|
+
// Merge shortcuts with explicit style (explicit style takes priority)
|
|
634
|
+
const finalStyles = mergeStyles(
|
|
635
|
+
shortcutStyles,
|
|
636
|
+
this.config.style as Record<string, string> | undefined
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
if (Object.keys(finalStyles).length > 0) {
|
|
640
|
+
Object.assign(el.style, finalStyles);
|
|
546
641
|
}
|
|
547
642
|
}
|
|
548
643
|
|
|
@@ -29,7 +29,7 @@ export class EzComponent extends EzBaseComponent {
|
|
|
29
29
|
|
|
30
30
|
async render(): Promise<HTMLElement> {
|
|
31
31
|
const el = document.createElement('div');
|
|
32
|
-
const { layout
|
|
32
|
+
const { layout } = this.config;
|
|
33
33
|
|
|
34
34
|
// 📦 Predefined layouts
|
|
35
35
|
if (layout === 'hbox') {
|
|
@@ -42,8 +42,8 @@ export class EzComponent extends EzBaseComponent {
|
|
|
42
42
|
el.style.flexDirection = 'column';
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// 🎨
|
|
46
|
-
|
|
45
|
+
// 🎨 Apply styles (includes shortcuts like p, m, bg, etc.)
|
|
46
|
+
this.applyStyles(el);
|
|
47
47
|
|
|
48
48
|
if (this.config.flex) {
|
|
49
49
|
el.style.flex = String(this.config.flex);
|
package/components/EzLabel.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { EzBaseComponent, EzBaseComponentConfig } from './EzBaseComponent.js';
|
|
2
2
|
|
|
3
|
+
declare const ez: {
|
|
4
|
+
_createElement(config: unknown): Promise<HTMLElement>;
|
|
5
|
+
};
|
|
6
|
+
|
|
3
7
|
export interface EzLabelConfig extends EzBaseComponentConfig {
|
|
4
8
|
text?: string;
|
|
5
9
|
}
|
|
@@ -12,10 +16,15 @@ export class EzLabel extends EzBaseComponent {
|
|
|
12
16
|
this.config = config;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
render(): HTMLSpanElement {
|
|
16
|
-
const el =
|
|
17
|
-
|
|
19
|
+
async render(): Promise<HTMLSpanElement> {
|
|
20
|
+
const el = await ez._createElement({
|
|
21
|
+
eztype: 'span',
|
|
22
|
+
text: this.config.text
|
|
23
|
+
}) as HTMLSpanElement;
|
|
24
|
+
|
|
25
|
+
this.applyCls(el);
|
|
18
26
|
this.applyStyles(el);
|
|
27
|
+
this.applyCommonBindings(el);
|
|
19
28
|
|
|
20
29
|
return el;
|
|
21
30
|
}
|
|
@@ -4,6 +4,10 @@ import { EzBaseComponent, EzBaseComponentConfig } from '../EzBaseComponent.js';
|
|
|
4
4
|
|
|
5
5
|
const cls = cx(styles);
|
|
6
6
|
|
|
7
|
+
declare const ez: {
|
|
8
|
+
_createElement(config: unknown): Promise<HTMLElement>;
|
|
9
|
+
};
|
|
10
|
+
|
|
7
11
|
const STATUS_MAP: Record<string, string> = {
|
|
8
12
|
'online': 'statusOnline',
|
|
9
13
|
'offline': 'statusOffline',
|
|
@@ -33,82 +37,108 @@ export class EzAvatar extends EzBaseComponent {
|
|
|
33
37
|
this.config = config;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
render(): HTMLDivElement {
|
|
37
|
-
const
|
|
40
|
+
async render(): Promise<HTMLDivElement> {
|
|
41
|
+
const items: unknown[] = [];
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
// Image or initials
|
|
44
|
+
if (this.config.src) {
|
|
45
|
+
items.push({
|
|
46
|
+
eztype: 'img',
|
|
47
|
+
cls: cls('avatarImg'),
|
|
48
|
+
src: this.config.src,
|
|
49
|
+
alt: this.config.alt || this.config.name || ''
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
items.push({
|
|
53
|
+
eztype: 'span',
|
|
54
|
+
cls: cls('avatarInitials'),
|
|
55
|
+
text: this._getInitials()
|
|
56
|
+
});
|
|
57
|
+
}
|
|
40
58
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
59
|
+
// Status indicator
|
|
60
|
+
if (this.config.status) {
|
|
61
|
+
const statusClass = STATUS_MAP[this.config.status] || 'statusOffline';
|
|
62
|
+
items.push({
|
|
63
|
+
eztype: 'span',
|
|
64
|
+
cls: cls('avatarStatus', statusClass)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
|
|
68
|
+
const el = await ez._createElement({
|
|
69
|
+
eztype: 'div',
|
|
70
|
+
cls: this._buildClasses(),
|
|
71
|
+
style: this._buildStyles(),
|
|
72
|
+
onClick: this.config.onClick ? (e: MouseEvent) => {
|
|
73
|
+
this.config.onClick!(e, this);
|
|
74
|
+
} : undefined,
|
|
75
|
+
items
|
|
76
|
+
}) as HTMLDivElement;
|
|
47
77
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
// Handle image error - fallback to initials
|
|
79
|
+
if (this.config.src) {
|
|
80
|
+
const img = el.querySelector('img');
|
|
81
|
+
if (img) {
|
|
82
|
+
img.onerror = async () => {
|
|
83
|
+
img.remove();
|
|
84
|
+
const initialsEl = await ez._createElement({
|
|
85
|
+
eztype: 'span',
|
|
86
|
+
cls: cls('avatarInitials'),
|
|
87
|
+
text: this._getInitials()
|
|
88
|
+
});
|
|
89
|
+
el.insertBefore(initialsEl, el.firstChild);
|
|
90
|
+
};
|
|
61
91
|
}
|
|
62
92
|
}
|
|
63
93
|
|
|
94
|
+
this.applyStyles(el);
|
|
95
|
+
|
|
96
|
+
return el;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private _buildClasses(): string[] {
|
|
100
|
+
const classes: string[] = [cls('avatar')];
|
|
101
|
+
|
|
64
102
|
if (this.config.variant) {
|
|
65
|
-
|
|
103
|
+
classes.push(cls(this.config.variant));
|
|
66
104
|
}
|
|
67
105
|
|
|
68
106
|
if (this.config.color) {
|
|
69
|
-
|
|
107
|
+
classes.push(cls(this.config.color));
|
|
70
108
|
}
|
|
71
109
|
|
|
72
110
|
if (this.config.onClick) {
|
|
73
|
-
|
|
74
|
-
el.addEventListener('click', e => {
|
|
75
|
-
this.config.onClick!(e, this);
|
|
76
|
-
});
|
|
111
|
+
classes.push(cls('clickable'));
|
|
77
112
|
}
|
|
78
113
|
|
|
79
|
-
if (this.config.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
img.src = this.config.src;
|
|
83
|
-
img.alt = this.config.alt || this.config.name || '';
|
|
114
|
+
if (typeof this.config.size === 'string') {
|
|
115
|
+
classes.push(cls(this.config.size));
|
|
116
|
+
}
|
|
84
117
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
el.appendChild(this._createInitials());
|
|
88
|
-
};
|
|
118
|
+
return classes;
|
|
119
|
+
}
|
|
89
120
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
el.appendChild(this._createInitials());
|
|
93
|
-
}
|
|
121
|
+
private _buildStyles(): Record<string, string> | undefined {
|
|
122
|
+
const styles: Record<string, string> = {};
|
|
94
123
|
|
|
95
|
-
if (this.config.
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
status.className = cls('avatarStatus', statusClass);
|
|
99
|
-
el.appendChild(status);
|
|
100
|
-
}
|
|
124
|
+
if (this.config.width || this.config.height) {
|
|
125
|
+
const width = this.config.width || this.config.height;
|
|
126
|
+
const height = this.config.height || this.config.width;
|
|
101
127
|
|
|
102
|
-
|
|
128
|
+
styles.width = typeof width === 'number' ? `${width}px` : String(width);
|
|
129
|
+
styles.height = typeof height === 'number' ? `${height}px` : String(height);
|
|
103
130
|
|
|
104
|
-
|
|
105
|
-
|
|
131
|
+
const sizeNum = typeof width === 'number' ? width : parseInt(String(width), 10);
|
|
132
|
+
if (sizeNum) {
|
|
133
|
+
styles.fontSize = `${Math.round(sizeNum * 0.4)}px`;
|
|
134
|
+
}
|
|
135
|
+
} else if (typeof this.config.size === 'number') {
|
|
136
|
+
styles.width = `${this.config.size}px`;
|
|
137
|
+
styles.height = `${this.config.size}px`;
|
|
138
|
+
styles.fontSize = `${Math.round(this.config.size * 0.4)}px`;
|
|
139
|
+
}
|
|
106
140
|
|
|
107
|
-
|
|
108
|
-
const initialsEl = document.createElement('span');
|
|
109
|
-
initialsEl.className = cls('avatarInitials');
|
|
110
|
-
initialsEl.textContent = this._getInitials();
|
|
111
|
-
return initialsEl;
|
|
141
|
+
return Object.keys(styles).length > 0 ? styles : undefined;
|
|
112
142
|
}
|
|
113
143
|
|
|
114
144
|
private _getInitials(): string {
|
|
@@ -4,6 +4,10 @@ import { EzBaseComponent, EzBaseComponentConfig } from '../EzBaseComponent.js';
|
|
|
4
4
|
|
|
5
5
|
const cls = cx(styles);
|
|
6
6
|
|
|
7
|
+
declare const ez: {
|
|
8
|
+
_createElement(config: unknown): Promise<HTMLElement>;
|
|
9
|
+
};
|
|
10
|
+
|
|
7
11
|
export interface EzBadgeConfig extends EzBaseComponentConfig {
|
|
8
12
|
variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
9
13
|
size?: 'sm' | 'lg';
|
|
@@ -21,53 +25,68 @@ export class EzBadge extends EzBaseComponent {
|
|
|
21
25
|
declare config: EzBadgeConfig;
|
|
22
26
|
declare el: HTMLSpanElement;
|
|
23
27
|
|
|
24
|
-
render(): HTMLSpanElement {
|
|
28
|
+
async render(): Promise<HTMLSpanElement> {
|
|
25
29
|
const cfg = this.config;
|
|
26
30
|
|
|
27
|
-
const
|
|
28
|
-
badge.className = cls(
|
|
31
|
+
const classes = cls(
|
|
29
32
|
'badge',
|
|
30
33
|
cfg.variant || 'default',
|
|
31
34
|
cfg.size,
|
|
32
35
|
cfg.pill && 'pill',
|
|
33
36
|
cfg.outline && 'outline',
|
|
34
|
-
cfg.dot && 'dot'
|
|
37
|
+
cfg.dot && 'dot',
|
|
38
|
+
cfg.onClick && 'clickable'
|
|
35
39
|
);
|
|
36
40
|
|
|
41
|
+
// Dot badge has no content
|
|
37
42
|
if (cfg.dot) {
|
|
43
|
+
const badge = await ez._createElement({
|
|
44
|
+
eztype: 'span',
|
|
45
|
+
cls: classes
|
|
46
|
+
}) as HTMLSpanElement;
|
|
47
|
+
|
|
48
|
+
this.applyStyles(badge);
|
|
49
|
+
this.el = badge;
|
|
38
50
|
return badge;
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
const items: unknown[] = [];
|
|
54
|
+
|
|
41
55
|
if (cfg.icon) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
items.push({
|
|
57
|
+
eztype: 'i',
|
|
58
|
+
cls: [cls('icon'), cfg.icon].join(' ')
|
|
59
|
+
});
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
if (cfg.text !== undefined) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
63
|
+
items.push({
|
|
64
|
+
eztype: 'span',
|
|
65
|
+
cls: cls('text'),
|
|
66
|
+
text: String(cfg.text)
|
|
67
|
+
});
|
|
52
68
|
}
|
|
53
69
|
|
|
54
70
|
if (cfg.closable) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
e
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
items.push({
|
|
72
|
+
eztype: 'button',
|
|
73
|
+
type: 'button',
|
|
74
|
+
cls: cls('close'),
|
|
75
|
+
items: [{ eztype: 'i', cls: 'fa-solid fa-xmark' }],
|
|
76
|
+
onClick: (e: MouseEvent) => {
|
|
77
|
+
e.stopPropagation();
|
|
78
|
+
if (cfg.onClose) cfg.onClose(e);
|
|
79
|
+
this.el?.remove();
|
|
80
|
+
}
|
|
63
81
|
});
|
|
64
|
-
badge.appendChild(close);
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
const badge = await ez._createElement({
|
|
85
|
+
eztype: 'span',
|
|
86
|
+
cls: classes,
|
|
87
|
+
onClick: cfg.onClick,
|
|
88
|
+
items
|
|
89
|
+
}) as HTMLSpanElement;
|
|
71
90
|
|
|
72
91
|
this.applyStyles(badge);
|
|
73
92
|
this.el = badge;
|
|
@@ -124,7 +124,7 @@ export class EzButton extends EzBaseComponent {
|
|
|
124
124
|
return items;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
private _applyLoadingState(el: HTMLButtonElement, loading: boolean): void {
|
|
127
|
+
private async _applyLoadingState(el: HTMLButtonElement, loading: boolean): Promise<void> {
|
|
128
128
|
const spinnerClass = cls('spinner');
|
|
129
129
|
|
|
130
130
|
if (loading) {
|
|
@@ -132,8 +132,10 @@ export class EzButton extends EzBaseComponent {
|
|
|
132
132
|
el.disabled = true;
|
|
133
133
|
|
|
134
134
|
if (!el.querySelector(`.${spinnerClass}`)) {
|
|
135
|
-
const spinner =
|
|
136
|
-
|
|
135
|
+
const spinner = await ez._createElement({
|
|
136
|
+
eztype: 'span',
|
|
137
|
+
cls: spinnerClass
|
|
138
|
+
});
|
|
137
139
|
el.insertBefore(spinner, el.firstChild);
|
|
138
140
|
}
|
|
139
141
|
} else {
|
|
@@ -25,20 +25,17 @@ export class EzButtonGroup extends EzBaseComponent {
|
|
|
25
25
|
|
|
26
26
|
async render(): Promise<HTMLDivElement> {
|
|
27
27
|
const cfg = this.config;
|
|
28
|
-
const el = document.createElement('div');
|
|
29
|
-
|
|
30
|
-
el.classList.add(cls('buttonGroup'));
|
|
31
28
|
|
|
29
|
+
const classes = [cls('buttonGroup')];
|
|
32
30
|
if (cfg.vertical) {
|
|
33
|
-
|
|
31
|
+
classes.push(cls('buttonGroupVertical'));
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
34
|
+
const el = await ez._createElement({
|
|
35
|
+
eztype: 'div',
|
|
36
|
+
cls: classes.join(' '),
|
|
37
|
+
items: cfg.items || []
|
|
38
|
+
}, cfg.controller || null, this) as HTMLDivElement;
|
|
42
39
|
|
|
43
40
|
this.applyStyles(el);
|
|
44
41
|
this.el = el;
|
|
@@ -69,10 +69,11 @@ export class EzCard extends EzBaseComponent {
|
|
|
69
69
|
result.push(this._buildHeader());
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Body
|
|
72
|
+
// Body - propagate parent CSS to children
|
|
73
73
|
result.push({
|
|
74
74
|
eztype: 'div',
|
|
75
75
|
cls: noPadding ? [cls('body'), cls('noPadding')] : cls('body'),
|
|
76
|
+
css: this.config.css,
|
|
76
77
|
items: items
|
|
77
78
|
});
|
|
78
79
|
|
|
@@ -2,6 +2,7 @@ import { EzBaseComponent, EzBaseComponentConfig } from '../EzBaseComponent.js';
|
|
|
2
2
|
import styles from './EzChart.module.scss';
|
|
3
3
|
|
|
4
4
|
declare const ez: {
|
|
5
|
+
_createElement(config: unknown): Promise<HTMLElement>;
|
|
5
6
|
registerComponent(name: string, component: unknown): void;
|
|
6
7
|
};
|
|
7
8
|
|
|
@@ -123,23 +124,27 @@ export class EzChart extends EzBaseComponent {
|
|
|
123
124
|
|
|
124
125
|
const { height = 280, cls = '' } = this.config;
|
|
125
126
|
|
|
126
|
-
const el =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
127
|
+
const el = await ez._createElement({
|
|
128
|
+
eztype: 'div',
|
|
129
|
+
cls: [styles.container, cls].filter(Boolean).join(' '),
|
|
130
|
+
style: {
|
|
131
|
+
height: height ? (typeof height === 'number' ? `${height}px` : height) : undefined,
|
|
132
|
+
...this.config.style as object
|
|
133
|
+
},
|
|
134
|
+
items: [
|
|
135
|
+
{
|
|
136
|
+
eztype: 'canvas',
|
|
137
|
+
_ezAfterRender: (canvas: HTMLCanvasElement) => {
|
|
138
|
+
this._canvas = canvas;
|
|
139
|
+
requestAnimationFrame(() => {
|
|
140
|
+
this._initChart(canvas);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}) as HTMLElement;
|
|
140
146
|
|
|
141
147
|
this._el = el;
|
|
142
|
-
this._canvas = canvas;
|
|
143
148
|
return el;
|
|
144
149
|
}
|
|
145
150
|
|