@phcdevworks/spectre-components 0.0.1
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/LICENSE +21 -0
- package/README.md +177 -0
- package/dist/button.cjs +288 -0
- package/dist/button.cjs.map +1 -0
- package/dist/button.d.cts +142 -0
- package/dist/button.d.ts +142 -0
- package/dist/button.js +282 -0
- package/dist/button.js.map +1 -0
- package/dist/checkbox.cjs +158 -0
- package/dist/checkbox.cjs.map +1 -0
- package/dist/checkbox.d.cts +98 -0
- package/dist/checkbox.d.ts +98 -0
- package/dist/checkbox.js +155 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/fieldset.cjs +179 -0
- package/dist/fieldset.cjs.map +1 -0
- package/dist/fieldset.d.cts +63 -0
- package/dist/fieldset.d.ts +63 -0
- package/dist/fieldset.js +176 -0
- package/dist/fieldset.js.map +1 -0
- package/dist/index.cjs +1600 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1576 -0
- package/dist/index.js.map +1 -0
- package/dist/input.cjs +235 -0
- package/dist/input.cjs.map +1 -0
- package/dist/input.d.cts +175 -0
- package/dist/input.d.ts +175 -0
- package/dist/input.js +230 -0
- package/dist/input.js.map +1 -0
- package/dist/label.cjs +156 -0
- package/dist/label.cjs.map +1 -0
- package/dist/label.d.cts +39 -0
- package/dist/label.d.ts +39 -0
- package/dist/label.js +153 -0
- package/dist/label.js.map +1 -0
- package/dist/radio.cjs +158 -0
- package/dist/radio.cjs.map +1 -0
- package/dist/radio.d.cts +98 -0
- package/dist/radio.d.ts +98 -0
- package/dist/radio.js +155 -0
- package/dist/radio.js.map +1 -0
- package/dist/select.cjs +272 -0
- package/dist/select.cjs.map +1 -0
- package/dist/select.d.cts +130 -0
- package/dist/select.d.ts +130 -0
- package/dist/select.js +268 -0
- package/dist/select.js.map +1 -0
- package/dist/textarea.cjs +423 -0
- package/dist/textarea.cjs.map +1 -0
- package/dist/textarea.d.cts +156 -0
- package/dist/textarea.d.ts +156 -0
- package/dist/textarea.js +420 -0
- package/dist/textarea.js.map +1 -0
- package/package.json +124 -0
package/dist/label.cjs
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lit = require('lit');
|
|
4
|
+
var ifDefined_js = require('lit/directives/if-defined.js');
|
|
5
|
+
|
|
6
|
+
// src/components/label/sp-label.ts
|
|
7
|
+
var SpectreLabelElement = class extends lit.LitElement {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.projectedContent = [];
|
|
11
|
+
}
|
|
12
|
+
get id() {
|
|
13
|
+
return this._id ?? "";
|
|
14
|
+
}
|
|
15
|
+
set id(value) {
|
|
16
|
+
if ((this._id ?? "") === value) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this._id = value;
|
|
20
|
+
const host = this;
|
|
21
|
+
if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
|
|
22
|
+
HTMLElement.prototype.removeAttribute.call(host, "id");
|
|
23
|
+
}
|
|
24
|
+
this.requestUpdate();
|
|
25
|
+
}
|
|
26
|
+
createRenderRoot() {
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
connectedCallback() {
|
|
30
|
+
super.connectedCallback();
|
|
31
|
+
const hostId = super.getAttribute("id");
|
|
32
|
+
if (hostId !== null) {
|
|
33
|
+
this.id = hostId;
|
|
34
|
+
}
|
|
35
|
+
this.syncProjectedContent();
|
|
36
|
+
this.startContentObserver();
|
|
37
|
+
}
|
|
38
|
+
disconnectedCallback() {
|
|
39
|
+
this.stopContentObserver();
|
|
40
|
+
super.disconnectedCallback();
|
|
41
|
+
}
|
|
42
|
+
getAttribute(qualifiedName) {
|
|
43
|
+
if (qualifiedName === "id") {
|
|
44
|
+
return this.id || null;
|
|
45
|
+
}
|
|
46
|
+
return super.getAttribute(qualifiedName);
|
|
47
|
+
}
|
|
48
|
+
hasAttribute(qualifiedName) {
|
|
49
|
+
if (qualifiedName === "id") {
|
|
50
|
+
return this.id !== "";
|
|
51
|
+
}
|
|
52
|
+
return super.hasAttribute(qualifiedName);
|
|
53
|
+
}
|
|
54
|
+
setAttribute(qualifiedName, value) {
|
|
55
|
+
if (qualifiedName === "id") {
|
|
56
|
+
this.id = value;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
super.setAttribute(qualifiedName, value);
|
|
60
|
+
}
|
|
61
|
+
removeAttribute(qualifiedName) {
|
|
62
|
+
if (qualifiedName === "id") {
|
|
63
|
+
this.id = "";
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
super.removeAttribute(qualifiedName);
|
|
67
|
+
}
|
|
68
|
+
update(changedProperties) {
|
|
69
|
+
this.stopContentObserver();
|
|
70
|
+
super.update(changedProperties);
|
|
71
|
+
this.startContentObserver();
|
|
72
|
+
}
|
|
73
|
+
get nativeLabel() {
|
|
74
|
+
return this.querySelector("[data-sp-label-native]");
|
|
75
|
+
}
|
|
76
|
+
startContentObserver() {
|
|
77
|
+
if (this.contentObserver) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.contentObserver = new MutationObserver((mutations) => {
|
|
81
|
+
const isInternalMovement = mutations.every((mutation) => {
|
|
82
|
+
return Array.from(mutation.removedNodes).every(
|
|
83
|
+
(node) => this.isInternalLabelNode(node) || this.contains(node)
|
|
84
|
+
) && Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node));
|
|
85
|
+
});
|
|
86
|
+
if (isInternalMovement) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (this.syncProjectedContent()) {
|
|
90
|
+
this.requestUpdate();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
this.contentObserver.observe(this, { childList: true });
|
|
94
|
+
}
|
|
95
|
+
stopContentObserver() {
|
|
96
|
+
this.contentObserver?.disconnect();
|
|
97
|
+
this.contentObserver = void 0;
|
|
98
|
+
}
|
|
99
|
+
syncProjectedContent() {
|
|
100
|
+
const nextProjectedContent = [];
|
|
101
|
+
Array.from(this.childNodes).forEach((node) => {
|
|
102
|
+
if (this.isInternalLabelNode(node)) {
|
|
103
|
+
this.projectedContent.forEach((projectedNode) => {
|
|
104
|
+
if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
|
|
105
|
+
nextProjectedContent.push(projectedNode);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
nextProjectedContent.push(node);
|
|
111
|
+
});
|
|
112
|
+
if (nextProjectedContent.length === this.projectedContent.length && nextProjectedContent.every((node, index) => node === this.projectedContent[index])) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
this.projectedContent = nextProjectedContent;
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
isInternalLabelNode(node) {
|
|
119
|
+
return node === this.nativeLabel;
|
|
120
|
+
}
|
|
121
|
+
focus(options) {
|
|
122
|
+
this.nativeLabel?.focus(options);
|
|
123
|
+
}
|
|
124
|
+
blur() {
|
|
125
|
+
this.nativeLabel?.blur();
|
|
126
|
+
}
|
|
127
|
+
render() {
|
|
128
|
+
return lit.html`
|
|
129
|
+
<label
|
|
130
|
+
class='sp-label'
|
|
131
|
+
data-sp-label-native
|
|
132
|
+
for=${ifDefined_js.ifDefined(this.htmlFor)}
|
|
133
|
+
id=${ifDefined_js.ifDefined(this.id || void 0)}
|
|
134
|
+
tabindex='-1'
|
|
135
|
+
>
|
|
136
|
+
${this.projectedContent.length > 0 ? this.projectedContent : lit.nothing}
|
|
137
|
+
</label>
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
SpectreLabelElement.properties = {
|
|
142
|
+
htmlFor: { attribute: "for", type: String }
|
|
143
|
+
};
|
|
144
|
+
function defineSpectreLabel(tagName = "sp-label") {
|
|
145
|
+
const existingElement = customElements.get(tagName);
|
|
146
|
+
if (existingElement) {
|
|
147
|
+
return existingElement;
|
|
148
|
+
}
|
|
149
|
+
customElements.define(tagName, SpectreLabelElement);
|
|
150
|
+
return SpectreLabelElement;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
exports.SpectreLabelElement = SpectreLabelElement;
|
|
154
|
+
exports.defineSpectreLabel = defineSpectreLabel;
|
|
155
|
+
//# sourceMappingURL=label.cjs.map
|
|
156
|
+
//# sourceMappingURL=label.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/label/sp-label.ts"],"names":["LitElement","html","ifDefined","nothing"],"mappings":"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","file":"label.cjs","sourcesContent":["import { LitElement, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport interface SpectreLabelProps {\n htmlFor?: string;\n}\n\nexport class SpectreLabelElement extends LitElement implements SpectreLabelProps {\n static properties = {\n htmlFor: { attribute: 'for', type: String },\n };\n\n htmlFor?: string;\n private _id?: string;\n private projectedContent: Node[] = [];\n private contentObserver?: MutationObserver | undefined;\n\n override get id(): string {\n return this._id ?? '';\n }\n\n override set id(value: string) {\n if ((this._id ?? '') === value) {\n return;\n }\n\n this._id = value;\n\n const host = this as unknown as HTMLElement;\n if (HTMLElement.prototype.hasAttribute.call(host, 'id')) {\n HTMLElement.prototype.removeAttribute.call(host, 'id');\n }\n\n this.requestUpdate();\n }\n\n createRenderRoot(): this {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n const hostId = super.getAttribute('id');\n\n if (hostId !== null) {\n this.id = hostId;\n }\n\n this.syncProjectedContent();\n this.startContentObserver();\n }\n\n override disconnectedCallback(): void {\n this.stopContentObserver();\n super.disconnectedCallback();\n }\n\n override getAttribute(qualifiedName: string): string | null {\n if (qualifiedName === 'id') {\n return this.id || null;\n }\n\n return super.getAttribute(qualifiedName);\n }\n\n override hasAttribute(qualifiedName: string): boolean {\n if (qualifiedName === 'id') {\n return this.id !== '';\n }\n\n return super.hasAttribute(qualifiedName);\n }\n\n override setAttribute(qualifiedName: string, value: string): void {\n if (qualifiedName === 'id') {\n this.id = value;\n return;\n }\n\n super.setAttribute(qualifiedName, value);\n }\n\n override removeAttribute(qualifiedName: string): void {\n if (qualifiedName === 'id') {\n this.id = '';\n return;\n }\n\n super.removeAttribute(qualifiedName);\n }\n\n protected override update(changedProperties: Map<PropertyKey, unknown>): void {\n this.stopContentObserver();\n super.update(changedProperties);\n this.startContentObserver();\n }\n\n private get nativeLabel(): HTMLLabelElement | null {\n return this.querySelector('[data-sp-label-native]');\n }\n\n private startContentObserver(): void {\n if (this.contentObserver) {\n return;\n }\n\n this.contentObserver = new MutationObserver((mutations) => {\n const isInternalMovement = mutations.every((mutation) => {\n return (\n Array.from(mutation.removedNodes).every(\n (node) => this.isInternalLabelNode(node) || this.contains(node),\n ) &&\n Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node))\n );\n });\n\n if (isInternalMovement) {\n return;\n }\n\n if (this.syncProjectedContent()) {\n this.requestUpdate();\n }\n });\n\n this.contentObserver.observe(this, { childList: true });\n }\n\n private stopContentObserver(): void {\n this.contentObserver?.disconnect();\n this.contentObserver = undefined;\n }\n\n private syncProjectedContent(): boolean {\n const nextProjectedContent: Node[] = [];\n\n Array.from(this.childNodes).forEach((node) => {\n if (this.isInternalLabelNode(node)) {\n this.projectedContent.forEach((projectedNode) => {\n if (projectedNode.parentNode !== this && this.contains(projectedNode)) {\n nextProjectedContent.push(projectedNode);\n }\n });\n return;\n }\n\n nextProjectedContent.push(node);\n });\n\n if (\n nextProjectedContent.length === this.projectedContent.length &&\n nextProjectedContent.every((node, index) => node === this.projectedContent[index])\n ) {\n return false;\n }\n\n this.projectedContent = nextProjectedContent;\n return true;\n }\n\n private isInternalLabelNode(node: Node): boolean {\n return node === this.nativeLabel;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeLabel?.focus(options);\n }\n\n override blur(): void {\n this.nativeLabel?.blur();\n }\n\n override render() {\n return html`\n <label\n class='sp-label'\n data-sp-label-native\n for=${ifDefined(this.htmlFor)}\n id=${ifDefined(this.id || undefined)}\n tabindex='-1'\n >\n ${this.projectedContent.length > 0 ? this.projectedContent : nothing}\n </label>\n `;\n }\n}\n\nexport function defineSpectreLabel(tagName = 'sp-label'): typeof SpectreLabelElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreLabelElement;\n }\n\n customElements.define(tagName, SpectreLabelElement);\n return SpectreLabelElement;\n}\n"]}
|
package/dist/label.d.cts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as lit_html from 'lit-html';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
|
|
4
|
+
interface SpectreLabelProps {
|
|
5
|
+
htmlFor?: string;
|
|
6
|
+
}
|
|
7
|
+
declare class SpectreLabelElement extends LitElement implements SpectreLabelProps {
|
|
8
|
+
static properties: {
|
|
9
|
+
htmlFor: {
|
|
10
|
+
attribute: string;
|
|
11
|
+
type: StringConstructor;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
htmlFor?: string;
|
|
15
|
+
private _id?;
|
|
16
|
+
private projectedContent;
|
|
17
|
+
private contentObserver?;
|
|
18
|
+
get id(): string;
|
|
19
|
+
set id(value: string);
|
|
20
|
+
createRenderRoot(): this;
|
|
21
|
+
connectedCallback(): void;
|
|
22
|
+
disconnectedCallback(): void;
|
|
23
|
+
getAttribute(qualifiedName: string): string | null;
|
|
24
|
+
hasAttribute(qualifiedName: string): boolean;
|
|
25
|
+
setAttribute(qualifiedName: string, value: string): void;
|
|
26
|
+
removeAttribute(qualifiedName: string): void;
|
|
27
|
+
protected update(changedProperties: Map<PropertyKey, unknown>): void;
|
|
28
|
+
private get nativeLabel();
|
|
29
|
+
private startContentObserver;
|
|
30
|
+
private stopContentObserver;
|
|
31
|
+
private syncProjectedContent;
|
|
32
|
+
private isInternalLabelNode;
|
|
33
|
+
focus(options?: FocusOptions): void;
|
|
34
|
+
blur(): void;
|
|
35
|
+
render(): lit_html.TemplateResult<1>;
|
|
36
|
+
}
|
|
37
|
+
declare function defineSpectreLabel(tagName?: string): typeof SpectreLabelElement;
|
|
38
|
+
|
|
39
|
+
export { SpectreLabelElement, type SpectreLabelProps, defineSpectreLabel };
|
package/dist/label.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as lit_html from 'lit-html';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
|
|
4
|
+
interface SpectreLabelProps {
|
|
5
|
+
htmlFor?: string;
|
|
6
|
+
}
|
|
7
|
+
declare class SpectreLabelElement extends LitElement implements SpectreLabelProps {
|
|
8
|
+
static properties: {
|
|
9
|
+
htmlFor: {
|
|
10
|
+
attribute: string;
|
|
11
|
+
type: StringConstructor;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
htmlFor?: string;
|
|
15
|
+
private _id?;
|
|
16
|
+
private projectedContent;
|
|
17
|
+
private contentObserver?;
|
|
18
|
+
get id(): string;
|
|
19
|
+
set id(value: string);
|
|
20
|
+
createRenderRoot(): this;
|
|
21
|
+
connectedCallback(): void;
|
|
22
|
+
disconnectedCallback(): void;
|
|
23
|
+
getAttribute(qualifiedName: string): string | null;
|
|
24
|
+
hasAttribute(qualifiedName: string): boolean;
|
|
25
|
+
setAttribute(qualifiedName: string, value: string): void;
|
|
26
|
+
removeAttribute(qualifiedName: string): void;
|
|
27
|
+
protected update(changedProperties: Map<PropertyKey, unknown>): void;
|
|
28
|
+
private get nativeLabel();
|
|
29
|
+
private startContentObserver;
|
|
30
|
+
private stopContentObserver;
|
|
31
|
+
private syncProjectedContent;
|
|
32
|
+
private isInternalLabelNode;
|
|
33
|
+
focus(options?: FocusOptions): void;
|
|
34
|
+
blur(): void;
|
|
35
|
+
render(): lit_html.TemplateResult<1>;
|
|
36
|
+
}
|
|
37
|
+
declare function defineSpectreLabel(tagName?: string): typeof SpectreLabelElement;
|
|
38
|
+
|
|
39
|
+
export { SpectreLabelElement, type SpectreLabelProps, defineSpectreLabel };
|
package/dist/label.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { LitElement, nothing, html } from 'lit';
|
|
2
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
3
|
+
|
|
4
|
+
// src/components/label/sp-label.ts
|
|
5
|
+
var SpectreLabelElement = class extends LitElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.projectedContent = [];
|
|
9
|
+
}
|
|
10
|
+
get id() {
|
|
11
|
+
return this._id ?? "";
|
|
12
|
+
}
|
|
13
|
+
set id(value) {
|
|
14
|
+
if ((this._id ?? "") === value) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this._id = value;
|
|
18
|
+
const host = this;
|
|
19
|
+
if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
|
|
20
|
+
HTMLElement.prototype.removeAttribute.call(host, "id");
|
|
21
|
+
}
|
|
22
|
+
this.requestUpdate();
|
|
23
|
+
}
|
|
24
|
+
createRenderRoot() {
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
connectedCallback() {
|
|
28
|
+
super.connectedCallback();
|
|
29
|
+
const hostId = super.getAttribute("id");
|
|
30
|
+
if (hostId !== null) {
|
|
31
|
+
this.id = hostId;
|
|
32
|
+
}
|
|
33
|
+
this.syncProjectedContent();
|
|
34
|
+
this.startContentObserver();
|
|
35
|
+
}
|
|
36
|
+
disconnectedCallback() {
|
|
37
|
+
this.stopContentObserver();
|
|
38
|
+
super.disconnectedCallback();
|
|
39
|
+
}
|
|
40
|
+
getAttribute(qualifiedName) {
|
|
41
|
+
if (qualifiedName === "id") {
|
|
42
|
+
return this.id || null;
|
|
43
|
+
}
|
|
44
|
+
return super.getAttribute(qualifiedName);
|
|
45
|
+
}
|
|
46
|
+
hasAttribute(qualifiedName) {
|
|
47
|
+
if (qualifiedName === "id") {
|
|
48
|
+
return this.id !== "";
|
|
49
|
+
}
|
|
50
|
+
return super.hasAttribute(qualifiedName);
|
|
51
|
+
}
|
|
52
|
+
setAttribute(qualifiedName, value) {
|
|
53
|
+
if (qualifiedName === "id") {
|
|
54
|
+
this.id = value;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
super.setAttribute(qualifiedName, value);
|
|
58
|
+
}
|
|
59
|
+
removeAttribute(qualifiedName) {
|
|
60
|
+
if (qualifiedName === "id") {
|
|
61
|
+
this.id = "";
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
super.removeAttribute(qualifiedName);
|
|
65
|
+
}
|
|
66
|
+
update(changedProperties) {
|
|
67
|
+
this.stopContentObserver();
|
|
68
|
+
super.update(changedProperties);
|
|
69
|
+
this.startContentObserver();
|
|
70
|
+
}
|
|
71
|
+
get nativeLabel() {
|
|
72
|
+
return this.querySelector("[data-sp-label-native]");
|
|
73
|
+
}
|
|
74
|
+
startContentObserver() {
|
|
75
|
+
if (this.contentObserver) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this.contentObserver = new MutationObserver((mutations) => {
|
|
79
|
+
const isInternalMovement = mutations.every((mutation) => {
|
|
80
|
+
return Array.from(mutation.removedNodes).every(
|
|
81
|
+
(node) => this.isInternalLabelNode(node) || this.contains(node)
|
|
82
|
+
) && Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node));
|
|
83
|
+
});
|
|
84
|
+
if (isInternalMovement) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (this.syncProjectedContent()) {
|
|
88
|
+
this.requestUpdate();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
this.contentObserver.observe(this, { childList: true });
|
|
92
|
+
}
|
|
93
|
+
stopContentObserver() {
|
|
94
|
+
this.contentObserver?.disconnect();
|
|
95
|
+
this.contentObserver = void 0;
|
|
96
|
+
}
|
|
97
|
+
syncProjectedContent() {
|
|
98
|
+
const nextProjectedContent = [];
|
|
99
|
+
Array.from(this.childNodes).forEach((node) => {
|
|
100
|
+
if (this.isInternalLabelNode(node)) {
|
|
101
|
+
this.projectedContent.forEach((projectedNode) => {
|
|
102
|
+
if (projectedNode.parentNode !== this && this.contains(projectedNode)) {
|
|
103
|
+
nextProjectedContent.push(projectedNode);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
nextProjectedContent.push(node);
|
|
109
|
+
});
|
|
110
|
+
if (nextProjectedContent.length === this.projectedContent.length && nextProjectedContent.every((node, index) => node === this.projectedContent[index])) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
this.projectedContent = nextProjectedContent;
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
isInternalLabelNode(node) {
|
|
117
|
+
return node === this.nativeLabel;
|
|
118
|
+
}
|
|
119
|
+
focus(options) {
|
|
120
|
+
this.nativeLabel?.focus(options);
|
|
121
|
+
}
|
|
122
|
+
blur() {
|
|
123
|
+
this.nativeLabel?.blur();
|
|
124
|
+
}
|
|
125
|
+
render() {
|
|
126
|
+
return html`
|
|
127
|
+
<label
|
|
128
|
+
class='sp-label'
|
|
129
|
+
data-sp-label-native
|
|
130
|
+
for=${ifDefined(this.htmlFor)}
|
|
131
|
+
id=${ifDefined(this.id || void 0)}
|
|
132
|
+
tabindex='-1'
|
|
133
|
+
>
|
|
134
|
+
${this.projectedContent.length > 0 ? this.projectedContent : nothing}
|
|
135
|
+
</label>
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
SpectreLabelElement.properties = {
|
|
140
|
+
htmlFor: { attribute: "for", type: String }
|
|
141
|
+
};
|
|
142
|
+
function defineSpectreLabel(tagName = "sp-label") {
|
|
143
|
+
const existingElement = customElements.get(tagName);
|
|
144
|
+
if (existingElement) {
|
|
145
|
+
return existingElement;
|
|
146
|
+
}
|
|
147
|
+
customElements.define(tagName, SpectreLabelElement);
|
|
148
|
+
return SpectreLabelElement;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { SpectreLabelElement, defineSpectreLabel };
|
|
152
|
+
//# sourceMappingURL=label.js.map
|
|
153
|
+
//# sourceMappingURL=label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/label/sp-label.ts"],"names":[],"mappings":"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","file":"label.js","sourcesContent":["import { LitElement, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport interface SpectreLabelProps {\n htmlFor?: string;\n}\n\nexport class SpectreLabelElement extends LitElement implements SpectreLabelProps {\n static properties = {\n htmlFor: { attribute: 'for', type: String },\n };\n\n htmlFor?: string;\n private _id?: string;\n private projectedContent: Node[] = [];\n private contentObserver?: MutationObserver | undefined;\n\n override get id(): string {\n return this._id ?? '';\n }\n\n override set id(value: string) {\n if ((this._id ?? '') === value) {\n return;\n }\n\n this._id = value;\n\n const host = this as unknown as HTMLElement;\n if (HTMLElement.prototype.hasAttribute.call(host, 'id')) {\n HTMLElement.prototype.removeAttribute.call(host, 'id');\n }\n\n this.requestUpdate();\n }\n\n createRenderRoot(): this {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n const hostId = super.getAttribute('id');\n\n if (hostId !== null) {\n this.id = hostId;\n }\n\n this.syncProjectedContent();\n this.startContentObserver();\n }\n\n override disconnectedCallback(): void {\n this.stopContentObserver();\n super.disconnectedCallback();\n }\n\n override getAttribute(qualifiedName: string): string | null {\n if (qualifiedName === 'id') {\n return this.id || null;\n }\n\n return super.getAttribute(qualifiedName);\n }\n\n override hasAttribute(qualifiedName: string): boolean {\n if (qualifiedName === 'id') {\n return this.id !== '';\n }\n\n return super.hasAttribute(qualifiedName);\n }\n\n override setAttribute(qualifiedName: string, value: string): void {\n if (qualifiedName === 'id') {\n this.id = value;\n return;\n }\n\n super.setAttribute(qualifiedName, value);\n }\n\n override removeAttribute(qualifiedName: string): void {\n if (qualifiedName === 'id') {\n this.id = '';\n return;\n }\n\n super.removeAttribute(qualifiedName);\n }\n\n protected override update(changedProperties: Map<PropertyKey, unknown>): void {\n this.stopContentObserver();\n super.update(changedProperties);\n this.startContentObserver();\n }\n\n private get nativeLabel(): HTMLLabelElement | null {\n return this.querySelector('[data-sp-label-native]');\n }\n\n private startContentObserver(): void {\n if (this.contentObserver) {\n return;\n }\n\n this.contentObserver = new MutationObserver((mutations) => {\n const isInternalMovement = mutations.every((mutation) => {\n return (\n Array.from(mutation.removedNodes).every(\n (node) => this.isInternalLabelNode(node) || this.contains(node),\n ) &&\n Array.from(mutation.addedNodes).every((node) => this.isInternalLabelNode(node))\n );\n });\n\n if (isInternalMovement) {\n return;\n }\n\n if (this.syncProjectedContent()) {\n this.requestUpdate();\n }\n });\n\n this.contentObserver.observe(this, { childList: true });\n }\n\n private stopContentObserver(): void {\n this.contentObserver?.disconnect();\n this.contentObserver = undefined;\n }\n\n private syncProjectedContent(): boolean {\n const nextProjectedContent: Node[] = [];\n\n Array.from(this.childNodes).forEach((node) => {\n if (this.isInternalLabelNode(node)) {\n this.projectedContent.forEach((projectedNode) => {\n if (projectedNode.parentNode !== this && this.contains(projectedNode)) {\n nextProjectedContent.push(projectedNode);\n }\n });\n return;\n }\n\n nextProjectedContent.push(node);\n });\n\n if (\n nextProjectedContent.length === this.projectedContent.length &&\n nextProjectedContent.every((node, index) => node === this.projectedContent[index])\n ) {\n return false;\n }\n\n this.projectedContent = nextProjectedContent;\n return true;\n }\n\n private isInternalLabelNode(node: Node): boolean {\n return node === this.nativeLabel;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeLabel?.focus(options);\n }\n\n override blur(): void {\n this.nativeLabel?.blur();\n }\n\n override render() {\n return html`\n <label\n class='sp-label'\n data-sp-label-native\n for=${ifDefined(this.htmlFor)}\n id=${ifDefined(this.id || undefined)}\n tabindex='-1'\n >\n ${this.projectedContent.length > 0 ? this.projectedContent : nothing}\n </label>\n `;\n }\n}\n\nexport function defineSpectreLabel(tagName = 'sp-label'): typeof SpectreLabelElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreLabelElement;\n }\n\n customElements.define(tagName, SpectreLabelElement);\n return SpectreLabelElement;\n}\n"]}
|
package/dist/radio.cjs
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lit = require('lit');
|
|
4
|
+
var ifDefined_js = require('lit/directives/if-defined.js');
|
|
5
|
+
|
|
6
|
+
// src/components/radio/sp-radio.ts
|
|
7
|
+
var SpectreRadioElement = class extends lit.LitElement {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.ariaLabel = null;
|
|
11
|
+
this.ariaLabelledBy = null;
|
|
12
|
+
this.ariaDescribedBy = null;
|
|
13
|
+
this.autofocus = false;
|
|
14
|
+
this.checked = false;
|
|
15
|
+
this.disabled = false;
|
|
16
|
+
this.invalid = false;
|
|
17
|
+
this.label = "";
|
|
18
|
+
this.required = false;
|
|
19
|
+
this.title = "";
|
|
20
|
+
this.value = "on";
|
|
21
|
+
}
|
|
22
|
+
get id() {
|
|
23
|
+
return this._id ?? "";
|
|
24
|
+
}
|
|
25
|
+
set id(value) {
|
|
26
|
+
if ((this._id ?? "") === value) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this._id = value;
|
|
30
|
+
const host = this;
|
|
31
|
+
if (HTMLElement.prototype.hasAttribute.call(host, "id")) {
|
|
32
|
+
HTMLElement.prototype.removeAttribute.call(host, "id");
|
|
33
|
+
}
|
|
34
|
+
this.requestUpdate();
|
|
35
|
+
}
|
|
36
|
+
createRenderRoot() {
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
connectedCallback() {
|
|
40
|
+
super.connectedCallback();
|
|
41
|
+
const hostId = super.getAttribute("id");
|
|
42
|
+
if (hostId !== null) {
|
|
43
|
+
this.id = hostId;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
getAttribute(qualifiedName) {
|
|
47
|
+
if (qualifiedName === "id") {
|
|
48
|
+
return this.id || null;
|
|
49
|
+
}
|
|
50
|
+
return super.getAttribute(qualifiedName);
|
|
51
|
+
}
|
|
52
|
+
hasAttribute(qualifiedName) {
|
|
53
|
+
if (qualifiedName === "id") {
|
|
54
|
+
return this.id !== "";
|
|
55
|
+
}
|
|
56
|
+
return super.hasAttribute(qualifiedName);
|
|
57
|
+
}
|
|
58
|
+
setAttribute(qualifiedName, value) {
|
|
59
|
+
if (qualifiedName === "id") {
|
|
60
|
+
this.id = value;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
super.setAttribute(qualifiedName, value);
|
|
64
|
+
}
|
|
65
|
+
removeAttribute(qualifiedName) {
|
|
66
|
+
if (qualifiedName === "id") {
|
|
67
|
+
this.id = "";
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
super.removeAttribute(qualifiedName);
|
|
71
|
+
}
|
|
72
|
+
willUpdate(changedProperties) {
|
|
73
|
+
if (changedProperties.has("value") && this.value == null) {
|
|
74
|
+
this.value = "on";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
get nativeInput() {
|
|
78
|
+
return this.querySelector("[data-sp-radio-native]");
|
|
79
|
+
}
|
|
80
|
+
get forwardedAriaLabel() {
|
|
81
|
+
const value = this.ariaLabel?.trim();
|
|
82
|
+
return value ? value : void 0;
|
|
83
|
+
}
|
|
84
|
+
get forwardedAriaLabelledBy() {
|
|
85
|
+
const value = this.ariaLabelledBy?.trim();
|
|
86
|
+
return value ? value : void 0;
|
|
87
|
+
}
|
|
88
|
+
get forwardedAriaDescribedBy() {
|
|
89
|
+
const value = this.ariaDescribedBy?.trim();
|
|
90
|
+
return value ? value : void 0;
|
|
91
|
+
}
|
|
92
|
+
handleInput(event) {
|
|
93
|
+
const input = event.currentTarget;
|
|
94
|
+
this.checked = input.checked;
|
|
95
|
+
}
|
|
96
|
+
handleChange(event) {
|
|
97
|
+
const input = event.currentTarget;
|
|
98
|
+
this.checked = input.checked;
|
|
99
|
+
}
|
|
100
|
+
focus(options) {
|
|
101
|
+
this.nativeInput?.focus(options);
|
|
102
|
+
}
|
|
103
|
+
blur() {
|
|
104
|
+
this.nativeInput?.blur();
|
|
105
|
+
}
|
|
106
|
+
render() {
|
|
107
|
+
return lit.html`
|
|
108
|
+
<label>
|
|
109
|
+
<input
|
|
110
|
+
aria-describedby=${ifDefined_js.ifDefined(this.forwardedAriaDescribedBy)}
|
|
111
|
+
aria-invalid=${ifDefined_js.ifDefined(this.invalid ? "true" : void 0)}
|
|
112
|
+
aria-label=${ifDefined_js.ifDefined(this.forwardedAriaLabel)}
|
|
113
|
+
aria-labelledby=${ifDefined_js.ifDefined(this.forwardedAriaLabelledBy)}
|
|
114
|
+
?autofocus=${this.autofocus}
|
|
115
|
+
data-sp-radio-native
|
|
116
|
+
?checked=${this.checked}
|
|
117
|
+
?disabled=${this.disabled}
|
|
118
|
+
id=${ifDefined_js.ifDefined(this.id || void 0)}
|
|
119
|
+
name=${ifDefined_js.ifDefined(this.name)}
|
|
120
|
+
?required=${this.required}
|
|
121
|
+
title=${ifDefined_js.ifDefined(this.title || void 0)}
|
|
122
|
+
type='radio'
|
|
123
|
+
value=${ifDefined_js.ifDefined(this.value || void 0)}
|
|
124
|
+
@change=${this.handleChange}
|
|
125
|
+
@input=${this.handleInput}
|
|
126
|
+
/>
|
|
127
|
+
<span class='sp-label'>${this.label}</span>
|
|
128
|
+
</label>
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
SpectreRadioElement.properties = {
|
|
133
|
+
ariaLabel: { attribute: "aria-label", type: String },
|
|
134
|
+
ariaLabelledBy: { attribute: "aria-labelledby", type: String },
|
|
135
|
+
ariaDescribedBy: { attribute: "aria-describedby", type: String },
|
|
136
|
+
autofocus: { type: Boolean, reflect: true },
|
|
137
|
+
checked: { type: Boolean, reflect: true },
|
|
138
|
+
disabled: { type: Boolean, reflect: true },
|
|
139
|
+
invalid: { type: Boolean, reflect: true },
|
|
140
|
+
label: { type: String, reflect: true },
|
|
141
|
+
name: { type: String },
|
|
142
|
+
required: { type: Boolean, reflect: true },
|
|
143
|
+
title: { type: String, reflect: true },
|
|
144
|
+
value: { type: String }
|
|
145
|
+
};
|
|
146
|
+
function defineSpectreRadio(tagName = "sp-radio") {
|
|
147
|
+
const existingElement = customElements.get(tagName);
|
|
148
|
+
if (existingElement) {
|
|
149
|
+
return existingElement;
|
|
150
|
+
}
|
|
151
|
+
customElements.define(tagName, SpectreRadioElement);
|
|
152
|
+
return SpectreRadioElement;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
exports.SpectreRadioElement = SpectreRadioElement;
|
|
156
|
+
exports.defineSpectreRadio = defineSpectreRadio;
|
|
157
|
+
//# sourceMappingURL=radio.cjs.map
|
|
158
|
+
//# sourceMappingURL=radio.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/radio/sp-radio.ts"],"names":["LitElement","html","ifDefined"],"mappings":"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","file":"radio.cjs","sourcesContent":["import { LitElement, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport interface SpectreRadioProps {\n autofocus?: boolean;\n checked?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n label?: string;\n name?: string;\n required?: boolean;\n title?: string;\n value?: string;\n}\n\nexport class SpectreRadioElement extends LitElement implements SpectreRadioProps {\n static properties = {\n ariaLabel: { attribute: 'aria-label', type: String },\n ariaLabelledBy: { attribute: 'aria-labelledby', type: String },\n ariaDescribedBy: { attribute: 'aria-describedby', type: String },\n autofocus: { type: Boolean, reflect: true },\n checked: { type: Boolean, reflect: true },\n disabled: { type: Boolean, reflect: true },\n invalid: { type: Boolean, reflect: true },\n label: { type: String, reflect: true },\n name: { type: String },\n required: { type: Boolean, reflect: true },\n title: { type: String, reflect: true },\n value: { type: String },\n };\n\n ariaLabel: string | null = null;\n ariaLabelledBy: string | null = null;\n ariaDescribedBy: string | null = null;\n autofocus = false;\n checked = false;\n disabled = false;\n invalid = false;\n label = '';\n name?: string;\n required = false;\n override title = '';\n value = 'on';\n private _id?: string;\n\n override get id(): string {\n return this._id ?? '';\n }\n\n override set id(value: string) {\n if ((this._id ?? '') === value) {\n return;\n }\n\n this._id = value;\n\n const host = this as unknown as HTMLElement;\n if (HTMLElement.prototype.hasAttribute.call(host, 'id')) {\n HTMLElement.prototype.removeAttribute.call(host, 'id');\n }\n\n this.requestUpdate();\n }\n\n createRenderRoot(): this {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n const hostId = super.getAttribute('id');\n\n if (hostId !== null) {\n this.id = hostId;\n }\n }\n\n override getAttribute(qualifiedName: string): string | null {\n if (qualifiedName === 'id') {\n return this.id || null;\n }\n\n return super.getAttribute(qualifiedName);\n }\n\n override hasAttribute(qualifiedName: string): boolean {\n if (qualifiedName === 'id') {\n return this.id !== '';\n }\n\n return super.hasAttribute(qualifiedName);\n }\n\n override setAttribute(qualifiedName: string, value: string): void {\n if (qualifiedName === 'id') {\n this.id = value;\n return;\n }\n\n super.setAttribute(qualifiedName, value);\n }\n\n override removeAttribute(qualifiedName: string): void {\n if (qualifiedName === 'id') {\n this.id = '';\n return;\n }\n\n super.removeAttribute(qualifiedName);\n }\n\n protected override willUpdate(changedProperties: Map<PropertyKey, unknown>): void {\n if (changedProperties.has('value') && this.value == null) {\n this.value = 'on';\n }\n }\n\n private get nativeInput(): HTMLInputElement | null {\n return this.querySelector('[data-sp-radio-native]');\n }\n\n private get forwardedAriaLabel(): string | undefined {\n const value = this.ariaLabel?.trim();\n return value ? value : undefined;\n }\n\n private get forwardedAriaLabelledBy(): string | undefined {\n const value = this.ariaLabelledBy?.trim();\n return value ? value : undefined;\n }\n\n private get forwardedAriaDescribedBy(): string | undefined {\n const value = this.ariaDescribedBy?.trim();\n return value ? value : undefined;\n }\n\n private handleInput(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n private handleChange(event: Event): void {\n const input = event.currentTarget as HTMLInputElement;\n this.checked = input.checked;\n }\n\n override focus(options?: FocusOptions): void {\n this.nativeInput?.focus(options);\n }\n\n override blur(): void {\n this.nativeInput?.blur();\n }\n\n override render() {\n return html`\n <label>\n <input\n aria-describedby=${ifDefined(this.forwardedAriaDescribedBy)}\n aria-invalid=${ifDefined(this.invalid ? 'true' : undefined)}\n aria-label=${ifDefined(this.forwardedAriaLabel)}\n aria-labelledby=${ifDefined(this.forwardedAriaLabelledBy)}\n ?autofocus=${this.autofocus}\n data-sp-radio-native\n ?checked=${this.checked}\n ?disabled=${this.disabled}\n id=${ifDefined(this.id || undefined)}\n name=${ifDefined(this.name)}\n ?required=${this.required}\n title=${ifDefined(this.title || undefined)}\n type='radio'\n value=${ifDefined(this.value || undefined)}\n @change=${this.handleChange}\n @input=${this.handleInput}\n />\n <span class='sp-label'>${this.label}</span>\n </label>\n `;\n }\n}\n\nexport function defineSpectreRadio(tagName = 'sp-radio'): typeof SpectreRadioElement {\n const existingElement = customElements.get(tagName);\n\n if (existingElement) {\n return existingElement as unknown as typeof SpectreRadioElement;\n }\n\n customElements.define(tagName, SpectreRadioElement);\n return SpectreRadioElement;\n}\n"]}
|