ds-one 0.2.5-alpha.9 → 0.3.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/DS1/0-face/device.ts +313 -29
  2. package/DS1/1-root/fonts/Iosevka-Regular.woff2 +0 -0
  3. package/DS1/1-root/one.css +124 -77
  4. package/DS1/2-core/ds-banner.ts +120 -1
  5. package/DS1/2-core/ds-button.ts +16 -93
  6. package/DS1/2-core/ds-card.ts +137 -0
  7. package/DS1/2-core/ds-cycle.ts +77 -179
  8. package/DS1/2-core/ds-date.ts +3 -10
  9. package/DS1/2-core/ds-gap.ts +38 -0
  10. package/DS1/2-core/ds-icon.ts +6 -35
  11. package/DS1/2-core/ds-input.ts +306 -1
  12. package/DS1/2-core/ds-pagedots.ts +52 -0
  13. package/DS1/2-core/ds-text.ts +55 -28
  14. package/DS1/2-core/ds-tooltip.ts +12 -58
  15. package/DS1/2-core/styles/ds-banner.css +77 -0
  16. package/DS1/2-core/styles/ds-button.css +67 -0
  17. package/DS1/2-core/styles/ds-cycle.css +21 -0
  18. package/DS1/2-core/styles/ds-date.css +9 -0
  19. package/DS1/2-core/styles/ds-gap.css +93 -0
  20. package/DS1/2-core/styles/ds-icon.css +30 -0
  21. package/DS1/2-core/styles/ds-input.css +46 -0
  22. package/DS1/2-core/styles/ds-pagedots.css +31 -0
  23. package/DS1/2-core/styles/ds-text.css +29 -0
  24. package/DS1/2-core/styles/ds-tooltip.css +49 -0
  25. package/DS1/3-unit/ds-accordion.ts +95 -0
  26. package/DS1/3-unit/ds-form.ts +304 -0
  27. package/DS1/3-unit/ds-list.ts +5 -14
  28. package/DS1/3-unit/ds-row.ts +3 -19
  29. package/DS1/3-unit/ds-table.ts +3 -86
  30. package/DS1/3-unit/styles/ds-accordion.css +46 -0
  31. package/DS1/3-unit/styles/ds-list.css +9 -0
  32. package/DS1/3-unit/styles/ds-row.css +19 -0
  33. package/DS1/3-unit/styles/ds-table.css +80 -0
  34. package/DS1/4-page/ds-container.ts +28 -0
  35. package/DS1/4-page/ds-grid.ts +37 -50
  36. package/DS1/4-page/ds-layout.ts +652 -163
  37. package/DS1/4-page/styles/ds-container.css +35 -0
  38. package/DS1/4-page/styles/ds-grid.css +56 -0
  39. package/DS1/4-page/styles/ds-layout.css +246 -0
  40. package/DS1/index.ts +8 -1
  41. package/DS1/vite-env.d.ts +13 -0
  42. package/DS1/x-icon/2x.svg +4 -0
  43. package/DS1/x-icon/2xdots.svg +18 -0
  44. package/DS1/x-icon/2xgrid.svg +6 -0
  45. package/DS1/x-icon/2xlines.svg +6 -0
  46. package/DS1/x-icon/4x4.svg +18 -0
  47. package/DS1/x-icon/apple.svg +4 -0
  48. package/DS1/x-icon/avatar.svg +4 -0
  49. package/DS1/x-icon/big.svg +4 -0
  50. package/DS1/x-icon/blank.svg +3 -0
  51. package/DS1/x-icon/check.svg +3 -0
  52. package/DS1/x-icon/close.svg +3 -0
  53. package/DS1/x-icon/collapse.svg +3 -0
  54. package/DS1/x-icon/color.svg +4 -0
  55. package/DS1/x-icon/column.svg +5 -0
  56. package/DS1/x-icon/default.svg +3 -0
  57. package/DS1/x-icon/delete.svg +5 -0
  58. package/DS1/x-icon/dictate.svg +6 -0
  59. package/DS1/x-icon/do.svg +3 -0
  60. package/DS1/x-icon/down.svg +3 -0
  61. package/DS1/x-icon/duplicate.svg +4 -0
  62. package/DS1/x-icon/gallery.svg +5 -0
  63. package/DS1/x-icon/google.svg +6 -0
  64. package/DS1/x-icon/head.svg +5 -0
  65. package/DS1/x-icon/home.svg +3 -0
  66. package/DS1/x-icon/icon.svg +4 -0
  67. package/DS1/x-icon/in.svg +4 -0
  68. package/DS1/x-icon/lock.svg +5 -0
  69. package/DS1/x-icon/loop.svg +5 -0
  70. package/DS1/x-icon/mic.svg +5 -0
  71. package/DS1/x-icon/minimize.svg +3 -0
  72. package/DS1/x-icon/more.svg +5 -0
  73. package/DS1/x-icon/neutral.svg +6 -0
  74. package/DS1/x-icon/note.svg +6 -0
  75. package/DS1/x-icon/page.svg +4 -0
  76. package/DS1/x-icon/plus.svg +3 -0
  77. package/DS1/x-icon/rewind.svg +4 -0
  78. package/DS1/x-icon/row.svg +5 -0
  79. package/DS1/x-icon/sdown.svg +3 -0
  80. package/DS1/x-icon/search.svg +4 -0
  81. package/DS1/x-icon/see.svg +4 -0
  82. package/DS1/x-icon/ship.svg +5 -0
  83. package/DS1/x-icon/star.svg +3 -0
  84. package/DS1/x-icon/status.svg +4 -0
  85. package/DS1/x-icon/sup.svg +3 -0
  86. package/DS1/x-icon/title.svg +3 -0
  87. package/DS1/x-icon/undo.svg +3 -0
  88. package/DS1/x-icon/ungroup.svg +4 -0
  89. package/DS1/x-icon/unhead.svg +3 -0
  90. package/DS1/x-icon/unicon.svg +3 -0
  91. package/DS1/x-icon/unlock.svg +5 -0
  92. package/DS1/x-icon/unmic.svg +6 -0
  93. package/DS1/x-icon/unsee.svg +5 -0
  94. package/DS1/x-icon/unstar.svg +3 -0
  95. package/DS1/x-icon/untitle.svg +3 -0
  96. package/DS1/x-icon/up.svg +3 -0
  97. package/LICENSE +1 -1
  98. package/README.md +4 -4
  99. package/dist/0-face/device.d.ts +52 -1
  100. package/dist/0-face/device.d.ts.map +1 -1
  101. package/dist/0-face/device.js +239 -21
  102. package/dist/2-core/ds-banner.d.ts +67 -0
  103. package/dist/2-core/ds-banner.d.ts.map +1 -1
  104. package/dist/2-core/ds-banner.js +97 -1
  105. package/dist/2-core/ds-button.d.ts +4 -15
  106. package/dist/2-core/ds-button.d.ts.map +1 -1
  107. package/dist/2-core/ds-button.js +14 -86
  108. package/dist/2-core/ds-card.d.ts +39 -0
  109. package/dist/2-core/ds-card.d.ts.map +1 -0
  110. package/dist/2-core/ds-card.js +119 -0
  111. package/dist/2-core/ds-cycle.d.ts +1 -5
  112. package/dist/2-core/ds-cycle.d.ts.map +1 -1
  113. package/dist/2-core/ds-cycle.js +74 -163
  114. package/dist/2-core/ds-date.d.ts.map +1 -1
  115. package/dist/2-core/ds-date.js +3 -9
  116. package/dist/2-core/ds-gap.d.ts +28 -0
  117. package/dist/2-core/ds-gap.d.ts.map +1 -0
  118. package/dist/2-core/ds-gap.js +25 -0
  119. package/dist/2-core/ds-icon.d.ts.map +1 -1
  120. package/dist/2-core/ds-icon.js +6 -35
  121. package/dist/2-core/ds-input.d.ts +127 -0
  122. package/dist/2-core/ds-input.d.ts.map +1 -1
  123. package/dist/2-core/ds-input.js +252 -1
  124. package/dist/2-core/ds-pagedots.d.ts +32 -0
  125. package/dist/2-core/ds-pagedots.d.ts.map +1 -0
  126. package/dist/2-core/ds-pagedots.js +36 -0
  127. package/dist/2-core/ds-text.d.ts +5 -3
  128. package/dist/2-core/ds-text.d.ts.map +1 -1
  129. package/dist/2-core/ds-text.js +49 -27
  130. package/dist/2-core/ds-tooltip.d.ts +2 -2
  131. package/dist/2-core/ds-tooltip.d.ts.map +1 -1
  132. package/dist/2-core/ds-tooltip.js +11 -57
  133. package/dist/3-unit/ds-accordion.d.ts +47 -0
  134. package/dist/3-unit/ds-accordion.d.ts.map +1 -0
  135. package/dist/3-unit/ds-accordion.js +75 -0
  136. package/dist/3-unit/ds-form.d.ts +70 -0
  137. package/dist/3-unit/ds-form.d.ts.map +1 -0
  138. package/dist/3-unit/ds-form.js +232 -0
  139. package/dist/3-unit/ds-list.d.ts.map +1 -1
  140. package/dist/3-unit/ds-list.js +5 -11
  141. package/dist/3-unit/ds-row.d.ts.map +1 -1
  142. package/dist/3-unit/ds-row.js +3 -19
  143. package/dist/3-unit/ds-table.d.ts.map +1 -1
  144. package/dist/3-unit/ds-table.js +3 -86
  145. package/dist/{3-unit/row-v1.d.ts → 4-page/ds-container.d.ts} +3 -11
  146. package/dist/4-page/ds-container.d.ts.map +1 -0
  147. package/dist/4-page/ds-container.js +11 -0
  148. package/dist/4-page/ds-grid.d.ts +5 -0
  149. package/dist/4-page/ds-grid.d.ts.map +1 -1
  150. package/dist/4-page/ds-grid.js +38 -56
  151. package/dist/4-page/ds-layout.d.ts +3 -3
  152. package/dist/4-page/ds-layout.d.ts.map +1 -1
  153. package/dist/4-page/ds-layout.js +651 -162
  154. package/dist/ds-one.bundle.js +3247 -2089
  155. package/dist/ds-one.bundle.js.map +1 -7
  156. package/dist/ds-one.bundle.min.js +3839 -550
  157. package/dist/ds-one.bundle.min.js.map +1 -7
  158. package/dist/index.d.ts +8 -1
  159. package/dist/index.d.ts.map +1 -1
  160. package/dist/index.js +8 -1
  161. package/package.json +4 -2
  162. package/dist/3-unit/doublenav-v1.d.ts +0 -51
  163. package/dist/3-unit/doublenav-v1.d.ts.map +0 -1
  164. package/dist/3-unit/doublenav-v1.js +0 -88
  165. package/dist/3-unit/ds-portfolio-doublenav.d.ts +0 -51
  166. package/dist/3-unit/ds-portfolio-doublenav.d.ts.map +0 -1
  167. package/dist/3-unit/ds-portfolio-doublenav.js +0 -88
  168. package/dist/3-unit/ds-portfolio-panel.d.ts +0 -11
  169. package/dist/3-unit/ds-portfolio-panel.d.ts.map +0 -1
  170. package/dist/3-unit/ds-portfolio-panel.js +0 -16
  171. package/dist/3-unit/ds-portfolio-singlenav.d.ts +0 -32
  172. package/dist/3-unit/ds-portfolio-singlenav.d.ts.map +0 -1
  173. package/dist/3-unit/ds-portfolio-singlenav.js +0 -62
  174. package/dist/3-unit/list-v1.d.ts +0 -11
  175. package/dist/3-unit/list-v1.d.ts.map +0 -1
  176. package/dist/3-unit/list-v1.js +0 -15
  177. package/dist/3-unit/panel-v1.d.ts +0 -11
  178. package/dist/3-unit/panel-v1.d.ts.map +0 -1
  179. package/dist/3-unit/panel-v1.js +0 -16
  180. package/dist/3-unit/row-v1.d.ts.map +0 -1
  181. package/dist/3-unit/row-v1.js +0 -32
  182. package/dist/3-unit/singlenav-v1.d.ts +0 -32
  183. package/dist/3-unit/singlenav-v1.d.ts.map +0 -1
  184. 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
