ecmact 1.0.2 → 2.0.0

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.
@@ -0,0 +1,28 @@
1
+ import { AttributeMap, GlobalAttributes } from './attributes';
2
+ export type TagName = keyof HTMLElementTagNameMap | (string & {});
3
+ type ElementOf<K extends string> = K extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[K] : HTMLElement;
4
+ type StyleProps = {
5
+ [P in keyof CSSStyleDeclaration as P extends string ? CSSStyleDeclaration[P] extends string ? P : never : never]?: string | number;
6
+ };
7
+ type EventHandlers = {
8
+ [E in keyof HTMLElementEventMap as `on${E}`]?: ((event: HTMLElementEventMap[E]) => void) | undefined;
9
+ };
10
+ interface BaseProps<K extends string> {
11
+ tag?: K;
12
+ content?: string;
13
+ html?: string;
14
+ style?: StyleProps;
15
+ children?: Node[];
16
+ ref?: (element: ElementOf<K>) => void;
17
+ }
18
+ type TagAttributes<K extends string> = K extends keyof AttributeMap ? AttributeMap[K] : K extends keyof HTMLElementTagNameMap ? unknown : {
19
+ [attribute: string]: unknown;
20
+ };
21
+ export type ComponentProps<K extends string = string> = BaseProps<K> & GlobalAttributes & EventHandlers & TagAttributes<K>;
22
+ export interface RenderState {
23
+ element: HTMLElement | null;
24
+ attributes: Set<string>;
25
+ styles: Set<string>;
26
+ listeners: Map<string, EventListener>;
27
+ }
28
+ export {};
@@ -0,0 +1,303 @@
1
+ export type Primitive = string | number | boolean | null | undefined;
2
+ type Size = number | string;
3
+ type Referrer = 'no-referrer' | 'no-referrer-when-downgrade' | 'origin' | 'origin-when-cross-origin' | 'same-origin' | 'strict-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url';
4
+ type CrossOrigin = 'anonymous' | 'use-credentials' | '';
5
+ type Target = '_self' | '_blank' | '_parent' | '_top' | (string & {});
6
+ type Preload = 'none' | 'metadata' | 'auto' | '';
7
+ export interface GlobalAttributes {
8
+ id?: string;
9
+ class?: string;
10
+ title?: string;
11
+ lang?: string;
12
+ dir?: 'ltr' | 'rtl' | 'auto';
13
+ hidden?: boolean | 'until-found';
14
+ inert?: boolean;
15
+ tabindex?: number;
16
+ role?: string;
17
+ slot?: string;
18
+ part?: string;
19
+ accesskey?: string;
20
+ translate?: 'yes' | 'no';
21
+ spellcheck?: 'true' | 'false';
22
+ draggable?: 'true' | 'false';
23
+ contenteditable?: 'true' | 'false' | 'plaintext-only' | '';
24
+ inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
25
+ [attribute: `data-${string}`]: Primitive;
26
+ [attribute: `aria-${string}`]: Primitive;
27
+ }
28
+ export interface AttributeMap {
29
+ a: {
30
+ href?: string;
31
+ target?: Target;
32
+ rel?: string;
33
+ download?: string | boolean;
34
+ hreflang?: string;
35
+ type?: string;
36
+ ping?: string;
37
+ referrerpolicy?: Referrer;
38
+ };
39
+ img: {
40
+ src?: string;
41
+ srcset?: string;
42
+ sizes?: string;
43
+ alt?: string;
44
+ width?: Size;
45
+ height?: Size;
46
+ loading?: 'eager' | 'lazy';
47
+ decoding?: 'sync' | 'async' | 'auto';
48
+ fetchpriority?: 'high' | 'low' | 'auto';
49
+ crossorigin?: CrossOrigin;
50
+ referrerpolicy?: Referrer;
51
+ usemap?: string;
52
+ ismap?: boolean;
53
+ };
54
+ input: {
55
+ type?: 'button' | 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'reset' | 'search' | 'submit' | 'tel' | 'text' | 'time' | 'url' | 'week';
56
+ name?: string;
57
+ value?: string | number;
58
+ placeholder?: string;
59
+ disabled?: boolean;
60
+ readonly?: boolean;
61
+ required?: boolean;
62
+ checked?: boolean;
63
+ multiple?: boolean;
64
+ autofocus?: boolean;
65
+ autocomplete?: string;
66
+ accept?: string;
67
+ min?: string | number;
68
+ max?: string | number;
69
+ step?: string | number;
70
+ minlength?: number;
71
+ maxlength?: number;
72
+ size?: number;
73
+ pattern?: string;
74
+ list?: string;
75
+ form?: string;
76
+ src?: string;
77
+ alt?: string;
78
+ width?: Size;
79
+ height?: Size;
80
+ };
81
+ button: {
82
+ type?: 'button' | 'submit' | 'reset';
83
+ name?: string;
84
+ value?: string;
85
+ disabled?: boolean;
86
+ autofocus?: boolean;
87
+ form?: string;
88
+ formaction?: string;
89
+ formmethod?: 'get' | 'post' | 'dialog';
90
+ formtarget?: Target;
91
+ formnovalidate?: boolean;
92
+ };
93
+ form: {
94
+ action?: string;
95
+ method?: 'get' | 'post' | 'dialog';
96
+ enctype?: string;
97
+ target?: Target;
98
+ name?: string;
99
+ novalidate?: boolean;
100
+ autocomplete?: string;
101
+ 'accept-charset'?: string;
102
+ };
103
+ label: {
104
+ for?: string;
105
+ form?: string;
106
+ };
107
+ select: {
108
+ name?: string;
109
+ disabled?: boolean;
110
+ multiple?: boolean;
111
+ required?: boolean;
112
+ autofocus?: boolean;
113
+ autocomplete?: string;
114
+ size?: number;
115
+ form?: string;
116
+ };
117
+ option: {
118
+ value?: string | number;
119
+ label?: string;
120
+ selected?: boolean;
121
+ disabled?: boolean;
122
+ };
123
+ optgroup: {
124
+ label?: string;
125
+ disabled?: boolean;
126
+ };
127
+ textarea: {
128
+ name?: string;
129
+ placeholder?: string;
130
+ rows?: number;
131
+ cols?: number;
132
+ wrap?: 'soft' | 'hard' | 'off';
133
+ disabled?: boolean;
134
+ readonly?: boolean;
135
+ required?: boolean;
136
+ autofocus?: boolean;
137
+ autocomplete?: string;
138
+ minlength?: number;
139
+ maxlength?: number;
140
+ form?: string;
141
+ };
142
+ fieldset: {
143
+ name?: string;
144
+ disabled?: boolean;
145
+ form?: string;
146
+ };
147
+ output: {
148
+ for?: string;
149
+ form?: string;
150
+ name?: string;
151
+ };
152
+ progress: {
153
+ value?: number;
154
+ max?: number;
155
+ };
156
+ meter: {
157
+ value?: number;
158
+ min?: number;
159
+ max?: number;
160
+ low?: number;
161
+ high?: number;
162
+ optimum?: number;
163
+ };
164
+ link: {
165
+ href?: string;
166
+ rel?: string;
167
+ type?: string;
168
+ media?: string;
169
+ as?: string;
170
+ sizes?: string;
171
+ hreflang?: string;
172
+ integrity?: string;
173
+ crossorigin?: CrossOrigin;
174
+ referrerpolicy?: Referrer;
175
+ };
176
+ script: {
177
+ src?: string;
178
+ type?: string;
179
+ async?: boolean;
180
+ defer?: boolean;
181
+ nomodule?: boolean;
182
+ integrity?: string;
183
+ crossorigin?: CrossOrigin;
184
+ referrerpolicy?: Referrer;
185
+ };
186
+ iframe: {
187
+ src?: string;
188
+ srcdoc?: string;
189
+ name?: string;
190
+ width?: Size;
191
+ height?: Size;
192
+ allow?: string;
193
+ allowfullscreen?: boolean;
194
+ sandbox?: string;
195
+ loading?: 'eager' | 'lazy';
196
+ referrerpolicy?: Referrer;
197
+ };
198
+ video: {
199
+ src?: string;
200
+ poster?: string;
201
+ width?: Size;
202
+ height?: Size;
203
+ controls?: boolean;
204
+ autoplay?: boolean;
205
+ loop?: boolean;
206
+ muted?: boolean;
207
+ playsinline?: boolean;
208
+ preload?: Preload;
209
+ crossorigin?: CrossOrigin;
210
+ };
211
+ audio: {
212
+ src?: string;
213
+ controls?: boolean;
214
+ autoplay?: boolean;
215
+ loop?: boolean;
216
+ muted?: boolean;
217
+ preload?: Preload;
218
+ crossorigin?: CrossOrigin;
219
+ };
220
+ source: {
221
+ src?: string;
222
+ srcset?: string;
223
+ sizes?: string;
224
+ type?: string;
225
+ media?: string;
226
+ width?: Size;
227
+ height?: Size;
228
+ };
229
+ canvas: {
230
+ width?: Size;
231
+ height?: Size;
232
+ };
233
+ td: {
234
+ colspan?: number;
235
+ rowspan?: number;
236
+ headers?: string;
237
+ };
238
+ th: {
239
+ colspan?: number;
240
+ rowspan?: number;
241
+ headers?: string;
242
+ scope?: string;
243
+ abbr?: string;
244
+ };
245
+ col: {
246
+ span?: number;
247
+ };
248
+ colgroup: {
249
+ span?: number;
250
+ };
251
+ ol: {
252
+ start?: number;
253
+ reversed?: boolean;
254
+ type?: '1' | 'a' | 'A' | 'i' | 'I';
255
+ };
256
+ li: {
257
+ value?: number;
258
+ };
259
+ details: {
260
+ open?: boolean;
261
+ name?: string;
262
+ };
263
+ dialog: {
264
+ open?: boolean;
265
+ };
266
+ blockquote: {
267
+ cite?: string;
268
+ };
269
+ q: {
270
+ cite?: string;
271
+ };
272
+ time: {
273
+ datetime?: string;
274
+ };
275
+ meta: {
276
+ name?: string;
277
+ content?: string;
278
+ charset?: string;
279
+ 'http-equiv'?: string;
280
+ };
281
+ track: {
282
+ src?: string;
283
+ kind?: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';
284
+ srclang?: string;
285
+ label?: string;
286
+ default?: boolean;
287
+ };
288
+ slot: {
289
+ name?: string;
290
+ };
291
+ data: {
292
+ value?: string;
293
+ };
294
+ del: {
295
+ cite?: string;
296
+ datetime?: string;
297
+ };
298
+ ins: {
299
+ cite?: string;
300
+ datetime?: string;
301
+ };
302
+ }
303
+ export {};
@@ -1,2 +1,2 @@
1
- export { em } from './em';
2
- export { mount } from './utils';
1
+ export type { AttributeMap, GlobalAttributes } from './attributes';
2
+ export type { ComponentProps, RenderState, TagName } from './BaseComponent';
@@ -0,0 +1,2 @@
1
+ import { ComponentProps } from '../types';
2
+ export declare const applyStyle: (element: HTMLElement, style: ComponentProps["style"], previous: Set<string>) => Set<string>;
@@ -1,5 +1,5 @@
1
- export { setEventListeners } from './setEventListeners';
2
- export { generateStyle } from './generateStyle';
3
- export { generateAttributes } from './generateAttributes';
4
- export { render } from './render';
1
+ export { applyStyle } from './applyStyle';
5
2
  export { mount } from './mount';
