@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.
- package/README.md +26 -31
- package/dist/cjs/elements/SwcForOf.js +6 -76
- package/dist/cjs/elements/SwcForOf.js.map +2 -2
- package/dist/cjs/elements/SwcHTMLElementBase.js +102 -0
- package/dist/cjs/elements/SwcHTMLElementBase.js.map +7 -0
- package/dist/cjs/elements/SwcIf.js +5 -13
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcObject.js +115 -0
- package/dist/cjs/elements/SwcObject.js.map +7 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/esm/elements/SwcForOf.js +6 -76
- package/dist/esm/elements/SwcForOf.js.map +2 -2
- package/dist/esm/elements/SwcHTMLElementBase.js +83 -0
- package/dist/esm/elements/SwcHTMLElementBase.js.map +7 -0
- package/dist/esm/elements/SwcIf.js +5 -13
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcObject.js +96 -0
- package/dist/esm/elements/SwcObject.js.map +7 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +184 -89
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/elements/SwcForOf.d.ts +2 -4
- package/dist/types/elements/SwcForOf.d.ts.map +1 -1
- package/dist/types/elements/SwcHTMLElementBase.d.ts +14 -0
- package/dist/types/elements/SwcHTMLElementBase.d.ts.map +1 -0
- package/dist/types/elements/SwcIf.d.ts +2 -2
- package/dist/types/elements/SwcIf.d.ts.map +1 -1
- package/dist/types/elements/SwcObject.d.ts +14 -0
- package/dist/types/elements/SwcObject.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +184 -89
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +1 -1
- package/src/elements/SwcForOf.ts +10 -85
- package/src/elements/SwcHTMLElementBase.ts +93 -0
- package/src/elements/SwcIf.ts +6 -25
- package/src/elements/SwcObject.ts +78 -0
- package/src/index.ts +2 -0
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
- **Surgical Updates**: High-performance rendering using the "Slot-per-Row" pattern.
|
|
9
9
|
- **Auto-Sync**: Decorators automatically re-bind when the DOM changes (via MutationObserver).
|
|
10
10
|
- **Native-First**: No Virtual DOM, just pure Custom Elements.
|
|
11
|
-
- **Built-in Logic Components**: Includes `swc-for-of`, `swc-if`, and `swc-
|
|
11
|
+
- **Built-in Logic Components**: Includes `swc-for-of`, `swc-if`, `swc-choose`, and `swc-object`.
|
|
12
|
+
- **Scoped Context**: Support for `as` and `as-index` to avoid naming collisions in nested structures.
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
@@ -32,12 +33,17 @@ pnpm add @dooboostore/simple-web-component
|
|
|
32
33
|
|
|
33
34
|
### Built-in Components
|
|
34
35
|
|
|
36
|
+
All built-in components extend `SwcHTMLElementBase` and support the `as` attribute for custom data scoping.
|
|
37
|
+
|
|
35
38
|
#### `swc-for-of` (Looping)
|
|
36
39
|
A high-performance list renderer that uses slots to update only changed items.
|
|
40
|
+
- `as`: (Optional) Alias for the item (default: `value`).
|
|
41
|
+
- `as-index`: (Optional) Alias for the index (default: `index`).
|
|
42
|
+
|
|
37
43
|
```html
|
|
38
44
|
<ul>
|
|
39
|
-
<swc-for-of id="my-list">
|
|
40
|
-
<li>{{
|
|
45
|
+
<swc-for-of id="my-list" as="item" as-index="i">
|
|
46
|
+
<li>{{i}}: {{item.name}}</li>
|
|
41
47
|
</swc-for-of>
|
|
42
48
|
</ul>
|
|
43
49
|
<script>
|
|
@@ -47,6 +53,20 @@ A high-performance list renderer that uses slots to update only changed items.
|
|
|
47
53
|
</script>
|
|
48
54
|
```
|
|
49
55
|
|
|
56
|
+
#### `swc-object` (Object Binding)
|
|
57
|
+
Binds a single object and updates the UI surgically when properties change.
|
|
58
|
+
```html
|
|
59
|
+
<swc-object id="user-profile" as="u">
|
|
60
|
+
<div>Name: {{u.name}}</div>
|
|
61
|
+
<div>Age: {{u.age}}</div>
|
|
62
|
+
</swc-object>
|
|
63
|
+
<script>
|
|
64
|
+
const el = document.getElementById('user-profile');
|
|
65
|
+
el.value = { name: 'Kim', age: 20 };
|
|
66
|
+
el.value.name = 'Lee'; // Automatically updates UI via Proxy
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
69
|
+
|
|
50
70
|
#### `swc-if` (Conditional)
|
|
51
71
|
Conditionally renders content based on a truthy value or expression.
|
|
52
72
|
```html
|
|
@@ -65,34 +85,9 @@ Provides a switch-case style branching logic.
|
|
|
65
85
|
</swc-choose>
|
|
66
86
|
```
|
|
67
87
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
import { elementDefind, template, style, query, addEventListener } from '@dooboostore/simple-web-component';
|
|
72
|
-
|
|
73
|
-
@elementDefind({
|
|
74
|
-
tagName: 'my-component',
|
|
75
|
-
useShadow: true
|
|
76
|
-
})
|
|
77
|
-
class MyComponent extends HTMLElement {
|
|
78
|
-
@query('.title') titleEl: HTMLElement;
|
|
79
|
-
|
|
80
|
-
@style
|
|
81
|
-
css() {
|
|
82
|
-
return `:host { display: block; } .title { color: blue; }`;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@template
|
|
86
|
-
render() {
|
|
87
|
-
return `<h1 class="title">Hello World</h1><button id="btn">Click</button>`;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@addEventListener({ selector: '#btn', eventName: 'click' })
|
|
91
|
-
onClick(e: Event) {
|
|
92
|
-
this.titleEl.textContent = 'Button Clicked!';
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
88
|
+
## Advanced: Extending SwcHTMLElementBase
|
|
89
|
+
|
|
90
|
+
You can create your own high-performance components by extending `SwcHTMLElementBase`. It provides `applyData`, `createReactiveProxy`, and automatic `as` handling.
|
|
96
91
|
|
|
97
92
|
## License
|
|
98
93
|
|
|
@@ -21,6 +21,7 @@ __export(SwcForOf_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(SwcForOf_exports);
|
|
23
23
|
var import__ = require("../index");
|
|
24
|
+
var import_SwcHTMLElementBase = require("./SwcHTMLElementBase");
|
|
24
25
|
var __decorate = function(decorators, target, key, desc) {
|
|
25
26
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
27
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -30,55 +31,28 @@ var __decorate = function(decorators, target, key, desc) {
|
|
|
30
31
|
var __metadata = function(k, v) {
|
|
31
32
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
32
33
|
};
|
|
33
|
-
let SwcForOf = class SwcForOf2 extends
|
|
34
|
+
let SwcForOf = class SwcForOf2 extends import_SwcHTMLElementBase.SwcHTMLElementBase {
|
|
34
35
|
constructor() {
|
|
35
36
|
super();
|
|
36
37
|
this._value = [];
|
|
37
|
-
this._masterTplNodes = [];
|
|
38
38
|
}
|
|
39
39
|
set value(val) {
|
|
40
40
|
if (!Array.isArray(val))
|
|
41
41
|
val = [];
|
|
42
|
-
this._value = this.
|
|
42
|
+
this._value = this.createReactiveProxy(val, () => this.renderAll(), (idx, v) => this.updateSingleRow(idx, v));
|
|
43
43
|
this.renderAll();
|
|
44
44
|
}
|
|
45
45
|
get value() {
|
|
46
46
|
return this._value;
|
|
47
47
|
}
|
|
48
|
-
createProxy(arr) {
|
|
49
|
-
return new Proxy(arr, {
|
|
50
|
-
set: (target, prop, val) => {
|
|
51
|
-
const isIndex = !isNaN(Number(prop));
|
|
52
|
-
target[prop] = val;
|
|
53
|
-
if (isIndex) {
|
|
54
|
-
this.updateSingleRow(Number(prop), val);
|
|
55
|
-
} else if (prop === "length" && val < target.length) {
|
|
56
|
-
this.renderAll();
|
|
57
|
-
}
|
|
58
|
-
return true;
|
|
59
|
-
},
|
|
60
|
-
deleteProperty: (target, prop) => {
|
|
61
|
-
const res = delete target[prop];
|
|
62
|
-
this.renderAll();
|
|
63
|
-
return res;
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
48
|
styles() {
|
|
68
|
-
return
|
|
69
|
-
:host { display: contents; }
|
|
70
|
-
`;
|
|
49
|
+
return `:host { display: contents; }`;
|
|
71
50
|
}
|
|
72
51
|
renderTemplate() {
|
|
73
|
-
return
|
|
74
|
-
<slot id="tpl-slot" style="display:none;"></slot>
|
|
75
|
-
`;
|
|
52
|
+
return `<slot id="tpl-slot" style="display:none;"></slot>`;
|
|
76
53
|
}
|
|
77
54
|
connectedCallback() {
|
|
78
|
-
|
|
79
|
-
if (tplSlot) {
|
|
80
|
-
this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
|
|
81
|
-
}
|
|
55
|
+
this.initCore();
|
|
82
56
|
this.renderAll();
|
|
83
57
|
}
|
|
84
58
|
updateSingleRow(index, newValue) {
|
|
@@ -89,50 +63,6 @@ let SwcForOf = class SwcForOf2 extends HTMLElement {
|
|
|
89
63
|
this.renderRow(newValue, index);
|
|
90
64
|
}
|
|
91
65
|
}
|
|
92
|
-
applyData(node, data, index) {
|
|
93
|
-
const getValueByPath = (obj, path) => {
|
|
94
|
-
if (path === "value")
|
|
95
|
-
return obj;
|
|
96
|
-
if (path.startsWith("value.")) {
|
|
97
|
-
return path.split(".").slice(1).reduce((acc, part) => acc && acc[part], obj);
|
|
98
|
-
}
|
|
99
|
-
return void 0;
|
|
100
|
-
};
|
|
101
|
-
const walk = (n) => {
|
|
102
|
-
if (n.nodeType === Node.TEXT_NODE) {
|
|
103
|
-
if (!n._original)
|
|
104
|
-
n._original = n.textContent;
|
|
105
|
-
let text = n._original;
|
|
106
|
-
text = text.replace(/{{(.*?)}}/g, (match, path) => {
|
|
107
|
-
path = path.trim();
|
|
108
|
-
if (path === "index")
|
|
109
|
-
return index.toString();
|
|
110
|
-
const val = getValueByPath(data, path);
|
|
111
|
-
return val !== void 0 ? val : match;
|
|
112
|
-
});
|
|
113
|
-
if (n.textContent !== text)
|
|
114
|
-
n.textContent = text;
|
|
115
|
-
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
|
116
|
-
const el = n;
|
|
117
|
-
Array.from(el.attributes).forEach((a) => {
|
|
118
|
-
if (!a._original)
|
|
119
|
-
a._original = a.value;
|
|
120
|
-
let val = a._original;
|
|
121
|
-
val = val.replace(/{{(.*?)}}/g, (match, path) => {
|
|
122
|
-
path = path.trim();
|
|
123
|
-
if (path === "index")
|
|
124
|
-
return index.toString();
|
|
125
|
-
const v = getValueByPath(data, path);
|
|
126
|
-
return v !== void 0 ? v : match;
|
|
127
|
-
});
|
|
128
|
-
if (a.value !== val)
|
|
129
|
-
a.value = val;
|
|
130
|
-
});
|
|
131
|
-
el.childNodes.forEach(walk);
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
walk(node);
|
|
135
|
-
}
|
|
136
66
|
renderRow(item, index) {
|
|
137
67
|
if (!this.shadowRoot || this._masterTplNodes.length === 0)
|
|
138
68
|
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
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA,eAA+C;;;;;;;;;;
|
|
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,eAA+C;AAC/C,gCAAmC;;;;;;;;;;AAG5B,IAAM,WAAN,MAAMA,kBAAiB,6CAAkB;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;MADpB,wBAAc,EAAE,SAAS,cAAc,WAAW,KAAI,CAAE;;GAC5C,QAAQ;",
|
|
6
6
|
"names": ["SwcForOf"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var SwcHTMLElementBase_exports = {};
|
|
19
|
+
__export(SwcHTMLElementBase_exports, {
|
|
20
|
+
SwcHTMLElementBase: () => SwcHTMLElementBase
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(SwcHTMLElementBase_exports);
|
|
23
|
+
class SwcHTMLElementBase extends HTMLElement {
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
this._masterTplNodes = [];
|
|
27
|
+
this._asKey = "value";
|
|
28
|
+
this._asIndexKey = "index";
|
|
29
|
+
}
|
|
30
|
+
initCore() {
|
|
31
|
+
this._asKey = this.getAttribute("as") || "value";
|
|
32
|
+
this._asIndexKey = this.getAttribute("as-index") || "index";
|
|
33
|
+
const tplSlot = this.shadowRoot?.getElementById("tpl-slot");
|
|
34
|
+
if (tplSlot) {
|
|
35
|
+
this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getValueByPath(obj, path) {
|
|
39
|
+
if (path === this._asKey) return obj;
|
|
40
|
+
if (path.startsWith(`${this._asKey}.`)) {
|
|
41
|
+
return path.split(".").slice(1).reduce((acc, part) => acc && acc[part], obj);
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
applyData(node, data, index) {
|
|
46
|
+
const context = {};
|
|
47
|
+
if (index !== void 0) {
|
|
48
|
+
context[this._asIndexKey] = index.toString();
|
|
49
|
+
}
|
|
50
|
+
const walk = (n) => {
|
|
51
|
+
if (n.nodeType === Node.TEXT_NODE) {
|
|
52
|
+
if (!n._original) n._original = n.textContent;
|
|
53
|
+
let text = n._original;
|
|
54
|
+
text = text.replace(/{{(.*?)}}/g, (match, path) => {
|
|
55
|
+
path = path.trim();
|
|
56
|
+
if (context[path] !== void 0) return context[path];
|
|
57
|
+
const val = this.getValueByPath(data, path);
|
|
58
|
+
return val !== void 0 ? val : match;
|
|
59
|
+
});
|
|
60
|
+
if (n.textContent !== text) n.textContent = text;
|
|
61
|
+
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
|
62
|
+
const el = n;
|
|
63
|
+
Array.from(el.attributes).forEach((a) => {
|
|
64
|
+
if (!a._original) a._original = a.value;
|
|
65
|
+
let val = a._original;
|
|
66
|
+
val = val.replace(/{{(.*?)}}/g, (match, path) => {
|
|
67
|
+
path = path.trim();
|
|
68
|
+
if (context[path] !== void 0) return context[path];
|
|
69
|
+
const v = this.getValueByPath(data, path);
|
|
70
|
+
return v !== void 0 ? v : match;
|
|
71
|
+
});
|
|
72
|
+
if (a.value !== val) a.value = val;
|
|
73
|
+
});
|
|
74
|
+
el.childNodes.forEach(walk);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
walk(node);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 객체/배열의 변경을 감지하는 Proxy 생성 유틸리티
|
|
81
|
+
*/
|
|
82
|
+
createReactiveProxy(target, onChange, onIndexChange) {
|
|
83
|
+
return new Proxy(target, {
|
|
84
|
+
set: (t, prop, val) => {
|
|
85
|
+
const isIndex = !isNaN(Number(prop));
|
|
86
|
+
t[prop] = val;
|
|
87
|
+
if (isIndex && onIndexChange) {
|
|
88
|
+
onIndexChange(Number(prop), val);
|
|
89
|
+
} else {
|
|
90
|
+
onChange();
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
deleteProperty: (t, prop) => {
|
|
95
|
+
delete t[prop];
|
|
96
|
+
onChange();
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# 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": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;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
|
+
}
|
|
@@ -21,6 +21,7 @@ __export(SwcIf_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(SwcIf_exports);
|
|
23
23
|
var import__ = require("../index");
|
|
24
|
+
var import_SwcHTMLElementBase = require("./SwcHTMLElementBase");
|
|
24
25
|
var __decorate = function(decorators, target, key, desc) {
|
|
25
26
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
27
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -30,11 +31,10 @@ var __decorate = function(decorators, target, key, desc) {
|
|
|
30
31
|
var __metadata = function(k, v) {
|
|
31
32
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
32
33
|
};
|
|
33
|
-
let SwcIf = class SwcIf2 extends
|
|
34
|
+
let SwcIf = class SwcIf2 extends import_SwcHTMLElementBase.SwcHTMLElementBase {
|
|
34
35
|
constructor() {
|
|
35
36
|
super();
|
|
36
37
|
this._value = false;
|
|
37
|
-
this._masterTplNodes = [];
|
|
38
38
|
this._observer = null;
|
|
39
39
|
}
|
|
40
40
|
set value(val) {
|
|
@@ -45,20 +45,13 @@ let SwcIf = class SwcIf2 extends HTMLElement {
|
|
|
45
45
|
return this._value;
|
|
46
46
|
}
|
|
47
47
|
styles() {
|
|
48
|
-
return
|
|
49
|
-
:host { display: contents; }
|
|
50
|
-
`;
|
|
48
|
+
return `:host { display: contents; }`;
|
|
51
49
|
}
|
|
52
50
|
renderTemplate() {
|
|
53
|
-
return
|
|
54
|
-
<slot id="tpl-slot" style="display:none;"></slot>
|
|
55
|
-
`;
|
|
51
|
+
return `<slot id="tpl-slot" style="display:none;"></slot>`;
|
|
56
52
|
}
|
|
57
53
|
connectedCallback() {
|
|
58
|
-
|
|
59
|
-
if (tplSlot) {
|
|
60
|
-
this._masterTplNodes = tplSlot.assignedNodes().map((n) => n.cloneNode(true));
|
|
61
|
-
}
|
|
54
|
+
this.initCore();
|
|
62
55
|
this._observer = new MutationObserver(() => this.render());
|
|
63
56
|
this._observer.observe(this, { attributes: true });
|
|
64
57
|
this.render();
|
|
@@ -101,7 +94,6 @@ let SwcIf = class SwcIf2 extends HTMLElement {
|
|
|
101
94
|
const clone = tplNode.cloneNode(true);
|
|
102
95
|
if (clone.nodeType === Node.ELEMENT_NODE) {
|
|
103
96
|
clone.setAttribute("slot", "if-content");
|
|
104
|
-
clone.style.display = "";
|
|
105
97
|
} else if (clone.nodeType === Node.TEXT_NODE) {
|
|
106
98
|
if (clone.textContent?.trim().length === 0)
|
|
107
99
|
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
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA,eAA+C;;;;;;;;;;
|
|
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,eAA+C;AAC/C,gCAAmC;;;;;;;;;;AAG5B,IAAM,QAAN,MAAMA,eAAc,6CAAkB;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;MADjB,wBAAc,EAAE,SAAS,UAAU,WAAW,KAAI,CAAE;;GACxC,KAAK;",
|
|
6
6
|
"names": ["SwcIf"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var SwcObject_exports = {};
|
|
19
|
+
__export(SwcObject_exports, {
|
|
20
|
+
SwcObject: () => SwcObject
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(SwcObject_exports);
|
|
23
|
+
var import__ = require("../index");
|
|
24
|
+
var import_SwcHTMLElementBase = require("./SwcHTMLElementBase");
|
|
25
|
+
var __decorate = function(decorators, target, key, desc) {
|
|
26
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
27
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
28
|
+
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;
|
|
29
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
30
|
+
};
|
|
31
|
+
var __metadata = function(k, v) {
|
|
32
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
|
+
};
|
|
34
|
+
let SwcObject = class SwcObject2 extends import_SwcHTMLElementBase.SwcHTMLElementBase {
|
|
35
|
+
constructor() {
|
|
36
|
+
super();
|
|
37
|
+
this._value = {};
|
|
38
|
+
this._renderedNodes = [];
|
|
39
|
+
}
|
|
40
|
+
set value(val) {
|
|
41
|
+
if (typeof val !== "object" || val === null)
|
|
42
|
+
val = {};
|
|
43
|
+
this._value = this.createReactiveProxy(val, () => this.updateUI());
|
|
44
|
+
this.render();
|
|
45
|
+
}
|
|
46
|
+
get value() {
|
|
47
|
+
return this._value;
|
|
48
|
+
}
|
|
49
|
+
styles() {
|
|
50
|
+
return `:host { display: contents; }`;
|
|
51
|
+
}
|
|
52
|
+
renderTemplate() {
|
|
53
|
+
return `<slot id="tpl-slot" style="display:none;"></slot>`;
|
|
54
|
+
}
|
|
55
|
+
connectedCallback() {
|
|
56
|
+
this.initCore();
|
|
57
|
+
this.render();
|
|
58
|
+
}
|
|
59
|
+
updateUI() {
|
|
60
|
+
this._renderedNodes.forEach((node) => {
|
|
61
|
+
this.applyData(node, this._value);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
render() {
|
|
65
|
+
if (!this.shadowRoot || this._masterTplNodes.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
this._renderedNodes.forEach((n) => {
|
|
68
|
+
if (n.parentElement === this)
|
|
69
|
+
this.removeChild(n);
|
|
70
|
+
});
|
|
71
|
+
this._renderedNodes = [];
|
|
72
|
+
let slot = this.shadowRoot.querySelector('slot[name="obj-content"]');
|
|
73
|
+
if (!slot) {
|
|
74
|
+
slot = document.createElement("slot");
|
|
75
|
+
slot.name = "obj-content";
|
|
76
|
+
this.shadowRoot.appendChild(slot);
|
|
77
|
+
}
|
|
78
|
+
this._masterTplNodes.forEach((tplNode) => {
|
|
79
|
+
const clone = tplNode.cloneNode(true);
|
|
80
|
+
if (clone.nodeType === Node.ELEMENT_NODE) {
|
|
81
|
+
clone.setAttribute("slot", "obj-content");
|
|
82
|
+
} else if (clone.nodeType === Node.TEXT_NODE) {
|
|
83
|
+
if (clone.textContent?.trim().length === 0)
|
|
84
|
+
return;
|
|
85
|
+
const span = document.createElement("span");
|
|
86
|
+
span.setAttribute("slot", "obj-content");
|
|
87
|
+
span.appendChild(clone);
|
|
88
|
+
this.appendChild(span);
|
|
89
|
+
this._renderedNodes.push(span);
|
|
90
|
+
this.applyData(span, this._value);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.appendChild(clone);
|
|
94
|
+
this._renderedNodes.push(clone);
|
|
95
|
+
this.applyData(clone, this._value);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
__decorate([
|
|
100
|
+
import__.style,
|
|
101
|
+
__metadata("design:type", Function),
|
|
102
|
+
__metadata("design:paramtypes", []),
|
|
103
|
+
__metadata("design:returntype", void 0)
|
|
104
|
+
], SwcObject.prototype, "styles", null);
|
|
105
|
+
__decorate([
|
|
106
|
+
import__.template,
|
|
107
|
+
__metadata("design:type", Function),
|
|
108
|
+
__metadata("design:paramtypes", []),
|
|
109
|
+
__metadata("design:returntype", void 0)
|
|
110
|
+
], SwcObject.prototype, "renderTemplate", null);
|
|
111
|
+
SwcObject = __decorate([
|
|
112
|
+
(0, import__.elementDefind)({ tagName: "swc-object", useShadow: true }),
|
|
113
|
+
__metadata("design:paramtypes", [])
|
|
114
|
+
], SwcObject);
|
|
115
|
+
//# 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,eAA+C;AAC/C,gCAAmC;;;;;;;;;;AAG5B,IAAM,YAAN,MAAMA,mBAAkB,6CAAkB;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;MADrB,wBAAc,EAAE,SAAS,cAAc,WAAW,KAAI,CAAE;;GAC5C,SAAS;",
|
|
6
|
+
"names": ["SwcObject"]
|
|
7
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -26,4 +26,6 @@ __reExport(src_exports, require("./elements/SwcIf"), module.exports);
|
|
|
26
26
|
__reExport(src_exports, require("./elements/SwcChoose"), module.exports);
|
|
27
27
|
__reExport(src_exports, require("./elements/SwcWhen"), module.exports);
|
|
28
28
|
__reExport(src_exports, require("./elements/SwcOther"), module.exports);
|
|
29
|
+
__reExport(src_exports, require("./elements/SwcObject"), module.exports);
|
|
30
|
+
__reExport(src_exports, require("./elements/SwcHTMLElementBase"), module.exports);
|
|
29
31
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -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;AAAA;AAAA,wBAAc,uCAAd;AACA,wBAAc,kCADd;AAEA,wBAAc,+BAFd;AAGA,wBAAc,0CAHd;AAIA,wBAAc,+BAJd;AAKA,wBAAc,kCALd;AAMA,wBAAc,0CANd;AAOA,wBAAc,gCAPd;AAQA,wBAAc,6BARd;AASA,wBAAc,iCATd;AAUA,wBAAc,+BAVd;AAWA,wBAAc,gCAXd;",
|
|
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;AAAA;AAAA,wBAAc,uCAAd;AACA,wBAAc,kCADd;AAEA,wBAAc,+BAFd;AAGA,wBAAc,0CAHd;AAIA,wBAAc,+BAJd;AAKA,wBAAc,kCALd;AAMA,wBAAc,0CANd;AAOA,wBAAc,gCAPd;AAQA,wBAAc,6BARd;AASA,wBAAc,iCATd;AAUA,wBAAc,+BAVd;AAWA,wBAAc,gCAXd;AAYA,wBAAc,iCAZd;AAaA,wBAAc,0CAbd;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|