@dooboostore/simple-web-component 1.0.43 → 1.0.45

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 (146) hide show
  1. package/README.md +312 -63
  2. package/dist/cjs/SwcAppEngine.js +3 -1
  3. package/dist/cjs/SwcAppEngine.js.map +2 -2
  4. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  5. package/dist/cjs/decorators/applyAttribute.js +66 -43
  6. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  7. package/dist/cjs/decorators/applyClass.js +110 -43
  8. package/dist/cjs/decorators/applyClass.js.map +3 -3
  9. package/dist/cjs/decorators/applyNode.js +200 -112
  10. package/dist/cjs/decorators/applyNode.js.map +2 -2
  11. package/dist/cjs/decorators/applyProperty.js +49 -45
  12. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  13. package/dist/cjs/decorators/applyStyle.js +92 -37
  14. package/dist/cjs/decorators/applyStyle.js.map +3 -3
  15. package/dist/cjs/decorators/{changedAttributeThis.js → changedAttribute.js} +6 -6
  16. package/dist/cjs/decorators/changedAttribute.js.map +7 -0
  17. package/dist/cjs/decorators/elementDefine.js +81 -31
  18. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  19. package/dist/cjs/decorators/emitCustomEvent.js +80 -52
  20. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  21. package/dist/cjs/decorators/index.js +1 -1
  22. package/dist/cjs/decorators/index.js.map +2 -2
  23. package/dist/cjs/decorators/publishSwcAppMessage.js +5 -5
  24. package/dist/cjs/decorators/publishSwcAppMessage.js.map +3 -3
  25. package/dist/cjs/decorators/query.js +133 -147
  26. package/dist/cjs/decorators/query.js.map +3 -3
  27. package/dist/cjs/decorators/queryAll.js +143 -132
  28. package/dist/cjs/decorators/queryAll.js.map +3 -3
  29. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +2 -0
  30. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  31. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -0
  32. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  33. package/dist/cjs/elements/SwcAppMixin.js +17 -2
  34. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  35. package/dist/cjs/examples/RxJSOperatorsExample.js +285 -0
  36. package/dist/cjs/examples/RxJSOperatorsExample.js.map +7 -0
  37. package/dist/cjs/index.js +1 -0
  38. package/dist/cjs/index.js.map +2 -2
  39. package/dist/cjs/router/ElementRouter.js +4 -0
  40. package/dist/cjs/router/ElementRouter.js.map +2 -2
  41. package/dist/cjs/types/window.d.js.map +1 -1
  42. package/dist/esm/SwcAppEngine.js +3 -1
  43. package/dist/esm/SwcAppEngine.js.map +2 -2
  44. package/dist/esm/decorators/addEventListener.js.map +2 -2
  45. package/dist/esm/decorators/applyAttribute.js +66 -43
  46. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  47. package/dist/esm/decorators/applyClass.js +110 -43
  48. package/dist/esm/decorators/applyClass.js.map +3 -3
  49. package/dist/esm/decorators/applyNode.js +200 -112
  50. package/dist/esm/decorators/applyNode.js.map +2 -2
  51. package/dist/esm/decorators/applyProperty.js +49 -45
  52. package/dist/esm/decorators/applyProperty.js.map +2 -2
  53. package/dist/esm/decorators/applyStyle.js +92 -37
  54. package/dist/esm/decorators/applyStyle.js.map +3 -3
  55. package/dist/esm/decorators/{changedAttributeThis.js → changedAttribute.js} +3 -3
  56. package/dist/esm/decorators/changedAttribute.js.map +7 -0
  57. package/dist/esm/decorators/elementDefine.js +79 -29
  58. package/dist/esm/decorators/elementDefine.js.map +2 -2
  59. package/dist/esm/decorators/emitCustomEvent.js +80 -52
  60. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  61. package/dist/esm/decorators/index.js +1 -1
  62. package/dist/esm/decorators/index.js.map +1 -1
  63. package/dist/esm/decorators/publishSwcAppMessage.js +5 -5
  64. package/dist/esm/decorators/publishSwcAppMessage.js.map +3 -3
  65. package/dist/esm/decorators/query.js +133 -147
  66. package/dist/esm/decorators/query.js.map +3 -3
  67. package/dist/esm/decorators/queryAll.js +143 -132
  68. package/dist/esm/decorators/queryAll.js.map +3 -3
  69. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +2 -0
  70. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  71. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -0
  72. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  73. package/dist/esm/elements/SwcAppMixin.js +18 -3
  74. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  75. package/dist/esm/examples/RxJSOperatorsExample.js +266 -0
  76. package/dist/esm/examples/RxJSOperatorsExample.js.map +7 -0
  77. package/dist/esm/index.js +1 -0
  78. package/dist/esm/index.js.map +2 -2
  79. package/dist/esm/router/ElementRouter.js +4 -0
  80. package/dist/esm/router/ElementRouter.js.map +2 -2
  81. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1118 -633
  82. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  83. package/dist/types/SwcAppEngine.d.ts.map +1 -1
  84. package/dist/types/decorators/addEventListener.d.ts +19 -15
  85. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  86. package/dist/types/decorators/applyAttribute.d.ts +45 -26
  87. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  88. package/dist/types/decorators/applyClass.d.ts +19 -38
  89. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  90. package/dist/types/decorators/applyNode.d.ts +175 -32
  91. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  92. package/dist/types/decorators/applyProperty.d.ts +38 -25
  93. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  94. package/dist/types/decorators/applyStyle.d.ts +10 -9
  95. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  96. package/dist/types/decorators/{changedAttributeThis.d.ts → changedAttribute.d.ts} +2 -2
  97. package/dist/types/decorators/changedAttribute.d.ts.map +1 -0
  98. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  99. package/dist/types/decorators/emitCustomEvent.d.ts +6 -12
  100. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  101. package/dist/types/decorators/index.d.ts +1 -1
  102. package/dist/types/decorators/index.d.ts.map +1 -1
  103. package/dist/types/decorators/publishSwcAppMessage.d.ts +1 -1
  104. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
  105. package/dist/types/decorators/query.d.ts +16 -29
  106. package/dist/types/decorators/query.d.ts.map +1 -1
  107. package/dist/types/decorators/queryAll.d.ts +16 -23
  108. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  109. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +1 -0
  110. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  111. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +2 -0
  112. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  113. package/dist/types/elements/SwcAppMixin.d.ts +4 -4
  114. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  115. package/dist/types/examples/RxJSOperatorsExample.d.ts +94 -0
  116. package/dist/types/examples/RxJSOperatorsExample.d.ts.map +1 -0
  117. package/dist/types/index.d.ts +1 -0
  118. package/dist/types/index.d.ts.map +1 -1
  119. package/dist/types/router/ElementRouter.d.ts.map +1 -1
  120. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1118 -633
  121. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  122. package/package.json +1 -1
  123. package/src/SwcAppEngine.ts +3 -1
  124. package/src/decorators/addEventListener.ts +31 -25
  125. package/src/decorators/applyAttribute.ts +164 -86
  126. package/src/decorators/applyClass.ts +161 -41
  127. package/src/decorators/applyNode.ts +408 -108
  128. package/src/decorators/applyProperty.ts +100 -89
  129. package/src/decorators/applyStyle.ts +131 -37
  130. package/src/decorators/{changedAttributeThis.ts → changedAttribute.ts} +1 -1
  131. package/src/decorators/elementDefine.ts +96 -30
  132. package/src/decorators/emitCustomEvent.ts +92 -60
  133. package/src/decorators/index.ts +1 -1
  134. package/src/decorators/publishSwcAppMessage.ts +1 -1
  135. package/src/decorators/query.ts +155 -162
  136. package/src/decorators/queryAll.ts +157 -139
  137. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +1 -0
  138. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +3 -1
  139. package/src/elements/SwcAppMixin.ts +43 -24
  140. package/src/examples/RxJSOperatorsExample.ts +279 -0
  141. package/src/index.ts +2 -0
  142. package/src/router/ElementRouter.ts +4 -0
  143. package/src/types/window.d.ts +3 -0
  144. package/dist/cjs/decorators/changedAttributeThis.js.map +0 -7
  145. package/dist/esm/decorators/changedAttributeThis.js.map +0 -7
  146. package/dist/types/decorators/changedAttributeThis.d.ts.map +0 -1
