@dooboostore/simple-web-component 1.0.22 → 1.0.24

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 (105) hide show
  1. package/README.md +568 -32
  2. package/dist/cjs/decorators/applyNode.js +195 -26
  3. package/dist/cjs/decorators/applyNode.js.map +2 -2
  4. package/dist/cjs/decorators/attribute.js +21 -3
  5. package/dist/cjs/decorators/attribute.js.map +2 -2
  6. package/dist/cjs/decorators/changedAttributeHost.js.map +2 -2
  7. package/dist/cjs/decorators/classList.js +82 -19
  8. package/dist/cjs/decorators/classList.js.map +2 -2
  9. package/dist/cjs/decorators/elementDefine.js +1 -2
  10. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  11. package/dist/cjs/decorators/index.js +0 -1
  12. package/dist/cjs/decorators/index.js.map +2 -2
  13. package/dist/cjs/decorators/lifecycles.js +25 -0
  14. package/dist/cjs/decorators/lifecycles.js.map +2 -2
  15. package/dist/cjs/decorators/query.js +77 -2
  16. package/dist/cjs/decorators/query.js.map +2 -2
  17. package/dist/cjs/decorators/queryAll.js +77 -2
  18. package/dist/cjs/decorators/queryAll.js.map +2 -2
  19. package/dist/cjs/decorators/setAttribute.js +4 -4
  20. package/dist/cjs/decorators/setAttribute.js.map +2 -2
  21. package/dist/cjs/decorators/style.js +70 -13
  22. package/dist/cjs/decorators/style.js.map +2 -2
  23. package/dist/cjs/index.js +4 -4
  24. package/dist/cjs/index.js.map +2 -2
  25. package/dist/cjs/utils/Utils.js +140 -1
  26. package/dist/cjs/utils/Utils.js.map +2 -2
  27. package/dist/esm/decorators/applyNode.js +195 -26
  28. package/dist/esm/decorators/applyNode.js.map +2 -2
  29. package/dist/esm/decorators/attribute.js +21 -3
  30. package/dist/esm/decorators/attribute.js.map +2 -2
  31. package/dist/esm/decorators/changedAttributeHost.js.map +2 -2
  32. package/dist/esm/decorators/classList.js +82 -19
  33. package/dist/esm/decorators/classList.js.map +2 -2
  34. package/dist/esm/decorators/elementDefine.js +1 -2
  35. package/dist/esm/decorators/elementDefine.js.map +2 -2
  36. package/dist/esm/decorators/index.js +0 -1
  37. package/dist/esm/decorators/index.js.map +2 -2
  38. package/dist/esm/decorators/lifecycles.js +25 -0
  39. package/dist/esm/decorators/lifecycles.js.map +2 -2
  40. package/dist/esm/decorators/query.js +77 -2
  41. package/dist/esm/decorators/query.js.map +2 -2
  42. package/dist/esm/decorators/queryAll.js +77 -2
  43. package/dist/esm/decorators/queryAll.js.map +2 -2
  44. package/dist/esm/decorators/setAttribute.js +4 -4
  45. package/dist/esm/decorators/setAttribute.js.map +2 -2
  46. package/dist/esm/decorators/style.js +70 -13
  47. package/dist/esm/decorators/style.js.map +2 -2
  48. package/dist/esm/index.js +4 -4
  49. package/dist/esm/index.js.map +2 -2
  50. package/dist/esm/utils/Utils.js +140 -1
  51. package/dist/esm/utils/Utils.js.map +2 -2
  52. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +678 -168
  53. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  54. package/dist/types/decorators/applyNode.d.ts +107 -2
  55. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  56. package/dist/types/decorators/attribute.d.ts +11 -4
  57. package/dist/types/decorators/attribute.d.ts.map +1 -1
  58. package/dist/types/decorators/classList.d.ts +22 -10
  59. package/dist/types/decorators/classList.d.ts.map +1 -1
  60. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  61. package/dist/types/decorators/index.d.ts +0 -1
  62. package/dist/types/decorators/index.d.ts.map +1 -1
  63. package/dist/types/decorators/lifecycles.d.ts +14 -0
  64. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  65. package/dist/types/decorators/query.d.ts +68 -7
  66. package/dist/types/decorators/query.d.ts.map +1 -1
  67. package/dist/types/decorators/queryAll.d.ts +70 -1
  68. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  69. package/dist/types/decorators/setAttribute.d.ts.map +1 -1
  70. package/dist/types/decorators/style.d.ts +37 -3
  71. package/dist/types/decorators/style.d.ts.map +1 -1
  72. package/dist/types/index.d.ts +1 -2
  73. package/dist/types/index.d.ts.map +1 -1
  74. package/dist/types/utils/Utils.d.ts +49 -0
  75. package/dist/types/utils/Utils.d.ts.map +1 -1
  76. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +678 -168
  77. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  78. package/package.json +2 -2
  79. package/src/decorators/applyNode.ts +319 -37
  80. package/src/decorators/attribute.ts +44 -11
  81. package/src/decorators/changedAttributeHost.ts +1 -1
  82. package/src/decorators/classList.ts +107 -22
  83. package/src/decorators/elementDefine.ts +1 -2
  84. package/src/decorators/index.ts +0 -1
  85. package/src/decorators/lifecycles.ts +40 -0
  86. package/src/decorators/query.ts +147 -7
  87. package/src/decorators/queryAll.ts +148 -2
  88. package/src/decorators/setAttribute.ts +6 -5
  89. package/src/decorators/style.ts +109 -13
  90. package/src/index.ts +6 -6
  91. package/src/utils/Utils.ts +144 -0
  92. package/dist/cjs/decorators/onConnectedInnerHtml.js +0 -48
  93. package/dist/cjs/decorators/onConnectedInnerHtml.js.map +0 -7
  94. package/dist/cjs/utils/TemplateUtils.js +0 -103
  95. package/dist/cjs/utils/TemplateUtils.js.map +0 -7
  96. package/dist/esm/decorators/onConnectedInnerHtml.js +0 -29
  97. package/dist/esm/decorators/onConnectedInnerHtml.js.map +0 -7
  98. package/dist/esm/utils/TemplateUtils.js +0 -84
  99. package/dist/esm/utils/TemplateUtils.js.map +0 -7
  100. package/dist/types/decorators/onConnectedInnerHtml.d.ts +0 -15
  101. package/dist/types/decorators/onConnectedInnerHtml.d.ts.map +0 -1
  102. package/dist/types/utils/TemplateUtils.d.ts +0 -54
  103. package/dist/types/utils/TemplateUtils.d.ts.map +0 -1
  104. package/src/decorators/onConnectedInnerHtml.ts +0 -42
  105. package/src/utils/TemplateUtils.ts +0 -83
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-web-component",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -92,8 +92,8 @@
92
92
  "webpack": "^5.93.0",
