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.
Files changed (43) hide show
  1. package/components/EzBaseComponent.ts +100 -5
  2. package/components/EzComponent.ts +3 -3
  3. package/components/EzLabel.ts +12 -3
  4. package/components/avatar/EzAvatar.ts +84 -54
  5. package/components/badge/EzBadge.ts +43 -24
  6. package/components/button/EzButton.ts +5 -3
  7. package/components/button/EzButtonGroup.ts +7 -10
  8. package/components/card/EzCard.ts +2 -1
  9. package/components/chart/EzChart.ts +20 -15
  10. package/components/checkbox/EzCheckbox.ts +47 -43
  11. package/components/dataview/EzDataView.ts +14 -29
  12. package/components/dataview/modes/EzDataViewCards.ts +51 -41
  13. package/components/dataview/modes/EzDataViewGrid.ts +5 -2
  14. package/components/datepicker/EzDatePicker.ts +2 -2
  15. package/components/dialog/EzDialog.ts +84 -67
  16. package/components/dropdown/EzDropdown.ts +72 -58
  17. package/components/form/EzForm.ts +45 -37
  18. package/components/kanban/EzKanban.module.scss +221 -0
  19. package/components/kanban/EzKanban.ts +222 -0
  20. package/components/kanban/EzKanbanTypes.ts +166 -0
  21. package/components/kanban/board/EzKanbanBoard.ts +117 -0
  22. package/components/kanban/card/EzKanbanCard.module.scss +173 -0
  23. package/components/kanban/card/EzKanbanCard.ts +275 -0
  24. package/components/kanban/card/EzKanbanCardEditor.ts +209 -0
  25. package/components/kanban/column/EzKanbanColumn.ts +253 -0
  26. package/components/kanban/state/EzKanbanController.ts +373 -0
  27. package/components/kanban/state/EzKanbanDragDrop.ts +226 -0
  28. package/components/panel/EzPanel.ts +59 -68
  29. package/components/picker/EzPicker.module.scss +14 -0
  30. package/components/picker/EzPicker.ts +118 -0
  31. package/components/radio/EzRadio.ts +55 -47
  32. package/components/select/EzSelect.ts +48 -44
  33. package/components/skeleton/EzSkeleton.ts +31 -26
  34. package/components/switch/EzSwitch.ts +52 -44
  35. package/components/tabs/EzTabPanel.ts +52 -48
  36. package/components/textarea/EzTextarea.ts +69 -54
  37. package/components/timepicker/EzTimePicker.ts +2 -2
  38. package/components/tooltip/EzTooltip.ts +20 -33
  39. package/core/ez.ts +7 -0
  40. package/core/loader.ts +2 -0
  41. package/core/renderer.ts +80 -4
  42. package/core/styleShortcuts.ts +418 -0
  43. package/package.json +1 -1
@@ -442,7 +442,7 @@ export class EzTimePicker extends EzBaseComponent {
442
442
  this._close();
443
443
  }
444
444
  };
445
- document.addEventListener('click', this._outsideClickHandler);
445
+ document.addEventListener('click', this._outsideClickHandler, true);
446
446
 
