Skip to content

Commit 335a9ca

Browse files
committed
Merge branch 'main' into copyright
2 parents 6c073e4 + 8088622 commit 335a9ca

8 files changed

Lines changed: 211 additions & 78 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,35 @@ jobs:
8282
- name: Copy package.json to build package
8383
run: cp package.json package/package
8484

85-
- name: Publish to NPM
85+
- name: Publish release to NPM
86+
if: "!github.event.release.prerelease"
8687
working-directory: ./package/package
8788
run: npm publish --provenance --access public
8889
env:
8990
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
9091

92+
- name: Publish release candidate to NPM
93+
if: github.event.release.prerelease
94+
working-directory: ./package/package
95+
run: npm publish --provenance --access public --tag rc
96+
env:
97+
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
98+
9199
- name: Generate docs
100+
if: "!github.event.release.prerelease"
92101
run: npm run docs
93102

94103
- name: Set up GitHub pages
104+
if: "!github.event.release.prerelease"
95105
uses: actions/configure-pages@v4
96106

97107
- name: Upload docs artifact to pages
108+
if: "!github.event.release.prerelease"
98109
uses: actions/upload-pages-artifact@v3
99110
with:
100111
path: docs
101112

102113
- name: Deploy to GitHub Pages
114+
if: "!github.event.release.prerelease"
103115
id: deployment
104116
uses: actions/deploy-pages@v4

‎package-lock.json‎

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/Component.ts‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,23 @@
1414
* You should have received a copy of the GNU Lesser General Public License along with @cldn/components.
1515
* If not, see <https://www.gnu.org/licenses/>.
1616
*/
17-
import {BaseComponent} from "./index.js";
17+
import {ElementComponent} from "./index.js";
1818