93
93
  "webpack-cli": "^5.1.4",
94
94
  "webpack-dev-server": "^5.2.0",
95
- "@dooboostore/core-web": "1.0.10",
96
95
  "@dooboostore/core": "1.0.30",
96
+ "@dooboostore/core-web": "1.0.10",
97
97
  "@dooboostore/core-node": "1.0.12",
98
98
  "@dooboostore/simple-boot": "1.0.54"
99
99
  },
@@ -1,10 +1,13 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { ensureInit, getElementConfig } from './elementDefine';
3
+ import { SwcRootType } from '../types';
4
+ import {SwcUtils} from "../utils/Utils";
3
5
 
4
- export type ApplyNodePosition = 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd' | 'replace' | 'replaceChildren' | 'innerHtml' | 'innerText';
6
+ export type ApplyNodePosition = 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd' | 'replace' | 'replaceChildren' | 'innerHtml' | 'innerText' | 'remove';
5
7
 
6
8
  export interface ApplyNodeOptions {
7
9
  position?: ApplyNodePosition;
10
+ root?: SwcRootType;
8
11
  }
9
12
 
10
13
  export interface ApplyNodeMetadata {
@@ -31,6 +34,8 @@ const normalizeNodes = (res: any, doc: Document): Node[] => {
31
34
  * @applyNode('#header', { position: 'afterBegin' }) prependItem() { return '<h1>Title</h1>'; } // prepend at start
32
35
  * @applyNode('#item', { position: 'replace' }) replaceItem() { return '<div>Replaced</div>'; } // replace element
33
36
  * @applyNode('#list', { position: 'replaceChildren' }) updateList() { return [item1, item2]; } // replace all children
37
+ * @applyNode('#notification', { position: 'remove' }) dismissNotification() { return shouldDismiss; } // remove if truthy
38
+ * @applyNode('.items', { position: 'remove', root: 'shadow' }) clearItems() { return true; } // remove shadow DOM elements
34
39
  *
35
40
  * Positions:
36
41
  * - 'beforeEnd' (default): Append at end of target
@@ -41,6 +46,13 @@ const normalizeNodes = (res: any, doc: Document): Node[] => {
41
46
  * - 'replaceChildren': Replace all children of target element
42
47
  * - 'innerHtml': Set target's innerHTML
43
48
  * - 'innerText': Set target's innerText
49
+ * - 'remove': Remove target element if returned value is truthy
50
+ *
51
+ * Root Options:
52
+ * - 'auto' (default): Search shadow DOM first, then light DOM
53
+ * - 'shadow': Search only in shadow DOM
54
+ * - 'light': Search only in light DOM
55
+ * - 'all': Use both (shadow preferred for query, both for remove)
44
56
  */
45
57
  export function applyNode(selector: string, options: ApplyNodeOptions = { position: 'beforeEnd' }): MethodDecorator {
46
58
  return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
@@ -61,43 +73,101 @@ export function applyNode(selector: string, options: ApplyNodeOptions = { positi
61
73
  const currentWin = (this as any)._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as Window);
62
74
  const currentDoc = currentWin.document;
63
75
 
64
- let targetEl: HTMLElement | null = null;
65
- if (selector === ':host' || !selector) {
66
- targetEl = this as any;
76
+ const pos = options.position || 'beforeEnd';
77
+ const r = options.root || 'auto';
78
+ const applyRoot = (t: any) => {
79
+ if (!t || !(t instanceof HTMLElement)) return t;
80
+ if (r === 'auto') return t.shadowRoot || t;
81
+ if (r === 'shadow') return t.shadowRoot;
82
+ if (r === 'light') return t;
83
+ if (r === 'all') return t.shadowRoot || t; // query only returns one, so shadow preferred
84
+ return t;
85
+ };
86
+
87
+ const hostSet = SwcUtils.getHostSet(this);
88
+ // const getTargetRoot = () => {
89
+ // if (r === 'shadow') return this.shadowRoot;
90
+ // if (r === 'light') return this as any;
91
+ // if (r === 'all') return this.shadowRoot || (this as any);
92
+ // return this.shadowRoot || (this as any); // auto
93
+ // };
94
+
95
+ if (pos === 'remove') {
96
+ // Remove element(s) if returned value is truthy
97
+ if (res) {
98
+ if (selector === ':host' || !selector) {
99
+ if (r === 'shadow' && this.shadowRoot) {
100
+ // Remove all children from shadow DOM
101
+ this.shadowRoot.replaceChildren();
102
+ } else {
103
+ // Remove the component itself
104
+ (this as any).remove();
105
+ }
106
+ } else {
107
+ const targetRoot = applyRoot(this);
108
+ if (targetRoot) {
109
+ const targets = targetRoot.querySelectorAll(selector);
110
+ targets.forEach((el: Element) => el.remove());
111
+ }
112
+ }
113
+ }
67
114
  } else {
68
- targetEl = (this.shadowRoot || (this as any)).querySelector(selector);
69
- }
115
+ let targetEl: any = null;
70
116
 
71
- if (targetEl) {
72
- const nodes = normalizeNodes(res, currentDoc);
73
- const pos = options.position || 'beforeEnd';
74
-
75
- if (pos === 'replace') {
76
- // Replace the entire target element with new nodes
77
- targetEl.replaceWith(...nodes);
78
- } else if (pos === 'replaceChildren') {
79
- // Replace all children of target element
80
- targetEl.replaceChildren(...nodes);
81
- } else if (pos === 'innerHtml') {
82
- // Set innerHTML
83
- targetEl.innerHTML = res !== undefined && res !== null ? String(res) : '';
84
- } else if (pos === 'innerText') {
85
- // Set innerText
86
- targetEl.innerText = res !== undefined && res !== null ? String(res) : '';
117
+ if (selector === ':host') {
118
+ targetEl = applyRoot(this)
119
+ } else if (selector === ':parentHost') {
120
+ targetEl = applyRoot(hostSet.$parentHost)
121
+ } else if (selector === ':appHost') {
122
+ targetEl = applyRoot(hostSet.$appHost)
123
+ } else if (selector === ':firstHost') {
124
+ targetEl = applyRoot(hostSet.$firstHost)
125
+ } else if (selector === ':lastHost') {
126
+ targetEl = applyRoot(hostSet.$lastHost)
127
+ } else if (selector === ':firstAppHost') {
128
+ targetEl = applyRoot(hostSet.$firstHost)
129
+ } else if (selector === ':lastAppHost') {
130
+ targetEl = applyRoot(hostSet.$lastAppHost);
87
131
  } else {
88
- /*
89
- <!-- beforebegin -->
90
- <p>
91
- <!-- afterbegin -->
92
- foo
93
- <!-- beforeend -->
94
- </p>
95
- <!-- afterend -->
96
- */
97
- if (pos === 'beforeEnd') targetEl.append(...nodes);
98
- else if (pos === 'afterBegin') targetEl.prepend(...nodes);
99
- else if (pos === 'beforeBegin') targetEl.before(...nodes);
100
- else if (pos === 'afterEnd') targetEl.after(...nodes);
132
+ const targetRoot = applyRoot(this);
133
+ targetEl = targetRoot ? targetRoot.querySelector(selector) : null;
134
+ }
135
+
136
+ if (targetEl) {
137
+ const isShadowRoot = targetEl instanceof ShadowRoot;
138
+ const nodes = normalizeNodes(res, currentDoc);
139
+
140
+ if (pos === 'replace') {
141
+ // ShadowRoot doesn't support replaceWith
142
+ if (!isShadowRoot) {
143
+ targetEl.replaceWith(...nodes);
144
+ }
145
+ } else if (pos === 'replaceChildren') {
146
+ // Replace all children of target element
147
+ targetEl.replaceChildren(...nodes);
148
+ } else if (pos === 'innerHtml') {
149
+ // Set innerHTML
150
+ targetEl.innerHTML = res !== undefined && res !== null ? String(res) : '';
151
+ } else if (pos === 'innerText') {
152
+ // Set innerText
153
+ if (targetEl.innerText !== undefined) {
154
+ targetEl.innerText = res !== undefined && res !== null ? String(res) : '';
155
+ }
156
+ } else {
157
+ /*
158
+ <!-- beforebegin -->
159
+ <p>
160
+ <!-- afterbegin -->
161
+ foo
162
+ <!-- beforeend -->
163
+ </p>
164
+ <!-- afterend -->
165
+ */
166
+ if (pos === 'beforeEnd') targetEl.append(...nodes);
167
+ else if (pos === 'afterBegin') targetEl.prepend(...nodes);
168
+ else if (pos === 'beforeBegin' && !isShadowRoot) targetEl.before(...nodes);
169
+ else if (pos === 'afterEnd' && !isShadowRoot) targetEl.after(...nodes);
170
+ }
101
171
  }
102
172
  }
103
173
  }
@@ -119,9 +189,221 @@ export const findAllApplyNodeMetadata = (target: any): Map<string | symbol, Appl
119
189
 
120
190
  /**
121
191
  * @applyNodeHost decorator - simplified version of @applyNode for :host selector
192
+ * Usage: @applyNodeHost addItem() { return '<li>New Item</li>'; }
122
193
  * Usage: @applyNodeHost() addItem() { return '<li>New Item</li>'; }
123
194
  * Usage: @applyNodeHost({ position: 'afterBegin' }) prependItem() { return '<h1>Title</h1>'; }
124
195
  */
125
- export function applyNodeHost(options: ApplyNodeOptions = { position: 'beforeEnd' }): MethodDecorator {
126
- return applyNode(':host', options);
196
+ export function applyNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
197
+ export function applyNodeHost(): MethodDecorator;
198
+ export function applyNodeHost(options: ApplyNodeOptions): MethodDecorator;
199
+ export function applyNodeHost(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
200
+ // Direct decorator usage: @applyNodeHost (no parentheses)
201
+ console.log('vvvvv')
202
+ if (propertyKey !== undefined && typeof propertyKey === 'string' || typeof propertyKey === 'symbol') {
203
+ return applyNode(':host', { position: 'beforeEnd' })(targetOrOptions, propertyKey, descriptor);
204
+ }
205
+
206
+ // @applyNodeHost() or @applyNodeHost(options)
207
+ if (typeof targetOrOptions === 'object' && targetOrOptions !== null) {
208
+ const options = targetOrOptions as ApplyNodeOptions;
209
+ return applyNode(':host', { ...options, position: options.position || 'beforeEnd' });
210
+ } else {
211
+ // @applyNodeHost() - use default position
212
+ return applyNode(':host', { position: 'beforeEnd' });
213
+ }
214
+ }
215
+
216
+ // Convenience decorators for specific positions
217
+
218
+ /**
219
+ * @applyBeforeBeginNode - Insert before target element
220
+ */
221
+ export function applyBeforeBeginNode(selector: string): MethodDecorator;
222
+ export function applyBeforeBeginNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
223
+ export function applyBeforeBeginNode(selector: string, options?: ApplyNodeOptions): any {
224
+ return applyNode(selector, { ...options, position: 'beforeBegin' });
225
+ }
226
+
227
+ /**
228
+ * @applyAfterBeginNode - Prepend to target element
229
+ */
230
+ export function applyAfterBeginNode(selector: string): MethodDecorator;
231
+ export function applyAfterBeginNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
232
+ export function applyAfterBeginNode(selector: string, options?: ApplyNodeOptions): any {
233
+ return applyNode(selector, { ...options, position: 'afterBegin' });
234
+ }
235
+
236
+ /**
237
+ * @applyBeforeEndNode - Append to target element (default)
238
+ */
239
+ export function applyBeforeEndNode(selector: string): MethodDecorator;
240
+ export function applyBeforeEndNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
241
+ export function applyBeforeEndNode(selector: string, options?: ApplyNodeOptions): any {
242
+ return applyNode(selector, { ...options, position: 'beforeEnd' });
243
+ }
244
+
245
+ /**
246
+ * @applyAfterEndNode - Insert after target element
247
+ */
248
+ export function applyAfterEndNode(selector: string): MethodDecorator;
249
+ export function applyAfterEndNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
250
+ export function applyAfterEndNode(selector: string, options?: ApplyNodeOptions): any {
251
+ return applyNode(selector, { ...options, position: 'afterEnd' });
252
+ }
253
+
254
+ /**
255
+ * @applyReplaceNode - Replace entire target element
256
+ */
257
+ export function applyReplaceNode(selector: string): MethodDecorator;
258
+ export function applyReplaceNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
259
+ export function applyReplaceNode(selector: string, options?: ApplyNodeOptions): any {
260
+ return applyNode(selector, { ...options, position: 'replace' });
261
+ }
262
+
263
+ /**
264
+ * @applyReplaceChildrenNode - Replace all children of target element
265
+ */
266
+ export function applyReplaceChildrenNode(selector: string): MethodDecorator;
267
+ export function applyReplaceChildrenNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
268
+ export function applyReplaceChildrenNode(selector: string, options?: ApplyNodeOptions): any {
269
+ return applyNode(selector, { ...options, position: 'replaceChildren' });
270
+ }
271
+
272
+ /**
273
+ * @applyInnerHtmlNode - Set target's innerHTML
274
+ */
275
+ export function applyInnerHtmlNode(selector: string): MethodDecorator;
276
+ export function applyInnerHtmlNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
277
+ export function applyInnerHtmlNode(selector: string, options?: ApplyNodeOptions): any {
278
+ return applyNode(selector, { ...options, position: 'innerHtml' });
279
+ }
280
+
281
+ /**
282
+ * @applyInnerTextNode - Set target's innerText
283
+ */
284
+ export function applyInnerTextNode(selector: string): MethodDecorator;
285
+ export function applyInnerTextNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
286
+ export function applyInnerTextNode(selector: string, options?: ApplyNodeOptions): any {
287
+ return applyNode(selector, { ...options, position: 'innerText' });
288
+ }
289
+
290
+ /**
291
+ * @applyRemoveNode - Remove target element if truthy
292
+ */
293
+ export function applyRemoveNode(selector: string): MethodDecorator;
294
+ export function applyRemoveNode(selector: string, options: ApplyNodeOptions): MethodDecorator;
295
+ export function applyRemoveNode(selector: string, options?: ApplyNodeOptions): any {
296
+ return applyNode(selector, { ...options, position: 'remove' });
297
+ }
298
+
299
+ // Host versions
300
+
301
+ /**
302
+ * @applyBeforeBeginNodeHost - Insert before :host
303
+ */
304
+ export function applyBeforeBeginNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;
305
+ export function applyBeforeBeginNodeHost(): MethodDecorator;
306
+ export function applyBeforeBeginNodeHost(options: ApplyNodeOptions): MethodDecorator;
307
+ export function applyBeforeBeginNodeHost(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
308
+ if (propertyKey !== undefined) {
309
+ const decorator = applyNode(':host', { position: 'beforeBegin' });
310
+ return decorator(targetOrOptions, propertyKey, descriptor);
311
+ }
312
+ return applyNode(':host', { ...(targetOrOptions as ApplyNodeOptions || {}), position: 'beforeBegin' });
313
+ }
314
+
315
+ /**
316
+ * @applyAfterBeginNodeHost - Prepend to :host
317
+ */export function applyAfterBeginNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyAfterBeginNodeHost(): MethodDecorator;
318
+ export function applyAfterBeginNodeHost(options: ApplyNodeOptions): MethodDecorator;
319
+ export function applyAfterBeginNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
320
+ if (propertyKey !== undefined) {
321
+ const decorator = applyNode(':host', { position: 'afterBegin' });
322
+ return decorator(optionsOrTarget, propertyKey, descriptor);
323
+ }
324
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'afterBegin' });
325
+ }
326
+
327
+ /**
328
+ * @applyBeforeEndNodeHost - Append to :host
329
+ */export function applyBeforeEndNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyBeforeEndNodeHost(): MethodDecorator;
330
+ export function applyBeforeEndNodeHost(options: ApplyNodeOptions): MethodDecorator;
331
+ export function applyBeforeEndNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
332
+ if (propertyKey !== undefined) {
333
+ const decorator = applyNode(':host', { position: 'beforeEnd' });
334
+ return decorator(optionsOrTarget, propertyKey, descriptor);
335
+ }
336
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'beforeEnd' });
337
+ }
338
+
339
+ /**
340
+ * @applyAfterEndNodeHost - Insert after :host
341
+ */export function applyAfterEndNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyAfterEndNodeHost(): MethodDecorator;
342
+ export function applyAfterEndNodeHost(options: ApplyNodeOptions): MethodDecorator;
343
+ export function applyAfterEndNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
344
+ if (propertyKey !== undefined) {
345
+ const decorator = applyNode(':host', { position: 'afterEnd' });
346
+ return decorator(optionsOrTarget, propertyKey, descriptor);
347
+ }
348
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'afterEnd' });
349
+ }
350
+
351
+ /**
352
+ * @applyReplaceNodeHost - Replace :host
353
+ */export function applyReplaceNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyReplaceNodeHost(): MethodDecorator;
354
+ export function applyReplaceNodeHost(options: ApplyNodeOptions): MethodDecorator;
355
+ export function applyReplaceNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
356
+ if (propertyKey !== undefined) {
357
+ const decorator = applyNode(':host', { position: 'replace' });
358
+ return decorator(optionsOrTarget, propertyKey, descriptor);
359
+ }
360
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'replace' });
361
+ }
362
+
363
+ /**
364
+ * @applyReplaceChildrenNodeHost - Replace children of :host
365
+ */export function applyReplaceChildrenNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyReplaceChildrenNodeHost(): MethodDecorator;
366
+ export function applyReplaceChildrenNodeHost(options: ApplyNodeOptions): MethodDecorator;
367
+ export function applyReplaceChildrenNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
368
+ if (propertyKey !== undefined) {
369
+ const decorator = applyNode(':host', { position: 'replaceChildren' });
370
+ return decorator(optionsOrTarget, propertyKey, descriptor);
371
+ }
372
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'replaceChildren' });
373
+ }
374
+
375
+ /**
376
+ * @applyInnerHtmlNodeHost - Set :host innerHTML
377
+ */export function applyInnerHtmlNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyInnerHtmlNodeHost(): MethodDecorator;
378
+ export function applyInnerHtmlNodeHost(options: ApplyNodeOptions): MethodDecorator;
379
+ export function applyInnerHtmlNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
380
+ if (propertyKey !== undefined) {
381
+ const decorator = applyNode(':host', { position: 'innerHtml' });
382
+ return decorator(optionsOrTarget, propertyKey, descriptor);
383
+ }
384
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'innerHtml' });
385
+ }
386
+
387
+ /**
388
+ * @applyInnerTextNodeHost - Set :host innerText
389
+ */export function applyInnerTextNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyInnerTextNodeHost(): MethodDecorator;
390
+ export function applyInnerTextNodeHost(options: ApplyNodeOptions): MethodDecorator;
391
+ export function applyInnerTextNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
392
+ if (propertyKey !== undefined) {
393
+ const decorator = applyNode(':host', { position: 'innerText' });
394
+ return decorator(optionsOrTarget, propertyKey, descriptor);
395
+ }
396
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'innerText' });
397
+ }
398
+
399
+ /**
400
+ * @applyRemoveNodeHost - Remove :host if truthy
401
+ */export function applyRemoveNodeHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): any;export function applyRemoveNodeHost(): MethodDecorator;
402
+ export function applyRemoveNodeHost(options: ApplyNodeOptions): MethodDecorator;
403
+ export function applyRemoveNodeHost(optionsOrTarget?: ApplyNodeOptions | any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
404
+ if (propertyKey !== undefined) {
405
+ const decorator = applyNode(':host', { position: 'remove' });
406
+ return decorator(optionsOrTarget, propertyKey, descriptor);
407
+ }
408
+ return applyNode(':host', { ...(optionsOrTarget as ApplyNodeOptions || {}), position: 'remove' });
127
409
  }