3
+ export { render } from './render';
4
+ export { setEventListeners } from './setEventListeners';
5
+ export { syncAttributes } from './syncAttributes';
@@ -0,0 +1 @@
1
+ export declare const mount: (target: string | Element, ...nodes: Node[]) => Element;
@@ -0,0 +1,2 @@
1
+ import { ComponentProps, RenderState } from '../types';
2
+ export declare const render: (root: ShadowRoot, props: ComponentProps, state: RenderState) => HTMLElement;
@@ -0,0 +1,2 @@
1
+ import { ComponentProps } from '../types';
2
+ export declare const setEventListeners: (element: HTMLElement, props: ComponentProps, previous: Map<string, EventListener>) => Map<string, EventListener>;
@@ -0,0 +1,2 @@
1
+ import { ComponentProps } from '../types';
2
+ export declare const syncAttributes: (element: HTMLElement, props: ComponentProps, previous: Set<string>) => Set<string>;
package/package.json CHANGED
@@ -1,30 +1,33 @@
1
1
  {
2
2
  "name": "ecmact",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
4
  "description": "Dynamic components library using Vite Vanilla and Web Components",
5
- "main": "dist/index.cjs.js",
6
- "module": "dist/index.es.js",
7
- "types": "dist/types/index.d.ts",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
8
  "type": "module",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./dist/index.es.js",
12
- "require": "./dist/index.cjs.js",
13
- "types": "./dist/types/index.d.ts"
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
14
  }
