ds-one 0.2.5-alpha.17 → 0.2.5-alpha.19
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/DS1/0-face/device.ts +130 -0
- package/DS1/0-face/scaling.ts +152 -0
- package/DS1/1-root/one.css +48 -18
- package/DS1/2-core/ds-banner.ts +3 -77
- package/DS1/2-core/ds-button.ts +3 -67
- package/DS1/2-core/ds-card.ts +137 -0
- package/DS1/2-core/ds-cycle.ts +3 -22
- package/DS1/2-core/ds-date.ts +3 -9
- package/DS1/2-core/ds-gap.ts +3 -75
- package/DS1/2-core/ds-icon.ts +3 -33
- package/DS1/2-core/ds-input.ts +306 -1
- package/DS1/2-core/ds-pagedots.ts +52 -0
- package/DS1/2-core/ds-text.ts +3 -29
- package/DS1/2-core/ds-tooltip.ts +3 -49
- package/DS1/2-core/styles/ds-banner.css +77 -0
- package/DS1/2-core/styles/ds-button.css +67 -0
- package/DS1/2-core/styles/ds-cycle.css +21 -0
- package/DS1/2-core/styles/ds-date.css +9 -0
- package/DS1/2-core/styles/ds-gap.css +93 -0
- package/DS1/2-core/styles/ds-icon.css +30 -0
- package/DS1/2-core/styles/ds-input.css +46 -0
- package/DS1/2-core/styles/ds-pagedots.css +27 -0
- package/DS1/2-core/styles/ds-text.css +29 -0
- package/DS1/2-core/styles/ds-tooltip.css +49 -0
- package/DS1/3-unit/ds-accordion.ts +3 -46
- package/DS1/3-unit/ds-form.ts +304 -0
- package/DS1/3-unit/ds-list.ts +5 -14
- package/DS1/3-unit/ds-row.ts +3 -19
- package/DS1/3-unit/ds-table.ts +3 -85
- package/DS1/3-unit/styles/ds-accordion.css +46 -0
- package/DS1/3-unit/styles/ds-list.css +9 -0
- package/DS1/3-unit/styles/ds-row.css +19 -0
- package/DS1/3-unit/styles/ds-table.css +80 -0
- package/DS1/4-page/ds-container.ts +3 -35
- package/DS1/4-page/ds-grid.ts +3 -56
- package/DS1/4-page/ds-layout.ts +528 -50
- package/DS1/4-page/styles/ds-container.css +35 -0
- package/DS1/4-page/styles/ds-grid.css +56 -0
- package/DS1/4-page/styles/ds-layout.css +251 -0
- package/DS1/index.ts +7 -2
- package/DS1/vite-env.d.ts +9 -0
- package/DS1/x-icon/2x.svg +4 -0
- package/DS1/x-icon/2xdots.svg +18 -0
- package/DS1/x-icon/2xgrid.svg +6 -0
- package/DS1/x-icon/2xlines.svg +6 -0
- package/DS1/x-icon/4x4.svg +18 -0
- package/DS1/x-icon/apple.svg +4 -0
- package/DS1/x-icon/avatar.svg +4 -0
- package/DS1/x-icon/big.svg +4 -0
- package/DS1/x-icon/blank.svg +3 -0
- package/DS1/x-icon/check.svg +3 -0
- package/DS1/x-icon/close.svg +3 -0
- package/DS1/x-icon/collapse.svg +3 -0
- package/DS1/x-icon/color.svg +4 -0
- package/DS1/x-icon/column.svg +5 -0
- package/DS1/x-icon/default.svg +3 -0
- package/DS1/x-icon/delete.svg +5 -0
- package/DS1/x-icon/dictate.svg +6 -0
- package/DS1/x-icon/do.svg +3 -0
- package/DS1/x-icon/down.svg +3 -0
- package/DS1/x-icon/duplicate.svg +4 -0
- package/DS1/x-icon/gallery.svg +5 -0
- package/DS1/x-icon/google.svg +6 -0
- package/DS1/x-icon/head.svg +5 -0
- package/DS1/x-icon/home.svg +3 -0
- package/DS1/x-icon/icon.svg +4 -0
- package/DS1/x-icon/in.svg +4 -0
- package/DS1/x-icon/lock.svg +5 -0
- package/DS1/x-icon/loop.svg +5 -0
- package/DS1/x-icon/mic.svg +5 -0
- package/DS1/x-icon/minimize.svg +3 -0
- package/DS1/x-icon/more.svg +5 -0
- package/DS1/x-icon/neutral.svg +6 -0
- package/DS1/x-icon/note.svg +6 -0
- package/DS1/x-icon/page.svg +4 -0
- package/DS1/x-icon/plus.svg +3 -0
- package/DS1/x-icon/rewind.svg +4 -0
- package/DS1/x-icon/row.svg +5 -0
- package/DS1/x-icon/sdown.svg +3 -0
- package/DS1/x-icon/search.svg +4 -0
- package/DS1/x-icon/see.svg +4 -0
- package/DS1/x-icon/ship.svg +5 -0
- package/DS1/x-icon/star.svg +3 -0
- package/DS1/x-icon/status.svg +4 -0
- package/DS1/x-icon/sup.svg +3 -0
- package/DS1/x-icon/title.svg +3 -0
- package/DS1/x-icon/undo.svg +3 -0
- package/DS1/x-icon/ungroup.svg +4 -0
- package/DS1/x-icon/unhead.svg +3 -0
- package/DS1/x-icon/unicon.svg +3 -0
- package/DS1/x-icon/unlock.svg +5 -0
- package/DS1/x-icon/unmic.svg +6 -0
- package/DS1/x-icon/unsee.svg +5 -0
- package/DS1/x-icon/unstar.svg +3 -0
- package/DS1/x-icon/untitle.svg +3 -0
- package/DS1/x-icon/up.svg +3 -0
- package/README.md +2 -2
- package/dist/0-face/device.d.ts +5 -0
- package/dist/0-face/device.d.ts.map +1 -1
- package/dist/0-face/device.js +105 -0
- package/dist/0-face/scaling.d.ts +48 -0
- package/dist/0-face/scaling.d.ts.map +1 -0
- package/dist/0-face/scaling.js +114 -0
- package/dist/2-core/ds-banner.d.ts.map +1 -1
- package/dist/2-core/ds-banner.js +3 -77
- package/dist/2-core/ds-button.d.ts.map +1 -1
- package/dist/2-core/ds-button.js +3 -67
- package/dist/2-core/ds-card.d.ts +39 -0
- package/dist/2-core/ds-card.d.ts.map +1 -0
- package/dist/2-core/ds-card.js +119 -0
- package/dist/2-core/ds-cycle.d.ts.map +1 -1
- package/dist/2-core/ds-cycle.js +3 -22
- package/dist/2-core/ds-date.d.ts.map +1 -1
- package/dist/2-core/ds-date.js +3 -9
- package/dist/2-core/ds-gap.d.ts.map +1 -1
- package/dist/2-core/ds-gap.js +3 -75
- package/dist/2-core/ds-icon.d.ts.map +1 -1
- package/dist/2-core/ds-icon.js +3 -33
- package/dist/2-core/ds-input.d.ts +127 -0
- package/dist/2-core/ds-input.d.ts.map +1 -1
- package/dist/2-core/ds-input.js +252 -1
- package/dist/2-core/ds-pagedots.d.ts +32 -0
- package/dist/2-core/ds-pagedots.d.ts.map +1 -0
- package/dist/2-core/ds-pagedots.js +36 -0
- package/dist/2-core/ds-text.d.ts.map +1 -1
- package/dist/2-core/ds-text.js +3 -29
- package/dist/2-core/ds-tooltip.d.ts.map +1 -1
- package/dist/2-core/ds-tooltip.js +3 -49
- package/dist/2-core/styles/ds-banner.css +77 -0
- package/dist/2-core/styles/ds-button.css +67 -0
- package/dist/2-core/styles/ds-cycle.css +21 -0
- package/dist/2-core/styles/ds-date.css +9 -0
- package/dist/2-core/styles/ds-gap.css +93 -0
- package/dist/2-core/styles/ds-icon.css +30 -0
- package/dist/2-core/styles/ds-input.css +46 -0
- package/dist/2-core/styles/ds-pagedots.css +26 -0
- package/dist/2-core/styles/ds-text.css +29 -0
- package/dist/2-core/styles/ds-tooltip.css +49 -0
- package/dist/3-unit/ds-accordion.d.ts.map +1 -1
- package/dist/3-unit/ds-accordion.js +3 -46
- package/dist/3-unit/ds-form.d.ts +70 -0
- package/dist/3-unit/ds-form.d.ts.map +1 -0
- package/dist/3-unit/ds-form.js +232 -0
- package/dist/3-unit/ds-list.d.ts.map +1 -1
- package/dist/3-unit/ds-list.js +5 -11
- package/dist/3-unit/ds-row.d.ts.map +1 -1
- package/dist/3-unit/ds-row.js +3 -19
- package/dist/3-unit/ds-table.d.ts.map +1 -1
- package/dist/3-unit/ds-table.js +3 -85
- package/dist/3-unit/styles/ds-accordion.css +46 -0
- package/dist/3-unit/styles/ds-list.css +9 -0
- package/dist/3-unit/styles/ds-row.css +19 -0
- package/dist/3-unit/styles/ds-table.css +80 -0
- package/dist/4-page/ds-container.d.ts.map +1 -1
- package/dist/4-page/ds-container.js +3 -35
- package/dist/4-page/ds-grid.d.ts.map +1 -1
- package/dist/4-page/ds-grid.js +3 -56
- package/dist/4-page/ds-layout.d.ts +1 -1
- package/dist/4-page/ds-layout.d.ts.map +1 -1
- package/dist/4-page/ds-layout.js +528 -50
- package/dist/4-page/styles/ds-container.css +35 -0
- package/dist/4-page/styles/ds-grid.css +56 -0
- package/dist/4-page/styles/ds-layout.css +251 -0
- package/dist/ds-one.bundle.css +700 -0
- package/dist/ds-one.bundle.css.map +7 -0
- package/dist/ds-one.bundle.js +1370 -535
- package/dist/ds-one.bundle.js.map +4 -4
- package/dist/ds-one.bundle.min.css +2 -0
- package/dist/ds-one.bundle.min.css.map +7 -0
- package/dist/ds-one.bundle.min.js +783 -527
- package/dist/ds-one.bundle.min.js.map +4 -4
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/package.json +1 -1
- package/dist/3-unit/doublenav-v1.d.ts +0 -51
- package/dist/3-unit/doublenav-v1.d.ts.map +0 -1
- package/dist/3-unit/doublenav-v1.js +0 -88
- package/dist/3-unit/ds-portfolio-doublenav.d.ts +0 -51
- package/dist/3-unit/ds-portfolio-doublenav.d.ts.map +0 -1
- package/dist/3-unit/ds-portfolio-doublenav.js +0 -88
- package/dist/3-unit/ds-portfolio-panel.d.ts +0 -11
- package/dist/3-unit/ds-portfolio-panel.d.ts.map +0 -1
- package/dist/3-unit/ds-portfolio-panel.js +0 -16
- package/dist/3-unit/ds-portfolio-singlenav.d.ts +0 -32
- package/dist/3-unit/ds-portfolio-singlenav.d.ts.map +0 -1
- package/dist/3-unit/ds-portfolio-singlenav.js +0 -62
- package/dist/3-unit/list-v1.d.ts +0 -11
- package/dist/3-unit/list-v1.d.ts.map +0 -1
- package/dist/3-unit/list-v1.js +0 -15
- package/dist/3-unit/panel-v1.d.ts +0 -11
- package/dist/3-unit/panel-v1.d.ts.map +0 -1
- package/dist/3-unit/panel-v1.js +0 -16
- package/dist/3-unit/row-v1.d.ts +0 -25
- package/dist/3-unit/row-v1.d.ts.map +0 -1
- package/dist/3-unit/row-v1.js +0 -32
- package/dist/3-unit/singlenav-v1.d.ts +0 -32
- package/dist/3-unit/singlenav-v1.d.ts.map +0 -1
- package/dist/3-unit/singlenav-v1.js +0 -62
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
// ds-form.ts
|
|
2
|
+
// Form component for handling form submissions and validation
|
|
3
|
+
|
|
4
|
+
import { LitElement, html, css } from "lit";
|
|
5
|
+
|
|
6
|
+
export interface FormData {
|
|
7
|
+
[key: string]: string | number | boolean | null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface FormValidationResult {
|
|
11
|
+
valid: boolean;
|
|
12
|
+
errors: { [key: string]: string };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class Form extends LitElement {
|
|
16
|
+
static properties = {
|
|
17
|
+
action: { type: String },
|
|
18
|
+
method: { type: String },
|
|
19
|
+
name: { type: String },
|
|
20
|
+
novalidate: { type: Boolean, reflect: true },
|
|
21
|
+
autocomplete: { type: String },
|
|
22
|
+
_isSubmitting: { type: Boolean, state: true },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
declare action: string;
|
|
26
|
+
declare method: "get" | "post";
|
|
27
|
+
declare name: string;
|
|
28
|
+
declare novalidate: boolean;
|
|
29
|
+
declare autocomplete: "on" | "off";
|
|
30
|
+
declare _isSubmitting: boolean;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.action = "";
|
|
35
|
+
this.method = "post";
|
|
36
|
+
this.name = "";
|
|
37
|
+
this.novalidate = false;
|
|
38
|
+
this.autocomplete = "on";
|
|
39
|
+
this._isSubmitting = false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static styles = css`
|
|
43
|
+
:host {
|
|
44
|
+
display: block;
|
|
45
|
+
width: 100%;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
form {
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
gap: calc(var(--05) * var(--sf, 1));
|
|
52
|
+
width: 100%;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
::slotted(*) {
|
|
56
|
+
width: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:host([disabled]) {
|
|
60
|
+
opacity: 0.6;
|
|
61
|
+
pointer-events: none;
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get all form data as an object
|
|
67
|
+
*/
|
|
68
|
+
getFormData(): FormData {
|
|
69
|
+
const data: FormData = {};
|
|
70
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
71
|
+
const elements = slot?.assignedElements({ flatten: true }) || [];
|
|
72
|
+
|
|
73
|
+
for (const element of elements) {
|
|
74
|
+
this._collectFormData(element as HTMLElement, data);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private _collectFormData(element: HTMLElement, data: FormData): void {
|
|
81
|
+
// Check if element has name and value properties
|
|
82
|
+
const name = element.getAttribute("name") || (element as any).name;
|
|
83
|
+
if (name) {
|
|
84
|
+
const value = (element as any).value;
|
|
85
|
+
if (value !== undefined) {
|
|
86
|
+
// Handle checkboxes and radio buttons
|
|
87
|
+
if (
|
|
88
|
+
element instanceof HTMLInputElement &&
|
|
89
|
+
(element.type === "checkbox" || element.type === "radio")
|
|
90
|
+
) {
|
|
91
|
+
if (element.type === "checkbox") {
|
|
92
|
+
data[name] = element.checked;
|
|
93
|
+
} else if (element.type === "radio" && element.checked) {
|
|
94
|
+
data[name] = value;
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
data[name] = value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Recursively check children
|
|
103
|
+
const children =
|
|
104
|
+
element.shadowRoot?.querySelectorAll("*") || element.querySelectorAll("*");
|
|
105
|
+
children.forEach((child) => {
|
|
106
|
+
this._collectFormData(child as HTMLElement, data);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Validate the form
|
|
112
|
+
*/
|
|
113
|
+
validate(): FormValidationResult {
|
|
114
|
+
const result: FormValidationResult = {
|
|
115
|
+
valid: true,
|
|
116
|
+
errors: {},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (this.novalidate) {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
124
|
+
const elements = slot?.assignedElements({ flatten: true }) || [];
|
|
125
|
+
|
|
126
|
+
for (const element of elements) {
|
|
127
|
+
this._validateElement(element as HTMLElement, result);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private _validateElement(
|
|
134
|
+
element: HTMLElement,
|
|
135
|
+
result: FormValidationResult
|
|
136
|
+
): void {
|
|
137
|
+
const name = element.getAttribute("name") || (element as any).name;
|
|
138
|
+
|
|
139
|
+
// Check for custom validation on ds-input elements
|
|
140
|
+
if (element.tagName.toLowerCase() === "ds-input") {
|
|
141
|
+
const input = element as any;
|
|
142
|
+
if (input.required && !input.value) {
|
|
143
|
+
result.valid = false;
|
|
144
|
+
result.errors[name || "unknown"] = "This field is required";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Check native form elements
|
|
149
|
+
if (
|
|
150
|
+
element instanceof HTMLInputElement ||
|
|
151
|
+
element instanceof HTMLTextAreaElement ||
|
|
152
|
+
element instanceof HTMLSelectElement
|
|
153
|
+
) {
|
|
154
|
+
if (!element.checkValidity()) {
|
|
155
|
+
result.valid = false;
|
|
156
|
+
result.errors[name || "unknown"] = element.validationMessage;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Recursively check children
|
|
161
|
+
const children =
|
|
162
|
+
element.shadowRoot?.querySelectorAll("*") || element.querySelectorAll("*");
|
|
163
|
+
children.forEach((child) => {
|
|
164
|
+
this._validateElement(child as HTMLElement, result);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Reset the form
|
|
170
|
+
*/
|
|
171
|
+
reset(): void {
|
|
172
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
173
|
+
const elements = slot?.assignedElements({ flatten: true }) || [];
|
|
174
|
+
|
|
175
|
+
for (const element of elements) {
|
|
176
|
+
this._resetElement(element as HTMLElement);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this.dispatchEvent(new CustomEvent("form-reset", { bubbles: true }));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private _resetElement(element: HTMLElement): void {
|
|
183
|
+
if (
|
|
184
|
+
element instanceof HTMLInputElement ||
|
|
185
|
+
element instanceof HTMLTextAreaElement ||
|
|
186
|
+
element instanceof HTMLSelectElement
|
|
187
|
+
) {
|
|
188
|
+
if (element instanceof HTMLInputElement && element.type === "checkbox") {
|
|
189
|
+
element.checked = false;
|
|
190
|
+
} else {
|
|
191
|
+
element.value = "";
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Handle ds-input elements
|
|
196
|
+
if (element.tagName.toLowerCase() === "ds-input") {
|
|
197
|
+
(element as any).value = "";
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Recursively reset children
|
|
201
|
+
const children =
|
|
202
|
+
element.shadowRoot?.querySelectorAll("*") || element.querySelectorAll("*");
|
|
203
|
+
children.forEach((child) => {
|
|
204
|
+
this._resetElement(child as HTMLElement);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Submit the form
|
|
210
|
+
*/
|
|
211
|
+
async submit(): Promise<void> {
|
|
212
|
+
if (this._isSubmitting) return;
|
|
213
|
+
|
|
214
|
+
const validationResult = this.validate();
|
|
215
|
+
if (!validationResult.valid) {
|
|
216
|
+
this.dispatchEvent(
|
|
217
|
+
new CustomEvent("form-invalid", {
|
|
218
|
+
detail: validationResult.errors,
|
|
219
|
+
bubbles: true,
|
|
220
|
+
})
|
|
221
|
+
);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
this._isSubmitting = true;
|
|
226
|
+
const formData = this.getFormData();
|
|
227
|
+
|
|
228
|
+
this.dispatchEvent(
|
|
229
|
+
new CustomEvent("form-submit", {
|
|
230
|
+
detail: { data: formData },
|
|
231
|
+
bubbles: true,
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// If action is provided, submit to the server
|
|
236
|
+
if (this.action) {
|
|
237
|
+
try {
|
|
238
|
+
const response = await fetch(this.action, {
|
|
239
|
+
method: this.method.toUpperCase(),
|
|
240
|
+
headers: {
|
|
241
|
+
"Content-Type": "application/json",
|
|
242
|
+
},
|
|
243
|
+
body: JSON.stringify(formData),
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
this.dispatchEvent(
|
|
247
|
+
new CustomEvent("form-response", {
|
|
248
|
+
detail: { response, data: formData },
|
|
249
|
+
bubbles: true,
|
|
250
|
+
})
|
|
251
|
+
);
|
|
252
|
+
} catch (error) {
|
|
253
|
+
this.dispatchEvent(
|
|
254
|
+
new CustomEvent("form-error", {
|
|
255
|
+
detail: { error, data: formData },
|
|
256
|
+
bubbles: true,
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
this._isSubmitting = false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private _handleSubmit(e: Event): void {
|
|
266
|
+
e.preventDefault();
|
|
267
|
+
this.submit();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private _handleKeydown(e: KeyboardEvent): void {
|
|
271
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
272
|
+
const target = e.target as HTMLElement;
|
|
273
|
+
// Don't submit if in a textarea
|
|
274
|
+
if (target.tagName.toLowerCase() !== "textarea") {
|
|
275
|
+
e.preventDefault();
|
|
276
|
+
this.submit();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
render() {
|
|
282
|
+
return html`
|
|
283
|
+
<form
|
|
284
|
+
.action=${this.action}
|
|
285
|
+
.method=${this.method}
|
|
286
|
+
.name=${this.name}
|
|
287
|
+
?novalidate=${this.novalidate}
|
|
288
|
+
autocomplete=${this.autocomplete}
|
|
289
|
+
@submit=${this._handleSubmit}
|
|
290
|
+
@keydown=${this._handleKeydown}
|
|
291
|
+
>
|
|
292
|
+
<slot></slot>
|
|
293
|
+
</form>
|
|
294
|
+
`;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
customElements.define("ds-form", Form);
|
|
299
|
+
|
|
300
|
+
declare global {
|
|
301
|
+
interface HTMLElementTagNameMap {
|
|
302
|
+
"ds-form": Form;
|
|
303
|
+
}
|
|
304
|
+
}
|
package/DS1/3-unit/ds-list.ts
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
// ds-
|
|
1
|
+
// ds-list.ts
|
|
2
2
|
// Unit component that
|
|
3
|
-
// can be used to show a list of items
|
|
3
|
+
// can be used to show a list of items consisting of components from core
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { LitElement, html, css } from "lit";
|
|
5
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
6
|
+
import styles from "./styles/ds-list.css?inline";
|
|
9
7
|
|
|
10
8
|
export class List extends LitElement {
|
|
11
|
-
static styles =
|
|
12
|
-
:host {
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
gap: 0;
|
|
16
|
-
width: 100%;
|
|
17
|
-
}
|
|
18
|
-
`;
|
|
9
|
+
static styles = unsafeCSS(styles);
|
|
19
10
|
|
|
20
11
|
render() {
|
|
21
12
|
return html`<slot></slot>`;
|
package/DS1/3-unit/ds-row.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { LitElement, html,
|
|
1
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
2
|
+
import styles from "./styles/ds-row.css?inline";
|
|
2
3
|
|
|
3
4
|
declare global {
|
|
4
5
|
interface CustomElementRegistry {
|
|
@@ -19,24 +20,7 @@ export class Row extends LitElement {
|
|
|
19
20
|
this.type = "fill";
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
static styles =
|
|
23
|
-
:host {
|
|
24
|
-
display: flex;
|
|
25
|
-
align-items: end;
|
|
26
|
-
width: calc(240px * var(--sf));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
:host([type="fill"]) {
|
|
30
|
-
justify-content: space-between;
|
|
31
|
-
height: calc(var(--1) * var(--sf));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
:host([type="centered"]) {
|
|
35
|
-
justify-content: center;
|
|
36
|
-
height: calc(var(--1) * var(--sf));
|
|
37
|
-
gap: calc(var(--025) * var(--sf));
|
|
38
|
-
}
|
|
39
|
-
`;
|
|
23
|
+
static styles = unsafeCSS(styles);
|
|
40
24
|
|
|
41
25
|
render() {
|
|
42
26
|
return html`<slot></slot>`;
|
package/DS1/3-unit/ds-table.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// ds-table.ts
|
|
2
2
|
// Data table component
|
|
3
3
|
|
|
4
|
-
import { LitElement, html,
|
|
4
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
5
|
+
import styles from "./styles/ds-table.css?inline";
|
|
5
6
|
|
|
6
7
|
export interface TableRow {
|
|
7
8
|
product: string;
|
|
@@ -28,90 +29,7 @@ export class DsTable extends LitElement {
|
|
|
28
29
|
this.showStatus = true;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
static styles =
|
|
32
|
-
:host {
|
|
33
|
-
display: block;
|
|
34
|
-
width: 100%;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.table-container {
|
|
38
|
-
display: flex;
|
|
39
|
-
flex-direction: column;
|
|
40
|
-
width: 100%;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.table-header {
|
|
44
|
-
display: grid;
|
|
45
|
-
grid-template-columns: 160px 80px 80px 80px;
|
|
46
|
-
height: 20px;
|
|
47
|
-
width: 400px;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.table-body {
|
|
51
|
-
display: grid;
|
|
52
|
-
grid-template-columns: 160px 80px 80px 80px;
|
|
53
|
-
border: 1px solid var(--black);
|
|
54
|
-
width: 400px;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.header-cell {
|
|
58
|
-
height: 20px;
|
|
59
|
-
display: flex;
|
|
60
|
-
align-items: center;
|
|
61
|
-
justify-content: left;
|
|
62
|
-
padding: 0 2px;
|
|
63
|
-
font-family: var(--typeface-regular);
|
|
64
|
-
font-size: var(--type-size-default);
|
|
65
|
-
font-weight: var(--type-weight-default);
|
|
66
|
-
line-height: var(--type-lineheight-default);
|
|
67
|
-
color: var(--black);
|
|
68
|
-
letter-spacing: -0.26px;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.data-cell {
|
|
72
|
-
height: 20px;
|
|
73
|
-
margin-top: -1px;
|
|
74
|
-
display: flex;
|
|
75
|
-
align-items: center;
|
|
76
|
-
justify-content: left;
|
|
77
|
-
|
|
78
|
-
outline: 1px solid var(--black);
|
|
79
|
-
|
|
80
|
-
font-family: var(--typeface-regular);
|
|
81
|
-
font-size: var(--type-size-default);
|
|
82
|
-
font-weight: var(--type-weight-default);
|
|
83
|
-
line-height: var(--type-lineheight-default);
|
|
84
|
-
color: var(--black);
|
|
85
|
-
letter-spacing: -0.26px;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.status-cell {
|
|
89
|
-
background-color: var(--apple-green);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.product-cell {
|
|
93
|
-
text-align: left;
|
|
94
|
-
justify-content: flex-start;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.users-cell,
|
|
98
|
-
.retention-cell {
|
|
99
|
-
text-align: center;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.status-cell {
|
|
103
|
-
text-align: center;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/* Responsive adjustments */
|
|
107
|
-
@media (max-width: 480px) {
|
|
108
|
-
.table-header,
|
|
109
|
-
.table-body {
|
|
110
|
-
width: 100%;
|
|
111
|
-
grid-template-columns: 1fr 60px 60px 60px;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
`;
|
|
32
|
+
static styles = unsafeCSS(styles);
|
|
115
33
|
|
|
116
34
|
render() {
|
|
117
35
|
return html`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* ds-accordion.css */
|
|
2
|
+
/* Accordion component styles using native <details>/<summary> */
|
|
3
|
+
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
width: calc(240px * var(--sf));
|
|
7
|
+
color: var(--text-color-primary);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
details {
|
|
11
|
+
width: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
summary {
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
user-select: none;
|
|
17
|
+
list-style: none;
|
|
18
|
+
outline: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
summary::-webkit-details-marker {
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.summaryRow {
|
|
26
|
+
width: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
ds-icon.chevron {
|
|
30
|
+
transform: rotate(0deg);
|
|
31
|
+
transition: transform 140ms ease;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
details[open] ds-icon.chevron {
|
|
35
|
+
transform: rotate(180deg);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.detailsBody {
|
|
39
|
+
padding-top: calc(var(--half) * var(--sf));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.detailsText {
|
|
43
|
+
display: block;
|
|
44
|
+
white-space: normal;
|
|
45
|
+
text-align: left;
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* ds-row.css */
|
|
2
|
+
/* Row component styles */
|
|
3
|
+
|
|
4
|
+
:host {
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: end;
|
|
7
|
+
width: calc(240px * var(--sf));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
:host([type="fill"]) {
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
height: calc(var(--1) * var(--sf));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:host([type="centered"]) {
|
|
16
|
+
justify-content: center;
|
|
17
|
+
height: calc(var(--1) * var(--sf));
|
|
18
|
+
gap: calc(var(--025) * var(--sf));
|
|
19
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/* ds-table.css */
|
|
2
|
+
/* Data table component styles */
|
|
3
|
+
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
width: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.table-container {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
width: 100%;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.table-header {
|
|
16
|
+
display: grid;
|
|
17
|
+
grid-template-columns: 160px 80px 80px 80px;
|
|
18
|
+
height: 20px;
|
|
19
|
+
width: 400px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.table-body {
|
|
23
|
+
display: grid;
|
|
24
|
+
grid-template-columns: 160px 80px 80px 80px;
|
|
25
|
+
border: 1px solid var(--black);
|
|
26
|
+
width: 400px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.header-cell {
|
|
30
|
+
height: 20px;
|
|
31
|
+
display: flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: left;
|
|
34
|
+
padding: 0 2px;
|
|
35
|
+
font-family: var(--typeface-regular);
|
|
36
|
+
font-size: var(--type-size-default);
|
|
37
|
+
font-weight: var(--type-weight-default);
|
|
38
|
+
line-height: var(--type-lineheight-default);
|
|
39
|
+
color: var(--black);
|
|
40
|
+
letter-spacing: -0.26px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.data-cell {
|
|
44
|
+
height: 20px;
|
|
45
|
+
margin-top: -1px;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: left;
|
|
49
|
+
outline: 1px solid var(--black);
|
|
50
|
+
font-family: var(--typeface-regular);
|
|
51
|
+
font-size: var(--type-size-default);
|
|
52
|
+
font-weight: var(--type-weight-default);
|
|
53
|
+
line-height: var(--type-lineheight-default);
|
|
54
|
+
color: var(--black);
|
|
55
|
+
letter-spacing: -0.26px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.status-cell {
|
|
59
|
+
background-color: var(--apple-green);
|
|
60
|
+
text-align: center;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.product-cell {
|
|
64
|
+
text-align: left;
|
|
65
|
+
justify-content: flex-start;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.users-cell,
|
|
69
|
+
.retention-cell {
|
|
70
|
+
text-align: center;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Responsive adjustments */
|
|
74
|
+
@media (max-width: 480px) {
|
|
75
|
+
.table-header,
|
|
76
|
+
.table-body {
|
|
77
|
+
width: 100%;
|
|
78
|
+
grid-template-columns: 1fr 60px 60px 60px;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// ds-container.ts
|
|
2
2
|
// Container component with responsive width constraints
|
|
3
3
|
|
|
4
|
-
import { LitElement, html,
|
|
4
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
5
|
+
import styles from "./styles/ds-container.css?inline";
|
|
5
6
|
|
|
6
7
|
declare global {
|
|
7
8
|
interface CustomElementRegistry {
|
|
@@ -11,40 +12,7 @@ declare global {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export class Container extends LitElement {
|
|
14
|
-
static styles =
|
|
15
|
-
:host {
|
|
16
|
-
display: flex;
|
|
17
|
-
width: 100%;
|
|
18
|
-
max-width: 100%;
|
|
19
|
-
flex-direction: column;
|
|
20
|
-
background-color: var(--background-color);
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/* Ensure children don't overflow */
|
|
25
|
-
:host ::slotted(*) {
|
|
26
|
-
max-width: 100%;
|
|
27
|
-
box-sizing: border-box;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* Mobile: 100% width */
|
|
31
|
-
@media (max-width: 820px) {
|
|
32
|
-
:host {
|
|
33
|
-
width: 100%;
|
|
34
|
-
max-width: 100%;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/* Desktop: max-width 1000px, centered */
|
|
39
|
-
@media (min-width: 821px) {
|
|
40
|
-
:host {
|
|
41
|
-
max-width: 1000px;
|
|
42
|
-
margin-left: auto;
|
|
43
|
-
margin-right: auto;
|
|
44
|
-
width: 100%;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
`;
|
|
15
|
+
static styles = unsafeCSS(styles);
|
|
48
16
|
|
|
49
17
|
render() {
|
|
50
18
|
return html`<slot></slot>`;
|