snice 1.14.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/templates/base/tsconfig.json +5 -4
- package/components/accordion/demo.html +403 -0
- package/components/accordion/snice-accordion-item.css +85 -0
- package/components/accordion/snice-accordion-item.ts +226 -0
- package/components/accordion/snice-accordion.css +31 -0
- package/components/accordion/snice-accordion.ts +182 -0
- package/components/accordion/snice-accordion.types.ts +32 -0
- package/components/alert/demo.html +445 -0
- package/components/alert/snice-alert.css +195 -0
- package/components/alert/snice-alert.ts +141 -0
- package/components/alert/snice-alert.types.ts +12 -0
- package/components/avatar/demo.html +598 -0
- package/components/avatar/snice-avatar.css +131 -0
- package/components/avatar/snice-avatar.ts +136 -0
- package/components/avatar/snice-avatar.types.ts +13 -0
- package/components/badge/demo.html +523 -0
- package/components/badge/snice-badge.css +161 -0
- package/components/badge/snice-badge.ts +117 -0
- package/components/badge/snice-badge.types.ts +16 -0
- package/components/breadcrumbs/demo.html +404 -0
- package/components/breadcrumbs/snice-breadcrumbs.css +133 -0
- package/components/breadcrumbs/snice-breadcrumbs.ts +191 -0
- package/components/breadcrumbs/snice-breadcrumbs.types.ts +26 -0
- package/components/breadcrumbs/snice-crumb.ts +26 -0
- package/components/button/demo.html +42 -0
- package/components/button/snice-button.css +230 -0
- package/components/button/snice-button.ts +169 -0
- package/components/button/snice-button.types.ts +25 -0
- package/components/card/demo.html +525 -0
- package/components/card/snice-card.css +140 -0
- package/components/card/snice-card.ts +102 -0
- package/components/card/snice-card.types.ts +10 -0
- package/components/checkbox/demo.html +253 -0
- package/components/checkbox/snice-checkbox.css +164 -0
- package/components/checkbox/snice-checkbox.ts +223 -0
- package/components/checkbox/snice-checkbox.types.ts +22 -0
- package/components/chip/demo.html +383 -0
- package/components/chip/snice-chip.css +195 -0
- package/components/chip/snice-chip.ts +139 -0
- package/components/chip/snice-chip.types.ts +15 -0
- package/components/date-picker/README.md +233 -0
- package/components/date-picker/demo.html +191 -0
- package/components/date-picker/snice-date-picker.css +330 -0
- package/components/date-picker/snice-date-picker.ts +777 -0
- package/components/date-picker/snice-date-picker.types.ts +83 -0
- package/components/divider/demo.html +233 -0
- package/components/divider/snice-divider.css +155 -0
- package/components/divider/snice-divider.ts +69 -0
- package/components/divider/snice-divider.types.ts +15 -0
- package/components/drawer/demo.html +328 -0
- package/components/drawer/snice-drawer.css +476 -0
- package/components/drawer/snice-drawer.ts +287 -0
- package/components/drawer/snice-drawer.types.ts +17 -0
- package/components/global.d.ts +14 -0
- package/components/input/demo.html +303 -0
- package/components/input/snice-input.css +257 -0
- package/components/input/snice-input.ts +442 -0
- package/components/input/snice-input.types.ts +59 -0
- package/components/input/test.html +77 -0
- package/components/layout/README.md +260 -0
- package/components/layout/demo.html +538 -0
- package/components/layout/snice-layout-blog.css +129 -0
- package/components/layout/snice-layout-blog.ts +48 -0
- package/components/layout/snice-layout-card.css +104 -0
- package/components/layout/snice-layout-card.ts +35 -0
- package/components/layout/snice-layout-centered.css +51 -0
- package/components/layout/snice-layout-centered.ts +22 -0
- package/components/layout/snice-layout-dashboard.css +98 -0
- package/components/layout/snice-layout-dashboard.ts +45 -0
- package/components/layout/snice-layout-fullscreen.css +72 -0
- package/components/layout/snice-layout-fullscreen.ts +34 -0
- package/components/layout/snice-layout-landing.css +92 -0
- package/components/layout/snice-layout-landing.ts +47 -0
- package/components/layout/snice-layout-minimal.css +16 -0
- package/components/layout/snice-layout-minimal.ts +19 -0
- package/components/layout/snice-layout-sidebar.css +117 -0
- package/components/layout/snice-layout-sidebar.ts +48 -0
- package/components/layout/snice-layout-split.css +103 -0
- package/components/layout/snice-layout-split.ts +29 -0
- package/components/layout/snice-layout.css +72 -0
- package/components/layout/snice-layout.ts +35 -0
- package/components/layout/snice-layout.types.ts +5 -0
- package/components/login/demo-auth-controller.ts +185 -0
- package/components/login/demo.html +470 -0
- package/components/login/snice-login.css +204 -0
- package/components/login/snice-login.ts +337 -0
- package/components/login/snice-login.types.ts +34 -0
- package/components/modal/demo.html +291 -0
- package/components/modal/snice-modal.css +203 -0
- package/components/modal/snice-modal.ts +233 -0
- package/components/modal/snice-modal.types.ts +21 -0
- package/components/pagination/demo.html +395 -0
- package/components/pagination/snice-pagination.ts +333 -0
- package/components/pagination/snice-pagination.types.ts +21 -0
- package/components/progress/demo.html +510 -0
- package/components/progress/snice-progress.css +267 -0
- package/components/progress/snice-progress.ts +247 -0
- package/components/progress/snice-progress.types.ts +19 -0
- package/components/radio/demo.html +287 -0
- package/components/radio/snice-radio.css +171 -0
- package/components/radio/snice-radio.ts +218 -0
- package/components/radio/snice-radio.types.ts +21 -0
- package/components/select/demo.html +511 -0
- package/components/select/snice-option.ts +52 -0
- package/components/select/snice-option.types.ts +14 -0
- package/components/select/snice-select.css +392 -0
- package/components/select/snice-select.ts +796 -0
- package/components/select/snice-select.types.ts +55 -0
- package/components/skeleton/demo.html +514 -0
- package/components/skeleton/snice-skeleton.css +109 -0
- package/components/skeleton/snice-skeleton.ts +126 -0
- package/components/skeleton/snice-skeleton.types.ts +11 -0
- package/components/switch/demo.html +284 -0
- package/components/switch/snice-switch.css +221 -0
- package/components/switch/snice-switch.ts +229 -0
- package/components/switch/snice-switch.types.ts +23 -0
- package/components/symbols.ts +23 -0
- package/components/table/demo-table-controller.ts +100 -0
- package/components/table/demo.html +480 -0
- package/components/table/snice-cell-boolean.ts +112 -0
- package/components/table/snice-cell-date.ts +210 -0
- package/components/table/snice-cell-duration.ts +91 -0
- package/components/table/snice-cell-filesize.ts +90 -0
- package/components/table/snice-cell-number.ts +165 -0
- package/components/table/snice-cell-progress.ts +83 -0
- package/components/table/snice-cell-rating.ts +82 -0
- package/components/table/snice-cell-sparkline.ts +253 -0
- package/components/table/snice-cell-text.ts +125 -0
- package/components/table/snice-cell.css +296 -0
- package/components/table/snice-cell.ts +473 -0
- package/components/table/snice-column.ts +353 -0
- package/components/table/snice-header.css +243 -0
- package/components/table/snice-header.ts +261 -0
- package/components/table/snice-progress.ts +66 -0
- package/components/table/snice-rating.ts +45 -0
- package/components/table/snice-row.css +255 -0
- package/components/table/snice-row.ts +331 -0
- package/components/table/snice-table.css +241 -0
- package/components/table/snice-table.ts +737 -0
- package/components/table/snice-table.types.ts +158 -0
- package/components/tabs/demo.html +487 -0
- package/components/tabs/snice-tab-panel.css +264 -0
- package/components/tabs/snice-tab-panel.ts +47 -0
- package/components/tabs/snice-tab.css +96 -0
- package/components/tabs/snice-tab.ts +65 -0
- package/components/tabs/snice-tabs.css +189 -0
- package/components/tabs/snice-tabs.ts +332 -0
- package/components/tabs/snice-tabs.types.ts +28 -0
- package/components/theme/theme.css +234 -0
- package/components/toast/demo.html +329 -0
- package/components/toast/snice-toast-container.ts +256 -0
- package/components/toast/snice-toast.css +213 -0
- package/components/toast/snice-toast.ts +276 -0
- package/components/toast/snice-toast.types.ts +35 -0
- package/components/tooltip/demo.html +350 -0
- package/components/tooltip/snice-tooltip-portal.css +79 -0
- package/components/tooltip/snice-tooltip.css +117 -0
- package/components/tooltip/snice-tooltip.ts +612 -0
- package/components/tooltip/snice-tooltip.types.ts +32 -0
- package/components/transitions.ts +94 -0
- package/components/tsconfig.json +18 -0
- package/dist/index.cjs +441 -329
- package/dist/index.cjs.map +1 -1
- package/dist/index.cjs.min.map +1 -1
- package/dist/index.esm.js +441 -329
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +3 -3
- package/dist/index.esm.min.js.map +1 -1
- package/dist/index.iife.js +441 -329
- package/dist/index.iife.js.map +1 -1
- package/dist/index.iife.min.js +3 -3
- package/dist/index.iife.min.js.map +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/controller.d.ts +1 -1
- package/dist/types/element.d.ts +10 -10
- package/dist/types/events.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/observe.d.ts +1 -1
- package/dist/types/request-response.d.ts +2 -3
- package/dist/types/router.d.ts +1 -1
- package/package.json +9 -3
- package/dist/index.cjs.min +0 -15
- package/dist/symbols.cjs +0 -103
- package/dist/transitions.cjs +0 -219
package/dist/index.iife.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v1.14.
|
|
2
|
+
* snice v1.14.3
|
|
3
3
|
* Imperative TypeScript framework for building vanilla web components with decorators, routing, and controllers. No virtual DOM, no build complexity.
|
|
4
4
|
* (c) 2024
|
|
5
5
|
* Released under the MIT License.
|
|
@@ -83,24 +83,27 @@ var Snice = (function (exports) {
|
|
|
83
83
|
selector = undefined;
|
|
84
84
|
opts = selectorOrOptions;
|
|
85
85
|
}
|
|
86
|
-
return function (target,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
86
|
+
return function (target, context) {
|
|
87
|
+
const propertyKey = context.name;
|
|
88
|
+
context.addInitializer(function () {
|
|
89
|
+
const constructor = this.constructor;
|
|
90
|
+
// Store event handler metadata
|
|
91
|
+
if (!constructor.prototype[ON_HANDLERS]) {
|
|
92
|
+
constructor.prototype[ON_HANDLERS] = [];
|
|
93
|
+
}
|
|
94
|
+
// Normalize to array and expand at decoration time
|
|
95
|
+
const eventNames = Array.isArray(eventName) ? eventName : [eventName];
|
|
96
|
+
// Create a handler entry for each event
|
|
97
|
+
for (const event of eventNames) {
|
|
98
|
+
constructor.prototype[ON_HANDLERS].push({
|
|
99
|
+
eventName: event,
|
|
100
|
+
selector,
|
|
101
|
+
methodName: propertyKey,
|
|
102
|
+
method: target,
|
|
103
|
+
options: opts
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
104
107
|
};
|
|
105
108
|
}
|
|
106
109
|
// Helper to setup event handlers for elements
|
|
@@ -294,13 +297,12 @@ var Snice = (function (exports) {
|
|
|
294
297
|
* @param options Optional configuration extending EventInit
|
|
295
298
|
*/
|
|
296
299
|
function dispatch(eventName, options) {
|
|
297
|
-
return function (
|
|
298
|
-
const originalMethod = descriptor.value;
|
|
300
|
+
return function (originalMethod, _context) {
|
|
299
301
|
// Create timing wrappers for dispatch
|
|
300
302
|
let debounceTimeout;
|
|
301
303
|
let throttleLastCall = 0;
|
|
302
304
|
let throttleTimeout;
|
|
303
|
-
|
|
305
|
+
return function (...args) {
|
|
304
306
|
// Call the original method
|
|
305
307
|
const result = originalMethod.apply(this, args);
|
|
306
308
|
// Helper to dispatch the event
|
|
@@ -355,7 +357,6 @@ var Snice = (function (exports) {
|
|
|
355
357
|
timedDispatch(result);
|
|
356
358
|
return result;
|
|
357
359
|
};
|
|
358
|
-
return descriptor;
|
|
359
360
|
};
|
|
360
361
|
}
|
|
361
362
|
|
|
@@ -382,27 +383,30 @@ var Snice = (function (exports) {
|
|
|
382
383
|
selector = undefined;
|
|
383
384
|
opts = selectorOrOptions;
|
|
384
385
|
}
|
|
385
|
-
return function (target,
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
type
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
386
|
+
return function (target, context) {
|
|
387
|
+
const propertyKey = context.name;
|
|
388
|
+
context.addInitializer(function () {
|
|
389
|
+
const constructor = this.constructor;
|
|
390
|
+
// Store observer metadata
|
|
391
|
+
if (!constructor.prototype[OBSERVERS]) {
|
|
392
|
+
constructor.prototype[OBSERVERS] = [];
|
|
393
|
+
}
|
|
394
|
+
// Normalize to array
|
|
395
|
+
const observeTargets = Array.isArray(observeTarget) ? observeTarget : [observeTarget];
|
|
396
|
+
// Create an observer entry for each target
|
|
397
|
+
for (const targetString of observeTargets) {
|
|
398
|
+
// Parse the observation type from the observeTarget string
|
|
399
|
+
const [type, ...modifiers] = targetString.split(':');
|
|
400
|
+
constructor.prototype[OBSERVERS].push({
|
|
401
|
+
type,
|
|
402
|
+
target: modifiers.join(':'), // Rejoin for media queries or mutation types
|
|
403
|
+
selector,
|
|
404
|
+
methodName: propertyKey,
|
|
405
|
+
method: target,
|
|
406
|
+
options: opts
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
});
|
|
406
410
|
};
|
|
407
411
|
}
|
|
408
412
|
// Helper to setup observers for elements
|
|
@@ -695,13 +699,12 @@ var Snice = (function (exports) {
|
|
|
695
699
|
* @param options Optional configuration
|
|
696
700
|
*/
|
|
697
701
|
function request(requestName, options) {
|
|
698
|
-
return function (
|
|
699
|
-
const originalMethod = descriptor.value;
|
|
702
|
+
return function (originalMethod, _context) {
|
|
700
703
|
// Create timing variables for debounce/throttle
|
|
701
704
|
let debounceTimeout;
|
|
702
705
|
let throttleLastCall = 0;
|
|
703
706
|
let throttleTimeout;
|
|
704
|
-
|
|
707
|
+
return async function (...args) {
|
|
705
708
|
const actualRequest = async () => {
|
|
706
709
|
// @request always acts as requester (client side)
|
|
707
710
|
const responseTimeout = options?.timeout ?? 120000; // Default 2 minute timeout
|
|
@@ -825,7 +828,6 @@ var Snice = (function (exports) {
|
|
|
825
828
|
// No timing applied, execute immediately
|
|
826
829
|
return actualRequest();
|
|
827
830
|
};
|
|
828
|
-
return descriptor;
|
|
829
831
|
};
|
|
830
832
|
}
|
|
831
833
|
/**
|
|
@@ -835,20 +837,22 @@ var Snice = (function (exports) {
|
|
|
835
837
|
* @param options Optional configuration
|
|
836
838
|
*/
|
|
837
839
|
function respond(requestName, options) {
|
|
838
|
-
return function (target,
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
840
|
+
return function (target, context) {
|
|
841
|
+
const propertyKey = context.name;
|
|
842
|
+
context.addInitializer(function () {
|
|
843
|
+
const constructor = this.constructor;
|
|
844
|
+
// Store response metadata on the prototype
|
|
845
|
+
// This will be picked up by setupResponseHandlers
|
|
846
|
+
if (!constructor.prototype[CHANNEL_HANDLERS]) {
|
|
847
|
+
constructor.prototype[CHANNEL_HANDLERS] = [];
|
|
848
|
+
}
|
|
849
|
+
constructor.prototype[CHANNEL_HANDLERS].push({
|
|
850
|
+
channelName: requestName,
|
|
851
|
+
methodName: propertyKey,
|
|
852
|
+
method: target,
|
|
853
|
+
options: options
|
|
854
|
+
});
|
|
850
855
|
});
|
|
851
|
-
return descriptor;
|
|
852
856
|
};
|
|
853
857
|
}
|
|
854
858
|
// Helper to setup response handlers for elements and controllers
|
|
@@ -999,7 +1003,7 @@ var Snice = (function (exports) {
|
|
|
999
1003
|
* @param name The name to register the controller under
|
|
1000
1004
|
*/
|
|
1001
1005
|
function controller(name) {
|
|
1002
|
-
return function (constructor) {
|
|
1006
|
+
return function (constructor, _context) {
|
|
1003
1007
|
snice.controllerRegistry.set(name, constructor);
|
|
1004
1008
|
// Mark as controller class for channel decorator detection
|
|
1005
1009
|
constructor.prototype[IS_CONTROLLER_CLASS] = true;
|
|
@@ -1346,10 +1350,12 @@ var Snice = (function (exports) {
|
|
|
1346
1350
|
// Mark that properties have been initialized
|
|
1347
1351
|
this[PROPERTIES_INITIALIZED] = true;
|
|
1348
1352
|
// Reflect properties that were explicitly set before connection
|
|
1349
|
-
//
|
|
1350
|
-
if (properties
|
|
1353
|
+
// AND also reflect initial values that have reflect: true
|
|
1354
|
+
if (properties) {
|
|
1351
1355
|
for (const [propName, propOptions] of properties) {
|
|
1352
|
-
|
|
1356
|
+
const wasExplicitlySet = this[EXPLICITLY_SET_PROPERTIES] && this[EXPLICITLY_SET_PROPERTIES].has(propName);
|
|
1357
|
+
const hasInitialValue = propName in this[PROPERTY_VALUES];
|
|
1358
|
+
if (propOptions.reflect && hasInitialValue && (wasExplicitlySet || this[PROPERTY_VALUES][propName] !== undefined)) {
|
|
1353
1359
|
const value = this[PROPERTY_VALUES][propName];
|
|
1354
1360
|
const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
|
|
1355
1361
|
if (value !== null && value !== undefined && value !== false &&
|
|
@@ -1598,176 +1604,224 @@ var Snice = (function (exports) {
|
|
|
1598
1604
|
};
|
|
1599
1605
|
}
|
|
1600
1606
|
function element(tagName) {
|
|
1601
|
-
return function (constructor) {
|
|
1607
|
+
return function (constructor, context) {
|
|
1608
|
+
// Transfer metadata from context to constructor
|
|
1609
|
+
if (context.metadata && context.metadata[PROPERTIES]) {
|
|
1610
|
+
if (!constructor[PROPERTIES]) {
|
|
1611
|
+
constructor[PROPERTIES] = new Map();
|
|
1612
|
+
}
|
|
1613
|
+
for (const [key, value] of context.metadata[PROPERTIES]) {
|
|
1614
|
+
constructor[PROPERTIES].set(key, value);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1602
1617
|
applyElementFunctionality(constructor);
|
|
1603
1618
|
customElements.define(tagName, constructor);
|
|
1619
|
+
return constructor;
|
|
1604
1620
|
};
|
|
1605
1621
|
}
|
|
1606
1622
|
function layout(tagName) {
|
|
1607
|
-
return function (constructor) {
|
|
1623
|
+
return function (constructor, context) {
|
|
1624
|
+
// Transfer metadata from context to constructor
|
|
1625
|
+
if (context.metadata && context.metadata[PROPERTIES]) {
|
|
1626
|
+
if (!constructor[PROPERTIES]) {
|
|
1627
|
+
constructor[PROPERTIES] = new Map();
|
|
1628
|
+
}
|
|
1629
|
+
for (const [key, value] of context.metadata[PROPERTIES]) {
|
|
1630
|
+
constructor[PROPERTIES].set(key, value);
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1608
1633
|
applyElementFunctionality(constructor);
|
|
1609
1634
|
customElements.define(tagName, constructor);
|
|
1635
|
+
return constructor;
|
|
1610
1636
|
};
|
|
1611
1637
|
}
|
|
1612
1638
|
function property(options) {
|
|
1613
|
-
return function (
|
|
1614
|
-
const
|
|
1615
|
-
//
|
|
1639
|
+
return function (_value, context) {
|
|
1640
|
+
const propertyKey = context.name;
|
|
1641
|
+
// Use metadata to store property information at decoration time
|
|
1642
|
+
if (!context.metadata) {
|
|
1643
|
+
context.metadata = {};
|
|
1644
|
+
}
|
|
1645
|
+
if (!context.metadata[PROPERTIES]) {
|
|
1646
|
+
context.metadata[PROPERTIES] = new Map();
|
|
1647
|
+
}
|
|
1648
|
+
context.metadata[PROPERTIES].set(propertyKey, options || {});
|
|
1649
|
+
// Warn about problematic reflection usage at decoration time
|
|
1616
1650
|
if (options?.reflect && options?.type === Array) {
|
|
1617
1651
|
console.warn(`⚠️ Property '${propertyKey}' uses reflect:true with Array type.`);
|
|
1618
1652
|
}
|
|
1619
1653
|
if (options?.reflect && options?.type === Object) {
|
|
1620
1654
|
console.warn(`⚠️ Property '${propertyKey}' uses reflect:true with Object type.`);
|
|
1621
1655
|
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
set(value) {
|
|
1634
|
-
if (!this[PROPERTY_VALUES]) {
|
|
1635
|
-
this[PROPERTY_VALUES] = {};
|
|
1636
|
-
}
|
|
1637
|
-
if (!this[EXPLICITLY_SET_PROPERTIES]) {
|
|
1638
|
-
this[EXPLICITLY_SET_PROPERTIES] = new Set();
|
|
1639
|
-
}
|
|
1640
|
-
const oldValue = this[PROPERTY_VALUES][propertyKey];
|
|
1641
|
-
// Don't update if value hasn't changed
|
|
1642
|
-
if (oldValue === value)
|
|
1643
|
-
return;
|
|
1644
|
-
// Mark as explicitly set in these cases:
|
|
1645
|
-
// 1. There was a previous value (normal property update)
|
|
1646
|
-
// 2. This is during element construction and we have a non-null/non-undefined value
|
|
1647
|
-
// (this handles default values declared in class properties)
|
|
1648
|
-
const isInitialDefaultValue = oldValue === undefined && !this[PROPERTIES_INITIALIZED];
|
|
1649
|
-
if (oldValue !== undefined || (isInitialDefaultValue && value !== null && value !== undefined)) {
|
|
1650
|
-
this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
|
|
1651
|
-
}
|
|
1652
|
-
this[PROPERTY_VALUES][propertyKey] = value;
|
|
1653
|
-
// Only reflect to attributes if:
|
|
1654
|
-
// 1. Properties have been initialized from attributes
|
|
1655
|
-
// 2. The property was explicitly set (not just default value)
|
|
1656
|
-
// This prevents default values from creating attributes
|
|
1657
|
-
if (options?.reflect && this.setAttribute && this[PROPERTIES_INITIALIZED] && this[EXPLICITLY_SET_PROPERTIES].has(propertyKey)) {
|
|
1658
|
-
const attributeName = typeof options.attribute === 'string' ? options.attribute : propertyKey.toLowerCase();
|
|
1659
|
-
if (value === null || value === undefined || value === false ||
|
|
1660
|
-
(options?.type === SimpleArray && Array.isArray(value) && value.length === 0)) {
|
|
1661
|
-
this.removeAttribute(attributeName);
|
|
1662
|
-
}
|
|
1663
|
-
else {
|
|
1664
|
-
// Handle special types for reflection
|
|
1665
|
-
let attributeValue;
|
|
1666
|
-
if (value instanceof Date) {
|
|
1667
|
-
attributeValue = value.toISOString();
|
|
1656
|
+
context.addInitializer(function () {
|
|
1657
|
+
// No longer need warnings here since they're at decoration time
|
|
1658
|
+
});
|
|
1659
|
+
// Return a field initializer function for new decorators
|
|
1660
|
+
return function (initialValue) {
|
|
1661
|
+
// Set up the property descriptor on first access
|
|
1662
|
+
if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
|
|
1663
|
+
const descriptor = {
|
|
1664
|
+
get() {
|
|
1665
|
+
if (!this[PROPERTY_VALUES]) {
|
|
1666
|
+
this[PROPERTY_VALUES] = {};
|
|
1668
1667
|
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1668
|
+
return this[PROPERTY_VALUES][propertyKey];
|
|
1669
|
+
},
|
|
1670
|
+
set(newValue) {
|
|
1671
|
+
if (!this[PROPERTY_VALUES]) {
|
|
1672
|
+
this[PROPERTY_VALUES] = {};
|
|
1671
1673
|
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
+
if (!this[EXPLICITLY_SET_PROPERTIES]) {
|
|
1675
|
+
this[EXPLICITLY_SET_PROPERTIES] = new Set();
|
|
1674
1676
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
+
const oldValue = this[PROPERTY_VALUES][propertyKey];
|
|
1678
|
+
if (oldValue === newValue)
|
|
1679
|
+
return;
|
|
1680
|
+
const isInitialDefaultValue = oldValue === undefined && !this[PROPERTIES_INITIALIZED];
|
|
1681
|
+
if (oldValue !== undefined || (isInitialDefaultValue && newValue !== null && newValue !== undefined)) {
|
|
1682
|
+
this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
|
|
1677
1683
|
}
|
|
1678
|
-
this
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
// Call specific property watchers
|
|
1685
|
-
if (watchers.has(propertyKey)) {
|
|
1686
|
-
const propertyWatchers = watchers.get(propertyKey);
|
|
1687
|
-
for (const watcher of propertyWatchers) {
|
|
1688
|
-
try {
|
|
1689
|
-
// Always pass oldValue, newValue, and propertyName
|
|
1690
|
-
watcher.method.call(this, oldValue, value, propertyKey);
|
|
1684
|
+
this[PROPERTY_VALUES][propertyKey] = newValue;
|
|
1685
|
+
if (options?.reflect && this.setAttribute && this[PROPERTIES_INITIALIZED] && this[EXPLICITLY_SET_PROPERTIES].has(propertyKey)) {
|
|
1686
|
+
const attributeName = typeof options.attribute === 'string' ? options.attribute : propertyKey.toLowerCase();
|
|
1687
|
+
if (newValue === null || newValue === undefined || newValue === false ||
|
|
1688
|
+
(options?.type === SimpleArray && Array.isArray(newValue) && newValue.length === 0)) {
|
|
1689
|
+
this.removeAttribute(attributeName);
|
|
1691
1690
|
}
|
|
1692
|
-
|
|
1693
|
-
|
|
1691
|
+
else {
|
|
1692
|
+
let attributeValue;
|
|
1693
|
+
if (newValue instanceof Date) {
|
|
1694
|
+
attributeValue = newValue.toISOString();
|
|
1695
|
+
}
|
|
1696
|
+
else if (typeof newValue === 'bigint') {
|
|
1697
|
+
attributeValue = newValue.toString() + 'n';
|
|
1698
|
+
}
|
|
1699
|
+
else if (options?.type === SimpleArray && Array.isArray(newValue)) {
|
|
1700
|
+
attributeValue = SimpleArray.serialize(newValue);
|
|
1701
|
+
}
|
|
1702
|
+
else {
|
|
1703
|
+
attributeValue = String(newValue);
|
|
1704
|
+
}
|
|
1705
|
+
this.setAttribute(attributeName, attributeValue);
|
|
1694
1706
|
}
|
|
1695
1707
|
}
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1708
|
+
const constructor = this.constructor;
|
|
1709
|
+
const watchers = constructor[PROPERTY_WATCHERS];
|
|
1710
|
+
if (watchers) {
|
|
1711
|
+
if (watchers.has(propertyKey)) {
|
|
1712
|
+
const propertyWatchers = watchers.get(propertyKey);
|
|
1713
|
+
for (const watcher of propertyWatchers) {
|
|
1714
|
+
try {
|
|
1715
|
+
watcher.method.call(this, oldValue, newValue, propertyKey);
|
|
1716
|
+
}
|
|
1717
|
+
catch (error) {
|
|
1718
|
+
console.error(`Error in @watch('${propertyKey}') method ${watcher.methodName}:`, error);
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1704
1721
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1722
|
+
if (watchers.has('*')) {
|
|
1723
|
+
const wildcardWatchers = watchers.get('*');
|
|
1724
|
+
for (const watcher of wildcardWatchers) {
|
|
1725
|
+
try {
|
|
1726
|
+
watcher.method.call(this, oldValue, newValue, propertyKey);
|
|
1727
|
+
}
|
|
1728
|
+
catch (error) {
|
|
1729
|
+
console.error(`Error in @watch('*') method ${watcher.methodName}:`, error);
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1707
1732
|
}
|
|
1708
1733
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1734
|
+
if (this.requestUpdate) {
|
|
1735
|
+
this.requestUpdate(propertyKey, oldValue);
|
|
1736
|
+
}
|
|
1737
|
+
},
|
|
1738
|
+
configurable: true,
|
|
1739
|
+
enumerable: true
|
|
1740
|
+
};
|
|
1741
|
+
Object.defineProperty(this.constructor.prototype, propertyKey, descriptor);
|
|
1742
|
+
}
|
|
1743
|
+
// Initialize the property value
|
|
1744
|
+
if (!this[PROPERTY_VALUES]) {
|
|
1745
|
+
this[PROPERTY_VALUES] = {};
|
|
1746
|
+
}
|
|
1747
|
+
this[PROPERTY_VALUES][propertyKey] = initialValue;
|
|
1748
|
+
return initialValue;
|
|
1718
1749
|
};
|
|
1719
|
-
Object.defineProperty(target, propertyKey, descriptor);
|
|
1720
1750
|
};
|
|
1721
1751
|
}
|
|
1722
1752
|
function query(selector, options = {}) {
|
|
1723
|
-
return function (
|
|
1753
|
+
return function (_value, context) {
|
|
1724
1754
|
// Default to shadow DOM only
|
|
1725
1755
|
const { light = false, shadow = true } = options;
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1756
|
+
const propertyKey = context.name;
|
|
1757
|
+
// Return a field initializer function for new decorators
|
|
1758
|
+
return function (initialValue) {
|
|
1759
|
+
// Set up the property descriptor on first access
|
|
1760
|
+
if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
|
|
1761
|
+
const descriptor = {
|
|
1762
|
+
get() {
|
|
1763
|
+
// Check if this is a controller using the symbol
|
|
1764
|
+
const isController = this[IS_CONTROLLER_INSTANCE] === true;
|
|
1765
|
+
const root = isController && this.element ? this.element : this;
|
|
1766
|
+
// Query in specified contexts
|
|
1767
|
+
let result = null;
|
|
1768
|
+
if (shadow && root.shadowRoot) {
|
|
1769
|
+
result = root.shadowRoot.querySelector(selector);
|
|
1770
|
+
}
|
|
1771
|
+
if (!result && light) {
|
|
1772
|
+
result = root.querySelector(selector);
|
|
1773
|
+
}
|
|
1774
|
+
return result || null;
|
|
1775
|
+
},
|
|
1776
|
+
set() {
|
|
1777
|
+
// Query results are read-only
|
|
1778
|
+
},
|
|
1779
|
+
configurable: true,
|
|
1780
|
+
enumerable: true
|
|
1781
|
+
};
|
|
1782
|
+
Object.defineProperty(this.constructor.prototype, propertyKey, descriptor);
|
|
1783
|
+
}
|
|
1784
|
+
return initialValue;
|
|
1785
|
+
};
|
|
1744
1786
|
};
|
|
1745
1787
|
}
|
|
1746
1788
|
function queryAll(selector, options = {}) {
|
|
1747
|
-
return function (
|
|
1789
|
+
return function (_value, context) {
|
|
1748
1790
|
// Default to shadow DOM only
|
|
1749
1791
|
const { light = false, shadow = true } = options;
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1792
|
+
const propertyKey = context.name;
|
|
1793
|
+
// Return a field initializer function for new decorators
|
|
1794
|
+
return function (initialValue) {
|
|
1795
|
+
// Set up the property descriptor on first access
|
|
1796
|
+
if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
|
|
1797
|
+
const descriptor = {
|
|
1798
|
+
get() {
|
|
1799
|
+
// Check if this is a controller using the symbol
|
|
1800
|
+
const isController = this[IS_CONTROLLER_INSTANCE] === true;
|
|
1801
|
+
const root = isController && this.element ? this.element : this;
|
|
1802
|
+
// Query in specified contexts and combine results
|
|
1803
|
+
const results = [];
|
|
1804
|
+
if (shadow && root.shadowRoot) {
|
|
1805
|
+
const shadowResults = root.shadowRoot.querySelectorAll(selector);
|
|
1806
|
+
results.push(...shadowResults);
|
|
1807
|
+
}
|
|
1808
|
+
if (light) {
|
|
1809
|
+
const lightResults = root.querySelectorAll(selector);
|
|
1810
|
+
results.push(...lightResults);
|
|
1811
|
+
}
|
|
1812
|
+
// Return a static NodeList-like object
|
|
1813
|
+
return results;
|
|
1814
|
+
},
|
|
1815
|
+
set() {
|
|
1816
|
+
// Query results are read-only
|
|
1817
|
+
},
|
|
1818
|
+
configurable: true,
|
|
1819
|
+
enumerable: true
|
|
1820
|
+
};
|
|
1821
|
+
Object.defineProperty(this.constructor.prototype, propertyKey, descriptor);
|
|
1822
|
+
}
|
|
1823
|
+
return initialValue;
|
|
1824
|
+
};
|
|
1771
1825
|
};
|
|
1772
1826
|
}
|
|
1773
1827
|
/**
|
|
@@ -1777,6 +1831,7 @@ var Snice = (function (exports) {
|
|
|
1777
1831
|
* Strings cannot contain the full-width comma character
|
|
1778
1832
|
*/
|
|
1779
1833
|
class SimpleArray {
|
|
1834
|
+
static { this.SEPARATOR = ','; } // U+FF0C Full-width comma
|
|
1780
1835
|
/**
|
|
1781
1836
|
* Serialize array to string for attribute storage
|
|
1782
1837
|
*/
|
|
@@ -1826,24 +1881,25 @@ var Snice = (function (exports) {
|
|
|
1826
1881
|
});
|
|
1827
1882
|
}
|
|
1828
1883
|
}
|
|
1829
|
-
SimpleArray.SEPARATOR = ','; // U+FF0C Full-width comma
|
|
1830
1884
|
function watch(...propertyNames) {
|
|
1831
|
-
return function (target,
|
|
1832
|
-
const
|
|
1833
|
-
|
|
1834
|
-
constructor
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1885
|
+
return function (target, context) {
|
|
1886
|
+
const methodName = context.name;
|
|
1887
|
+
context.addInitializer(function () {
|
|
1888
|
+
const constructor = this.constructor;
|
|
1889
|
+
if (!constructor[PROPERTY_WATCHERS]) {
|
|
1890
|
+
constructor[PROPERTY_WATCHERS] = new Map();
|
|
1891
|
+
}
|
|
1892
|
+
// Store the watcher method for each property
|
|
1893
|
+
for (const propertyName of propertyNames) {
|
|
1894
|
+
if (!constructor[PROPERTY_WATCHERS].has(propertyName)) {
|
|
1895
|
+
constructor[PROPERTY_WATCHERS].set(propertyName, []);
|
|
1896
|
+
}
|
|
1897
|
+
constructor[PROPERTY_WATCHERS].get(propertyName).push({
|
|
1898
|
+
methodName,
|
|
1899
|
+
method: target
|
|
1900
|
+
});
|
|
1840
1901
|
}
|
|
1841
|
-
|
|
1842
|
-
methodName,
|
|
1843
|
-
method: descriptor.value
|
|
1844
|
-
});
|
|
1845
|
-
}
|
|
1846
|
-
return descriptor;
|
|
1902
|
+
});
|
|
1847
1903
|
};
|
|
1848
1904
|
}
|
|
1849
1905
|
/**
|
|
@@ -1851,46 +1907,57 @@ var Snice = (function (exports) {
|
|
|
1851
1907
|
* The context is automatically provided to page components by the router
|
|
1852
1908
|
*/
|
|
1853
1909
|
function context() {
|
|
1854
|
-
return function (
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1910
|
+
return function (_value, context) {
|
|
1911
|
+
const propertyKey = context.name;
|
|
1912
|
+
// Return a field initializer function for new decorators
|
|
1913
|
+
return function (initialValue) {
|
|
1914
|
+
// Set up the property descriptor on first access
|
|
1915
|
+
if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
|
|
1916
|
+
const descriptor = {
|
|
1917
|
+
get() {
|
|
1918
|
+
// First check if context is stored directly on this element
|
|
1919
|
+
if (this[ROUTER_CONTEXT] !== undefined) {
|
|
1920
|
+
return this[ROUTER_CONTEXT];
|
|
1921
|
+
}
|
|
1922
|
+
// Otherwise, request context from parent page via event
|
|
1923
|
+
const detail = { target: this };
|
|
1924
|
+
const event = new CustomEvent('@context/request', {
|
|
1925
|
+
bubbles: true,
|
|
1926
|
+
cancelable: true,
|
|
1927
|
+
detail
|
|
1928
|
+
});
|
|
1929
|
+
// Dispatch event and wait for response
|
|
1930
|
+
// Check if this is a controller using the symbol
|
|
1931
|
+
const isController = this[IS_CONTROLLER_INSTANCE] === true;
|
|
1932
|
+
let targetElement = isController && this.element ? this.element : this;
|
|
1933
|
+
// If element is null (e.g., controller was detached), can't get context
|
|
1934
|
+
if (!targetElement || !targetElement.dispatchEvent) {
|
|
1935
|
+
return undefined;
|
|
1936
|
+
}
|
|
1937
|
+
// If we're in shadow DOM, dispatch on the host element to ensure proper bubbling
|
|
1938
|
+
if (targetElement.getRootNode && targetElement.getRootNode() instanceof ShadowRoot) {
|
|
1939
|
+
const shadowRoot = targetElement.getRootNode();
|
|
1940
|
+
targetElement = shadowRoot.host;
|
|
1941
|
+
}
|
|
1942
|
+
targetElement.dispatchEvent(event);
|
|
1943
|
+
// Check if context was provided via the event
|
|
1944
|
+
if (detail.context !== undefined) {
|
|
1945
|
+
// Cache it for future use
|
|
1946
|
+
this[ROUTER_CONTEXT] = detail.context;
|
|
1947
|
+
return detail.context;
|
|
1948
|
+
}
|
|
1949
|
+
return undefined;
|
|
1950
|
+
},
|
|
1951
|
+
set() {
|
|
1952
|
+
// Context is read-only
|
|
1953
|
+
},
|
|
1954
|
+
configurable: true,
|
|
1955
|
+
enumerable: true
|
|
1956
|
+
};
|
|
1957
|
+
Object.defineProperty(this.constructor.prototype, propertyKey, descriptor);
|
|
1958
|
+
}
|
|
1959
|
+
return initialValue;
|
|
1960
|
+
};
|
|
1894
1961
|
};
|
|
1895
1962
|
}
|
|
1896
1963
|
/**
|
|
@@ -1899,16 +1966,18 @@ var Snice = (function (exports) {
|
|
|
1899
1966
|
* Supports async methods
|
|
1900
1967
|
*/
|
|
1901
1968
|
function ready() {
|
|
1902
|
-
return function (target,
|
|
1903
|
-
const
|
|
1904
|
-
|
|
1905
|
-
constructor
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1969
|
+
return function (target, context) {
|
|
1970
|
+
const methodName = context.name;
|
|
1971
|
+
context.addInitializer(function () {
|
|
1972
|
+
const constructor = this.constructor;
|
|
1973
|
+
if (!constructor[READY_HANDLERS]) {
|
|
1974
|
+
constructor[READY_HANDLERS] = [];
|
|
1975
|
+
}
|
|
1976
|
+
constructor[READY_HANDLERS].push({
|
|
1977
|
+
methodName,
|
|
1978
|
+
method: target
|
|
1979
|
+
});
|
|
1910
1980
|
});
|
|
1911
|
-
return descriptor;
|
|
1912
1981
|
};
|
|
1913
1982
|
}
|
|
1914
1983
|
/**
|
|
@@ -1916,16 +1985,18 @@ var Snice = (function (exports) {
|
|
|
1916
1985
|
* Used for cleanup tasks when element is removed from DOM
|
|
1917
1986
|
*/
|
|
1918
1987
|
function dispose() {
|
|
1919
|
-
return function (target,
|
|
1920
|
-
const
|
|
1921
|
-
|
|
1922
|
-
constructor
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1988
|
+
return function (target, context) {
|
|
1989
|
+
const methodName = context.name;
|
|
1990
|
+
context.addInitializer(function () {
|
|
1991
|
+
const constructor = this.constructor;
|
|
1992
|
+
if (!constructor[DISPOSE_HANDLERS]) {
|
|
1993
|
+
constructor[DISPOSE_HANDLERS] = [];
|
|
1994
|
+
}
|
|
1995
|
+
constructor[DISPOSE_HANDLERS].push({
|
|
1996
|
+
methodName,
|
|
1997
|
+
method: target
|
|
1998
|
+
});
|
|
1927
1999
|
});
|
|
1928
|
-
return descriptor;
|
|
1929
2000
|
};
|
|
1930
2001
|
}
|
|
1931
2002
|
/**
|
|
@@ -1934,27 +2005,20 @@ var Snice = (function (exports) {
|
|
|
1934
2005
|
* When the decorated method is called, it automatically re-renders its part
|
|
1935
2006
|
*/
|
|
1936
2007
|
function part(partName, options = {}) {
|
|
1937
|
-
return function (
|
|
1938
|
-
const
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
const originalMethod = descriptor.value;
|
|
1949
|
-
if (!constructor[PARTS]) {
|
|
1950
|
-
constructor[PARTS] = new Map();
|
|
1951
|
-
}
|
|
1952
|
-
constructor[PARTS].set(partName, {
|
|
1953
|
-
methodName,
|
|
1954
|
-
method: originalMethod
|
|
2008
|
+
return function (originalMethod, context) {
|
|
2009
|
+
const methodName = context.name;
|
|
2010
|
+
context.addInitializer(function () {
|
|
2011
|
+
const constructor = this.constructor;
|
|
2012
|
+
if (!constructor[PARTS]) {
|
|
2013
|
+
constructor[PARTS] = new Map();
|
|
2014
|
+
}
|
|
2015
|
+
constructor[PARTS].set(partName, {
|
|
2016
|
+
methodName,
|
|
2017
|
+
method: originalMethod
|
|
2018
|
+
});
|
|
1955
2019
|
});
|
|
1956
|
-
//
|
|
1957
|
-
|
|
2020
|
+
// Return wrapped method that automatically re-renders the part when called
|
|
2021
|
+
return function (...args) {
|
|
1958
2022
|
// Initialize timers storage if not present
|
|
1959
2023
|
if (!this[PART_TIMERS]) {
|
|
1960
2024
|
this[PART_TIMERS] = new Map();
|
|
@@ -1968,58 +2032,96 @@ var Snice = (function (exports) {
|
|
|
1968
2032
|
});
|
|
1969
2033
|
}
|
|
1970
2034
|
const timers = this[PART_TIMERS].get(partName);
|
|
1971
|
-
//
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
const content = result instanceof Promise ? await result : result;
|
|
1976
|
-
// Re-render the part if shadow DOM exists and content is defined
|
|
2035
|
+
// Call the original method first to get its result
|
|
2036
|
+
const result = originalMethod.apply(this, args);
|
|
2037
|
+
// Helper function to update DOM
|
|
2038
|
+
const updateDOM = (content) => {
|
|
1977
2039
|
if (this.shadowRoot && content !== undefined) {
|
|
1978
2040
|
const partElement = this.shadowRoot.querySelector(`[part="${partName}"]`);
|
|
1979
2041
|
if (partElement) {
|
|
1980
2042
|
partElement.innerHTML = content;
|
|
1981
2043
|
}
|
|
1982
2044
|
}
|
|
1983
|
-
return content;
|
|
1984
2045
|
};
|
|
1985
|
-
//
|
|
1986
|
-
if (
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2046
|
+
// Check if result is a Promise (async method)
|
|
2047
|
+
if (result instanceof Promise) {
|
|
2048
|
+
// Handle async method
|
|
2049
|
+
if (options.debounce !== undefined && options.debounce > 0) {
|
|
2050
|
+
// Debounce: defer DOM update, return original Promise
|
|
2051
|
+
if (timers.debounceTimer) {
|
|
2052
|
+
clearTimeout(timers.debounceTimer);
|
|
2053
|
+
}
|
|
1991
2054
|
timers.debounceTimer = setTimeout(async () => {
|
|
1992
|
-
const
|
|
1993
|
-
|
|
2055
|
+
const content = await result;
|
|
2056
|
+
updateDOM(content);
|
|
1994
2057
|
}, options.debounce);
|
|
2058
|
+
return result;
|
|
2059
|
+
}
|
|
2060
|
+
if (options.throttle !== undefined && options.throttle > 0) {
|
|
2061
|
+
// Throttle: handle timing but return original Promise
|
|
2062
|
+
const now = Date.now();
|
|
2063
|
+
if (timers.lastThrottleCall === 0 || now - timers.lastThrottleCall >= options.throttle) {
|
|
2064
|
+
timers.lastThrottleCall = now;
|
|
2065
|
+
return result.then(content => {
|
|
2066
|
+
updateDOM(content);
|
|
2067
|
+
return content;
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
else {
|
|
2071
|
+
if (!timers.throttleTimer) {
|
|
2072
|
+
const remainingTime = options.throttle - (now - timers.lastThrottleCall);
|
|
2073
|
+
timers.throttleTimer = setTimeout(async () => {
|
|
2074
|
+
timers.throttleTimer = null;
|
|
2075
|
+
timers.lastThrottleCall = Date.now();
|
|
2076
|
+
const content = await result;
|
|
2077
|
+
updateDOM(content);
|
|
2078
|
+
}, remainingTime);
|
|
2079
|
+
}
|
|
2080
|
+
return result;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
// No timing: update DOM after Promise resolves
|
|
2084
|
+
return result.then(content => {
|
|
2085
|
+
updateDOM(content);
|
|
2086
|
+
return content;
|
|
1995
2087
|
});
|
|
1996
2088
|
}
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
timers.
|
|
2002
|
-
|
|
2089
|
+
else {
|
|
2090
|
+
// Handle sync method
|
|
2091
|
+
if (options.debounce !== undefined && options.debounce > 0) {
|
|
2092
|
+
// Debounce: defer DOM update, return result immediately
|
|
2093
|
+
if (timers.debounceTimer) {
|
|
2094
|
+
clearTimeout(timers.debounceTimer);
|
|
2095
|
+
}
|
|
2096
|
+
timers.debounceTimer = setTimeout(() => {
|
|
2097
|
+
updateDOM(result);
|
|
2098
|
+
}, options.debounce);
|
|
2099
|
+
return result;
|
|
2003
2100
|
}
|
|
2004
|
-
|
|
2005
|
-
//
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
timers.
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2101
|
+
if (options.throttle !== undefined && options.throttle > 0) {
|
|
2102
|
+
// Throttle: handle timing for DOM updates
|
|
2103
|
+
const now = Date.now();
|
|
2104
|
+
if (timers.lastThrottleCall === 0 || now - timers.lastThrottleCall >= options.throttle) {
|
|
2105
|
+
timers.lastThrottleCall = now;
|
|
2106
|
+
updateDOM(result);
|
|
2107
|
+
}
|
|
2108
|
+
else {
|
|
2109
|
+
if (!timers.throttleTimer) {
|
|
2110
|
+
const remainingTime = options.throttle - (now - timers.lastThrottleCall);
|
|
2111
|
+
timers.throttleTimer = setTimeout(() => {
|
|
2112
|
+
timers.throttleTimer = null;
|
|
2113
|
+
timers.lastThrottleCall = Date.now();
|
|
2114
|
+
updateDOM(result);
|
|
2115
|
+
}, remainingTime);
|
|
2116
|
+
}
|
|
2013
2117
|
}
|
|
2014
|
-
|
|
2015
|
-
// The actual render will happen in the scheduled timeout
|
|
2016
|
-
return undefined;
|
|
2118
|
+
return result;
|
|
2017
2119
|
}
|
|
2120
|
+
// No timing: update DOM immediately
|
|
2121
|
+
updateDOM(result);
|
|
2122
|
+
return result;
|
|
2018
2123
|
}
|
|
2019
|
-
// No throttle/debounce - render immediately
|
|
2020
|
-
return await renderPart();
|
|
2021
2124
|
};
|
|
2022
|
-
return descriptor;
|
|
2023
2125
|
};
|
|
2024
2126
|
}
|
|
2025
2127
|
|
|
@@ -2791,7 +2893,16 @@ var Snice = (function (exports) {
|
|
|
2791
2893
|
* @returns A decorator function to apply to a custom element class.
|
|
2792
2894
|
*/
|
|
2793
2895
|
function page(pageOptions) {
|
|
2794
|
-
return function (constructor) {
|
|
2896
|
+
return function (constructor, context) {
|
|
2897
|
+
// Transfer metadata from context to constructor (for new decorators)
|
|
2898
|
+
if (context.metadata && context.metadata[PROPERTIES]) {
|
|
2899
|
+
if (!constructor[PROPERTIES]) {
|
|
2900
|
+
constructor[PROPERTIES] = new Map();
|
|
2901
|
+
}
|
|
2902
|
+
for (const [key, value] of context.metadata[PROPERTIES]) {
|
|
2903
|
+
constructor[PROPERTIES].set(key, value);
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2795
2906
|
// Apply all element functionality (properties, queries, watchers, controllers, etc.)
|
|
2796
2907
|
applyElementFunctionality(constructor);
|
|
2797
2908
|
// Store transition config on constructor for later use
|
|
@@ -2831,6 +2942,7 @@ var Snice = (function (exports) {
|
|
|
2831
2942
|
customElements.define(pageOptions.tag, constructor);
|
|
2832
2943
|
// Register the routes with guards and layout
|
|
2833
2944
|
pageOptions.routes.forEach(route => register(route, pageOptions.tag, pageOptions.transition, pageOptions.guards, pageOptions.layout));
|
|
2945
|
+
return constructor;
|
|
2834
2946
|
};
|
|
2835
2947
|
}
|
|
2836
2948
|
/**
|