@dooboostore/simple-web-component 1.0.1 → 1.0.2

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 (41) hide show
  1. package/README.md +26 -31
  2. package/dist/cjs/elements/SwcForOf.js +6 -76
  3. package/dist/cjs/elements/SwcForOf.js.map +2 -2
  4. package/dist/cjs/elements/SwcHTMLElementBase.js +102 -0
  5. package/dist/cjs/elements/SwcHTMLElementBase.js.map +7 -0
  6. package/dist/cjs/elements/SwcIf.js +5 -13
  7. package/dist/cjs/elements/SwcIf.js.map +2 -2
  8. package/dist/cjs/elements/SwcObject.js +115 -0
  9. package/dist/cjs/elements/SwcObject.js.map +7 -0
  10. package/dist/cjs/index.js +2 -0
  11. package/dist/cjs/index.js.map +2 -2
  12. package/dist/esm/elements/SwcForOf.js +6 -76
  13. package/dist/esm/elements/SwcForOf.js.map +2 -2
  14. package/dist/esm/elements/SwcHTMLElementBase.js +83 -0
  15. package/dist/esm/elements/SwcHTMLElementBase.js.map +7 -0
  16. package/dist/esm/elements/SwcIf.js +5 -13
  17. package/dist/esm/elements/SwcIf.js.map +2 -2
  18. package/dist/esm/elements/SwcObject.js +96 -0
  19. package/dist/esm/elements/SwcObject.js.map +7 -0
  20. package/dist/esm/index.js +2 -0
  21. package/dist/esm/index.js.map +2 -2
  22. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +184 -89
  23. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  24. package/dist/types/elements/SwcForOf.d.ts +2 -4
  25. package/dist/types/elements/SwcForOf.d.ts.map +1 -1
  26. package/dist/types/elements/SwcHTMLElementBase.d.ts +14 -0
  27. package/dist/types/elements/SwcHTMLElementBase.d.ts.map +1 -0
  28. package/dist/types/elements/SwcIf.d.ts +2 -2
  29. package/dist/types/elements/SwcIf.d.ts.map +1 -1
  30. package/dist/types/elements/SwcObject.d.ts +14 -0
  31. package/dist/types/elements/SwcObject.d.ts.map +1 -0
  32. package/dist/types/index.d.ts +2 -0
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +184 -89
  35. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  36. package/package.json +1 -1
  37. package/src/elements/SwcForOf.ts +10 -85
  38. package/src/elements/SwcHTMLElementBase.ts +93 -0
  39. package/src/elements/SwcIf.ts +6 -25
  40. package/src/elements/SwcObject.ts +78 -0
  41. package/src/index.ts +2 -0
