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