@coherent.js/web-components 1.0.0-beta.6 → 1.0.0-beta.7
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/dist/index.js +110 -0
- package/dist/index.js.map +7 -0
- package/package.json +12 -3
- package/src/index.js +98 -7
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// src/index.js
|
|
2
|
+
import { render } from "@coherent.js/core";
|
|
3
|
+
function defineComponent(name, component, options = {}) {
|
|
4
|
+
if (typeof window === "undefined") {
|
|
5
|
+
return { name, component, options };
|
|
6
|
+
}
|
|
7
|
+
if (!window.customElements) {
|
|
8
|
+
throw new Error("Custom Elements API not supported");
|
|
9
|
+
}
|
|
10
|
+
const observedAttrs = options.observedAttributes || [];
|
|
11
|
+
const defaults = options.defaults || {};
|
|
12
|
+
class CoherentElement extends HTMLElement {
|
|
13
|
+
static get observedAttributes() {
|
|
14
|
+
return observedAttrs;
|
|
15
|
+
}
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
this._props = { ...defaults };
|
|
19
|
+
this._connected = false;
|
|
20
|
+
this.component = component;
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
this._connected = true;
|
|
25
|
+
for (const attr of observedAttrs) {
|
|
26
|
+
if (this.hasAttribute(attr)) {
|
|
27
|
+
this._props[attr] = this.getAttribute(attr);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
this._render();
|
|
31
|
+
}
|
|
32
|
+
disconnectedCallback() {
|
|
33
|
+
this._connected = false;
|
|
34
|
+
if (options.shadow && this.shadowRoot) {
|
|
35
|
+
this.shadowRoot.innerHTML = "";
|
|
36
|
+
} else {
|
|
37
|
+
this.innerHTML = "";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
|
41
|
+
if (oldValue === newValue) return;
|
|
42
|
+
this._props[attrName] = newValue;
|
|
43
|
+
if (this._connected) {
|
|
44
|
+
this._render();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Set a property and re-render
|
|
49
|
+
*/
|
|
50
|
+
setProperty(key, value) {
|
|
51
|
+
this._props[key] = value;
|
|
52
|
+
if (this._connected) {
|
|
53
|
+
this._render();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get current props
|
|
58
|
+
*/
|
|
59
|
+
getProperties() {
|
|
60
|
+
return { ...this._props };
|
|
61
|
+
}
|
|
62
|
+
_render() {
|
|
63
|
+
const componentDef = typeof this.component === "function" ? this.component(this._props) : this.component;
|
|
64
|
+
const html = render(componentDef);
|
|
65
|
+
if (this.options.shadow) {
|
|
66
|
+
if (!this.shadowRoot) {
|
|
67
|
+
this.attachShadow({ mode: "open" });
|
|
68
|
+
}
|
|
69
|
+
this.shadowRoot.innerHTML = html;
|
|
70
|
+
this._delegateEvents(this.shadowRoot);
|
|
71
|
+
} else {
|
|
72
|
+
this.innerHTML = html;
|
|
73
|
+
this._delegateEvents(this);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Delegate data-action events to component handlers
|
|
78
|
+
*/
|
|
79
|
+
_delegateEvents(root) {
|
|
80
|
+
const actionElements = root.querySelectorAll("[data-action]");
|
|
81
|
+
for (const el of actionElements) {
|
|
82
|
+
const action = el.dataset.action;
|
|
83
|
+
const [eventType, handlerName] = action.includes(":") ? action.split(":") : ["click", action];
|
|
84
|
+
el.addEventListener(eventType, (event) => {
|
|
85
|
+
this.dispatchEvent(new CustomEvent("coherent-action", {
|
|
86
|
+
bubbles: true,
|
|
87
|
+
detail: { action: handlerName, event, element: el }
|
|
88
|
+
}));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
window.customElements.define(name, CoherentElement);
|
|
94
|
+
return CoherentElement;
|
|
95
|
+
}
|
|
96
|
+
function integrateWithWebComponents(_runtime) {
|
|
97
|
+
return {
|
|
98
|
+
defineComponent: (name, component, options) => defineComponent(name, component, options)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function defineCoherentElement(name, component, options = {}) {
|
|
102
|
+
return defineComponent(name, component, options);
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
defineComponent as default,
|
|
106
|
+
defineCoherentElement,
|
|
107
|
+
defineComponent,
|
|
108
|
+
integrateWithWebComponents
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Coherent.js Web Components Integration\n * Provides custom element and web component utilities\n */\n\nimport { render } from '@coherent.js/core';\n\n/**\n * Define a Coherent.js component as a custom element\n *\n * @param {string} name - Custom element tag name (must contain a hyphen)\n * @param {Function|Object} component - Coherent.js component (function or object)\n * @param {Object} [options] - Configuration options\n * @param {boolean} [options.shadow] - Use Shadow DOM for style encapsulation\n * @param {string[]} [options.observedAttributes] - Attributes to watch for changes\n * @param {Object} [options.defaults] - Default property values\n * @returns {Function|Object} The custom element class, or a server-side placeholder\n */\nexport function defineComponent(name, component, options = {}) {\n if (typeof window === 'undefined') {\n // Server-side: return a placeholder for SSR\n return { name, component, options };\n }\n\n if (!window.customElements) {\n throw new Error('Custom Elements API not supported');\n }\n\n const observedAttrs = options.observedAttributes || [];\n const defaults = options.defaults || {};\n\n class CoherentElement extends HTMLElement {\n static get observedAttributes() {\n return observedAttrs;\n }\n\n constructor() {\n super();\n this._props = { ...defaults };\n this._connected = false;\n this.component = component;\n this.options = options;\n }\n\n connectedCallback() {\n this._connected = true;\n // Copy initial attributes to props\n for (const attr of observedAttrs) {\n if (this.hasAttribute(attr)) {\n this._props[attr] = this.getAttribute(attr);\n }\n }\n this._render();\n }\n\n disconnectedCallback() {\n this._connected = false;\n // Cleanup: remove event listeners and clear content\n if (options.shadow && this.shadowRoot) {\n this.shadowRoot.innerHTML = '';\n } else {\n this.innerHTML = '';\n }\n }\n\n attributeChangedCallback(attrName, oldValue, newValue) {\n if (oldValue === newValue) return;\n this._props[attrName] = newValue;\n if (this._connected) {\n this._render();\n }\n }\n\n /**\n * Set a property and re-render\n */\n setProperty(key, value) {\n this._props[key] = value;\n if (this._connected) {\n this._render();\n }\n }\n\n /**\n * Get current props\n */\n getProperties() {\n return { ...this._props };\n }\n\n _render() {\n const componentDef = typeof this.component === 'function'\n ? this.component(this._props)\n : this.component;\n\n const html = render(componentDef);\n\n if (this.options.shadow) {\n if (!this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n this.shadowRoot.innerHTML = html;\n this._delegateEvents(this.shadowRoot);\n } else {\n this.innerHTML = html;\n this._delegateEvents(this);\n }\n }\n\n /**\n * Delegate data-action events to component handlers\n */\n _delegateEvents(root) {\n const actionElements = root.querySelectorAll('[data-action]');\n for (const el of actionElements) {\n const action = el.dataset.action;\n const [eventType, handlerName] = action.includes(':')\n ? action.split(':')\n : ['click', action];\n\n el.addEventListener(eventType, (event) => {\n this.dispatchEvent(new CustomEvent('coherent-action', {\n bubbles: true,\n detail: { action: handlerName, event, element: el }\n }));\n });\n }\n }\n }\n\n window.customElements.define(name, CoherentElement);\n return CoherentElement;\n}\n\n/**\n * Integration utilities for runtime environments\n */\nexport function integrateWithWebComponents(_runtime) {\n return {\n defineComponent: (name, component, options) => defineComponent(name, component, options)\n };\n}\n\n/**\n * Alias for defineComponent\n */\nexport function defineCoherentElement(name, component, options = {}) {\n return defineComponent(name, component, options);\n}\n\nexport { defineComponent as default };\n"],
|
|
5
|
+
"mappings": ";AAKA,SAAS,cAAc;AAahB,SAAS,gBAAgB,MAAM,WAAW,UAAU,CAAC,GAAG;AAC7D,MAAI,OAAO,WAAW,aAAa;AAEjC,WAAO,EAAE,MAAM,WAAW,QAAQ;AAAA,EACpC;AAEA,MAAI,CAAC,OAAO,gBAAgB;AAC1B,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,gBAAgB,QAAQ,sBAAsB,CAAC;AACrD,QAAM,WAAW,QAAQ,YAAY,CAAC;AAAA,EAEtC,MAAM,wBAAwB,YAAY;AAAA,IACxC,WAAW,qBAAqB;AAC9B,aAAO;AAAA,IACT;AAAA,IAEA,cAAc;AACZ,YAAM;AACN,WAAK,SAAS,EAAE,GAAG,SAAS;AAC5B,WAAK,aAAa;AAClB,WAAK,YAAY;AACjB,WAAK,UAAU;AAAA,IACjB;AAAA,IAEA,oBAAoB;AAClB,WAAK,aAAa;AAElB,iBAAW,QAAQ,eAAe;AAChC,YAAI,KAAK,aAAa,IAAI,GAAG;AAC3B,eAAK,OAAO,IAAI,IAAI,KAAK,aAAa,IAAI;AAAA,QAC5C;AAAA,MACF;AACA,WAAK,QAAQ;AAAA,IACf;AAAA,IAEA,uBAAuB;AACrB,WAAK,aAAa;AAElB,UAAI,QAAQ,UAAU,KAAK,YAAY;AACrC,aAAK,WAAW,YAAY;AAAA,MAC9B,OAAO;AACL,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAAA,IAEA,yBAAyB,UAAU,UAAU,UAAU;AACrD,UAAI,aAAa,SAAU;AAC3B,WAAK,OAAO,QAAQ,IAAI;AACxB,UAAI,KAAK,YAAY;AACnB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,YAAY,KAAK,OAAO;AACtB,WAAK,OAAO,GAAG,IAAI;AACnB,UAAI,KAAK,YAAY;AACnB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAgB;AACd,aAAO,EAAE,GAAG,KAAK,OAAO;AAAA,IAC1B;AAAA,IAEA,UAAU;AACR,YAAM,eAAe,OAAO,KAAK,cAAc,aAC3C,KAAK,UAAU,KAAK,MAAM,IAC1B,KAAK;AAET,YAAM,OAAO,OAAO,YAAY;AAEhC,UAAI,KAAK,QAAQ,QAAQ;AACvB,YAAI,CAAC,KAAK,YAAY;AACpB,eAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAAA,QACpC;AACA,aAAK,WAAW,YAAY;AAC5B,aAAK,gBAAgB,KAAK,UAAU;AAAA,MACtC,OAAO;AACL,aAAK,YAAY;AACjB,aAAK,gBAAgB,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAgB,MAAM;AACpB,YAAM,iBAAiB,KAAK,iBAAiB,eAAe;AAC5D,iBAAW,MAAM,gBAAgB;AAC/B,cAAM,SAAS,GAAG,QAAQ;AAC1B,cAAM,CAAC,WAAW,WAAW,IAAI,OAAO,SAAS,GAAG,IAChD,OAAO,MAAM,GAAG,IAChB,CAAC,SAAS,MAAM;AAEpB,WAAG,iBAAiB,WAAW,CAAC,UAAU;AACxC,eAAK,cAAc,IAAI,YAAY,mBAAmB;AAAA,YACpD,SAAS;AAAA,YACT,QAAQ,EAAE,QAAQ,aAAa,OAAO,SAAS,GAAG;AAAA,UACpD,CAAC,CAAC;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,eAAe,OAAO,MAAM,eAAe;AAClD,SAAO;AACT;AAKO,SAAS,2BAA2B,UAAU;AACnD,SAAO;AAAA,IACL,iBAAiB,CAAC,MAAM,WAAW,YAAY,gBAAgB,MAAM,WAAW,OAAO;AAAA,EACzF;AACF;AAKO,SAAS,sBAAsB,MAAM,WAAW,UAAU,CAAC,GAAG;AACnE,SAAO,gBAAgB,MAAM,WAAW,OAAO;AACjD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coherent.js/web-components",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.7",
|
|
4
4
|
"description": "Web Components integration for Coherent.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": "Coherent.js Team",
|
|
17
17
|
"license": "MIT",
|
|
18
|
-
"
|
|
19
|
-
"@coherent.js/core": "1.0.0-beta.
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@coherent.js/core": "1.0.0-beta.7"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"vitest": "^3.2.4"
|
|
@@ -25,11 +25,20 @@
|
|
|
25
25
|
"type": "git",
|
|
26
26
|
"url": "git+https://github.com/Tomdrouv1/coherent.js.git"
|
|
27
27
|
},
|
|
28
|
+
"homepage": "https://github.com/Tomdrouv1/coherent.js",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/Tomdrouv1/coherent.js/issues"
|
|
31
|
+
},
|
|
28
32
|
"publishConfig": {
|
|
29
33
|
"access": "public"
|
|
30
34
|
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20.0.0"
|
|
37
|
+
},
|
|
31
38
|
"types": "./types/index.d.ts",
|
|
32
39
|
"files": [
|
|
40
|
+
"dist/",
|
|
41
|
+
"src/",
|
|
33
42
|
"LICENSE",
|
|
34
43
|
"README.md",
|
|
35
44
|
"types/"
|
package/src/index.js
CHANGED
|
@@ -7,10 +7,18 @@ import { render } from '@coherent.js/core';
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Define a Coherent.js component as a custom element
|
|
10
|
+
*
|
|
11
|
+
* @param {string} name - Custom element tag name (must contain a hyphen)
|
|
12
|
+
* @param {Function|Object} component - Coherent.js component (function or object)
|
|
13
|
+
* @param {Object} [options] - Configuration options
|
|
14
|
+
* @param {boolean} [options.shadow] - Use Shadow DOM for style encapsulation
|
|
15
|
+
* @param {string[]} [options.observedAttributes] - Attributes to watch for changes
|
|
16
|
+
* @param {Object} [options.defaults] - Default property values
|
|
17
|
+
* @returns {Function|Object} The custom element class, or a server-side placeholder
|
|
10
18
|
*/
|
|
11
19
|
export function defineComponent(name, component, options = {}) {
|
|
12
20
|
if (typeof window === 'undefined') {
|
|
13
|
-
// Server-side:
|
|
21
|
+
// Server-side: return a placeholder for SSR
|
|
14
22
|
return { name, component, options };
|
|
15
23
|
}
|
|
16
24
|
|
|
@@ -18,24 +26,104 @@ export function defineComponent(name, component, options = {}) {
|
|
|
18
26
|
throw new Error('Custom Elements API not supported');
|
|
19
27
|
}
|
|
20
28
|
|
|
29
|
+
const observedAttrs = options.observedAttributes || [];
|
|
30
|
+
const defaults = options.defaults || {};
|
|
31
|
+
|
|
21
32
|
class CoherentElement extends HTMLElement {
|
|
33
|
+
static get observedAttributes() {
|
|
34
|
+
return observedAttrs;
|
|
35
|
+
}
|
|
36
|
+
|
|
22
37
|
constructor() {
|
|
23
38
|
super();
|
|
39
|
+
this._props = { ...defaults };
|
|
40
|
+
this._connected = false;
|
|
24
41
|
this.component = component;
|
|
25
42
|
this.options = options;
|
|
26
43
|
}
|
|
27
44
|
|
|
28
45
|
connectedCallback() {
|
|
29
|
-
this.
|
|
46
|
+
this._connected = true;
|
|
47
|
+
// Copy initial attributes to props
|
|
48
|
+
for (const attr of observedAttrs) {
|
|
49
|
+
if (this.hasAttribute(attr)) {
|
|
50
|
+
this._props[attr] = this.getAttribute(attr);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
this._render();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
disconnectedCallback() {
|
|
57
|
+
this._connected = false;
|
|
58
|
+
// Cleanup: remove event listeners and clear content
|
|
59
|
+
if (options.shadow && this.shadowRoot) {
|
|
60
|
+
this.shadowRoot.innerHTML = '';
|
|
61
|
+
} else {
|
|
62
|
+
this.innerHTML = '';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
|
67
|
+
if (oldValue === newValue) return;
|
|
68
|
+
this._props[attrName] = newValue;
|
|
69
|
+
if (this._connected) {
|
|
70
|
+
this._render();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Set a property and re-render
|
|
76
|
+
*/
|
|
77
|
+
setProperty(key, value) {
|
|
78
|
+
this._props[key] = value;
|
|
79
|
+
if (this._connected) {
|
|
80
|
+
this._render();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get current props
|
|
86
|
+
*/
|
|
87
|
+
getProperties() {
|
|
88
|
+
return { ...this._props };
|
|
30
89
|
}
|
|
31
90
|
|
|
32
|
-
|
|
33
|
-
const
|
|
91
|
+
_render() {
|
|
92
|
+
const componentDef = typeof this.component === 'function'
|
|
93
|
+
? this.component(this._props)
|
|
94
|
+
: this.component;
|
|
95
|
+
|
|
96
|
+
const html = render(componentDef);
|
|
97
|
+
|
|
34
98
|
if (this.options.shadow) {
|
|
35
|
-
|
|
36
|
-
|
|
99
|
+
if (!this.shadowRoot) {
|
|
100
|
+
this.attachShadow({ mode: 'open' });
|
|
101
|
+
}
|
|
102
|
+
this.shadowRoot.innerHTML = html;
|
|
103
|
+
this._delegateEvents(this.shadowRoot);
|
|
37
104
|
} else {
|
|
38
105
|
this.innerHTML = html;
|
|
106
|
+
this._delegateEvents(this);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Delegate data-action events to component handlers
|
|
112
|
+
*/
|
|
113
|
+
_delegateEvents(root) {
|
|
114
|
+
const actionElements = root.querySelectorAll('[data-action]');
|
|
115
|
+
for (const el of actionElements) {
|
|
116
|
+
const action = el.dataset.action;
|
|
117
|
+
const [eventType, handlerName] = action.includes(':')
|
|
118
|
+
? action.split(':')
|
|
119
|
+
: ['click', action];
|
|
120
|
+
|
|
121
|
+
el.addEventListener(eventType, (event) => {
|
|
122
|
+
this.dispatchEvent(new CustomEvent('coherent-action', {
|
|
123
|
+
bubbles: true,
|
|
124
|
+
detail: { action: handlerName, event, element: el }
|
|
125
|
+
}));
|
|
126
|
+
});
|
|
39
127
|
}
|
|
40
128
|
}
|
|
41
129
|
}
|
|
@@ -45,7 +133,7 @@ export function defineComponent(name, component, options = {}) {
|
|
|
45
133
|
}
|
|
46
134
|
|
|
47
135
|
/**
|
|
48
|
-
* Integration utilities
|
|
136
|
+
* Integration utilities for runtime environments
|
|
49
137
|
*/
|
|
50
138
|
export function integrateWithWebComponents(_runtime) {
|
|
51
139
|
return {
|
|
@@ -53,6 +141,9 @@ export function integrateWithWebComponents(_runtime) {
|
|
|
53
141
|
};
|
|
54
142
|
}
|
|
55
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Alias for defineComponent
|
|
146
|
+
*/
|
|
56
147
|
export function defineCoherentElement(name, component, options = {}) {
|
|
57
148
|
return defineComponent(name, component, options);
|
|
58
149
|
}
|