+ }
@@ -1,21 +1,12 @@
1
- // ds-banner.ts
1
+ // ds-list.ts
2
2
  // Unit component that
3
- // can be used to show a list of items consiting of compoentnts from core
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 = css`
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>`;
@@ -1,4 +1,5 @@
1
- import { LitElement, html, css } from "lit";
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 = css`
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>`;
@@ -1,7 +1,8 @@
1
1
  // ds-table.ts
2
2
  // Data table component
3
3
 
4
- import { LitElement, html, css } from "lit";
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,96 +29,12 @@ export class DsTable extends LitElement {
28
29
  this.showStatus = true;
29
30
  }
30
31
 
31
- static styles = css`
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);
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);
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(--light-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`
118
36
  <div class="table-container">
119
37
  <div class="table-header">
120
-
121
38
  <div class="header-cell product-cell">Product</div>
122
39
  <div class="header-cell users-cell">Users</div>
123
40
  <div class="header-cell retention-cell">Retention</div>
@@ -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,9 @@
1
+ /* ds-list.css */
2
+ /* List component styles for displaying a list of items */
3
+
4
+ :host {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 0;
8
+ width: 100%;
9
+ }
@@ -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
+ }
@@ -0,0 +1,28 @@
1
+ // ds-container.ts
2
+ // Container component with responsive width constraints
3
+
4
+ import { LitElement, html, unsafeCSS } from "lit";
5
+ import styles from "./styles/ds-container.css?inline";
6
+
7
+ declare global {
8
+ interface CustomElementRegistry {
9
+ define(name: string, constructor: typeof LitElement): void;
10
+ }
11
+ var customElements: CustomElementRegistry;
12
+ }
13
+
14
+ export class Container extends LitElement {
15
+ static styles = unsafeCSS(styles);
16
+
17
+ render() {
18
+ return html`<slot></slot>`;
19
+ }
20
+ }
21
+
22
+ customElements.define("ds-container", Container);
23
+
24
+ declare global {
25
+ interface HTMLElementTagNameMap {
26
+ "ds-container": Container;
27
+ }
28
+ }