15
15
  },
16
16
  "files": [
17
17
  "dist"
18
18
  ],
19
19
  "engines": {
20
- "node": ">=22.0.0"
20
+ "node": ">=22.12.0"
21
21
  },
22
22
  "scripts": {
23
23
  "build": "vite build",
24
- "test": "vitest",
25
- "lint": "eslint . --ext .ts --fix",
26
- "format": "prettier --write \"src/**/*.{ts,js,json,css,md}\"",
27
- "release": "npm publish --access public"
24
+ "typecheck": "tsc",
25
+ "test": "vitest run --coverage",
26
+ "lint": "eslint .",
27
+ "lint:fix": "eslint . --fix",
28
+ "format": "prettier --write .",
29
+ "format:check": "prettier --check .",
30
+ "prepublishOnly": "npm run build"
28
31
  },
29
32
  "keywords": [
30
33
  "vite",
@@ -36,15 +39,35 @@
36
39
  "author": "Alexandr Priadchenko",
37
40
  "license": "MIT",
38
41
  "devDependencies": {
39
- "eslint-plugin-prettier": "^5.2.5",
40
- "jiti": "^2.4.2",
41
- "prettier": "^3.5.3",
42
- "typescript-eslint": "^8.28.0",
43
- "vite": "^6.2.4",
44
- "vite-plugin-dts": "^4.5.3"
42
+ "@eslint/js": "^10.0.1",
43
+ "@types/node": "^22.20.5",
44
+ "@vitest/coverage-v8": "^5.1.0",
45
+ "eslint": "^10.14.0",
46
+ "eslint-config-prettier": "^10.1.8",
47
+ "eslint-plugin-prettier": "^5.5.7",
48
+ "happy-dom": "^21.0.4",
49
+ "jiti": "^2.7.0",
50
+ "prettier": "^3.9.10",
51
+ "typescript": "~6.0.3",
52
+ "typescript-eslint": "^8.72.1",
53
+ "vite": "^8.3.6",
54
+ "vite-plugin-dts": "^5.1.2",
55
+ "vitest": "^5.1.0"
45
56
  },
46
57
  "repository": {
47
58
  "type": "git",
48
59
  "url": "https://github.com/eternalvision/ecmact.git"
60
+ },
61
+ "sideEffects": false,
62
+ "bugs": {
63
+ "url": "https://github.com/eternalvision/ecmact/issues"
64
+ },
65
+ "homepage": "https://github.com/eternalvision/ecmact#readme",
66
+ "publishConfig": {
67
+ "access": "public",
68
+ "provenance": true
69
+ },
70
+ "overrides": {
71
+ "minimatch": "^11.0.1"
49
72
  }
50
73
  }