@@ -8,55 +8,29 @@ var __metadata = function(k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { elementDefind, template, style } from "../index.js";
11
- let SwcForOf = class SwcForOf2 extends HTMLElement {
11
+ import { SwcHTMLElementBase } from "./SwcHTMLElementBase.js";
12
+ let SwcForOf = class SwcForOf2 extends SwcHTMLElementBase {
12
13
  constructor() {
13
14
  super();
14
15
  this._value = [];
15
- this._masterTplNodes = [];
16
16
  }
17
17
  set value(val) {
18
18
  if (!Array.isArray(val))
19
19
  val = [];
20
- this._value = this.createProxy(val);
20
+ this._value = this.createReactiveProxy(val, () => this.renderAll(), (idx, v) => this.updateSingleRow(idx, v));
21
21
  this.renderAll();
22
22
  }
23
23
  get value() {
24
24
  return this._value;
25
25
  }
26
- createProxy(arr) {
27
- return new Proxy(arr, {
28
- set: (target, prop, val) => {
29
- const isIndex = !isNaN(Number(prop));
30
- target[prop] = val;
31
- if (isIndex) {
32
- this.updateSingleRow(Number(prop), val);
33
- } else if (prop === "length" && val < target.length) {
34
- this.renderAll();
35
- }
36
- return true;
37
- },
38
- deleteProperty: (target, prop) => {
39
- const res = delete target[prop];
40
- this.renderAll();
41
- return res;
42
- }
43
- });
44
- }
45
26
  styles() {
46
- return `
47
- :host { display: contents; }
48
- `;
27
+ return `:host { display: contents; }`;
49
28
  }
50
29
  renderTemplate() {
51
- return `
52
- <slot id="tpl-slot" style="display:none;"></slot>
53
- `;
30
+ return `<slot id="tpl-slot" style="display:none;"></slot>`;
54
31
  }
55
32
  connectedCallback() {
56
- const tplSlot = this.shadowRoot?.getElementById("tpl-slot");
57
- if (tplSlot) {
58
- this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
59
- }
33
+ this.initCore();
60
34
  this.renderAll();
61
35
  }
62
36
  updateSingleRow(index, newValue) {
@@ -67,50 +41,6 @@ let SwcForOf = class SwcForOf2 extends HTMLElement {
67
41
  this.renderRow(newValue, index);
68
42
  }
69
43
  }
70
- applyData(node, data, index) {
71
- const getValueByPath = (obj, path) => {
72
- if (path === "value")
73
- return obj;
74
- if (path.startsWith("value.")) {
75
- return path.split(".").slice(1).reduce((acc, part) => acc && acc[part], obj);
76
- }
77
- return void 0;
78
- };
79
- const walk = (n) => {
80
- if (n.nodeType === Node.TEXT_NODE) {
81
- if (!n._original)
82
- n._original = n.textContent;
83
- let text = n._original;
84
- text = text.replace(/{{(.*?)}}/g, (match, path) => {
85
- path = path.trim();
86
- if (path === "index")
87
- return index.toString();
88
- const val = getValueByPath(data, path);
89
- return val !== void 0 ? val : match;
90
- });
91
- if (n.textContent !== text)
92
- n.textContent = text;
93
- } else if (n.nodeType === Node.ELEMENT_NODE) {
94
- const el = n;
95
- Array.from(el.attributes).forEach((a) => {
96
- if (!a._original)
97
- a._original = a.value;
98
- let val = a._original;
99
- val = val.replace(/{{(.*?)}}/g, (match, path) => {
100
- path = path.trim();
101
- if (path === "index")
102
- return index.toString();
103
- const v = getValueByPath(data, path);
104
- return v !== void 0 ? v : match;
105
- });
106
- if (a.value !== val)
107
- a.value = val;
108
- });
109
- el.childNodes.forEach(walk);
110
- }
111
- };
112
- walk(node);
113
- }
114
44
  renderRow(item, index) {
115
45
  if (!this.shadowRoot || this._masterTplNodes.length === 0)
116
46
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/elements/SwcForOf.ts"],
4
- "sourcesContent": ["import { elementDefind, template, style } from '../index';\n\n@elementDefind({ tagName: 'swc-for-of', useShadow: true })\nexport class SwcForOf extends HTMLElement {\n private _value: any[] = [];\n private _masterTplNodes: Node[] = [];\n\n constructor() {\n super();\n }\n\n set value(val: any[]) {\n if (!Array.isArray(val)) val = [];\n this._value = this.createProxy(val);\n this.renderAll();\n }\n\n get value(): any[] {\n return this._value;\n }\n\n private createProxy(arr: any[]) {\n return new Proxy(arr, {\n set: (target, prop, val) => {\n const isIndex = !isNaN(Number(prop));\n target[prop as any] = val;\n\n if (isIndex) {\n this.updateSingleRow(Number(prop), val);\n } else if (prop === 'length' && val < target.length) {\n this.renderAll();\n }\n return true;\n },\n deleteProperty: (target, prop) => {\n const res = delete target[prop as any];\n this.renderAll();\n return res;\n }\n });\n }\n\n @style\n styles() {\n // display: contents를 통해 swc-for-of 태그 자체를 레이아웃에서 투명하게 만듭니다.\n return `\n :host { display: contents; }\n `;\n }\n\n @template\n renderTemplate() {\n // 감싸는 div 없이 tpl-slot만 둡니다.\n return `\n <slot id=\"tpl-slot\" style=\"display:none;\"></slot>\n `;\n }\n\n connectedCallback() {\n const tplSlot = this.shadowRoot?.getElementById('tpl-slot') as HTMLSlotElement;\n if (tplSlot) {\n this._masterTplNodes = tplSlot.assignedNodes().map(n => n.cloneNode(true));\n }\n this.renderAll();\n }\n\n public updateSingleRow(index: number, newValue: any) {\n const targets = this.querySelectorAll(`[slot=\"row-${index}\"]`);\n if (targets.length > 0) {\n targets.forEach(target => this.applyData(target, newValue, index));\n } else {\n this.renderRow(newValue, index);\n }\n }\n\n private applyData(node: Node, data: any, index: number) {\n const getValueByPath = (obj: any, path: string) => {\n if (path === 'value') return obj;\n if (path.startsWith('value.')) {\n return path\n .split('.')\n .slice(1)\n .reduce((acc, part) => acc && acc[part], obj);\n }\n return undefined;\n };\n\n const walk = (n: Node) => {\n if (n.nodeType === Node.TEXT_NODE) {\n if (!(n as any)._original) (n as any)._original = n.textContent;\n let text = (n as any)._original;\n\n text = text.replace(/{{(.*?)}}/g, (match: string, path: string) => {\n path = path.trim();\n if (path === 'index') return index.toString();\n const val = getValueByPath(data, path);\n return val !== undefined ? val : match;\n });\n if (n.textContent !== text) n.textContent = text;\n } else if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as Element;\n Array.from(el.attributes).forEach(a => {\n if (!(a as any)._original) (a as any)._original = a.value;\n let val = (a as any)._original;\n\n val = val.replace(/{{(.*?)}}/g, (match: string, path: string) => {\n path = path.trim();\n if (path === 'index') return index.toString();\n const v = getValueByPath(data, path);\n return v !== undefined ? v : match;\n });\n if (a.value !== val) a.value = val;\n });\n\n // 중요: swc-choose 같은 커스텀 엘리먼트 내부의 자식들도 템플릿 치환이 필요함\n el.childNodes.forEach(walk);\n }\n };\n walk(node);\n }\n\n private renderRow(item: any, index: number) {\n if (!this.shadowRoot || this._masterTplNodes.length === 0) return;\n\n const slotName = `row-${index}`;\n // Shadow Root에 직접 슬롯 추가\n if (!this.shadowRoot.querySelector(`slot[name=\"${slotName}\"]`)) {\n const slot = document.createElement('slot');\n slot.name = slotName;\n this.shadowRoot.appendChild(slot);\n }\n\n this._masterTplNodes.forEach(tplNode => {\n const clone = tplNode.cloneNode(true);\n if (clone.nodeType === Node.ELEMENT_NODE) {\n (clone as HTMLElement).setAttribute('slot', slotName);\n (clone as HTMLElement).style.display = '';\n } else if (clone.nodeType === Node.TEXT_NODE) {\n if (clone.textContent?.trim().length === 0) return;\n const span = document.createElement('span');\n span.setAttribute('slot', slotName);\n span.appendChild(clone);\n this.appendChild(span);\n this.applyData(span, item, index);\n return;\n }\n this.appendChild(clone);\n this.applyData(clone, item, index);\n });\n }\n\n private renderAll() {\n if (this._masterTplNodes.length === 0 || !this.shadowRoot) return;\n\n // 기존 데이터 노드 삭제\n Array.from(this.children).forEach(c => {\n const slot = c.getAttribute('slot');\n if (slot && slot.startsWith('row-')) {\n c.remove();\n }\n });\n\n // Shadow Root의 기존 슬롯들 삭제 (tpl-slot 제외)\n Array.from(this.shadowRoot.querySelectorAll('slot')).forEach(s => {\n if (s.id !== 'tpl-slot') s.remove();\n });\n\n this._value.forEach((item, index) => this.renderRow(item, index));\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { elementDefind, template, style } from '../index';\nimport { SwcHTMLElementBase } from './SwcHTMLElementBase';\n\n@elementDefind({ tagName: 'swc-for-of', useShadow: true })\nexport class SwcForOf extends SwcHTMLElementBase {\n private _value: any[] = [];\n\n constructor() {\n super();\n }\n\n set value(val: any[]) {\n if (!Array.isArray(val)) val = [];\n this._value = this.createReactiveProxy(\n val,\n () => this.renderAll(),\n (idx, v) => this.updateSingleRow(idx, v)\n );\n this.renderAll();\n }\n\n get value(): any[] {\n return this._value;\n }\n\n @style\n styles() {\n return `:host { display: contents; }`;\n }\n\n @template\n renderTemplate() {\n return `<slot id=\"tpl-slot\" style=\"display:none;\"></slot>`;\n }\n\n connectedCallback() {\n this.initCore();\n this.renderAll();\n }\n\n public updateSingleRow(index: number, newValue: any) {\n const targets = this.querySelectorAll(`[slot=\"row-${index}\"]`);\n if (targets.length > 0) {\n targets.forEach(target => this.applyData(target, newValue, index));\n } else {\n this.renderRow(newValue, index);\n }\n }\n\n private renderRow(item: any, index: number) {\n if (!this.shadowRoot || this._masterTplNodes.length === 0) return;\n\n const slotName = `row-${index}`;\n if (!this.shadowRoot.querySelector(`slot[name=\"${slotName}\"]`)) {\n const slot = document.createElement('slot');\n slot.name = slotName;\n this.shadowRoot.appendChild(slot);\n }\n\n this._masterTplNodes.forEach(tplNode => {\n const clone = tplNode.cloneNode(true);\n if (clone.nodeType === Node.ELEMENT_NODE) {\n (clone as HTMLElement).setAttribute('slot', slotName);\n (clone as HTMLElement).style.display = '';\n } else if (clone.nodeType === Node.TEXT_NODE) {\n if (clone.textContent?.trim().length === 0) return;\n const span = document.createElement('span');\n span.setAttribute('slot', slotName);\n span.appendChild(clone);\n this.appendChild(span);\n this.applyData(span, item, index);\n return;\n }\n this.appendChild(clone);\n this.applyData(clone, item, index);\n });\n }\n\n private renderAll() {\n if (this._masterTplNodes.length === 0 || !this.shadowRoot) return;\n\n Array.from(this.children).forEach(c => {\n const slot = c.getAttribute('slot');\n if (slot && slot.startsWith('row-')) {\n c.remove();\n }\n });\n\n Array.from(this.shadowRoot.querySelectorAll('slot')).forEach(s => {\n if (s.id !== 'tpl-slot') s.remove();\n });\n\n this._value.forEach((item, index) => this.renderRow(item, index));\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;AAAA,SAAS,eAAe,UAAU,aAAa;AAC/C,SAAS,0BAA0B;AAG5B,IAAM,WAAN,MAAMA,kBAAiB,mBAAkB;EAG9C,cAAA;AACE,UAAK;AAHC,SAAA,SAAgB,CAAA;EAIxB;EAEA,IAAI,MAAM,KAAU;AAClB,QAAI,CAAC,MAAM,QAAQ,GAAG;AAAG,YAAM,CAAA;AAC/B,SAAK,SAAS,KAAK,oBACjB,KACA,MAAM,KAAK,UAAS,GACpB,CAAC,KAAK,MAAM,KAAK,gBAAgB,KAAK,CAAC,CAAC;AAE1C,SAAK,UAAS;EAChB;EAEA,IAAI,QAAK;AACP,WAAO,KAAK;EACd;EAGA,SAAM;AACJ,WAAO;EACT;EAGA,iBAAc;AACZ,WAAO;EACT;EAEA,oBAAiB;AACf,SAAK,SAAQ;AACb,SAAK,UAAS;EAChB;EAEO,gBAAgB,OAAe,UAAa;AACjD,UAAM,UAAU,KAAK,iBAAiB,cAAc,KAAK,IAAI;AAC7D,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ,QAAQ,YAAU,KAAK,UAAU,QAAQ,UAAU,KAAK,CAAC;IACnE,OAAO;AACL,WAAK,UAAU,UAAU,KAAK;IAChC;EACF;EAEQ,UAAU,MAAW,OAAa;AACxC,QAAI,CAAC,KAAK,cAAc,KAAK,gBAAgB,WAAW;AAAG;AAE3D,UAAM,WAAW,OAAO,KAAK;AAC7B,QAAI,CAAC,KAAK,WAAW,cAAc,cAAc,QAAQ,IAAI,GAAG;AAC9D,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,OAAO;AACZ,WAAK,WAAW,YAAY,IAAI;IAClC;AAEA,SAAK,gBAAgB,QAAQ,aAAU;AACrC,YAAM,QAAQ,QAAQ,UAAU,IAAI;AACpC,UAAI,MAAM,aAAa,KAAK,cAAc;AACvC,cAAsB,aAAa,QAAQ,QAAQ;AACnD,cAAsB,MAAM,UAAU;MACzC,WAAW,MAAM,aAAa,KAAK,WAAW;AAC5C,YAAI,MAAM,aAAa,KAAI,EAAG,WAAW;AAAG;AAC5C,cAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,aAAK,aAAa,QAAQ,QAAQ;AAClC,aAAK,YAAY,KAAK;AACtB,aAAK,YAAY,IAAI;AACrB,aAAK,UAAU,MAAM,MAAM,KAAK;AAChC;MACF;AACA,WAAK,YAAY,KAAK;AACtB,WAAK,UAAU,OAAO,MAAM,KAAK;IACnC,CAAC;EACH;EAEQ,YAAS;AACf,QAAI,KAAK,gBAAgB,WAAW,KAAK,CAAC,KAAK;AAAY;AAE3D,UAAM,KAAK,KAAK,QAAQ,EAAE,QAAQ,OAAI;AACpC,YAAM,OAAO,EAAE,aAAa,MAAM;AAClC,UAAI,QAAQ,KAAK,WAAW,MAAM,GAAG;AACnC,UAAE,OAAM;MACV;IACF,CAAC;AAED,UAAM,KAAK,KAAK,WAAW,iBAAiB,MAAM,CAAC,EAAE,QAAQ,OAAI;AAC/D,UAAI,EAAE,OAAO;AAAY,UAAE,OAAM;IACnC,CAAC;AAED,SAAK,OAAO,QAAQ,CAAC,MAAM,UAAU,KAAK,UAAU,MAAM,KAAK,CAAC;EAClE;;AAnEA,WAAA;EADC;;;;;AAMD,WAAA;EADC;;;;;AA1BU,WAAQ,WAAA;EADpB,cAAc,EAAE,SAAS,cAAc,WAAW,KAAI,CAAE;;GAC5C,QAAQ;",
6
6
  "names": ["SwcForOf"]
7
7
  }
@@ -0,0 +1,83 @@
1
+ class SwcHTMLElementBase extends HTMLElement {
2
+ constructor() {
3
+ super();
4
+ this._masterTplNodes = [];
5
+ this._asKey = "value";
6
+ this._asIndexKey = "index";
7
+ }
8
+ initCore() {
9
+ this._asKey = this.getAttribute("as") || "value";
10
+ this._asIndexKey = this.getAttribute("as-index") || "index";
11
+ const tplSlot = this.shadowRoot?.getElementById("tpl-slot");
12
+ if (tplSlot) {
13
+ this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
14
+ }
15
+ }
16
+ getValueByPath(obj, path) {
17
+ if (path === this._asKey) return obj;
18
+ if (path.startsWith(`${this._asKey}.`)) {
19
+ return path.split(".").slice(1).reduce((acc, part) => acc && acc[part], obj);
20
+ }
21
+ return void 0;
22
+ }
23
+ applyData(node, data, index) {
24
+ const context = {};
25
+ if (index !== void 0) {
26
+ context[this._asIndexKey] = index.toString();
27
+ }
28
+ const walk = (n) => {
29
+ if (n.nodeType === Node.TEXT_NODE) {
30
+ if (!n._original) n._original = n.textContent;
31
+ let text = n._original;
32
+ text = text.replace(/{{(.*?)}}/g, (match, path) => {
33
+ path = path.trim();
34
+ if (context[path] !== void 0) return context[path];
35
+ const val = this.getValueByPath(data, path);
36
+ return val !== void 0 ? val : match;
37
+ });
38
+ if (n.textContent !== text) n.textContent = text;
39
+ } else if (n.nodeType === Node.ELEMENT_NODE) {
40
+ const el = n;
41
+ Array.from(el.attributes).forEach((a) => {
42
+ if (!a._original) a._original = a.value;
43
+ let val = a._original;
44
+ val = val.replace(/{{(.*?)}}/g, (match, path) => {
45
+ path = path.trim();
46
+ if (context[path] !== void 0) return context[path];
47
+ const v = this.getValueByPath(data, path);
48
+ return v !== void 0 ? v : match;
49
+ });
50
+ if (a.value !== val) a.value = val;
51
+ });
52
+ el.childNodes.forEach(walk);
53
+ }
54
+ };
55
+ walk(node);
56
+ }
57
+ /**
58
+ * 객체/배열의 변경을 감지하는 Proxy 생성 유틸리티
59
+ */
60
+ createReactiveProxy(target, onChange, onIndexChange) {
61
+ return new Proxy(target, {
62
+ set: (t, prop, val) => {
63
+ const isIndex = !isNaN(Number(prop));
64
+ t[prop] = val;
65
+ if (isIndex && onIndexChange) {
66
+ onIndexChange(Number(prop), val);
67
+ } else {
68
+ onChange();
69
+ }
70
+ return true;
71
+ },
72
+ deleteProperty: (t, prop) => {
73
+ delete t[prop];
74
+ onChange();
75
+ return true;
76
+ }
77
+ });
78
+ }
79
+ }
80
+ export {
81
+ SwcHTMLElementBase
82
+ };
83
+ //# sourceMappingURL=SwcHTMLElementBase.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/elements/SwcHTMLElementBase.ts"],
4
+ "sourcesContent": ["import { getTemplateMethod } from '../decorators/template';\nimport { getStyleMethod } from '../decorators/style';\n\nexport abstract class SwcHTMLElementBase extends HTMLElement {\n protected _masterTplNodes: Node[] = [];\n protected _asKey: string = 'value';\n protected _asIndexKey: string = 'index';\n\n constructor() {\n super();\n }\n\n protected initCore() {\n this._asKey = this.getAttribute('as') || 'value';\n this._asIndexKey = this.getAttribute('as-index') || 'index';\n const tplSlot = this.shadowRoot?.getElementById('tpl-slot') as HTMLSlotElement;\n if (tplSlot) {\n this._masterTplNodes = tplSlot.assignedNodes().map(n => n.cloneNode(true));\n }\n }\n\n protected getValueByPath(obj: any, path: string) {\n if (path === this._asKey) return obj;\n if (path.startsWith(`${this._asKey}.`)) {\n return path\n .split('.')\n .slice(1)\n .reduce((acc, part) => acc && acc[part], obj);\n }\n return undefined;\n }\n\n protected applyData(node: Node, data: any, index?: number) {\n const context: Record<string, any> = {};\n if (index !== undefined) {\n context[this._asIndexKey] = index.toString();\n }\n\n const walk = (n: Node) => {\n if (n.nodeType === Node.TEXT_NODE) {\n if (!(n as any)._original) (n as any)._original = n.textContent;\n let text = (n as any)._original;\n\n text = text.replace(/{{(.*?)}}/g, (match: string, path: string) => {\n path = path.trim();\n if (context[path] !== undefined) return context[path];\n const val = this.getValueByPath(data, path);\n return val !== undefined ? val : match;\n });\n if (n.textContent !== text) n.textContent = text;\n } else if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as Element;\n Array.from(el.attributes).forEach(a => {\n if (!(a as any)._original) (a as any)._original = a.value;\n let val = (a as any)._original;\n\n val = val.replace(/{{(.*?)}}/g, (match: string, path: string) => {\n path = path.trim();\n if (context[path] !== undefined) return context[path];\n const v = this.getValueByPath(data, path);\n return v !== undefined ? v : match;\n });\n if (a.value !== val) a.value = val;\n });\n el.childNodes.forEach(walk);\n }\n };\n walk(node);\n }\n\n /**\n * \uAC1D\uCCB4/\uBC30\uC5F4\uC758 \uBCC0\uACBD\uC744 \uAC10\uC9C0\uD558\uB294 Proxy \uC0DD\uC131 \uC720\uD2F8\uB9AC\uD2F0\n */\n protected createReactiveProxy(target: any, onChange: () => void, onIndexChange?: (index: number, val: any) => void) {\n return new Proxy(target, {\n set: (t, prop, val) => {\n const isIndex = !isNaN(Number(prop));\n t[prop] = val;\n if (isIndex && onIndexChange) {\n onIndexChange(Number(prop), val);\n } else {\n onChange();\n }\n return true;\n },\n deleteProperty: (t, prop) => {\n delete t[prop];\n onChange();\n return true;\n }\n });\n }\n}\n"],
5
+ "mappings": "AAGO,MAAe,2BAA2B,YAAY;AAAA,EAK3D,cAAc;AACZ,UAAM;AALR,SAAU,kBAA0B,CAAC;AACrC,SAAU,SAAiB;AAC3B,SAAU,cAAsB;AAAA,EAIhC;AAAA,EAEU,WAAW;AACnB,SAAK,SAAS,KAAK,aAAa,IAAI,KAAK;AACzC,SAAK,cAAc,KAAK,aAAa,UAAU,KAAK;AACpD,UAAM,UAAU,KAAK,YAAY,eAAe,UAAU;AAC1D,QAAI,SAAS;AACX,WAAK,kBAAkB,QAAQ,cAAc,EAAE,IAAI,OAAK,EAAE,UAAU,IAAI,CAAC;AAAA,IAC3E;AAAA,EACF;AAAA,EAEU,eAAe,KAAU,MAAc;AAC/C,QAAI,SAAS,KAAK,OAAQ,QAAO;AACjC,QAAI,KAAK,WAAW,GAAG,KAAK,MAAM,GAAG,GAAG;AACtC,aAAO,KACJ,MAAM,GAAG,EACT,MAAM,CAAC,EACP,OAAO,CAAC,KAAK,SAAS,OAAO,IAAI,IAAI,GAAG,GAAG;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEU,UAAU,MAAY,MAAW,OAAgB;AACzD,UAAM,UAA+B,CAAC;AACtC,QAAI,UAAU,QAAW;AACvB,cAAQ,KAAK,WAAW,IAAI,MAAM,SAAS;AAAA,IAC7C;AAEA,UAAM,OAAO,CAAC,MAAY;AACxB,UAAI,EAAE,aAAa,KAAK,WAAW;AACjC,YAAI,CAAE,EAAU,UAAW,CAAC,EAAU,YAAY,EAAE;AACpD,YAAI,OAAQ,EAAU;AAEtB,eAAO,KAAK,QAAQ,cAAc,CAAC,OAAe,SAAiB;AACjE,iBAAO,KAAK,KAAK;AACjB,cAAI,QAAQ,IAAI,MAAM,OAAW,QAAO,QAAQ,IAAI;AACpD,gBAAM,MAAM,KAAK,eAAe,MAAM,IAAI;AAC1C,iBAAO,QAAQ,SAAY,MAAM;AAAA,QACnC,CAAC;AACD,YAAI,EAAE,gBAAgB,KAAM,GAAE,cAAc;AAAA,MAC9C,WAAW,EAAE,aAAa,KAAK,cAAc;AAC3C,cAAM,KAAK;AACX,cAAM,KAAK,GAAG,UAAU,EAAE,QAAQ,OAAK;AACrC,cAAI,CAAE,EAAU,UAAW,CAAC,EAAU,YAAY,EAAE;AACpD,cAAI,MAAO,EAAU;AAErB,gBAAM,IAAI,QAAQ,cAAc,CAAC,OAAe,SAAiB;AAC/D,mBAAO,KAAK,KAAK;AACjB,gBAAI,QAAQ,IAAI,MAAM,OAAW,QAAO,QAAQ,IAAI;AACpD,kBAAM,IAAI,KAAK,eAAe,MAAM,IAAI;AACxC,mBAAO,MAAM,SAAY,IAAI;AAAA,UAC/B,CAAC;AACD,cAAI,EAAE,UAAU,IAAK,GAAE,QAAQ;AAAA,QACjC,CAAC;AACD,WAAG,WAAW,QAAQ,IAAI;AAAA,MAC5B;AAAA,IACF;AACA,SAAK,IAAI;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAoB,QAAa,UAAsB,eAAmD;AAClH,WAAO,IAAI,MAAM,QAAQ;AAAA,MACvB,KAAK,CAAC,GAAG,MAAM,QAAQ;AACrB,cAAM,UAAU,CAAC,MAAM,OAAO,IAAI,CAAC;AACnC,UAAE,IAAI,IAAI;AACV,YAAI,WAAW,eAAe;AAC5B,wBAAc,OAAO,IAAI,GAAG,GAAG;AAAA,QACjC,OAAO;AACL,mBAAS;AAAA,QACX;AACA,eAAO;AAAA,MACT;AAAA,MACA,gBAAgB,CAAC,GAAG,SAAS;AAC3B,eAAO,EAAE,IAAI;AACb,iBAAS;AACT,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
6
+ "names": []
7
+ }
@@ -8,11 +8,11 @@ var __metadata = function(k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { elementDefind, template, style } from "../index.js";
11
- let SwcIf = class SwcIf2 extends HTMLElement {
11
+ import { SwcHTMLElementBase } from "./SwcHTMLElementBase.js";
12
+ let SwcIf = class SwcIf2 extends SwcHTMLElementBase {
12
13
  constructor() {
13
14
  super();
14
15
  this._value = false;
15
- this._masterTplNodes = [];
16
16
  this._observer = null;
17
17
  }
18
18
  set value(val) {
@@ -23,20 +23,13 @@ let SwcIf = class SwcIf2 extends HTMLElement {
23
23
  return this._value;
24
24
  }
25
25
  styles() {
26
- return `
27
- :host { display: contents; }
28
- `;
26
+ return `:host { display: contents; }`;
29
27
  }
30
28
  renderTemplate() {
31
- return `
32
- <slot id="tpl-slot" style="display:none;"></slot>
33
- `;
29
+ return `<slot id="tpl-slot" style="display:none;"></slot>`;
34
30
  }
35
31
  connectedCallback() {
36
- const tplSlot = this.shadowRoot?.getElementById("tpl-slot");
37
- if (tplSlot) {
38
- this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
39
- }
32
+ this.initCore();
40
33
  this._observer = new MutationObserver(() => this.render());
41
34
  this._observer.observe(this, { attributes: true });
42
35
  this.render();
@@ -79,7 +72,6 @@ let SwcIf = class SwcIf2 extends HTMLElement {
79
72
  const clone = tplNode.cloneNode(true);
80
73
  if (clone.nodeType === Node.ELEMENT_NODE) {
81
74
  clone.setAttribute("slot", "if-content");
82
- clone.style.display = "";
83
75
  } else if (clone.nodeType === Node.TEXT_NODE) {
84
76
  if (clone.textContent?.trim().length === 0)
85
77
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/elements/SwcIf.ts"],
4
- "sourcesContent": ["import { elementDefind, template, style } from '../index';\n\n@elementDefind({ tagName: 'swc-if', useShadow: true })\nexport class SwcIf extends HTMLElement {\n private _value: any = false;\n private _masterTplNodes: Node[] = [];\n private _observer: MutationObserver | null = null;\n\n constructor() {\n super();\n }\n\n set value(val: any) {\n this._value = val;\n this.render();\n }\n\n get value(): any {\n return this._value;\n }\n\n @style\n styles() {\n return `\n :host { display: contents; }\n `;\n }\n\n @template\n renderTemplate() {\n return `\n <slot id=\"tpl-slot\" style=\"display:none;\"></slot>\n `;\n }\n\n connectedCallback() {\n const tplSlot = this.shadowRoot?.getElementById('tpl-slot') as HTMLSlotElement;\n if (tplSlot) {\n // 초기 자식들을 템플릿으로 보관\n this._masterTplNodes = tplSlot.assignedNodes().map(n => n.cloneNode(true));\n }\n\n this._observer = new MutationObserver(() => this.render());\n this._observer.observe(this, { attributes: true });\n\n this.render();\n }\n\n disconnectedCallback() {\n this._observer?.disconnect();\n }\n\n private render() {\n if (!this.shadowRoot) return;\n\n const attrValue = this.getAttribute('value');\n if (attrValue !== null && attrValue.includes('{{')) return; // 치환 전이면 대기\n\n // 로직 결정: attribute가 있으면 우선, 없으면 property 사용\n let displayValue = attrValue !== null ? attrValue : this._value;\n\n // \"false\", \"null\", \"undefined\" 문자열 처리 및 기본 truthy 체크\n let isTruthy = !!displayValue;\n if (typeof displayValue === 'string') {\n if (displayValue === 'false' || displayValue === '0' || displayValue === '') isTruthy = false;\n else {\n // 식인 경우 평가 시도 (예: \"10 > 5\")\n try {\n isTruthy = !!new Function(`return ${displayValue}`)();\n } catch (e) {\n // 단순 문자열이면 true로 간주\n isTruthy = true;\n }\n }\n }\n\n // 1. 기존에 렌더링된 노드들 삭제\n Array.from(this.children).forEach(c => {\n if (c.getAttribute('slot') === 'if-content') {\n c.remove();\n }\n });\n\n // 2. Shadow DOM의 컨텐츠 슬롯 삭제\n const existingSlot = this.shadowRoot.querySelector('slot[name=\"if-content\"]');\n if (existingSlot) existingSlot.remove();\n\n // 3. 조건이 참일 때만 노드들을 복제해서 삽입\n if (isTruthy && this._masterTplNodes.length > 0) {\n const contentSlot = document.createElement('slot');\n contentSlot.name = 'if-content';\n this.shadowRoot.appendChild(contentSlot);\n\n this._masterTplNodes.forEach(tplNode => {\n const clone = tplNode.cloneNode(true);\n if (clone.nodeType === Node.ELEMENT_NODE) {\n (clone as HTMLElement).setAttribute('slot', 'if-content');\n (clone as HTMLElement).style.display = '';\n } else if (clone.nodeType === Node.TEXT_NODE) {\n if (clone.textContent?.trim().length === 0) return;\n const span = document.createElement('span');\n span.setAttribute('slot', 'if-content');\n span.appendChild(clone);\n this.appendChild(span);\n return;\n }\n this.appendChild(clone);\n });\n }\n }\n}\n"],
5
- "mappings": ";;;;;;;;;AAAA,SAAS,eAAe,UAAU,aAAa;AAGxC,IAAM,QAAN,MAAMA,eAAc,YAAW;EAKpC,cAAA;AACE,UAAK;AALC,SAAA,SAAc;AACd,SAAA,kBAA0B,CAAA;AAC1B,SAAA,YAAqC;EAI7C;EAEA,IAAI,MAAM,KAAQ;AAChB,SAAK,SAAS;AACd,SAAK,OAAM;EACb;EAEA,IAAI,QAAK;AACP,WAAO,KAAK;EACd;EAGA,SAAM;AACJ,WAAO;;;EAGT;EAGA,iBAAc;AACZ,WAAO;;;EAGT;EAEA,oBAAiB;AACf,UAAM,UAAU,KAAK,YAAY,eAAe,UAAU;AAC1D,QAAI,SAAS;AAEX,WAAK,kBAAkB,QAAQ,cAAa,EAAG,IAAI,OAAK,EAAE,UAAU,IAAI,CAAC;IAC3E;AAEA,SAAK,YAAY,IAAI,iBAAiB,MAAM,KAAK,OAAM,CAAE;AACzD,SAAK,UAAU,QAAQ,MAAM,EAAE,YAAY,KAAI,CAAE;AAEjD,SAAK,OAAM;EACb;EAEA,uBAAoB;AAClB,SAAK,WAAW,WAAU;EAC5B;EAEQ,SAAM;AACZ,QAAI,CAAC,KAAK;AAAY;AAEtB,UAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,QAAI,cAAc,QAAQ,UAAU,SAAS,IAAI;AAAG;AAGpD,QAAI,eAAe,cAAc,OAAO,YAAY,KAAK;AAGzD,QAAI,WAAW,CAAC,CAAC;AACjB,QAAI,OAAO,iBAAiB,UAAU;AACpC,UAAI,iBAAiB,WAAW,iBAAiB,OAAO,iBAAiB;AAAI,mBAAW;WACnF;AAEH,YAAI;AACF,qBAAW,CAAC,CAAC,IAAI,SAAS,UAAU,YAAY,EAAE,EAAC;QACrD,SAAS,GAAG;AAEV,qBAAW;QACb;MACF;IACF;AAGA,UAAM,KAAK,KAAK,QAAQ,EAAE,QAAQ,OAAI;AACpC,UAAI,EAAE,aAAa,MAAM,MAAM,cAAc;AAC3C,UAAE,OAAM;MACV;IACF,CAAC;AAGD,UAAM,eAAe,KAAK,WAAW,cAAc,yBAAyB;AAC5E,QAAI;AAAc,mBAAa,OAAM;AAGrC,QAAI,YAAY,KAAK,gBAAgB,SAAS,GAAG;AAC/C,YAAM,cAAc,SAAS,cAAc,MAAM;AACjD,kBAAY,OAAO;AACnB,WAAK,WAAW,YAAY,WAAW;AAEvC,WAAK,gBAAgB,QAAQ,aAAU;AACrC,cAAM,QAAQ,QAAQ,UAAU,IAAI;AACpC,YAAI,MAAM,aAAa,KAAK,cAAc;AACvC,gBAAsB,aAAa,QAAQ,YAAY;AACvD,gBAAsB,MAAM,UAAU;QACzC,WAAW,MAAM,aAAa,KAAK,WAAW;AAC5C,cAAI,MAAM,aAAa,KAAI,EAAG,WAAW;AAAG;AAC5C,gBAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,eAAK,aAAa,QAAQ,YAAY;AACtC,eAAK,YAAY,KAAK;AACtB,eAAK,YAAY,IAAI;AACrB;QACF;AACA,aAAK,YAAY,KAAK;MACxB,CAAC;IACH;EACF;;AAvFA,WAAA;EADC;;;;;AAQD,WAAA;EADC;;;;;AAzBU,QAAK,WAAA;EADjB,cAAc,EAAE,SAAS,UAAU,WAAW,KAAI,CAAE;;GACxC,KAAK;",
4
+ "sourcesContent": ["import { elementDefind, template, style } from '../index';\nimport { SwcHTMLElementBase } from './SwcHTMLElementBase';\n\n@elementDefind({ tagName: 'swc-if', useShadow: true })\nexport class SwcIf extends SwcHTMLElementBase {\n private _value: any = false;\n private _observer: MutationObserver | null = null;\n\n constructor() {\n super();\n }\n\n set value(val: any) {\n this._value = val;\n this.render();\n }\n\n get value(): any {\n return this._value;\n }\n\n @style\n styles() {\n return `:host { display: contents; }`;\n }\n\n @template\n renderTemplate() {\n return `<slot id=\"tpl-slot\" style=\"display:none;\"></slot>`;\n }\n\n connectedCallback() {\n this.initCore();\n this._observer = new MutationObserver(() => this.render());\n this._observer.observe(this, { attributes: true });\n this.render();\n }\n\n disconnectedCallback() {\n this._observer?.disconnect();\n }\n\n private render() {\n if (!this.shadowRoot) return;\n\n const attrValue = this.getAttribute('value');\n if (attrValue !== null && attrValue.includes('{{')) return;\n\n let displayValue = attrValue !== null ? attrValue : this._value;\n let isTruthy = !!displayValue;\n if (typeof displayValue === 'string') {\n if (displayValue === 'false' || displayValue === '0' || displayValue === '') isTruthy = false;\n else {\n try {\n isTruthy = !!new Function(`return ${displayValue}`)();\n } catch (e) {\n isTruthy = true;\n }\n }\n }\n\n Array.from(this.children).forEach(c => {\n if (c.getAttribute('slot') === 'if-content') {\n c.remove();\n }\n });\n\n const existingSlot = this.shadowRoot.querySelector('slot[name=\"if-content\"]');\n if (existingSlot) existingSlot.remove();\n\n if (isTruthy && this._masterTplNodes.length > 0) {\n const contentSlot = document.createElement('slot');\n contentSlot.name = 'if-content';\n this.shadowRoot.appendChild(contentSlot);\n\n this._masterTplNodes.forEach(tplNode => {\n const clone = tplNode.cloneNode(true);\n if (clone.nodeType === Node.ELEMENT_NODE) {\n (clone as HTMLElement).setAttribute('slot', 'if-content');\n } else if (clone.nodeType === Node.TEXT_NODE) {\n if (clone.textContent?.trim().length === 0) return;\n const span = document.createElement('span');\n span.setAttribute('slot', 'if-content');\n span.appendChild(clone);\n this.appendChild(span);\n return;\n }\n this.appendChild(clone);\n });\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;AAAA,SAAS,eAAe,UAAU,aAAa;AAC/C,SAAS,0BAA0B;AAG5B,IAAM,QAAN,MAAMA,eAAc,mBAAkB;EAI3C,cAAA;AACE,UAAK;AAJC,SAAA,SAAc;AACd,SAAA,YAAqC;EAI7C;EAEA,IAAI,MAAM,KAAQ;AAChB,SAAK,SAAS;AACd,SAAK,OAAM;EACb;EAEA,IAAI,QAAK;AACP,WAAO,KAAK;EACd;EAGA,SAAM;AACJ,WAAO;EACT;EAGA,iBAAc;AACZ,WAAO;EACT;EAEA,oBAAiB;AACf,SAAK,SAAQ;AACb,SAAK,YAAY,IAAI,iBAAiB,MAAM,KAAK,OAAM,CAAE;AACzD,SAAK,UAAU,QAAQ,MAAM,EAAE,YAAY,KAAI,CAAE;AACjD,SAAK,OAAM;EACb;EAEA,uBAAoB;AAClB,SAAK,WAAW,WAAU;EAC5B;EAEQ,SAAM;AACZ,QAAI,CAAC,KAAK;AAAY;AAEtB,UAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,QAAI,cAAc,QAAQ,UAAU,SAAS,IAAI;AAAG;AAEpD,QAAI,eAAe,cAAc,OAAO,YAAY,KAAK;AACzD,QAAI,WAAW,CAAC,CAAC;AACjB,QAAI,OAAO,iBAAiB,UAAU;AACpC,UAAI,iBAAiB,WAAW,iBAAiB,OAAO,iBAAiB;AAAI,mBAAW;WACnF;AACH,YAAI;AACF,qBAAW,CAAC,CAAC,IAAI,SAAS,UAAU,YAAY,EAAE,EAAC;QACrD,SAAS,GAAG;AACV,qBAAW;QACb;MACF;IACF;AAEA,UAAM,KAAK,KAAK,QAAQ,EAAE,QAAQ,OAAI;AACpC,UAAI,EAAE,aAAa,MAAM,MAAM,cAAc;AAC3C,UAAE,OAAM;MACV;IACF,CAAC;AAED,UAAM,eAAe,KAAK,WAAW,cAAc,yBAAyB;AAC5E,QAAI;AAAc,mBAAa,OAAM;AAErC,QAAI,YAAY,KAAK,gBAAgB,SAAS,GAAG;AAC/C,YAAM,cAAc,SAAS,cAAc,MAAM;AACjD,kBAAY,OAAO;AACnB,WAAK,WAAW,YAAY,WAAW;AAEvC,WAAK,gBAAgB,QAAQ,aAAU;AACrC,cAAM,QAAQ,QAAQ,UAAU,IAAI;AACpC,YAAI,MAAM,aAAa,KAAK,cAAc;AACvC,gBAAsB,aAAa,QAAQ,YAAY;QAC1D,WAAW,MAAM,aAAa,KAAK,WAAW;AAC5C,cAAI,MAAM,aAAa,KAAI,EAAG,WAAW;AAAG;AAC5C,gBAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,eAAK,aAAa,QAAQ,YAAY;AACtC,eAAK,YAAY,KAAK;AACtB,eAAK,YAAY,IAAI;AACrB;QACF;AACA,aAAK,YAAY,KAAK;MACxB,CAAC;IACH;EACF;;AApEA,WAAA;EADC;;;;;AAMD,WAAA;EADC;;;;;AAtBU,QAAK,WAAA;EADjB,cAAc,EAAE,SAAS,UAAU,WAAW,KAAI,CAAE;;GACxC,KAAK;",
6
6
  "names": ["SwcIf"]
7
7
  }
@@ -0,0 +1,96 @@
1
+ var __decorate = function(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = function(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { elementDefind, template, style } from "../index.js";
11
+ import { SwcHTMLElementBase } from "./SwcHTMLElementBase.js";
12
+ let SwcObject = class SwcObject2 extends SwcHTMLElementBase {
13
+ constructor() {
14
+ super();
15
+ this._value = {};
16
+ this._renderedNodes = [];
17
+ }
18
+ set value(val) {
19
+ if (typeof val !== "object" || val === null)
20
+ val = {};
21
+ this._value = this.createReactiveProxy(val, () => this.updateUI());
22
+ this.render();
23
+ }
24
+ get value() {
25
+ return this._value;
26
+ }
27
+ styles() {
28
+ return `:host { display: contents; }`;
29
+ }
30
+ renderTemplate() {
31
+ return `<slot id="tpl-slot" style="display:none;"></slot>`;
32
+ }
33
+ connectedCallback() {
34
+ this.initCore();
35
+ this.render();
36
+ }
37
+ updateUI() {
38
+ this._renderedNodes.forEach((node) => {
39
+ this.applyData(node, this._value);
40
+ });
41
+ }
42
+ render() {
43
+ if (!this.shadowRoot || this._masterTplNodes.length === 0)
44
+ return;
45
+ this._renderedNodes.forEach((n) => {
46
+ if (n.parentElement === this)
47
+ this.removeChild(n);
48
+ });
49
+ this._renderedNodes = [];
50
+ let slot = this.shadowRoot.querySelector('slot[name="obj-content"]');
51
+ if (!slot) {
52
+ slot = document.createElement("slot");
53
+ slot.name = "obj-content";
54
+ this.shadowRoot.appendChild(slot);
55
+ }
56
+ this._masterTplNodes.forEach((tplNode) => {
57
+ const clone = tplNode.cloneNode(true);
58
+ if (clone.nodeType === Node.ELEMENT_NODE) {
59
+ clone.setAttribute("slot", "obj-content");
60
+ } else if (clone.nodeType === Node.TEXT_NODE) {
61
+ if (clone.textContent?.trim().length === 0)
62
+ return;
63
+ const span = document.createElement("span");
64
+ span.setAttribute("slot", "obj-content");
65
+ span.appendChild(clone);
66
+ this.appendChild(span);
67
+ this._renderedNodes.push(span);
68
+ this.applyData(span, this._value);
69
+ return;
70
+ }
71
+ this.appendChild(clone);
72
+ this._renderedNodes.push(clone);
73
+ this.applyData(clone, this._value);
74
+ });
75
+ }
76
+ };
77
+ __decorate([
78
+ style,
79
+ __metadata("design:type", Function),
80
+ __metadata("design:paramtypes", []),
81
+ __metadata("design:returntype", void 0)
82
+ ], SwcObject.prototype, "styles", null);
83
+ __decorate([
84
+ template,
85
+ __metadata("design:type", Function),
86
+ __metadata("design:paramtypes", []),
87
+ __metadata("design:returntype", void 0)
88
+ ], SwcObject.prototype, "renderTemplate", null);
89
+ SwcObject = __decorate([
90
+ elementDefind({ tagName: "swc-object", useShadow: true }),
91
+ __metadata("design:paramtypes", [])
92
+ ], SwcObject);
93
+ export {
94
+ SwcObject
95
+ };
96
+ //# sourceMappingURL=SwcObject.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/elements/SwcObject.ts"],
4
+ "sourcesContent": ["import { elementDefind, template, style } from '../index';\nimport { SwcHTMLElementBase } from './SwcHTMLElementBase';\n\n@elementDefind({ tagName: 'swc-object', useShadow: true })\nexport class SwcObject extends SwcHTMLElementBase {\n private _value: any = {};\n private _renderedNodes: Node[] = [];\n\n constructor() {\n super();\n }\n\n set value(val: any) {\n if (typeof val !== 'object' || val === null) val = {};\n this._value = this.createReactiveProxy(val, () => this.updateUI());\n this.render();\n }\n\n get value(): any {\n return this._value;\n }\n\n @style\n styles() {\n return `:host { display: contents; }`;\n }\n\n @template\n renderTemplate() {\n return `<slot id=\"tpl-slot\" style=\"display:none;\"></slot>`;\n }\n\n connectedCallback() {\n this.initCore();\n this.render();\n }\n\n private updateUI() {\n this._renderedNodes.forEach(node => {\n this.applyData(node, this._value);\n });\n }\n\n private render() {\n if (!this.shadowRoot || this._masterTplNodes.length === 0) return;\n\n this._renderedNodes.forEach(n => {\n if (n.parentElement === this) this.removeChild(n);\n });\n this._renderedNodes = [];\n\n let slot = this.shadowRoot.querySelector('slot[name=\"obj-content\"]');\n if (!slot) {\n slot = document.createElement('slot');\n (slot as HTMLSlotElement).name = 'obj-content';\n this.shadowRoot.appendChild(slot);\n }\n\n this._masterTplNodes.forEach(tplNode => {\n const clone = tplNode.cloneNode(true);\n if (clone.nodeType === Node.ELEMENT_NODE) {\n (clone as HTMLElement).setAttribute('slot', 'obj-content');\n } else if (clone.nodeType === Node.TEXT_NODE) {\n if (clone.textContent?.trim().length === 0) return;\n const span = document.createElement('span');\n span.setAttribute('slot', 'obj-content');\n span.appendChild(clone);\n this.appendChild(span);\n this._renderedNodes.push(span);\n this.applyData(span, this._value);\n return;\n }\n this.appendChild(clone);\n this._renderedNodes.push(clone);\n this.applyData(clone, this._value);\n });\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;AAAA,SAAS,eAAe,UAAU,aAAa;AAC/C,SAAS,0BAA0B;AAG5B,IAAM,YAAN,MAAMA,mBAAkB,mBAAkB;EAI/C,cAAA;AACE,UAAK;AAJC,SAAA,SAAc,CAAA;AACd,SAAA,iBAAyB,CAAA;EAIjC;EAEA,IAAI,MAAM,KAAQ;AAChB,QAAI,OAAO,QAAQ,YAAY,QAAQ;AAAM,YAAM,CAAA;AACnD,SAAK,SAAS,KAAK,oBAAoB,KAAK,MAAM,KAAK,SAAQ,CAAE;AACjE,SAAK,OAAM;EACb;EAEA,IAAI,QAAK;AACP,WAAO,KAAK;EACd;EAGA,SAAM;AACJ,WAAO;EACT;EAGA,iBAAc;AACZ,WAAO;EACT;EAEA,oBAAiB;AACf,SAAK,SAAQ;AACb,SAAK,OAAM;EACb;EAEQ,WAAQ;AACd,SAAK,eAAe,QAAQ,UAAO;AACjC,WAAK,UAAU,MAAM,KAAK,MAAM;IAClC,CAAC;EACH;EAEQ,SAAM;AACZ,QAAI,CAAC,KAAK,cAAc,KAAK,gBAAgB,WAAW;AAAG;AAE3D,SAAK,eAAe,QAAQ,OAAI;AAC9B,UAAI,EAAE,kBAAkB;AAAM,aAAK,YAAY,CAAC;IAClD,CAAC;AACD,SAAK,iBAAiB,CAAA;AAEtB,QAAI,OAAO,KAAK,WAAW,cAAc,0BAA0B;AACnE,QAAI,CAAC,MAAM;AACT,aAAO,SAAS,cAAc,MAAM;AACnC,WAAyB,OAAO;AACjC,WAAK,WAAW,YAAY,IAAI;IAClC;AAEA,SAAK,gBAAgB,QAAQ,aAAU;AACrC,YAAM,QAAQ,QAAQ,UAAU,IAAI;AACpC,UAAI,MAAM,aAAa,KAAK,cAAc;AACvC,cAAsB,aAAa,QAAQ,aAAa;MAC3D,WAAW,MAAM,aAAa,KAAK,WAAW;AAC5C,YAAI,MAAM,aAAa,KAAI,EAAG,WAAW;AAAG;AAC5C,cAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,aAAK,aAAa,QAAQ,aAAa;AACvC,aAAK,YAAY,KAAK;AACtB,aAAK,YAAY,IAAI;AACrB,aAAK,eAAe,KAAK,IAAI;AAC7B,aAAK,UAAU,MAAM,KAAK,MAAM;AAChC;MACF;AACA,WAAK,YAAY,KAAK;AACtB,WAAK,eAAe,KAAK,KAAK;AAC9B,WAAK,UAAU,OAAO,KAAK,MAAM;IACnC,CAAC;EACH;;AArDA,WAAA;EADC;;;;;AAMD,WAAA;EADC;;;;;AAvBU,YAAS,WAAA;EADrB,cAAc,EAAE,SAAS,cAAc,WAAW,KAAI,CAAE;;GAC5C,SAAS;",
6
+ "names": ["SwcObject"]
7
+ }
package/dist/esm/index.js CHANGED
@@ -10,4 +10,6 @@ export * from "./elements/SwcIf.js";
10
10
  export * from "./elements/SwcChoose.js";
11
11
  export * from "./elements/SwcWhen.js";
12
12
  export * from "./elements/SwcOther.js";
13
+ export * from "./elements/SwcObject.js";
14
+ export * from "./elements/SwcHTMLElementBase.js";
13
15
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export * from './decorators/elementDefind';\nexport * from './decorators/template';\nexport * from './decorators/style';\nexport * from './decorators/attributeChanged';\nexport * from './decorators/query';\nexport * from './decorators/queryAll';\nexport * from './decorators/addEventListener';\nexport * from './elements/SwcForOf';\nexport * from './elements/SwcIf';\nexport * from './elements/SwcChoose';\nexport * from './elements/SwcWhen';\nexport * from './elements/SwcOther';\n"],
5
- "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export * from './decorators/elementDefind';\nexport * from './decorators/template';\nexport * from './decorators/style';\nexport * from './decorators/attributeChanged';\nexport * from './decorators/query';\nexport * from './decorators/queryAll';\nexport * from './decorators/addEventListener';\nexport * from './elements/SwcForOf';\nexport * from './elements/SwcIf';\nexport * from './elements/SwcChoose';\nexport * from './elements/SwcWhen';\nexport * from './elements/SwcOther';\nexport * from './elements/SwcObject';\nexport * from './elements/SwcHTMLElementBase';\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
6
6
  "names": []
7
7
  }