447
447
  this._input.addEventListener('keydown', (e) => {
448
448
  if (e.key === 'Escape') {
@@ -530,7 +530,7 @@ export class EzTimePicker extends EzBaseComponent {
530
530
 
531
531
  destroy(): void {
532
532
  if (this._outsideClickHandler) {
533
- document.removeEventListener('click', this._outsideClickHandler);
533
+ document.removeEventListener('click', this._outsideClickHandler, true);
534
534
  }
535
535
  if (this._dropdown && this._dropdown.parentNode) {
536
536
  this._dropdown.parentNode.removeChild(this._dropdown);
@@ -3,6 +3,7 @@ import { cx } from '../../utils/cssModules.js';
3
3
  import { EzBaseComponent, EzBaseComponentConfig } from '../EzBaseComponent.js';
4
4
 
5
5
  declare const ez: {
6
+ _createElement(config: unknown, controller?: string | null, parent?: unknown): Promise<HTMLElement>;
6
7
  _createChildElements(items: unknown[], controller: string | null, state: unknown): Promise<Node[]>;
7
8
  };
8
9
 
@@ -33,34 +34,25 @@ export class EzTooltip extends EzBaseComponent {
33
34
  async render(): Promise<HTMLElement> {
34
35
  const cfg = this.config;
35
36
 
36
- const wrapper = document.createElement('div');
37
- wrapper.className = cls('tooltipWrapper');
38
-
39
- if (cfg.items && cfg.items.length > 0) {
40
- const children = await ez._createChildElements(
41
- cfg.items,
42
- this.config.controller || null,
43
- null
44
- );
45
- for (const child of children) {
46
- if (child instanceof Node) {
47
- wrapper.appendChild(child);
48
- }
49
- }
50
- }
51
-
52
- const tooltip = document.createElement('div');
53
- tooltip.className = cls(
54
- 'tooltip',
55
- cfg.variant || 'dark'
56
- );
57
- tooltip.textContent = cfg.text || '';
58
- tooltip.style.opacity = '0';
59
- tooltip.style.visibility = 'hidden';
60
-
61
- const arrow = document.createElement('div');
62
- arrow.className = cls('arrow');
63
- tooltip.appendChild(arrow);
37
+ const wrapper = await ez._createElement({
38
+ eztype: 'div',
39
+ cls: cls('tooltipWrapper'),
40
+ items: cfg.items || [],
41
+ onMouseEnter: () => this._scheduleShow(),
42
+ onMouseLeave: () => this._scheduleHide(),
43
+ onFocus: () => this._scheduleShow(),
44
+ onBlur: () => this._scheduleHide()
45
+ }, this.config.controller || null, this) as HTMLElement;
46
+
47
+ const tooltip = await ez._createElement({
48
+ eztype: 'div',
49
+ cls: cls('tooltip', cfg.variant || 'dark'),
50
+ text: cfg.text || '',
51
+ style: { opacity: '0', visibility: 'hidden' },
52
+ items: [
53
+ { eztype: 'div', cls: cls('arrow') }
54
+ ]
55
+ }) as HTMLElement;
64
56
 
65
57
  document.body.appendChild(tooltip);
66
58
 
@@ -70,11 +62,6 @@ export class EzTooltip extends EzBaseComponent {
70
62
  this._delay = cfg.delay ?? 200;
71
63
  this._hideDelay = cfg.hideDelay ?? 0;
72
64
 
73
- wrapper.addEventListener('mouseenter', () => this._scheduleShow());
74
- wrapper.addEventListener('mouseleave', () => this._scheduleHide());
75
- wrapper.addEventListener('focus', () => this._scheduleShow(), true);
76
- wrapper.addEventListener('blur', () => this._scheduleHide(), true);
77
-
78
65
  return wrapper;
79
66
  }
80
67
 
package/core/ez.ts CHANGED
@@ -152,7 +152,9 @@ export interface EzFramework {
152
152
  registerComponent(eztype: string, cls: unknown): void;
153
153
  installModules(mods: Record<string, () => Promise<unknown>>): void;
154
154
  installStyles(styles: Record<string, () => Promise<unknown>>): void;
155
+ readonly _modules: Record<string, () => Promise<unknown>>;
155
156
  hasStyles(name: string): boolean;
157
+ getStylesSync(name: string): Record<string, string> | null;
156
158
  resolveStyles(name: string): Promise<Record<string, string> | null>;
157
159
  get(name: string): unknown;
158
160
  getController(name: string): Promise<ControllerDefinition> | ControllerDefinition;
@@ -337,6 +339,11 @@ const ez: EzFramework = {
337
339
  this._styles = styles;
338
340
  },
339
341
 
342
+ // Expose modules for island hydration runtime
343
+ get _modules(): Record<string, () => Promise<unknown>> {
344
+ return this._loader?.getModules() || {};
345
+ },
346
+
340
347
  hasStyles(name: string): boolean {
341
348
  if (!name || !this._styles) return false;
342
349
  const lowerName = name.toLowerCase();
package/core/loader.ts CHANGED
@@ -65,6 +65,8 @@ interface EzInstance {
65
65
  };
66
66
  _router?: EzRouter;
67
67
  registerComponent(name: string, component: unknown): void;
68
+ hasStyles(name: string): boolean;
69
+ resolveStyles(name: string): Promise<Record<string, string> | null>;
68
70
  }
69
71
 
70
72
  export class EzLoader {
package/core/renderer.ts CHANGED
@@ -2,11 +2,14 @@ import { EzError } from './EzError.js';
2
2
  import { EzBaseComponent, EzBaseComponentConfig } from '../components/EzBaseComponent.js';
3
3
  import tooltipStyles from '../components/tooltip/EzTooltip.module.scss';
4
4
  import { cx } from '../utils/cssModules.js';
5
+ import { extractStyleShortcuts, mergeStyles, ALL_SHORTCUT_KEYS, EzStyleShortcuts } from './styleShortcuts.js';
5
6
 
6
7
  const tooltipCls = cx(tooltipStyles);
7
8
 
8
9
  export type LazyMode = 'visible' | 'idle';
9
10
 
11
+ type StyleValue = string | number | undefined;
12
+
10
13
  export interface ComponentConfig extends EzBaseComponentConfig {
11
14
  eztype?: string;
12
15
  controller?: string;
@@ -40,6 +43,72 @@ export interface ComponentConfig extends EzBaseComponentConfig {
40
43
  routeParams?: Record<string, string>;
41
44
  layout?: string;
42
45
  style?: Record<string, string>;
46
+
47
+ // Style shortcuts - Spacing
48
+ p?: StyleValue;
49
+ pt?: StyleValue;
50
+ pr?: StyleValue;
51
+ pb?: StyleValue;
52
+ pl?: StyleValue;
53
+ px?: StyleValue;
54
+ py?: StyleValue;
55
+ m?: StyleValue;
56
+ mt?: StyleValue;
57
+ mr?: StyleValue;
58
+ mb?: StyleValue;
59
+ ml?: StyleValue;
60
+ mx?: StyleValue;
61
+ my?: StyleValue;
62
+ gap?: StyleValue;
63
+
64
+ // Style shortcuts - Sizing
65
+ w?: StyleValue;
66
+ h?: StyleValue;
67
+ minW?: StyleValue;
68
+ maxW?: StyleValue;
69
+ minH?: StyleValue;
70
+ maxH?: StyleValue;
71
+
72
+ // Style shortcuts - Flexbox
73
+ justify?: string;
74
+ align?: string;
75
+ alignSelf?: string;
76
+ wrap?: string | boolean;
77
+
78
+ // Style shortcuts - Typography
79
+ fs?: StyleValue;
80
+ fw?: StyleValue;
81
+ ta?: string;
82
+ lh?: StyleValue;
83
+
84
+ // Style shortcuts - Visual
85
+ bg?: string;
86
+ color?: string;
87
+ rounded?: StyleValue | boolean;
88
+ br?: StyleValue | boolean;
89
+ brt?: StyleValue;
90
+ brb?: StyleValue;
91
+ brl?: StyleValue;
92
+ brr?: StyleValue;
93
+ brtl?: StyleValue;
94
+ brtr?: StyleValue;
95
+ brbl?: StyleValue;
96
+ brbr?: StyleValue;
97
+ shadow?: string;
98
+ opacity?: number;
99
+
100
+ // Style shortcuts - Layout
101
+ d?: string;
102
+ pos?: string;
103
+ z?: number;
104
+ overflow?: string;
105
+ top?: StyleValue;
106
+ right?: StyleValue;
107
+ bottom?: StyleValue;
108
+ left?: StyleValue;
109
+
110
+ // Wrapper for grouping shortcuts
111
+ ezStyle?: EzStyleShortcuts;
43
112
  }
44
113
 
45
114
  interface TooltipConfig {
@@ -457,6 +526,7 @@ export class EzRenderer {
457
526
 
458
527
  const registeredController = typeof Registered === 'object' ? Registered.controller : null;
459
528
  const activeController = config.controller || registeredController || controllerName || '';
529
+
460
530
  await this.ez._loader.resolveController(activeController);
461
531
 
462
532
  this.ez._context.controller = activeController;
@@ -670,7 +740,8 @@ export class EzRenderer {
670
740
  const inheritedEztype = merged.eztype;
671
741
  const inheritedStyle = merged.style;
672
742
 
673
- const tpl = merged.template(merged, this.ez._controllers[activeController], controllerState);
743
+ const templateProps = merged.props || merged;
744
+ const tpl = merged.template(templateProps, this.ez._controllers[activeController], controllerState);
674
745
  if (!tpl || typeof tpl !== 'object') {
675
746
  throw new EzError({
676
747
  code: 'EZ_TEMPLATE_001',
@@ -699,6 +770,11 @@ export class EzRenderer {
699
770
  if (inheritedStyle && !merged.style) {
700
771
  merged.style = inheritedStyle;
701
772
  }
773
+
774
+ // Load style module for template result if css is set but module not loaded
775
+ if (merged.css && !merged._styleModule) {
776
+ merged._styleModule = (await this.ez.resolveStyles(merged.css)) || undefined;
777
+ }
702
778
  }
703
779
 
704
780
  el = await this.createElement(merged, activeController, controllerState);
@@ -776,9 +852,9 @@ export class EzRenderer {
776
852
  const parentSource = (inheritedState as { _ezSourcePath?: string })?._ezSourcePath || null;
777
853
 
778
854
  for (const item of items) {
779
- const localItem = item?.controller
780
- ? this.cloneConfig(item)
781
- : { ...this.cloneConfig(item), controller: controllerName };
855
+ // Don't override controller here - let createElement resolve it
856
+ // based on: config.controller > registeredController > controllerName
857
+ const localItem = this.cloneConfig(item);
782
858
 
783
859
  if (!localItem._ezSourcePath) {
784
860
  localItem._ezSourcePath = parentSource || undefined;
@@ -0,0 +1,418 @@
1
+ type StyleValue = string | number | undefined;
2
+
3
+ interface StyleShortcuts {
4
+ // Spacing
5
+ p?: StyleValue;
6
+ pt?: StyleValue;
7
+ pr?: StyleValue;
8
+ pb?: StyleValue;
9
+ pl?: StyleValue;
10
+ px?: StyleValue;
11
+ py?: StyleValue;
12
+ m?: StyleValue;
13
+ mt?: StyleValue;
14
+ mr?: StyleValue;
15
+ mb?: StyleValue;
16
+ ml?: StyleValue;
17
+ mx?: StyleValue;
18
+ my?: StyleValue;
19
+ gap?: StyleValue;
20
+
21
+ // Sizing
22
+ w?: StyleValue;
23
+ h?: StyleValue;
24
+ minW?: StyleValue;
25
+ maxW?: StyleValue;
26
+ minH?: StyleValue;
27
+ maxH?: StyleValue;
28
+
29
+ // Flexbox
30
+ justify?: string;
31
+ align?: string;
32
+ alignSelf?: string;
33
+ wrap?: string | boolean;
34
+
35
+ // Typography
36
+ fs?: StyleValue;
37
+ fw?: StyleValue;
38
+ ta?: string;
39
+ lh?: StyleValue;
40
+
41
+ // Visual
42
+ bg?: string;
43
+ color?: string;
44
+ rounded?: StyleValue | boolean;
45
+ br?: StyleValue | boolean;
46
+ brt?: StyleValue;
47
+ brb?: StyleValue;
48
+ brl?: StyleValue;
49
+ brr?: StyleValue;
50
+ brtl?: StyleValue;
51
+ brtr?: StyleValue;
52
+ brbl?: StyleValue;
53
+ brbr?: StyleValue;
54
+ shadow?: string;
55
+ opacity?: number;
56
+
57
+ // Layout
58
+ d?: string;
59
+ pos?: string;
60
+ z?: number;
61
+ overflow?: string;
62
+ top?: StyleValue;
63
+ right?: StyleValue;
64
+ bottom?: StyleValue;
65
+ left?: StyleValue;
66
+
67
+ // Wrapper for grouping shortcuts
68
+ ezStyle?: Omit<StyleShortcuts, 'ezStyle'>;
69
+ }
70
+
71
+ const SHADOW_PRESETS: Record<string, string> = {
72
+ none: 'none',
73
+ sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
74
+ md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
75
+ lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
76
+ xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
77
+ '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
78
+ inner: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)'
79
+ };
80
+
81
+ const FRACTION_MAP: Record<string, string> = {
82
+ 'full': '100%',
83
+ 'half': '50%',
84
+ '1/2': '50%',
85
+ '1/3': '33.333333%',
86
+ '2/3': '66.666667%',
87
+ '1/4': '25%',
88
+ '2/4': '50%',
89
+ '3/4': '75%',
90
+ '1/5': '20%',
91
+ '2/5': '40%',
92
+ '3/5': '60%',
93
+ '4/5': '80%',
94
+ '1/6': '16.666667%',
95
+ '5/6': '83.333333%',
96
+ 'auto': 'auto',
97
+ 'fit': 'fit-content',
98
+ 'min': 'min-content',
99
+ 'max': 'max-content',
100
+ 'screen': '100vh',
101
+ 'screenW': '100vw'
102
+ };
103
+
104
+ const JUSTIFY_MAP: Record<string, string> = {
105
+ start: 'flex-start',
106
+ end: 'flex-end',
107
+ center: 'center',
108
+ between: 'space-between',
109
+ around: 'space-around',
110
+ evenly: 'space-evenly',
111
+ stretch: 'stretch'
112
+ };
113
+
114
+ const ALIGN_MAP: Record<string, string> = {
115
+ start: 'flex-start',
116
+ end: 'flex-end',
117
+ center: 'center',
118
+ baseline: 'baseline',
119
+ stretch: 'stretch'
120
+ };
121
+
122
+ function convertValue(value: StyleValue, defaultUnit: string = 'rem'): string {
123
+ if (value === undefined || value === null) return '';
124
+
125
+ if (typeof value === 'string') {
126
+ if (FRACTION_MAP[value]) {
127
+ return FRACTION_MAP[value];
128
+ }
129
+ return value;
130
+ }
131
+
132
+ if (typeof value === 'number') {
133
+ if (value === 0) return '0';
134
+ return `${value}${defaultUnit}`;
135
+ }
136
+
137
+ return String(value);
138
+ }
139
+
140
+ function convertPixelValue(value: StyleValue): string {
141
+ if (value === undefined || value === null) return '';
142
+
143
+ if (typeof value === 'string') {
144
+ if (FRACTION_MAP[value]) {
145
+ return FRACTION_MAP[value];
146
+ }
147
+ return value;
148
+ }
149
+
150
+ if (typeof value === 'number') {
151
+ if (value === 0) return '0';
152
+ return `${value}px`;
153
+ }
154
+
155
+ return String(value);
156
+ }
157
+
158
+ export function extractStyleShortcuts(config: Record<string, unknown>): {
159
+ styles: Record<string, string>;
160
+ cleanConfig: Record<string, unknown>;
161
+ } {
162
+ const cleanConfig: Record<string, unknown> = {};
163
+
164
+ const shortcutKeys = new Set([
165
+ 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py',
166
+ 'm', 'mt', 'mr', 'mb', 'ml', 'mx', 'my',
167
+ 'gap', 'w', 'h', 'minW', 'maxW', 'minH', 'maxH',
168
+ 'justify', 'align', 'alignSelf', 'wrap',
169
+ 'fs', 'fw', 'ta', 'lh',
170
+ 'bg', 'color', 'rounded', 'br', 'brt', 'brb', 'brl', 'brr',
171
+ 'brtl', 'brtr', 'brbl', 'brbr', 'shadow', 'opacity',
172
+ 'd', 'pos', 'z', 'overflow',
173
+ 'top', 'right', 'bottom', 'left',
174
+ 'ezStyle'
175
+ ]);
176
+
177
+ for (const key in config) {
178
+ if (!shortcutKeys.has(key)) {
179
+ cleanConfig[key] = config[key];
180
+ }
181
+ }
182
+
183
+ // Merge ezStyle with top-level shortcuts (top-level takes priority)
184
+ const ezStyleObj = (config.ezStyle as Record<string, unknown>) || {};
185
+ const mergedShortcuts = { ...ezStyleObj, ...config } as StyleShortcuts;
186
+ delete (mergedShortcuts as Record<string, unknown>).ezStyle;
187
+
188
+ const shortcuts = mergedShortcuts;
189
+ const styles: Record<string, string> = {};
190
+
191
+ // Padding
192
+ if (shortcuts.p !== undefined) {
193
+ styles.padding = convertValue(shortcuts.p);
194
+ }
195
+ if (shortcuts.pt !== undefined) {
196
+ styles.paddingTop = convertValue(shortcuts.pt);
197
+ }
198
+ if (shortcuts.pr !== undefined) {
199
+ styles.paddingRight = convertValue(shortcuts.pr);
200
+ }
201
+ if (shortcuts.pb !== undefined) {
202
+ styles.paddingBottom = convertValue(shortcuts.pb);
203
+ }
204
+ if (shortcuts.pl !== undefined) {
205
+ styles.paddingLeft = convertValue(shortcuts.pl);
206
+ }
207
+ if (shortcuts.px !== undefined) {
208
+ const val = convertValue(shortcuts.px);
209
+ styles.paddingLeft = val;
210
+ styles.paddingRight = val;
211
+ }
212
+ if (shortcuts.py !== undefined) {
213
+ const val = convertValue(shortcuts.py);
214
+ styles.paddingTop = val;
215
+ styles.paddingBottom = val;
216
+ }
217
+
218
+ // Margin
219
+ if (shortcuts.m !== undefined) {
220
+ styles.margin = convertValue(shortcuts.m);
221
+ }
222
+ if (shortcuts.mt !== undefined) {
223
+ styles.marginTop = convertValue(shortcuts.mt);
224
+ }
225
+ if (shortcuts.mr !== undefined) {
226
+ styles.marginRight = convertValue(shortcuts.mr);
227
+ }
228
+ if (shortcuts.mb !== undefined) {
229
+ styles.marginBottom = convertValue(shortcuts.mb);
230
+ }
231
+ if (shortcuts.ml !== undefined) {
232
+ styles.marginLeft = convertValue(shortcuts.ml);
233
+ }
234
+ if (shortcuts.mx !== undefined) {
235
+ const val = convertValue(shortcuts.mx);
236
+ styles.marginLeft = val;
237
+ styles.marginRight = val;
238
+ }
239
+ if (shortcuts.my !== undefined) {
240
+ const val = convertValue(shortcuts.my);
241
+ styles.marginTop = val;
242
+ styles.marginBottom = val;
243
+ }
244
+
245
+ // Gap
246
+ if (shortcuts.gap !== undefined) {
247
+ styles.gap = convertValue(shortcuts.gap);
248
+ }
249
+
250
+ // Sizing
251
+ if (shortcuts.w !== undefined) {
252
+ styles.width = convertPixelValue(shortcuts.w);
253
+ }
254
+ if (shortcuts.h !== undefined) {
255
+ styles.height = convertPixelValue(shortcuts.h);
256
+ }
257
+ if (shortcuts.minW !== undefined) {
258
+ styles.minWidth = convertPixelValue(shortcuts.minW);
259
+ }
260
+ if (shortcuts.maxW !== undefined) {
261
+ styles.maxWidth = convertPixelValue(shortcuts.maxW);
262
+ }
263
+ if (shortcuts.minH !== undefined) {
264
+ styles.minHeight = convertPixelValue(shortcuts.minH);
265
+ }
266
+ if (shortcuts.maxH !== undefined) {
267
+ styles.maxHeight = convertPixelValue(shortcuts.maxH);
268
+ }
269
+
270
+ // Flexbox
271
+ if (shortcuts.justify !== undefined) {
272
+ styles.justifyContent = JUSTIFY_MAP[shortcuts.justify] || shortcuts.justify;
273
+ }
274
+ if (shortcuts.align !== undefined) {
275
+ styles.alignItems = ALIGN_MAP[shortcuts.align] || shortcuts.align;
276
+ }
277
+ if (shortcuts.alignSelf !== undefined) {
278
+ styles.alignSelf = ALIGN_MAP[shortcuts.alignSelf] || shortcuts.alignSelf;
279
+ }
280
+ if (shortcuts.wrap !== undefined) {
281
+ if (typeof shortcuts.wrap === 'boolean') {
282
+ styles.flexWrap = shortcuts.wrap ? 'wrap' : 'nowrap';
283
+ } else {
284
+ styles.flexWrap = shortcuts.wrap;
285
+ }
286
+ }
287
+
288
+ // Typography
289
+ if (shortcuts.fs !== undefined) {
290
+ styles.fontSize = convertValue(shortcuts.fs);
291
+ }
292
+ if (shortcuts.fw !== undefined) {
293
+ styles.fontWeight = String(shortcuts.fw);
294
+ }
295
+ if (shortcuts.ta !== undefined) {
296
+ styles.textAlign = shortcuts.ta;
297
+ }
298
+ if (shortcuts.lh !== undefined) {
299
+ styles.lineHeight = typeof shortcuts.lh === 'number'
300
+ ? String(shortcuts.lh)
301
+ : shortcuts.lh;
302
+ }
303
+
304
+ // Visual
305
+ if (shortcuts.bg !== undefined) {
306
+ styles.background = shortcuts.bg;
307
+ }
308
+ if (shortcuts.color !== undefined) {
309
+ styles.color = shortcuts.color;
310
+ }
311
+ // Border radius - rounded and br are aliases
312
+ const brValue = shortcuts.br ?? shortcuts.rounded;
313
+ if (brValue !== undefined) {
314
+ if (typeof brValue === 'boolean') {
315
+ if (brValue) {
316
+ styles.borderRadius = '0.5rem';
317
+ }
318
+ } else {
319
+ styles.borderRadius = convertValue(brValue);
320
+ }
321
+ }
322
+ if (shortcuts.brt !== undefined) {
323
+ const val = convertValue(shortcuts.brt);
324
+ styles.borderTopLeftRadius = val;
325
+ styles.borderTopRightRadius = val;
326
+ }
327
+ if (shortcuts.brb !== undefined) {
328
+ const val = convertValue(shortcuts.brb);
329
+ styles.borderBottomLeftRadius = val;
330
+ styles.borderBottomRightRadius = val;
331
+ }
332
+ if (shortcuts.brl !== undefined) {
333
+ const val = convertValue(shortcuts.brl);
334
+ styles.borderTopLeftRadius = val;
335
+ styles.borderBottomLeftRadius = val;
336
+ }
337
+ if (shortcuts.brr !== undefined) {
338
+ const val = convertValue(shortcuts.brr);
339
+ styles.borderTopRightRadius = val;
340
+ styles.borderBottomRightRadius = val;
341
+ }
342
+ if (shortcuts.brtl !== undefined) {
343
+ styles.borderTopLeftRadius = convertValue(shortcuts.brtl);
344
+ }
345
+ if (shortcuts.brtr !== undefined) {
346
+ styles.borderTopRightRadius = convertValue(shortcuts.brtr);
347
+ }
348
+ if (shortcuts.brbl !== undefined) {
349
+ styles.borderBottomLeftRadius = convertValue(shortcuts.brbl);
350
+ }
351
+ if (shortcuts.brbr !== undefined) {
352
+ styles.borderBottomRightRadius = convertValue(shortcuts.brbr);
353
+ }
354
+ if (shortcuts.shadow !== undefined) {
355
+ styles.boxShadow = SHADOW_PRESETS[shortcuts.shadow] || shortcuts.shadow;
356
+ }
357
+ if (shortcuts.opacity !== undefined) {
358
+ styles.opacity = String(shortcuts.opacity);
359
+ }
360
+
361
+ // Layout
362
+ if (shortcuts.d !== undefined) {
363
+ styles.display = shortcuts.d;
364
+ }
365
+ if (shortcuts.pos !== undefined) {
366
+ styles.position = shortcuts.pos;
367
+ }
368
+ if (shortcuts.z !== undefined) {
369
+ styles.zIndex = String(shortcuts.z);
370
+ }
371
+ if (shortcuts.overflow !== undefined) {
372
+ styles.overflow = shortcuts.overflow;
373
+ }
374
+
375
+ // Position values
376
+ if (shortcuts.top !== undefined) {
377
+ styles.top = convertPixelValue(shortcuts.top);
378
+ }
379
+ if (shortcuts.right !== undefined) {
380
+ styles.right = convertPixelValue(shortcuts.right);
381
+ }
382
+ if (shortcuts.bottom !== undefined) {
383
+ styles.bottom = convertPixelValue(shortcuts.bottom);
384
+ }
385
+ if (shortcuts.left !== undefined) {
386
+ styles.left = convertPixelValue(shortcuts.left);
387
+ }
388
+
389
+ return { styles, cleanConfig };
390
+ }
391
+
392
+ export function mergeStyles(
393
+ shortcutStyles: Record<string, string>,
394
+ configStyles?: Record<string, string>
395
+ ): Record<string, string> {
396
+ if (!configStyles || Object.keys(configStyles).length === 0) {
397
+ return shortcutStyles;
398
+ }
399
+ // configStyles has priority over shortcuts
400
+ return { ...shortcutStyles, ...configStyles };
401
+ }
402
+
403
+ export type EzStyleShortcuts = Omit<StyleShortcuts, 'ezStyle'>;
404
+
405
+ export const ALL_SHORTCUT_KEYS = [
406
+ 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py',
407
+ 'm', 'mt', 'mr', 'mb', 'ml', 'mx', 'my',
408
+ 'gap', 'w', 'h', 'minW', 'maxW', 'minH', 'maxH',
409
+ 'justify', 'align', 'alignSelf', 'wrap',
410
+ 'fs', 'fw', 'ta', 'lh',
411
+ 'bg', 'color', 'rounded', 'br', 'brt', 'brb', 'brl', 'brr',
412
+ 'brtl', 'brtr', 'brbl', 'brbr', 'shadow', 'opacity',
413
+ 'd', 'pos', 'z', 'overflow',
414
+ 'top', 'right', 'bottom', 'left',
415
+ 'ezStyle'
416
+ ] as const;
417
+
418
+ export type ShortcutKey = typeof ALL_SHORTCUT_KEYS[number];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ezfw-core",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Ez Framework - A declarative component framework for building modern web applications",
5
5
  "type": "module",
6
6
  "main": "./core/ez.ts",