@@ -1,7 +1,7 @@
1
- import { ReflectUtils } from '@dooboostore/core';
2
- import { ensureInit, getElementConfig } from './elementDefine';
3
- import { SwcUtils } from '../utils/Utils';
4
- import { SpecialSelector, SwcQueryOptions } from '../types';
1
+ import {ReflectUtils} from '@dooboostore/core';
2
+ import {ensureInit, getElementConfig} from './elementDefine';
3
+ import {SwcUtils} from '../utils/Utils';
4
+ import {SpecialSelector, SwcQueryOptions} from '../types';
5
5
 
6
6
  export interface AttributeOptions extends SwcQueryOptions {
7
7
  name?: string;
@@ -97,7 +97,7 @@ export function attribute(selector: string, options: AttributeOptions = {}): Pro
97
97
  metaList = [];
98
98
  ReflectUtils.defineMetadata(ATTRIBUTE_METADATA_KEY, metaList, constructor);
99
99
  }
100
- metaList.push({ propertyKey, selector, options, privateKey });
100
+ metaList.push({propertyKey, selector, options, privateKey});
101
101
 
102
102
  // Helper function to apply setAttribute to targets
103
103
  const applySetAttribute = (inst: any, targets: HTMLElement[], attrName: string, nv: any) => {
@@ -143,7 +143,7 @@ export function attribute(selector: string, options: AttributeOptions = {}): Pro
143
143
  },