1919
type ElementToTagName<T extends HTMLElement> = {
2020
[K in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[K] extends T ? K : never
2121
}[keyof HTMLElementTagNameMap];
2222

23+
type HtmlTagString<T extends HTMLElement> =
24+
`<${{ [K in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[K] extends T ? K : never }[keyof HTMLElementTagNameMap]}>${string}`
25+
| `<${{ [K in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[K] extends T ? K : never }[keyof HTMLElementTagNameMap]} ${string}`;
26+
2327
/**
2428
* An {@link !HTMLElement} component.
2529
*
2630
* To create your own HTML component, it's recommended to extend this class.
2731
* @typeParam T Component element type
2832
*/
29-
export class Component<T extends HTMLElement = HTMLElement> extends BaseComponent<T> {
33+
export class Component<T extends HTMLElement = HTMLElement> extends ElementComponent<T> {
3034
/**
3135
* Create Component instance
3236
* @param element Instance or tag name
@@ -44,7 +48,7 @@ export class Component<T extends HTMLElement = HTMLElement> extends BaseComponen
4448
*
4549
* Note: only the first child of the HTML code will be used.
4650
*/
47-
public static from<T extends HTMLElement = HTMLElement>(html: `<${ElementToTagName<T>}${">" | " "}${string}`) {
51+
public static from<T extends HTMLElement = HTMLElement>(html: HtmlTagString<T>) {
4852
return new Component<T>(document.createRange().createContextualFragment(html).children[0] as T);
4953
}
5054

@@ -57,7 +61,7 @@ export class Component<T extends HTMLElement = HTMLElement> extends BaseComponen
5761
* @typeParam T Component element type
5862
*/
5963
public select<T extends HTMLElement = HTMLElement>(selectors: string): Component<T> | null {
60-
const element = this.element.querySelector<T>(selectors);
64+
const element = this.node.querySelector<T>(selectors);
6165
if (element == null) return null;
6266
return new Component<T>(element);
6367
}
@@ -70,7 +74,7 @@ export class Component<T extends HTMLElement = HTMLElement> extends BaseComponen
7074
* @typeParam T Component element type
7175
*/
7276
public selectAll<T extends HTMLElement = HTMLElement>(selectors: string): Component<T>[] {
73-
return [...this.element.querySelectorAll<T>(selectors)].map(e => new Component<T>(e));
77+
return [...this.node.querySelectorAll<T>(selectors)].map(e => new Component<T>(e));
7478
}
7579

7680
/**
@@ -99,7 +103,7 @@ export class Component<T extends HTMLElement = HTMLElement> extends BaseComponen
99103
const name: string = args[0];
100104
const value: string = args[1];
101105
const priority: boolean = args[2] ?? false;
102-
this.element.style.setProperty(name, value, priority ? "important" : void 0);
106+
this.node.style.setProperty(name, value, priority ? "important" : undefined);
103107
}
104108
else {
105109
const properties: Record<string, string> = args[0];
@@ -109,7 +113,10 @@ export class Component<T extends HTMLElement = HTMLElement> extends BaseComponen
109113
return this;
110114
}
111115

112-
public override on<K extends keyof HTMLElementEventMap>(type: K, listener: (ev: HTMLElementEventMap[K], component: this) => any, options?: boolean | AddEventListenerOptions) {
113-
return super.on(type as any, listener, options);
116+
public override on<K extends keyof HTMLElementEventMap>(type: K, listener: (ev: HTMLElementEventMap[K], component: this) => any): typeof this;
117+
public override on<K extends keyof HTMLElementEventMap>(type: K, listener: (ev: HTMLElementEventMap[K], component: this) => any, options: AddEventListenerOptions): typeof this;
118+
public override on<K extends keyof HTMLElementEventMap>(type: K, listener: (ev: HTMLElementEventMap[K], component: this) => any, useCapture: boolean): typeof this;
119+
public override on<K extends keyof HTMLElementEventMap>(type: K, listener: (ev: HTMLElementEventMap[K], component: this) => any, c?: boolean | AddEventListenerOptions): typeof this {
120+
return super.on(type as any, listener, c as any);
114121
}
115122
}
Lines changed: 37 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,63 @@
1414
* You should have received a copy of the GNU Lesser General Public License along with @cldn/components.
1515
* If not, see <https://www.gnu.org/licenses/>.
1616
*/
17+
import {NodeComponent} from "./NodeComponent.js";
1718

1819
/**
1920
* Non-readonly non-method keys
2021
*/
21-
type WritableKeys<T> = Extract<
22-
{
23-
[Prop in keyof T]: (
24-
(<G>() => G extends Pick<T, Prop> ? 1 : 2) extends
25-
(<G>() => G extends Record<Prop, T[Prop]> ? 1 : 2)
26-
? true
27-
: false
22+
type WritableKeys<T> = {
23+
[Prop in keyof T]: (
24+
(<G>() => G extends Pick<T, Prop> ? 1 : 2) extends (
25+
<G>() => G extends Record<Prop, T[Prop]> ? 1 : 2
26+
) ? true : false
2827
) extends false
2928
? never
30-
: Prop;
31-
}[keyof T],
32-
{
33-
[K in keyof T]: T[K] extends Function ? never : K;
34-
}[keyof T]
35-
>;
29+
: (T[Prop] extends Function | null | undefined ? never : Prop);
30+
}[keyof T];
31+
32+
/**
33+
* Non-method keys
34+
*/
35+
type ReadableKeys<T> = {
36+
[Prop in keyof T]: T[Prop] extends Function | null | undefined ? never : Prop;
37+
}[keyof T];
3638

3739

3840
/**
3941
* An {@link !Element} component
4042
* @typeParam T Component element type
4143
*/
42-
export abstract class BaseComponent<T extends Element> {
43-
/**
44-
* This component's element
45-
*/
46-
public readonly element: T;
47-
44+
export abstract class ElementComponent<T extends Element> extends NodeComponent<T> {
4845
/**
4946
* @param element Initial element for this component
5047
* @protected
5148
*/
5249
protected constructor(element: T) {
53-
this.element = element;
54-
}
55-
56-
/**
57-
* Insert component after the last child
58-
*/
59-
public append(...components: BaseComponent<any>[]) {
60-
components.forEach((component) => this.element.appendChild(component.element))
61-
return this;
50+
super(element);
6251
}
6352

6453
/**
6554
* Insert component before the first child
6655
*/
67-
public prepend(...components: BaseComponent<any>[]) {
68-
components.forEach((component) => this.element.prepend(component.element))
56+
public prepend(...components: NodeComponent<any>[]) {
57+
components.forEach((component) => this.node.prepend(component.node))
6958
return this;
7059
}
7160

7261
/**
7362
* Add classes
7463
*/
7564
public class(...classes: string[]) {
76-
this.element.classList.add(...classes.flatMap(c => c.split(" ")));
65+
this.node.classList.add(...classes.flatMap(c => c.split(" ")));
7766
return this;
7867
}
7968

8069
/**
8170
* Remove classes
8271
*/
8372
public removeClass(...classes: string[]) {
84-
this.element.classList.remove(...classes.flatMap(c => c.split(" ")));
73+
this.node.classList.remove(...classes.flatMap(c => c.split(" ")));
8574
return this;
8675
}
8776

@@ -90,7 +79,7 @@ export abstract class BaseComponent<T extends Element> {
9079
*/
9180
public toggleClass(...classes: string[]) {
9281
for (const c of new Set(classes.flatMap(c => c.split(" "))))
93-
this.element.classList.toggle(c);
82+
this.node.classList.toggle(c);
9483
return this;
9584
}
9685

@@ -115,7 +104,7 @@ export abstract class BaseComponent<T extends Element> {
115104
* @returns true if component has all the specified classes
116105
*/
117106
public hasClass(...classes: string[]) {
118-
return classes.every(c => this.element.classList.contains(c));
107+
return classes.every(c => this.node.classList.contains(c));
119108
}
120109

121110
/**
@@ -124,7 +113,7 @@ export abstract class BaseComponent<T extends Element> {
124113
* @param [value] attribute value
125114
*/
126115
public attr(name: string, value?: string) {
127-
this.element.setAttribute(name, value ?? "");
116+
this.node.setAttribute(name, value ?? "");
128117
return this;
129118
}
130119

@@ -133,23 +122,15 @@ export abstract class BaseComponent<T extends Element> {
133122
* @param name attribute name
134123
*/
135124
public removeAttr(name: string) {
136-
this.element.removeAttribute(name);
137-
return this;
138-
}
139-
140-
/**
141-
* Set text content
142-
*/
143-
public text(text: string) {
144-
this.element.textContent = text;
125+
this.node.removeAttribute(name);
145126
return this;
146127
}
147128

148129
/**
149130
* Set inner HTML
150131
*/
151132
public html(html: string) {
152-
this.element.innerHTML = html;
133+
this.node.innerHTML = html;
153134
return this;
154135
}
155136

@@ -159,41 +140,37 @@ export abstract class BaseComponent<T extends Element> {
159140
* @param value property value
160141
*/
161142
public set<K extends WritableKeys<T>>(name: K, value: T[K]) {
162-
this.element[name] = value;
143+
this.node[name] = value;
163144
return this;
164145
}
165146

166147
/**
167148
* Get element property
168149
* @param name property name
169150
*/
170-
public get<K extends WritableKeys<T>>(name: K): T[K] {
171-
return this.element[name];
151+
public get<K extends ReadableKeys<T>>(name: K): T[K] {
152+
return this.node[name];
172153
}
173154

174155
/**
175156
* Remove the element
176157
*/
177158
public remove(): this {
178-
this.element.remove();
159+
this.node.remove();
179160
return this;
180161
}
181162

182-
/**
183-
* Add event listener
184-
* @param type
185-
* @param listener
186-
* @param options
187-
*/
188-
public on<K extends keyof ElementEventMap>(type: K, listener: (ev: ElementEventMap[K], component: this) => any, options?: boolean | AddEventListenerOptions) {
189-
this.element.addEventListener(type, e => listener(e, this), options);
190-
return this;
163+
public override on<K extends keyof ElementEventMap>(type: K, listener: (ev: ElementEventMap[K], component: this) => any): typeof this;
164+
public override on<K extends keyof ElementEventMap>(type: K, listener: (ev: ElementEventMap[K], component: this) => any, options: AddEventListenerOptions): typeof this;
165+
public override on<K extends keyof ElementEventMap>(type: K, listener: (ev: ElementEventMap[K], component: this) => any, useCapture: boolean): typeof this;
166+
public override on<K extends keyof ElementEventMap>(type: K, listener: (ev: ElementEventMap[K], component: this) => any, c?: boolean | AddEventListenerOptions): typeof this {
167+
return super.on(type as any, listener, c as any);
191168
}
192169

193170
/**
194171
* Get this component's outer HTML
195172
*/
196-
public toString() {
197-
return this.element.outerHTML;
173+
public override toString() {
174+
return this.node.outerHTML;
198175
}
199176
}

0 commit comments

Comments
 (0)