@xtia/jel 0.4.0 → 0.4.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 +2 -6
- package/index.d.ts +27 -10
- package/index.js +31 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,9 +27,7 @@ body.append($.form([
|
|
|
27
27
|
$.button("Sign in"),
|
|
28
28
|
$.a({
|
|
29
29
|
content: ["Having trouble? ", $.strong("Recover account")],
|
|
30
|
-
|
|
31
|
-
href: "/recover-account",
|
|
32
|
-
}
|
|
30
|
+
href: "/recover-account",
|
|
33
31
|
})
|
|
34
32
|
]));
|
|
35
33
|
|
|
@@ -39,9 +37,7 @@ body.append([
|
|
|
39
37
|
files.map(file => $.li(
|
|
40
38
|
$.a({
|
|
41
39
|
content: file.name,
|
|
42
|
-
|
|
43
|
-
href: `/files/${file.name}`,
|
|
44
|
-
}
|
|
40
|
+
href: `/files/${file.name}`,
|
|
45
41
|
})
|
|
46
42
|
))
|
|
47
43
|
)
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type ElementClassDescriptor = string | Record<string, boolean> | ElementClassDescriptor[];
|
|
2
2
|
export type DOMContent = number | null | string | Element | JelEntity<object> | Text | DOMContent[];
|
|
3
3
|
export type DomEntity<T extends HTMLElement> = JelEntity<ElementAPI<T>>;
|
|
4
|
+
export type AppendableDomEntity = DomEntity<AppendableElement>;
|
|
5
|
+
type AppendableElement = HTMLElementTagNameMap[Exclude<keyof HTMLElementTagNameMap, ContentlessTag>];
|
|
4
6
|
type PartConstructor<Spec, API extends object | void, EventDataMap> = (spec: Spec & EventSpec<EventDataMap>) => JelEntity<EventHost<API, EventDataMap>>;
|
|
5
7
|
type EventSpec<EventDataMap> = EventDataMap extends object ? {
|
|
6
8
|
on?: {
|
|
@@ -18,19 +20,28 @@ type StylesDescriptor = {
|
|
|
18
20
|
] extends [string, string] ? K : never]+?: CSSValue;
|
|
19
21
|
};
|
|
20
22
|
type StyleAccessor = StylesDescriptor & ((styles: StylesDescriptor) => void) & ((property: keyof StylesDescriptor, value: CSSValue) => void);
|
|
21
|
-
|
|
23
|
+
type ContentlessTag = "area" | "base" | "basefont" | "br" | "col" | "frame" | "hr" | "img" | "input" | "isindex" | "link" | "meta" | "param" | "textarea";
|
|
24
|
+
type TagWithHref = "a" | "link";
|
|
25
|
+
type TagWithSrc = "img" | "script" | "iframe";
|
|
26
|
+
type ElementDescriptor<Tag extends string> = {
|
|
22
27
|
classes?: ElementClassDescriptor;
|
|
23
|
-
content?: DOMContent;
|
|
24
28
|
attribs?: Record<string, string | number | boolean>;
|
|
25
29
|
on?: {
|
|
26
30
|
[E in keyof HTMLElementEventMap]+?: (event: HTMLElementEventMap[E]) => void;
|
|
27
31
|
};
|
|
28
32
|
style?: StylesDescriptor;
|
|
29
33
|
cssVariables?: Record<string, CSSValue>;
|
|
30
|
-
}
|
|
34
|
+
} & (Tag extends "input" | "textarea" ? {
|
|
35
|
+
value?: string | number;
|
|
36
|
+
} : Tag extends ContentlessTag ? {} : {
|
|
37
|
+
content?: DOMContent;
|
|
38
|
+
}) & (Tag extends TagWithSrc ? {
|
|
39
|
+
src?: string;
|
|
40
|
+
} : Tag extends TagWithHref ? {
|
|
41
|
+
href?: string;
|
|
42
|
+
} : {});
|
|
31
43
|
type ElementAPI<T extends HTMLElement> = EventHost<{
|
|
32
44
|
readonly element: T;
|
|
33
|
-
content: DOMContent;
|
|
34
45
|
classes: DOMTokenList;
|
|
35
46
|
attribs: {
|
|
36
47
|
[key: string]: string | null;
|
|
@@ -45,18 +56,24 @@ type ElementAPI<T extends HTMLElement> = EventHost<{
|
|
|
45
56
|
getRect(): DOMRect;
|
|
46
57
|
focus(): void;
|
|
47
58
|
blur(): void;
|
|
48
|
-
} & (T extends
|
|
59
|
+
} & (T extends AppendableElement ? {
|
|
60
|
+
content: DOMContent;
|
|
61
|
+
} : {}) & (T extends HTMLInputElement ? {
|
|
49
62
|
value: string;
|
|
50
63
|
select(): void;
|
|
51
64
|
} : T extends HTMLCanvasElement ? {
|
|
52
65
|
width: number;
|
|
53
66
|
height: number;
|
|
54
67
|
getContext: HTMLCanvasElement["getContext"];
|
|
68
|
+
} : T extends HTMLElementTagNameMap[TagWithSrc] ? {
|
|
69
|
+
src: string;
|
|
70
|
+
} : T extends HTMLElementTagNameMap[TagWithHref] ? {
|
|
71
|
+
href: string;
|
|
55
72
|
} : {}), HTMLElementEventMap>;
|
|
56
|
-
type DomHelper = ((<T extends keyof HTMLElementTagNameMap>(tagName: T, descriptor: ElementDescriptor) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: `${T}#${string}`, content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: `${T}.${string}`, content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: T, content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends HTMLElement>(element: T) => DomEntity<T>) & {
|
|
57
|
-
[T in keyof HTMLElementTagNameMap]: (descriptor: ElementDescriptor) => DomEntity<HTMLElementTagNameMap[T]>;
|
|
73
|
+
type DomHelper = ((<T extends keyof HTMLElementTagNameMap>(tagName: T, descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: `${T}#${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: `${T}.${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends keyof HTMLElementTagNameMap>(selector: T, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & (<T extends HTMLElement>(element: T) => DomEntity<T>) & {
|
|
74
|
+
[T in keyof HTMLElementTagNameMap]: (descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>;
|
|
58
75
|
} & {
|
|
59
|
-
[T in keyof HTMLElementTagNameMap]: (content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>;
|
|
76
|
+
[T in keyof HTMLElementTagNameMap]: T extends ContentlessTag ? () => DomEntity<HTMLElementTagNameMap[T]> : (content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>;
|
|
60
77
|
});
|
|
61
78
|
type JelEntityData = {
|
|
62
79
|
dom: DOMContent;
|
|
@@ -74,6 +91,6 @@ type EventHost<API extends object | void, EventDataMap> = (API extends object ?
|
|
|
74
91
|
export declare const $: DomHelper;
|
|
75
92
|
declare const entityDataSymbol: unique symbol;
|
|
76
93
|
export declare function createEntity<API extends object>(content: DOMContent, api: API extends DOMContent ? never : API): JelEntity<API>;
|
|
77
|
-
export declare function createEntity(content: DOMContent
|
|
78
|
-
export declare function definePart<Spec extends ForbidKey<"on">, API extends ForbidKey<"on"> | void = void, EventDataMap extends Record<string, any> = {}>(defaultOptions: Optionals<Spec>, init: (spec: Required<Spec>, append: (content: DOMContent) => void, trigger: <K extends keyof EventDataMap>(eventId: K, eventData: EventDataMap[K]) => void) => API): PartConstructor<Spec, API, EventDataMap>;
|
|
94
|
+
export declare function createEntity(content: DOMContent): JelEntity<void>;
|
|
95
|
+
export declare function definePart<Spec extends ForbidKey<"on">, API extends ForbidKey<"on"> | void = void, EventDataMap extends Record<string, any> = {}>(defaultOptions: Optionals<Spec>, init: (spec: Required<Spec>, append: (...content: DOMContent[]) => void, trigger: <K extends keyof EventDataMap>(eventId: K, eventData: EventDataMap[K]) => void) => API): PartConstructor<Spec, API, EventDataMap>;
|
|
79
96
|
export {};
|
package/index.js
CHANGED
|
@@ -26,8 +26,11 @@ const styleProxy = {
|
|
|
26
26
|
};
|
|
27
27
|
function createElement(tag, descriptor = {}) {
|
|
28
28
|
if (isContent(descriptor))
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
return createElement(tag, {
|
|
30
|
+
content: descriptor,
|
|
31
|
+
});
|
|
32
|
+
const domElement = document.createElement(tag);
|
|
33
|
+
const ent = getWrappedElement(domElement);
|
|
31
34
|
const applyClasses = (classes) => {
|
|
32
35
|
if (Array.isArray(classes)) {
|
|
33
36
|
return classes.forEach(c => applyClasses(c));
|
|
@@ -42,16 +45,21 @@ function createElement(tag, descriptor = {}) {
|
|
|
42
45
|
});
|
|
43
46
|
};
|
|
44
47
|
applyClasses(descriptor.classes || []);
|
|
48
|
+
["value", "src", "href"].forEach(prop => {
|
|
49
|
+
if (descriptor[prop] !== undefined)
|
|
50
|
+
domElement.setAttribute(prop, descriptor[prop]);
|
|
51
|
+
});
|
|
52
|
+
// attribs.value / attribs.src / attribs.href override descriptor.*
|
|
45
53
|
if (descriptor.attribs) {
|
|
46
54
|
Object.entries(descriptor.attribs).forEach(([k, v]) => {
|
|
47
55
|
if (v === false) {
|
|
48
56
|
return;
|
|
49
57
|
}
|
|
50
|
-
|
|
58
|
+
domElement.setAttribute(k, v === true ? k : v);
|
|
51
59
|
});
|
|
52
60
|
}
|
|
53
61
|
if (descriptor.content !== undefined)
|
|
54
|
-
recursiveAppend(
|
|
62
|
+
recursiveAppend(domElement, descriptor.content);
|
|
55
63
|
if (descriptor.style) {
|
|
56
64
|
ent.style(descriptor.style);
|
|
57
65
|
}
|
|
@@ -205,6 +213,18 @@ function getWrappedElement(element) {
|
|
|
205
213
|
set value(v) {
|
|
206
214
|
element.value = v;
|
|
207
215
|
},
|
|
216
|
+
get href() {
|
|
217
|
+
return element.href;
|
|
218
|
+
},
|
|
219
|
+
set href(v) {
|
|
220
|
+
element.href = v;
|
|
221
|
+
},
|
|
222
|
+
get src() {
|
|
223
|
+
return element.src;
|
|
224
|
+
},
|
|
225
|
+
set src(v) {
|
|
226
|
+
element.src = v;
|
|
227
|
+
},
|
|
208
228
|
get width() {
|
|
209
229
|
return element.width;
|
|
210
230
|
},
|
|
@@ -252,6 +272,7 @@ function createEntity(content, api) {
|
|
|
252
272
|
;
|
|
253
273
|
function definePart(defaultOptions, init) {
|
|
254
274
|
return ((spec) => {
|
|
275
|
+
var _a;
|
|
255
276
|
const fullSpec = Object.assign(Object.assign({}, defaultOptions), spec);
|
|
256
277
|
const eventHandlers = {};
|
|
257
278
|
const addEventListener = (eventId, fn) => {
|
|
@@ -265,27 +286,21 @@ function definePart(defaultOptions, init) {
|
|
|
265
286
|
});
|
|
266
287
|
let entity;
|
|
267
288
|
const content = [];
|
|
268
|
-
const append = (c) => {
|
|
289
|
+
const append = (...c) => {
|
|
269
290
|
if (entity)
|
|
270
291
|
throw new Error("Component root content can only be added during initialisation");
|
|
271
|
-
content.push(c);
|
|
292
|
+
content.push(...c);
|
|
272
293
|
};
|
|
273
294
|
const trigger = (eventId, data) => {
|
|
274
295
|
var _a;
|
|
275
296
|
(_a = eventHandlers[eventId]) === null || _a === void 0 ? void 0 : _a.forEach(fn => fn.call(entity, data));
|
|
276
297
|
};
|
|
277
|
-
const api = init(fullSpec, append, trigger);
|
|
278
|
-
Object.
|
|
279
|
-
[entityDataSymbol]: {
|
|
280
|
-
value: {
|
|
281
|
-
dom: content
|
|
282
|
-
}
|
|
283
|
-
},
|
|
298
|
+
const api = (_a = init(fullSpec, append, trigger)) !== null && _a !== void 0 ? _a : {};
|
|
299
|
+
entity = createEntity(content, Object.create(api, {
|
|
284
300
|
on: {
|
|
285
|
-
|
|
301
|
+
value: addEventListener,
|
|
286
302
|
}
|
|
287
|
-
});
|
|
288
|
-
entity = api;
|
|
303
|
+
}));
|
|
289
304
|
return entity;
|
|
290
305
|
});
|
|
291
306
|
}
|