144
144
  set(this: any, nv: any) {
145
145
  const targetType = options.type || designType;
146
- console.log('---set', propertyKey, targetType, nv, this, this.__swc_syncing_init);
146
+ // console.log('---set', propertyKey, targetType, nv, this, this.__swc_syncing_init);
147
147
 
148
148
  const attrName = options.name || String(propertyKey);
149
149
  const conf = getElementConfig(this);
@@ -183,10 +183,43 @@ export const findAllAttributeMetadata = (target: any): AttributeMetadata[] => {
183
183
  };
184
184
 
185
185
  /**
186
- * @hostAttribute decorator - simplified version of @attribute for :host selector
187
- * Usage: @hostAttribute('data-product-id')
188
- * Usage: @hostAttribute('disabled', { type: Boolean })
186
+ * @attributeHost decorator - simplified version of @attribute for :host selector
187
+ * Usage: @attributeHost - uses field name as attribute name
188
+ * Usage: @attributeHost() - uses field name as attribute name
189
+ * Usage: @attributeHost('data-id') - uses custom attribute name
190
+ * Usage: @attributeHost({ type: Boolean }) - uses field name with options
191
+ * Usage: @attributeHost('data-id', { type: Boolean }) - uses custom name with options
189
192
  */
190
- export function attributeHost(attrName: string, options: AttributeOptions = {}): PropertyDecorator {
191
- return attribute(':host', { ...options, name: attrName });
193
+ export function attributeHost(target: Object, propertyKey: string | symbol): void;
194
+ export function attributeHost(): PropertyDecorator;
195
+ export function attributeHost(options: AttributeOptions): PropertyDecorator;
196
+ export function attributeHost(attrName: string): PropertyDecorator;
197
+ export function attributeHost(attrName: string, options: AttributeOptions): PropertyDecorator;
198
+ export function attributeHost(targetOrAttrOrOptions?: any, propertyKeyOrOptions?: any): any {
199
+ // Direct decorator usage: @attributeHost (no parentheses)
200
+ if (propertyKeyOrOptions !== undefined && (typeof propertyKeyOrOptions === 'string' || typeof propertyKeyOrOptions === 'symbol')) {
201
+ const fieldName = String(propertyKeyOrOptions);
202
+ return attribute(':host', { name: fieldName })(targetOrAttrOrOptions, propertyKeyOrOptions);
203
+ }
204
+
205
+ // @attributeHost() or @attributeHost(options) or @attributeHost('name')
206
+ if (typeof targetOrAttrOrOptions === 'string') {
207
+ // @attributeHost('customName') or @attributeHost('customName', options)
208
+ const attrName = targetOrAttrOrOptions;
209
+ const options = (typeof propertyKeyOrOptions === 'object' ? propertyKeyOrOptions : {}) as AttributeOptions;
210
+ return attribute(':host', { ...options, name: attrName });
211
+ } else if (typeof targetOrAttrOrOptions === 'object') {
212
+ // @attributeHost(options) - use field name as attribute name
213
+ const options = targetOrAttrOrOptions as AttributeOptions;
214
+ return (target: Object, propertyKey: string | symbol) => {
215
+ const fieldName = String(propertyKey);
216
+ return attribute(':host', { ...options, name: fieldName })(target, propertyKey);
217
+ };
218
+ } else {
219
+ // @attributeHost() - use field name as attribute name
220
+ return (target: Object, propertyKey: string | symbol) => {
221
+ const fieldName = String(propertyKey);
222
+ return attribute(':host', { name: fieldName })(target, propertyKey);
223
+ };
224
+ }
192
225
  }
@@ -1,4 +1,4 @@
1
- import { ReflectUtils } from '@dooboostore/core';
1
+ import {ReflectUtils} from '@dooboostore/core';
2
2
 
3
3
  export const ON_ATTRIBUTE_CHANGED_METADATA_KEY = Symbol('simple-web-component:on-attribute-changed');
4
4