snice 3.10.2 → 3.10.3

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v3.10.1
2
+ * snice v3.10.2
3
3
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -3015,17 +3015,19 @@ var Snice = (function (exports) {
3015
3015
  }
3016
3016
  }
3017
3017
  }
3018
- // Apply any properties that were set before element was connected
3019
- // BUT only if they don't have an HTML attribute (don't override HTML attributes)
3018
+ // Clear pre-init values for properties that have HTML attributes
3019
+ // This prevents field initializers from overwriting HTML attributes later
3020
3020
  if (this[PRE_INIT_PROPERTY_VALUES]) {
3021
- for (const [propName, propValue] of this[PRE_INIT_PROPERTY_VALUES]) {
3022
- // Remove from map first so getter doesn't return it during setter call
3023
- this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3024
- // Only apply pre-init value if NO HTML attribute exists
3025
- // This prevents field initializers from overwriting HTML attributes
3021
+ for (const [propName, propValue] of Array.from(this[PRE_INIT_PROPERTY_VALUES].entries())) {
3026
3022
  const propOptions = properties?.get(propName);
3027
3023
  const attributeName = typeof propOptions?.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3028
- if (!this.hasAttribute(attributeName)) {
3024
+ if (this.hasAttribute(attributeName)) {
3025
+ // Attribute exists - remove from PRE_INIT to prevent overwriting
3026
+ this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3027
+ }
3028
+ else {
3029
+ // No attribute - apply the pre-init value
3030
+ this[PRE_INIT_PROPERTY_VALUES].delete(propName);
3029
3031
  this[propName] = propValue;
3030
3032
  }
3031
3033
  }
@@ -3285,16 +3287,18 @@ var Snice = (function (exports) {
3285
3287
  context.metadata[PROPERTIES].set(propertyKey, options || {});
3286
3288
  // Return a field initializer function for new decorators
3287
3289
  return function (initialValue) {
3290
+ // Ensure constructor[PROPERTIES] exists
3291
+ const constructor = this.constructor;
3292
+ if (!constructor[PROPERTIES]) {
3293
+ constructor[PROPERTIES] = new Map();
3294
+ }
3288
3295
  // Detect type from initial value if not explicitly provided
3289
3296
  const finalOptions = { ...options };
3290
3297
  if (!finalOptions.type && initialValue !== undefined) {
3291
3298
  finalOptions.type = detectType(initialValue);
3292
- // Update the metadata with the detected type
3293
- const constructor = this.constructor;
3294
- if (constructor[PROPERTIES]) {
3295
- constructor[PROPERTIES].set(propertyKey, finalOptions);
3296
- }
3297
3299
  }
3300
+ // Always store property options on constructor for runtime access
3301
+ constructor[PROPERTIES].set(propertyKey, finalOptions);
3298
3302
  // Set up the property descriptor on first access
3299
3303
  if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
3300
3304
  const descriptor = {
@@ -3323,8 +3327,9 @@ var Snice = (function (exports) {
3323
3327
  // Get old value by calling the getter (which reads from attribute)
3324
3328
  const oldValue = this[propertyKey];
3325
3329
  // Check if value actually changed
3326
- if (oldValue === newValue)
3330
+ if (oldValue === newValue) {
3327
3331
  return;
3332
+ }
3328
3333
  // Don't reflect to DOM until connectedCallback has started
3329
3334
  // This prevents field initializers from overwriting HTML attributes
3330
3335
  if (!this[PROPERTIES_INITIALIZED]) {