@@ -34,9 +34,11 @@ export interface PropertyOptions extends SwcQueryOptions {
34
34
  valueKey?: symbol | string;
35
35
  }
36
36
 
37
+ export type PropertySelector = string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null);
38
+
37
39
  export interface PropertyMetadata {
38
40
  propertyKey: string | symbol;
39
- selector: string;
41
+ selector: PropertySelector;
40
42
  targetPropertyKey: string | symbol;
41
43
  options: PropertyOptions;
42
44
  type: 'property' | 'method';
@@ -50,15 +52,42 @@ export const PROPERTY_METADATA_KEY = Symbol.for('simple-web-component:property')
50
52
 
51
53
  /**
52
54
  * Resolve target elements based on selector and options
53
- * Handles special selectors ($this, $host, etc.) and CSS selectors
55
+ * Handles special selectors ($this, $host, etc.), CSS selectors, and function-based selectors
54
56
  * Returns HTMLElement[] but can include Window and Document for property access
55
57
  */
56
- export const resolvePropertyTargets = (inst: any, selector: string, options: PropertyOptions): any[] => {
58
+ export const resolvePropertyTargets = (inst: any, selector: PropertySelector, options: PropertyOptions): any[] => {
57
59
  const conf = getElementConfig(inst);
58
60
  const currentWin = conf.window;
59
61
  const r = options.root || 'auto';
60
62
  const results: any[] = [];
61
63
 
64
+ // Resolve selector if it's a function
65
+ let resolvedSelector: string | Element | NodeList | Element[] | null = selector as any;
66
+ if (typeof selector === 'function') {
67
+ const hostSet = SwcUtils.getHelperAndHostSet(currentWin, inst);
68
+ resolvedSelector = selector(inst, hostSet);
69
+ }
70
+
71
+ // If selector function returned elements directly, use them
72
+ if (resolvedSelector instanceof currentWin.Element) {
73
+ results.push(resolvedSelector);
74
+ return results;
75
+ }
76
+ if (resolvedSelector instanceof currentWin.NodeList) {
77
+ results.push(...Array.from(resolvedSelector));
78
+ return results;
79
+ }
80
+ if (Array.isArray(resolvedSelector)) {
81
+ results.push(...resolvedSelector);
82
+ return results;
83
+ }
84
+ if (resolvedSelector === null) {
85
+ return results;
86
+ }
87
+
88
+ // Handle string selector
89
+ const stringSelector = resolvedSelector as string;
90
+
62
91
  const applyRoot = (target: any) => {
63
92
  if (!target) return;
64
93
  if (r === 'auto') {
@@ -69,37 +98,37 @@ export const resolvePropertyTargets = (inst: any, selector: string, options: Pro
69
98
  }
70
99
  };
71
100
 
72
- if (selector === '$this' || !selector) {
101
+ if (stringSelector === '$this' || !stringSelector) {
73
102
  applyRoot(inst);
74
- } else if (selector === '$window') {
103
+ } else if (stringSelector === '$window') {
75
104
  results.push(currentWin);
76
- } else if (selector === '$document') {
105
+ } else if (stringSelector === '$document') {
77
106
  results.push(currentWin.document);
78
107
  } else {
79
108
  const hostSet = SwcUtils.getHostSet(inst);
80
- if (selector === '$host') applyRoot(hostSet.$host);
81
- else if (selector === '$parentHost') applyRoot(hostSet.$parentHost);
82
- else if (selector === '$appHost') applyRoot(hostSet.$appHost as any);
83
- else if (selector === '$firstHost') applyRoot(hostSet.$firstHost);
84
- else if (selector === '$lastHost') applyRoot(hostSet.$lastHost);
85
- else if (selector === '$firstAppHost') applyRoot(hostSet.$firstAppHost as any);
86
- else if (selector === '$lastAppHost') applyRoot(hostSet.$lastAppHost as any);
87
- else if (selector === '$hosts') hostSet.$hosts.forEach(applyRoot);
88
- else if (selector === '$appHosts') hostSet.$appHosts.forEach(applyRoot);
109
+ if (stringSelector === '$host') applyRoot(hostSet.$host);
110
+ else if (stringSelector === '$parentHost') applyRoot(hostSet.$parentHost);
111
+ else if (stringSelector === '$appHost') applyRoot(hostSet.$appHost as any);
112
+ else if (stringSelector === '$firstHost') applyRoot(hostSet.$firstHost);
113
+ else if (stringSelector === '$lastHost') applyRoot(hostSet.$lastHost);
114
+ else if (stringSelector === '$firstAppHost') applyRoot(hostSet.$firstAppHost as any);
115
+ else if (stringSelector === '$lastAppHost') applyRoot(hostSet.$lastAppHost as any);
116
+ else if (stringSelector === '$hosts') hostSet.$hosts.forEach(applyRoot);
117
+ else if (stringSelector === '$appHosts') hostSet.$appHosts.forEach(applyRoot);
89
118
  else {
90
119
  if (r === 'shadow') {
91
- const found = inst.shadowRoot?.querySelectorAll(selector);
120
+ const found = inst.shadowRoot?.querySelectorAll(stringSelector);
92
121
  if (found) results.push(...found);
93
122
  } else if (r === 'light') {
94
- const found = inst.querySelectorAll(selector);
123
+ const found = inst.querySelectorAll(stringSelector);
95
124
  if (found) results.push(...found);
96
125
  } else if (r === 'all') {
97
- const sMatch = inst.shadowRoot?.querySelectorAll(selector);
98
- const lMatch = inst.querySelectorAll(selector);
126
+ const sMatch = inst.shadowRoot?.querySelectorAll(stringSelector);
127
+ const lMatch = inst.querySelectorAll(stringSelector);
99
128
  if (sMatch) results.push(...sMatch);
100
129
  if (lMatch) results.push(...lMatch);
101
130
  } else {
102
- const found = (inst.shadowRoot || inst).querySelectorAll(selector);
131
+ const found = (inst.shadowRoot || inst).querySelectorAll(stringSelector);
103
132
  if (found) results.push(...found);
104
133
  }
105
134
  }
@@ -114,11 +143,12 @@ export const resolvePropertyTargets = (inst: any, selector: string, options: Pro
114
143
  * - @applyProperty('selector', 'propertyName') - Set property with explicit name
115
144
  * - @applyProperty('selector') - Use property name as target property name
116
145
  * - @applyProperty('selector', { name: 'propertyName' }) - Set property via options
146
+ * - @applyProperty((this, helper) => 'selector', 'propertyName') - Function-based selector
117
147
  * - Return null/undefined to skip setting
118
148
  */
119
- export function applyProperty(selector: string, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
120
- export function applyProperty(selector: string, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
121
- export function applyProperty(selector: string, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator & PropertyDecorator {
149
+ export function applyProperty(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
150
+ export function applyProperty(selector: PropertySelector, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
151
+ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator & PropertyDecorator {
122
152
  return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
123
153
  // ensureInit(target as any);
124
154
 
@@ -150,7 +180,7 @@ export function applyProperty(selector: string, targetPropertyKeyOrOptions?: str
150
180
  }
151
181
  metaList.push({
152
182
  propertyKey,
153
- selector,
183
+ selector: selector as PropertySelector,
154
184
  targetPropertyKey,
155
185
  options: finalOptions,
156
186
  type: metaType
@@ -260,81 +290,62 @@ export function applyProperty(selector: string, targetPropertyKeyOrOptions?: str
260
290
  // ============================================
261
291
 
262
292
  /**
263
- * @property - Alias for @applyProperty
264
- */
265
- export function property(selector: string, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
266
- export function property(selector: string, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
267
- export function property(selector: string, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator & PropertyDecorator {
268
- return applyProperty(selector, targetPropertyKeyOrOptions as any, options);
269
- }
270
-
271
- /**
272
- * @propertyThis - Apply property on $this element
273
- * Can be used as: @propertyThis or @propertyThis('propertyName') or @propertyThis({ name: 'propertyName' })
293
+ * @property - Field decorator for binding element properties (read/write)
294
+ *
295
+ * Usage:
296
+ * - @property('selector', 'propertyName') - Bind to specific property
297
+ * - @property('selector') - Use field name as property name
298
+ * - @property('selector', options) - Bind with options
299
+ * - @property((this, helper) => 'selector', 'propertyName') - Function-based selector
300
+ * - @property - Bare decorator (binds to $this with field name)
301
+ *
302
+ * Note: This decorator is for FIELDS ONLY. For methods, use @setProperty.
274
303
  */
275
- export function propertyThis(target: Object, propertyKey: string | symbol): void;
276
- export function propertyThis(targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
277
- export function propertyThis(options?: PropertyOptions): MethodDecorator & PropertyDecorator;
278
- export function propertyThis(targetOrOptions?: any, propertyKeyOrOptions?: any, descriptor?: PropertyDescriptor): any {
279
- // Direct decorator usage: @propertyThis
280
- if (typeof targetOrOptions === 'object' && targetOrOptions !== null && !Array.isArray(targetOrOptions) &&
281
- (typeof propertyKeyOrOptions === 'string' || typeof propertyKeyOrOptions === 'symbol')) {
282
- // Called as @propertyThis (target, propertyKey)
283
- return applyProperty('$this', undefined as any, {})(targetOrOptions, propertyKeyOrOptions, descriptor);
304
+ export function property(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
305
+ export function property(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): PropertyDecorator;
306
+ export function property(selector: PropertySelector, options?: PropertyOptions): PropertyDecorator;
307
+ export function property(selectorOrTarget?: PropertySelector | Object, targetPropertyKeyOrOptions?: any, optionsOrDescriptor?: any): any {
308
+ // Bare decorator: @property
309
+ if (optionsOrDescriptor !== undefined && (typeof targetPropertyKeyOrOptions === 'string' || typeof targetPropertyKeyOrOptions === 'symbol')) {
310
+ return applyProperty('$this', undefined as any, {})(selectorOrTarget as Object, targetPropertyKeyOrOptions, optionsOrDescriptor as PropertyDescriptor);
284
311
  }
285
-
286
- // Called with parameters
287
- if (typeof targetOrOptions === 'string' || typeof targetOrOptions === 'symbol') {
288
- // @propertyThis('propertyName', options?)
289
- return applyProperty('$this', targetOrOptions, propertyKeyOrOptions);
290
- } else if (targetOrOptions && typeof targetOrOptions === 'object') {
291
- // @propertyThis({ name: 'propertyName' })
292
- return applyProperty('$this', undefined as any, targetOrOptions);
293
- } else {
294
- // @propertyThis() or @propertyThis
295
- return applyProperty('$this', undefined as any, {});
312
+ // With selector
313
+ if (typeof selectorOrTarget === 'string') {
314
+ return applyProperty(selectorOrTarget, targetPropertyKeyOrOptions as any, optionsOrDescriptor as PropertyOptions);
296
315
  }
316
+ // Without selector (defaults to $this)
317
+ return applyProperty('$this', undefined as any, selectorOrTarget as PropertyOptions);
297
318
  }
298
319
 
299
320
  /**
300
- * @setProperty - Alias for @applyProperty (method-decorator semantics)
301
- */
302
- export function setProperty(selector: string, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator;
303
- export function setProperty(selector: string, options?: PropertyOptions): MethodDecorator;
304
- export function setProperty(selector: string, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator {
305
- return applyProperty(selector, targetPropertyKeyOrOptions as any, options) as MethodDecorator;
306
- }
307
-
308
- /**
309
- * @setPropertyThis - Set property on $this element
310
- * Can be used as: @setPropertyThis or @setPropertyThis('propertyName') or @setPropertyThis({ name: 'propertyName' })
321
+ * @setProperty - Method decorator for setting element properties from method return value
322
+ *
323
+ * Usage:
324
+ * - @setProperty('selector', 'propertyName') - Set specific property
325
+ * - @setProperty('selector') - Use method name as property name
326
+ * - @setProperty('selector', options) - Set with options
327
+ * - @setProperty((this, helper) => 'selector', 'propertyName') - Function-based selector
328
+ * - @setProperty - Bare decorator (sets on $this with method name)
329
+ *
330
+ * Note: This decorator is for METHODS ONLY. For fields, use @property.
331
+ *
332
+ * Example:
333
+ * @setProperty('selector', 'disabled')
334
+ * disableElement() {
335
+ * return true;
336
+ * }
311
337
  */
312
- export function setPropertyThis(target: Object, propertyKey: string | symbol): void;
313
- export function setPropertyThis(targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator;
314
- export function setPropertyThis(options?: PropertyOptions): MethodDecorator;
315
- export function setPropertyThis(targetOrOptions?: any, propertyKeyOrOptions?: any, descriptor?: PropertyDescriptor): any {
316
- // Direct decorator usage: @setPropertyThis
317
- if (typeof targetOrOptions === 'object' && targetOrOptions !== null && !Array.isArray(targetOrOptions) &&
318
- (typeof propertyKeyOrOptions === 'string' || typeof propertyKeyOrOptions === 'symbol')) {
319
- // Called as @setPropertyThis (target, propertyKey)
320
- return applyProperty('$this', undefined as any, {})(targetOrOptions, propertyKeyOrOptions, descriptor);
321
- }
322
-
323
- // Called with parameters
324
- if (typeof targetOrOptions === 'string' || typeof targetOrOptions === 'symbol') {
325
- // @setPropertyThis('propertyName', options?)
326
- return applyProperty('$this', targetOrOptions, propertyKeyOrOptions) as MethodDecorator;
327
- } else if (targetOrOptions && typeof targetOrOptions === 'object') {
328
- // @setPropertyThis({ name: 'propertyName' })
329
- return applyProperty('$this', undefined as any, targetOrOptions) as MethodDecorator;
330
- } else {
331
- // @setPropertyThis() or @setPropertyThis
332
- return applyProperty('$this', undefined as any, {}) as MethodDecorator;
338
+ export function setProperty(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator;
339
+ export function setProperty(selector: PropertySelector, options?: PropertyOptions): MethodDecorator;
340
+ export function setProperty(selectorOrOptions?: PropertySelector | PropertyOptions, targetPropertyKeyOrOptions?: any, optionsOrUndefined?: PropertyOptions): MethodDecorator {
341
+ // With selector
342
+ if (typeof selectorOrOptions === 'string') {
343
+ return applyProperty(selectorOrOptions, targetPropertyKeyOrOptions as any, optionsOrUndefined as PropertyOptions) as MethodDecorator;
333
344
  }
345
+ // Without selector (defaults to $this)
346
+ return applyProperty('$this', undefined as any, selectorOrOptions as PropertyOptions) as MethodDecorator;
334
347
  }
335
348
 
336
-
337
-
338
349
  // ============================================
339
350
  // Metadata Helpers
340
351
  // ============================================
@@ -15,17 +15,86 @@ export interface StyleApplyOptions extends SwcQueryOptions {
15
15
  valueKey?: symbol | string;
16
16
  }
17
17
 
18
+ export type StyleSelector = string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null);
19
+
18
20
  export interface StyleApplyMetadata {
19
21
  propertyKey: string | symbol;
20
- selector: string;
22
+ selector: StyleSelector;
21
23
  action: StyleAction;
22
24
  options: StyleApplyOptions;
23
25
  }
24
26
 
25
27
  export const STYLE_METADATA_KEY = Symbol.for('simple-web-component:style');
26
28
 
29
+ /**
30
+ * Resolve selector to string or elements
31
+ * Handles function-based selectors and returns elements if applicable
32
+ */
33
+ const resolveSelector = (selector: StyleSelector, inst: any, win: Window): string | HTMLElement[] => {
34
+ if (typeof selector === 'function') {
35
+ const hostSet = SwcUtils.getHelperAndHostSet(win, inst);
36
+ const result = selector(inst, hostSet);
37
+
38
+ if (result instanceof win.Element) {
39
+ return [result as HTMLElement];
40
+ }
41
+ if (result instanceof win.NodeList) {
42
+ return Array.from(result) as HTMLElement[];
43
+ }
44
+ if (Array.isArray(result)) {
45
+ return result as HTMLElement[];
46
+ }
47
+ if (result === null) {
48
+ return [];
49
+ }
50
+ return result as string;
51
+ }
52
+ return selector as string;
53
+ };
54
+
55
+ /**
56
+ * Get target elements from selector
57
+ */
58
+ const getTargetElements = (selector: StyleSelector, inst: any, win: Window, root: string): HTMLElement[] => {
59
+ const resolved = resolveSelector(selector, inst, win);
60
+
61
+ if (Array.isArray(resolved)) {
62
+ return resolved;
63
+ }
64
+
65
+ const stringSelector = resolved as string;
66
+ const targetEls: HTMLElement[] = [];
67
+ const host = inst as unknown as HTMLElement;
68
+ const hostSet = SwcUtils.getHelperAndHostSet(win, inst);
69
+
70
+ const applyRoot = (t: any) => {
71
+ if (!t || !(t instanceof win.HTMLElement)) return;
72
+ targetEls.push(t);
73
+ };
74
+
75
+ if (stringSelector === '$this' || !stringSelector) applyRoot(host);
76
+ else if (stringSelector === '$host') applyRoot(hostSet.$host);
77
+ else if (stringSelector === '$parentHost') applyRoot(hostSet.$parentHost);
78
+ else if (stringSelector === '$appHost') applyRoot(hostSet.$appHost);
79
+ else if (stringSelector === '$firstHost') applyRoot(hostSet.$firstHost);
80
+ else if (stringSelector === '$lastHost') applyRoot(hostSet.$lastHost);
81
+ else if (stringSelector === '$firstAppHost') applyRoot(hostSet.$firstAppHost);
82
+ else if (stringSelector === '$lastAppHost') applyRoot(hostSet.$lastAppHost);
83
+ else if (stringSelector === '$hosts') hostSet.$hosts.forEach(applyRoot);
84
+ else if (stringSelector === '$appHosts') hostSet.$appHosts.forEach(applyRoot);
85
+ else {
86
+ const targetRoot = root === 'auto' ? (host.shadowRoot || host) : (root === 'shadow' ? host.shadowRoot : host);
87
+ if (targetRoot) {
88
+ const found = targetRoot.querySelectorAll(stringSelector);
89
+ if (found) targetEls.push(...(Array.from(found) as HTMLElement[]));
90
+ }
91
+ }
92
+
93
+ return targetEls;
94
+ };
95
+
27
96
  function createStyleDecorator(action: StyleAction) {
28
- return (selector: string, options: StyleApplyOptions = {}): MethodDecorator => {
97
+ return (selector: StyleSelector, options: StyleApplyOptions = {}): MethodDecorator => {
29
98
  return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
30
99
  const constructor = target.constructor;
31
100
  let metaList = ReflectUtils.getOwnMetadata(STYLE_METADATA_KEY, constructor) as Map<string | symbol, StyleApplyMetadata>;
@@ -62,30 +131,7 @@ function createStyleDecorator(action: StyleAction) {
62
131
  const host = this as unknown as HTMLElement;
63
132
  const hostSet = { ...SwcUtils.getHelperAndHostSet(win, host), $this: this };
64
133
  const r = options.root || 'auto';
65
- const targetEls: HTMLElement[] = [];
66
-
67
- const applyRoot = (t: any) => {
68
- if (!t || !(t instanceof win.HTMLElement)) return;
69
- targetEls.push(t);
70
- };
71
-
72
- if (selector === '$this' || !selector) applyRoot(host);
73
- else if (selector === '$host') applyRoot(hostSet.$host);
74
- else if (selector === '$parentHost') applyRoot(hostSet.$parentHost);
75
- else if (selector === '$appHost') applyRoot(hostSet.$appHost);
76
- else if (selector === '$firstHost') applyRoot(hostSet.$firstHost);
77
- else if (selector === '$lastHost') applyRoot(hostSet.$lastHost);
78
- else if (selector === '$firstAppHost') applyRoot(hostSet.$firstAppHost);
79
- else if (selector === '$lastAppHost') applyRoot(hostSet.$lastAppHost);
80
- else if (selector === '$hosts') hostSet.$hosts.forEach(applyRoot);
81
- else if (selector === '$appHosts') hostSet.$appHosts.forEach(applyRoot);
82
- else {
83
- const targetRoot = r === 'auto' ? (host.shadowRoot || host) : (r === 'shadow' ? host.shadowRoot : host);
84
- if (targetRoot) {
85
- const found = targetRoot.querySelectorAll(selector);
86
- if (found) targetEls.push(...(Array.from(found) as HTMLElement[]));
87
- }
88
- }
134
+ const targetEls = getTargetElements(selector, this, win, r);
89
135
 
90
136
  targetEls.forEach(targetEl => {
91
137
  if (options.filter && !options.filter(targetEl, resolvedValue, {currentThis: this, helper: hostSet})) {
@@ -137,21 +183,69 @@ function createStyleDecorator(action: StyleAction) {
137
183
  };
138
184
  }
139
185
 
140
- export function applyStyle(selector: string, action: StyleAction = 'update', options: StyleApplyOptions = {}): MethodDecorator {
141
- return createStyleDecorator(action)(selector, options);
186
+ export function applyStyle(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
187
+ export function applyStyle(selector: StyleSelector, action?: StyleAction, options?: StyleApplyOptions): MethodDecorator;
188
+ export function applyStyle(selectorOrTarget?: any, actionOrPropertyKey?: any, optionsOrDescriptor?: any): any {
189
+ // Bare decorator: @applyStyle
190
+ if (optionsOrDescriptor !== undefined && (typeof actionOrPropertyKey === 'string' || typeof actionOrPropertyKey === 'symbol')) {
191
+ return createStyleDecorator('update')('$this', {})(selectorOrTarget as Object, actionOrPropertyKey, optionsOrDescriptor as PropertyDescriptor);
192
+ }
193
+ // With selector
194
+ if (typeof selectorOrTarget === 'string') {
195
+ const action = (typeof actionOrPropertyKey === 'string' ? actionOrPropertyKey : 'update') as StyleAction;
196
+ const options = (typeof actionOrPropertyKey === 'object' ? actionOrPropertyKey : optionsOrDescriptor) as StyleApplyOptions | undefined;
197
+ return createStyleDecorator(action)(selectorOrTarget, options);
198
+ }
199
+ // Without selector (defaults to $this)
200
+ const action = (typeof selectorOrTarget === 'string' ? selectorOrTarget : 'update') as StyleAction;
201
+ const options = (typeof selectorOrTarget === 'object' ? selectorOrTarget : actionOrPropertyKey) as StyleApplyOptions | undefined;
202
+ return createStyleDecorator(action)('$this', options);
142
203
  }
143
204
 
144
- export const setStyle = (selector: string, options: StyleApplyOptions = {}) => createStyleDecorator('set')(selector, options);
145
- export const updateStyle = (selector: string, options: StyleApplyOptions = {}) => createStyleDecorator('update')(selector, options);
146
- export const removeStyle = (selector: string, options: StyleApplyOptions = {}) => createStyleDecorator('remove')(selector, options);
205
+ export function setStyle(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
206
+ export function setStyle(selector: StyleSelector, options?: StyleApplyOptions): MethodDecorator;
207
+ export function setStyle(selectorOrTarget?: any, optionsOrPropertyKey?: any, descriptor?: any): any {
208
+ // Bare decorator: @setStyle
209
+ if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
210
+ return createStyleDecorator('set')('$this', {})(selectorOrTarget as Object, optionsOrPropertyKey, descriptor as PropertyDescriptor);
211
+ }
212
+ // With selector
213
+ if (typeof selectorOrTarget === 'string') {
214
+ return createStyleDecorator('set')(selectorOrTarget, optionsOrPropertyKey as StyleApplyOptions);
215
+ }
216
+ // Without selector (defaults to $this)
217
+ return createStyleDecorator('set')('$this', selectorOrTarget as StyleApplyOptions);
218
+ }
147
219
 
148
- // This versions
149
- export function applyStyleThis(action: StyleAction = 'update', options: StyleApplyOptions = {}): MethodDecorator {
150
- return createStyleDecorator(action)('$this', options);
220
+ export function updateStyle(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
221
+ export function updateStyle(selector: StyleSelector, options?: StyleApplyOptions): MethodDecorator;
222
+ export function updateStyle(selectorOrTarget?: any, optionsOrPropertyKey?: any, descriptor?: any): any {
223
+ // Bare decorator: @updateStyle
224
+ if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
225
+ return createStyleDecorator('update')('$this', {})(selectorOrTarget as Object, optionsOrPropertyKey, descriptor as PropertyDescriptor);
226
+ }
227
+ // With selector
228
+ if (typeof selectorOrTarget === 'string') {
229
+ return createStyleDecorator('update')(selectorOrTarget, optionsOrPropertyKey as StyleApplyOptions);
230
+ }
231
+ // Without selector (defaults to $this)
232
+ return createStyleDecorator('update')('$this', selectorOrTarget as StyleApplyOptions);
233
+ }
234
+
235
+ export function removeStyle(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
236
+ export function removeStyle(selector: StyleSelector, options?: StyleApplyOptions): MethodDecorator;
237
+ export function removeStyle(selectorOrTarget?: any, optionsOrPropertyKey?: any, descriptor?: any): any {
238
+ // Bare decorator: @removeStyle
239
+ if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
240
+ return createStyleDecorator('remove')('$this', {})(selectorOrTarget as Object, optionsOrPropertyKey, descriptor as PropertyDescriptor);
241
+ }
242
+ // With selector
243
+ if (typeof selectorOrTarget === 'string') {
244
+ return createStyleDecorator('remove')(selectorOrTarget, optionsOrPropertyKey as StyleApplyOptions);
245
+ }
246
+ // Without selector (defaults to $this)
247
+ return createStyleDecorator('remove')('$this', selectorOrTarget as StyleApplyOptions);
151
248
  }
152
- export const setStyleThis = (options: StyleApplyOptions = {}) => createStyleDecorator('set')('$this', options);
153
- export const updateStyleThis = (options: StyleApplyOptions = {}) => createStyleDecorator('update')('$this', options);
154
- export const removeStyleThis = (options: StyleApplyOptions = {}) => createStyleDecorator('remove')('$this', options);
155
249
 
156
250
  export const findAllStyleMetadata = (target: any): Map<string | symbol, StyleApplyMetadata> => {
157
251
  const result = new Map<string | symbol, StyleApplyMetadata>();
@@ -23,7 +23,7 @@ const convertValue = (val: any, type: any): any => {
23
23
  /**
24
24
  * @changedAttributeThis decorator - fires when any attribute on $this changes
25
25
  */
26
- export function changedAttributeThis(attributeName?: string, options: ChangedAttributeThisOptions = {}): MethodDecorator {
26
+ export function changedAttribute(attributeName?: string, options: ChangedAttributeThisOptions = {}): MethodDecorator {
27
27
  return (target: Object, propertyKey: string | symbol) => {
28
28
  const constructor = target.constructor;
29
29
  let metaList = ReflectUtils.getOwnMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, constructor) as ChangedAttributeThisMetadata[];