package/dist/cjs/index.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=({props:s,shadowRoot:t})=>{Object.entries(s).forEach(([e,n])=>{if(e.startsWith("on")&&typeof n=="function"){const o=e.slice(2).toLowerCase();t.querySelector(s.tag||"div")?.addEventListener(o,n)}})},p=({style:s,tag:t})=>{if(Object.keys(s).length===0)return"";const e=Object.entries(s).map(([n,o])=>`${n.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${o};`).join(" ");return`<style>${t} { ${e} }</style>`},l=({props:s})=>Object.entries(s).filter(([t])=>!["content","tag","style","children"].includes(t)&&!t.startsWith("on")).map(([t,e])=>`${t}="${e}"`).join(" "),h=({props:s,shadowRoot:t,generateStyle:e})=>{const{content:n="",tag:o="div",children:r=[]}=s;t.innerHTML=`
2
- ${e()}
3
- <${o} ${l({props:s})}>
4
- ${n.length>0?n:""}
5
- ${r.length>0?"<slot></slot>":""}
6
- </${o}>
7
- `;const c=t.querySelector("slot");r.forEach(i=>c.appendChild(i))},d=(s,...t)=>{const e=document.querySelector(s);e&&e.append(...t)};class u extends HTMLElement{_props;constructor(t={}){super(),this.attachShadow({mode:"open"}),this._props=t}#t(){return a({props:this.props,shadowRoot:this.shadowRoot})}#s(){const{style:t={},tag:e="div"}=this.props;return p({style:t,tag:e})}#e(){return h({props:this._props,shadowRoot:this.shadowRoot,generateStyle:()=>this.#s()})}connectedCallback(){this.#e(),this.#t()}setState(t){this.props={...this._props,...t}}get props(){return this._props}set props(t){this._props=t,this.#e(),this.#t()}}const m=new Proxy({},{get(s,t){const e=`em-${t.toLowerCase()}`;return customElements.get(e)||customElements.define(e,class extends u{constructor(n){super(n)}}),n=>{const o=document.createElement(e);return o.props=n,o}}});exports.em=m;exports.mount=d;
8
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/setEventListeners.ts","../../src/utils/generateStyle.ts","../../src/utils/generateAttributes.ts","../../src/utils/render.ts","../../src/utils/mount.ts","../../src/component.ts","../../src/em.ts"],"sourcesContent":["export const setEventListeners = ({ props, shadowRoot }) => {\n Object.entries(props).forEach(([key, value]) => {\n if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase();\n shadowRoot.querySelector(props.tag || 'div')?.addEventListener(event, value);\n }\n });\n};\n","export const generateStyle = ({ style, tag }) => {\n if (Object.keys(style).length === 0) return '';\n\n const css = Object.entries(style)\n .map(([key, value]) => `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)\n .join(' ');\n\n return `<style>${tag} { ${css} }</style>`;\n};\n","export const generateAttributes = ({ props }) =>\n Object.entries(props)\n .filter(\n ([key]) => !['content', 'tag', 'style', 'children'].includes(key) && !key.startsWith('on'),\n )\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join(' ');\n","import { generateAttributes } from './generateAttributes';\n\nexport const render = ({ props, shadowRoot, generateStyle }) => {\n const { content = '', tag = 'div', children = [] } = props;\n\n shadowRoot!.innerHTML = `\n ${generateStyle()}\n <${tag} ${generateAttributes({ props })}>\n ${content.length > 0 ? content : ''}\n ${children.length > 0 ? `<slot></slot>` : ''}\n </${tag}>\n `;\n\n const slot = shadowRoot!.querySelector('slot') as HTMLSlotElement;\n children.forEach((child: any) => slot.appendChild(child));\n};\n","export const mount = (elementId: string, ...nodes: Node[]) => {\n const container = document.querySelector(elementId);\n if (container) container.append(...nodes);\n};\n","import type { ComponentProps } from '@types';\nimport { setEventListeners, generateStyle, render } from '@utils';\n\nexport class component extends HTMLElement {\n private _props: ComponentProps;\n\n constructor(props: ComponentProps = {}) {\n super();\n this.attachShadow({ mode: 'open' });\n this._props = props;\n }\n\n #setEventListeners() {\n return setEventListeners({\n props: this.props,\n shadowRoot: this.shadowRoot,\n });\n }\n\n #generateStyle() {\n const { style = {}, tag = 'div' } = this.props;\n return generateStyle({ style, tag });\n }\n\n #render() {\n return render({\n props: this._props,\n shadowRoot: this.shadowRoot,\n generateStyle: () => this.#generateStyle(),\n });\n }\n\n connectedCallback() {\n this.#render();\n this.#setEventListeners();\n }\n\n setState(newProps: Partial<ComponentProps>) {\n this.props = {\n ...this._props,\n ...newProps,\n };\n }\n\n get props() {\n return this._props;\n }\n\n set props(newProps: ComponentProps) {\n this._props = newProps;\n this.#render();\n this.#setEventListeners();\n }\n}\n","import { component } from './component';\nimport type { ComponentProps } from '@types';\n\ninterface ComponentRegistry {\n [key: string]: (props: ComponentProps) => component;\n}\n\nconst em: ComponentRegistry = new Proxy({} as ComponentRegistry, {\n get(_, prop: string) {\n const tagName = `em-${prop.toLowerCase()}`;\n\n if (!customElements.get(tagName)) {\n customElements.define(\n tagName,\n class extends component {\n constructor(props: ComponentProps) {\n super(props);\n }\n },\n );\n }\n\n return (props: ComponentProps): component => {\n const element = document.createElement(tagName) as component;\n element.props = props;\n return element;\n };\n },\n});\n\nexport { em };\n"],"names":["setEventListeners","props","shadowRoot","key","value","event","generateStyle","style","tag","css","generateAttributes","render","content","children","slot","child","mount","elementId","nodes","container","component","#setEventListeners","#generateStyle","#render","newProps","em","_","prop","tagName","element"],"mappings":"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"}
package/dist/es/index.js DELETED
@@ -1,87 +0,0 @@
1
- const p = ({ props: s, shadowRoot: t }) => {
2
- Object.entries(s).forEach(([e, n]) => {
3
- if (e.startsWith("on") && typeof n == "function") {
4
- const o = e.slice(2).toLowerCase();
5
- t.querySelector(s.tag || "div")?.addEventListener(o, n);
6
- }
7
- });
8
- }, a = ({ style: s, tag: t }) => {
9
- if (Object.keys(s).length === 0) return "";
10
- const e = Object.entries(s).map(([n, o]) => `${n.replace(/([A-Z])/g, "-$1").toLowerCase()}: ${o};`).join(" ");
11
- return `<style>${t} { ${e} }</style>`;
12
- }, h = ({ props: s }) => Object.entries(s).filter(
13
- ([t]) => !["content", "tag", "style", "children"].includes(t) && !t.startsWith("on")
14
- ).map(([t, e]) => `${t}="${e}"`).join(" "), l = ({ props: s, shadowRoot: t, generateStyle: e }) => {
15
- const { content: n = "", tag: o = "div", children: r = [] } = s;
16
- t.innerHTML = `
17
- ${e()}
18
- <${o} ${h({ props: s })}>
19
- ${n.length > 0 ? n : ""}
20
- ${r.length > 0 ? "<slot></slot>" : ""}
21
- </${o}>
22
- `;
23
- const c = t.querySelector("slot");
24
- r.forEach((i) => c.appendChild(i));
25
- }, u = (s, ...t) => {
26
- const e = document.querySelector(s);
27
- e && e.append(...t);
28
- };
29
- class d extends HTMLElement {
30
- _props;
31
- constructor(t = {}) {
32
- super(), this.attachShadow({ mode: "open" }), this._props = t;
33
- }
34
- #t() {
35
- return p({
36
- props: this.props,
37
- shadowRoot: this.shadowRoot
38
- });
39
- }
40
- #s() {
41
- const { style: t = {}, tag: e = "div" } = this.props;
42
- return a({ style: t, tag: e });
43
- }
44
- #e() {
45
- return l({
46
- props: this._props,
47
- shadowRoot: this.shadowRoot,
48
- generateStyle: () => this.#s()
49
- });
50
- }
51
- connectedCallback() {
52
- this.#e(), this.#t();
53
- }
54
- setState(t) {
55
- this.props = {
56
- ...this._props,
57
- ...t
58
- };
59
- }
60
- get props() {
61
- return this._props;
62
- }
63
- set props(t) {
64
- this._props = t, this.#e(), this.#t();
65
- }
66
- }
67
- const m = new Proxy({}, {
68
- get(s, t) {
69
- const e = `em-${t.toLowerCase()}`;
70
- return customElements.get(e) || customElements.define(
71
- e,
72
- class extends d {
73
- constructor(n) {
74
- super(n);
75
- }
76
- }
77
- ), (n) => {
78
- const o = document.createElement(e);
79
- return o.props = n, o;
80
- };
81
- }
82
- });
83
- export {
84
- m as em,
85
- u as mount
86
- };
87
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/setEventListeners.ts","../../src/utils/generateStyle.ts","../../src/utils/generateAttributes.ts","../../src/utils/render.ts","../../src/utils/mount.ts","../../src/component.ts","../../src/em.ts"],"sourcesContent":["export const setEventListeners = ({ props, shadowRoot }) => {\n Object.entries(props).forEach(([key, value]) => {\n if (key.startsWith('on') && typeof value === 'function') {\n const event = key.slice(2).toLowerCase();\n shadowRoot.querySelector(props.tag || 'div')?.addEventListener(event, value);\n }\n });\n};\n","export const generateStyle = ({ style, tag }) => {\n if (Object.keys(style).length === 0) return '';\n\n const css = Object.entries(style)\n .map(([key, value]) => `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)\n .join(' ');\n\n return `<style>${tag} { ${css} }</style>`;\n};\n","export const generateAttributes = ({ props }) =>\n Object.entries(props)\n .filter(\n ([key]) => !['content', 'tag', 'style', 'children'].includes(key) && !key.startsWith('on'),\n )\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join(' ');\n","import { generateAttributes } from './generateAttributes';\n\nexport const render = ({ props, shadowRoot, generateStyle }) => {\n const { content = '', tag = 'div', children = [] } = props;\n\n shadowRoot!.innerHTML = `\n ${generateStyle()}\n <${tag} ${generateAttributes({ props })}>\n ${content.length > 0 ? content : ''}\n ${children.length > 0 ? `<slot></slot>` : ''}\n </${tag}>\n `;\n\n const slot = shadowRoot!.querySelector('slot') as HTMLSlotElement;\n children.forEach((child: any) => slot.appendChild(child));\n};\n","export const mount = (elementId: string, ...nodes: Node[]) => {\n const container = document.querySelector(elementId);\n if (container) container.append(...nodes);\n};\n","import type { ComponentProps } from '@types';\nimport { setEventListeners, generateStyle, render } from '@utils';\n\nexport class component extends HTMLElement {\n private _props: ComponentProps;\n\n constructor(props: ComponentProps = {}) {\n super();\n this.attachShadow({ mode: 'open' });\n this._props = props;\n }\n\n #setEventListeners() {\n return setEventListeners({\n props: this.props,\n shadowRoot: this.shadowRoot,\n });\n }\n\n #generateStyle() {\n const { style = {}, tag = 'div' } = this.props;\n return generateStyle({ style, tag });\n }\n\n #render() {\n return render({\n props: this._props,\n shadowRoot: this.shadowRoot,\n generateStyle: () => this.#generateStyle(),\n });\n }\n\n connectedCallback() {\n this.#render();\n this.#setEventListeners();\n }\n\n setState(newProps: Partial<ComponentProps>) {\n this.props = {\n ...this._props,\n ...newProps,\n };\n }\n\n get props() {\n return this._props;\n }\n\n set props(newProps: ComponentProps) {\n this._props = newProps;\n this.#render();\n this.#setEventListeners();\n }\n}\n","import { component } from './component';\nimport type { ComponentProps } from '@types';\n\ninterface ComponentRegistry {\n [key: string]: (props: ComponentProps) => component;\n}\n\nconst em: ComponentRegistry = new Proxy({} as ComponentRegistry, {\n get(_, prop: string) {\n const tagName = `em-${prop.toLowerCase()}`;\n\n if (!customElements.get(tagName)) {\n customElements.define(\n tagName,\n class extends component {\n constructor(props: ComponentProps) {\n super(props);\n }\n },\n );\n }\n\n return (props: ComponentProps): component => {\n const element = document.createElement(tagName) as component;\n element.props = props;\n return element;\n };\n },\n});\n\nexport { em };\n"],"names":["setEventListeners","props","shadowRoot","key","value","event","generateStyle","style","tag","css","generateAttributes","render","content","children","slot","child","mount","elementId","nodes","container","component","#setEventListeners","#generateStyle","#render","newProps","em","_","prop","tagName","element"],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import { ComponentProps } from './types';
2
- export declare class component extends HTMLElement {
3
- #private;
4
- private _props;
5
- constructor(props?: ComponentProps);
6
- connectedCallback(): void;
7
- setState(newProps: Partial<ComponentProps>): void;
8
- get props(): ComponentProps;
9
- set props(newProps: ComponentProps);
10
- }
@@ -1,7 +0,0 @@
1
- import { component } from './component';
2
- import { ComponentProps } from './types';
3
- interface ComponentRegistry {
4
- [key: string]: (props: ComponentProps) => component;
5
- }
6
- declare const em: ComponentRegistry;
7
- export { em };
@@ -1,10 +0,0 @@
1
- export interface ComponentProps {
2
- content?: string;
3
- tag?: string;
4
- style?: Partial<CSSStyleDeclaration>;
5
- children?: HTMLElement[];
6
- slots?: Record<string, string>;
7
- ref?: (element: HTMLElement) => void;
8
- customEvents?: Record<string, (event: Event) => void>;
9
- [key: string]: any;
10
- }
@@ -1 +0,0 @@
1
- export type { ComponentProps } from './BaseComponent';
@@ -1,3 +0,0 @@
1
- export declare const generateAttributes: ({ props }: {
2
- props: any;
3
- }) => string;
@@ -1,4 +0,0 @@
1
- export declare const generateStyle: ({ style, tag }: {
2
- style: any;
3
- tag: any;
4
- }) => string;
@@ -1 +0,0 @@
1
- export declare const mount: (elementId: string, ...nodes: Node[]) => void;
@@ -1,5 +0,0 @@
1
- export declare const render: ({ props, shadowRoot, generateStyle }: {
2
- props: any;
3
- shadowRoot: any;
4
- generateStyle: any;
5
- }) => void;
@@ -1,4 +0,0 @@
1
- export declare const setEventListeners: ({ props, shadowRoot }: {
2
- props: any;
3
- shadowRoot: any;
4
- }) => void;