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.
Files changed (199) hide show
  1. package/DS1/0-face/device.ts +130 -0
  2. package/DS1/0-face/scaling.ts +152 -0
  3. package/DS1/1-root/one.css +48 -18
  4. package/DS1/2-core/ds-banner.ts +3 -77
  5. package/DS1/2-core/ds-button.ts +3 -67
  6. package/DS1/2-core/ds-card.ts +137 -0
  7. package/DS1/2-core/ds-cycle.ts +3 -22
  8. package/DS1/2-core/ds-date.ts +3 -9
  9. package/DS1/2-core/ds-gap.ts +3 -75
  10. package/DS1/2-core/ds-icon.ts +3 -33
  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 +3 -29
  14. package/DS1/2-core/ds-tooltip.ts +3 -49
  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 +27 -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 +3 -46
  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 -85
  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 +3 -35
  35. package/DS1/4-page/ds-grid.ts +3 -56
  36. package/DS1/4-page/ds-layout.ts +528 -50
  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 +251 -0
  40. package/DS1/index.ts +7 -2
  41. package/DS1/vite-env.d.ts +9 -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/README.md +2 -2
  98. package/dist/0-face/device.d.ts +5 -0
  99. package/dist/0-face/device.d.ts.map +1 -1
  100. package/dist/0-face/device.js +105 -0
  101. package/dist/0-face/scaling.d.ts +48 -0
  102. package/dist/0-face/scaling.d.ts.map +1 -0
  103. package/dist/0-face/scaling.js +114 -0
  104. package/dist/2-core/ds-banner.d.ts.map +1 -1
  105. package/dist/2-core/ds-banner.js +3 -77
  106. package/dist/2-core/ds-button.d.ts.map +1 -1
  107. package/dist/2-core/ds-button.js +3 -67
  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.map +1 -1
  112. package/dist/2-core/ds-cycle.js +3 -22
  113. package/dist/2-core/ds-date.d.ts.map +1 -1
  114. package/dist/2-core/ds-date.js +3 -9
  115. package/dist/2-core/ds-gap.d.ts.map +1 -1
  116. package/dist/2-core/ds-gap.js +3 -75
  117. package/dist/2-core/ds-icon.d.ts.map +1 -1
  118. package/dist/2-core/ds-icon.js +3 -33
  119. package/dist/2-core/ds-input.d.ts +127 -0
  120. package/dist/2-core/ds-input.d.ts.map +1 -1
  121. package/dist/2-core/ds-input.js +252 -1
  122. package/dist/2-core/ds-pagedots.d.ts +32 -0
  123. package/dist/2-core/ds-pagedots.d.ts.map +1 -0
  124. package/dist/2-core/ds-pagedots.js +36 -0
  125. package/dist/2-core/ds-text.d.ts.map +1 -1
  126. package/dist/2-core/ds-text.js +3 -29
  127. package/dist/2-core/ds-tooltip.d.ts.map +1 -1
  128. package/dist/2-core/ds-tooltip.js +3 -49
  129. package/dist/2-core/styles/ds-banner.css +77 -0
  130. package/dist/2-core/styles/ds-button.css +67 -0
  131. package/dist/2-core/styles/ds-cycle.css +21 -0
  132. package/dist/2-core/styles/ds-date.css +9 -0
  133. package/dist/2-core/styles/ds-gap.css +93 -0
  134. package/dist/2-core/styles/ds-icon.css +30 -0
  135. package/dist/2-core/styles/ds-input.css +46 -0
  136. package/dist/2-core/styles/ds-pagedots.css +26 -0
  137. package/dist/2-core/styles/ds-text.css +29 -0
  138. package/dist/2-core/styles/ds-tooltip.css +49 -0
  139. package/dist/3-unit/ds-accordion.d.ts.map +1 -1
  140. package/dist/3-unit/ds-accordion.js +3 -46
  141. package/dist/3-unit/ds-form.d.ts +70 -0
  142. package/dist/3-unit/ds-form.d.ts.map +1 -0
  143. package/dist/3-unit/ds-form.js +232 -0
  144. package/dist/3-unit/ds-list.d.ts.map +1 -1
  145. package/dist/3-unit/ds-list.js +5 -11
  146. package/dist/3-unit/ds-row.d.ts.map +1 -1
  147. package/dist/3-unit/ds-row.js +3 -19
  148. package/dist/3-unit/ds-table.d.ts.map +1 -1
  149. package/dist/3-unit/ds-table.js +3 -85
  150. package/dist/3-unit/styles/ds-accordion.css +46 -0
  151. package/dist/3-unit/styles/ds-list.css +9 -0
  152. package/dist/3-unit/styles/ds-row.css +19 -0
  153. package/dist/3-unit/styles/ds-table.css +80 -0
  154. package/dist/4-page/ds-container.d.ts.map +1 -1
  155. package/dist/4-page/ds-container.js +3 -35
  156. package/dist/4-page/ds-grid.d.ts.map +1 -1
  157. package/dist/4-page/ds-grid.js +3 -56
  158. package/dist/4-page/ds-layout.d.ts +1 -1
  159. package/dist/4-page/ds-layout.d.ts.map +1 -1
  160. package/dist/4-page/ds-layout.js +528 -50
  161. package/dist/4-page/styles/ds-container.css +35 -0
  162. package/dist/4-page/styles/ds-grid.css +56 -0
  163. package/dist/4-page/styles/ds-layout.css +251 -0
  164. package/dist/ds-one.bundle.css +700 -0
  165. package/dist/ds-one.bundle.css.map +7 -0
  166. package/dist/ds-one.bundle.js +1370 -535
  167. package/dist/ds-one.bundle.js.map +4 -4
  168. package/dist/ds-one.bundle.min.css +2 -0
  169. package/dist/ds-one.bundle.min.css.map +7 -0
  170. package/dist/ds-one.bundle.min.js +783 -527
  171. package/dist/ds-one.bundle.min.js.map +4 -4
  172. package/dist/index.d.ts +7 -2
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.js +7 -2
  175. package/package.json +1 -1
  176. package/dist/3-unit/doublenav-v1.d.ts +0 -51
  177. package/dist/3-unit/doublenav-v1.d.ts.map +0 -1
  178. package/dist/3-unit/doublenav-v1.js +0 -88
  179. package/dist/3-unit/ds-portfolio-doublenav.d.ts +0 -51
  180. package/dist/3-unit/ds-portfolio-doublenav.d.ts.map +0 -1
  181. package/dist/3-unit/ds-portfolio-doublenav.js +0 -88
  182. package/dist/3-unit/ds-portfolio-panel.d.ts +0 -11
  183. package/dist/3-unit/ds-portfolio-panel.d.ts.map +0 -1
  184. package/dist/3-unit/ds-portfolio-panel.js +0 -16
  185. package/dist/3-unit/ds-portfolio-singlenav.d.ts +0 -32
  186. package/dist/3-unit/ds-portfolio-singlenav.d.ts.map +0 -1
  187. package/dist/3-unit/ds-portfolio-singlenav.js +0 -62
  188. package/dist/3-unit/list-v1.d.ts +0 -11
  189. package/dist/3-unit/list-v1.d.ts.map +0 -1
  190. package/dist/3-unit/list-v1.js +0 -15
  191. package/dist/3-unit/panel-v1.d.ts +0 -11
  192. package/dist/3-unit/panel-v1.d.ts.map +0 -1
  193. package/dist/3-unit/panel-v1.js +0 -16
  194. package/dist/3-unit/row-v1.d.ts +0 -25
  195. package/dist/3-unit/row-v1.d.ts.map +0 -1
  196. package/dist/3-unit/row-v1.js +0 -32
  197. package/dist/3-unit/singlenav-v1.d.ts +0 -32
  198. package/dist/3-unit/singlenav-v1.d.ts.map +0 -1
  199. package/dist/3-unit/singlenav-v1.js +0 -62
@@ -0,0 +1,137 @@
1
+ // ds-card.ts
2
+ // Card component for displaying content in a contained box
3
+
4
+ import { LitElement, html, css } from "lit";
5
+
6
+ export class Card extends LitElement {
7
+ static properties = {
8
+ variant: { type: String, reflect: true },
9
+ elevation: { type: Number, reflect: true },
10
+ interactive: { type: Boolean, reflect: true },
11
+ disabled: { type: Boolean, reflect: true },
12
+ padding: { type: String, reflect: true },
13
+ };
14
+
15
+ declare variant: "default" | "outlined" | "elevated" | "filled";
16
+ declare elevation: number;
17
+ declare interactive: boolean;
18
+ declare disabled: boolean;
19
+ declare padding: "none" | "small" | "medium" | "large";
20
+
21
+ constructor() {
22
+ super();
23
+ this.variant = "default";
24
+ this.elevation = 1;
25
+ this.interactive = false;
26
+ this.disabled = false;
27
+ this.padding = "medium";
28
+ }
29
+
30
+ static styles = css`
31
+ :host {
32
+ display: block;
33
+ box-sizing: border-box;
34
+ border-radius: calc(var(--025) * var(--sf, 1));
35
+ background-color: var(--card-background, var(--surface-color, #fff));
36
+ color: var(--text-color-primary);
37
+ transition:
38
+ box-shadow 0.2s ease,
39
+ transform 0.2s ease;
40
+ }
41
+
42
+ :host([variant="default"]) {
43
+ background-color: var(--card-background, var(--surface-color, #fff));
44
+ border: 1px solid var(--border-color, rgba(0, 0, 0, 0.1));
45
+ }
46
+
47
+ :host([variant="outlined"]) {
48
+ background-color: transparent;
49
+ border: 1px solid var(--border-color, rgba(0, 0, 0, 0.2));
50
+ }
51
+
52
+ :host([variant="elevated"]) {
53
+ background-color: var(--card-background, var(--surface-color, #fff));
54
+ border: none;
55
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
56
+ }
57
+
58
+ :host([variant="filled"]) {
59
+ background-color: var(
60
+ --card-background-filled,
61
+ var(--surface-color-secondary, #f5f5f5)
62
+ );
63
+ border: none;
64
+ }
65
+
66
+ :host([elevation="0"]) {
67
+ box-shadow: none;
68
+ }
69
+
70
+ :host([elevation="1"]) {
71
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
72
+ }
73
+
74
+ :host([elevation="2"]) {
75
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
76
+ }
77
+
78
+ :host([elevation="3"]) {
79
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16);
80
+ }
81
+
82
+ :host([interactive]) {
83
+ cursor: pointer;
84
+ }
85
+
86
+ :host([interactive]:hover:not([disabled])) {
87
+ transform: translateY(-2px);
88
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
89
+ }
90
+
91
+ :host([interactive]:active:not([disabled])) {
92
+ transform: translateY(0);
93
+ }
94
+
95
+ :host([disabled]) {
96
+ opacity: 0.5;
97
+ pointer-events: none;
98
+ }
99
+
100
+ :host([padding="none"]) {
101
+ padding: 0;
102
+ }
103
+
104
+ :host([padding="small"]) {
105
+ padding: calc(var(--025) * var(--sf, 1));
106
+ }
107
+
108
+ :host([padding="medium"]) {
109
+ padding: calc(var(--05) * var(--sf, 1));
110
+ }
111
+
112
+ :host([padding="large"]) {
113
+ padding: calc(var(--1) * var(--sf, 1));
114
+ }
115
+
116
+ .card-content {
117
+ width: 100%;
118
+ height: 100%;
119
+ }
120
+ `;
121
+
122
+ render() {
123
+ return html`
124
+ <div class="card-content" part="content">
125
+ <slot></slot>
126
+ </div>
127
+ `;
128
+ }
129
+ }
130
+
131
+ customElements.define("ds-card", Card);
132
+
133
+ declare global {
134
+ interface HTMLElementTagNameMap {
135
+ "ds-card": Card;
136
+ }
137
+ }
@@ -1,4 +1,4 @@
1
- import { LitElement, html, css } from "lit";
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
2
  import {
3
3
  translate,
4
4
  currentLanguage,
@@ -13,6 +13,7 @@ import { savePreferences } from "../0-face/preferences";
13
13
  import "./ds-button";
14
14
  import "./ds-icon";
15
15
  import "./ds-text";
16
+ import styles from "./styles/ds-cycle.css?inline";
16
17
 
17
18
  // Accent color utilities
18
19
  const saveAccentColor = (color: string) => {
@@ -62,27 +63,7 @@ export class Cycle extends LitElement {
62
63
  };
63
64
  }
64
65
 
65
- static styles = css`
66
- :host {
67
- display: inline-flex;
68
- align-items: center;
69
- }
70
-
71
- .cycle {
72
- display: inline-flex;
73
- align-items: center;
74
- gap: var(--025);
75
- }
76
-
77
- .color-preview {
78
- width: var(--05);
79
- height: var(--05);
80
- border-radius: 999px;
81
- border: 1px solid
82
- color-mix(in srgb, var(--text-color-primary) 20%, transparent);
83
- flex: 0 0 auto;
84
- }
85
- `;
66
+ static styles = unsafeCSS(styles);
86
67
 
87
68
  // Add runtime properties using the any type
88
69
  // These are just for TypeScript and don't create shadowing fields
@@ -1,4 +1,5 @@
1
- import { LitElement, html, css } from "lit";
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import styles from "./styles/ds-date.css?inline";
2
3
 
3
4
  /**
4
5
  * A component for displaying the current year
@@ -6,14 +7,7 @@ import { LitElement, html, css } from "lit";
6
7
  * @element ds-date
7
8
  */
8
9
  export class DateComponent extends LitElement {
9
- static styles = css`
10
- :host {
11
- display: inline;
12
- font-family: var(--typeface-regular, var(--typeface-regular-regular));
13
- font-size: inherit;
14
- color: inherit;
15
- }
16
- `;
10
+ static styles = unsafeCSS(styles);
17
11
 
18
12
  render() {
19
13
  const year = new Date().getFullYear();
@@ -1,4 +1,5 @@
1
- import { LitElement, html, css } from "lit";
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import styles from "./styles/ds-gap.css?inline";
2
3
 
3
4
  /**
4
5
  * Full-width vertical spacer.
@@ -21,80 +22,7 @@ export class Gap extends LitElement {
21
22
  this.size = "";
22
23
  }
23
24
 
24
- static styles = css`
25
- :host {
26
- display: block;
27
- width: 100%;
28
- /* Default if no attribute is provided */
29
- --gap-size: var(--unit);
30
- height: var(--gap-size);
31
- flex: 0 0 auto;
32
- }
33
-
34
- /* Semantic sizing tokens (from DS1/1-root/one.css) */
35
- :host([tenth]) {
36
- --gap-size: var(--tenth);
37
- }
38
- :host([quarter]) {
39
- --gap-size: var(--quarter);
40
- }
41
- :host([half]) {
42
- --gap-size: var(--half);
43
- }
44
- :host([eight-tenth]) {
45
- --gap-size: var(--eight-tenth);
46
- }
47
- :host([unit]) {
48
- --gap-size: var(--unit);
49
- }
50
- :host([double]) {
51
- --gap-size: var(--double);
52
- }
53
- :host([triple]) {
54
- --gap-size: var(--triple);
55
- }
56
- :host([quad]) {
57
- --gap-size: var(--quad);
58
- }
59
- :host([oct]) {
60
- --gap-size: var(--oct);
61
- }
62
- :host([dozen]) {
63
- --gap-size: var(--dozen);
64
- }
65
-
66
- /* Raw scale sizing (size="...") */
67
- :host([size="01"]) {
68
- --gap-size: var(--01);
69
- }
70
- :host([size="025"]) {
71
- --gap-size: var(--025);
72
- }
73
- :host([size="05"]) {
74
- --gap-size: var(--05);
75
- }
76
- :host([size="08"]) {
77
- --gap-size: var(--08);
78
- }
79
- :host([size="1"]) {
80
- --gap-size: var(--1);
81
- }
82
- :host([size="2"]) {
83
- --gap-size: var(--2);
84
- }
85
- :host([size="3"]) {
86
- --gap-size: var(--3);
87
- }
88
- :host([size="4"]) {
89
- --gap-size: var(--4);
90
- }
91
- :host([size="8"]) {
92
- --gap-size: var(--8);
93
- }
94
- :host([size="12"]) {
95
- --gap-size: var(--12);
96
- }
97
- `;
25
+ static styles = unsafeCSS(styles);
98
26
 
99
27
  render() {
100
28
  return html``;
@@ -1,5 +1,6 @@
1
- import { LitElement, html, css, type PropertyValues } from "lit";
1
+ import { LitElement, html, unsafeCSS, type PropertyValues } from "lit";
2
2
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
3
+ import styles from "./styles/ds-icon.css?inline";
3
4
 
4
5
  export class Icon extends LitElement {
5
6
  static properties = {
@@ -21,38 +22,7 @@ export class Icon extends LitElement {
21
22
  this.requestUpdate("type", oldVal);
22
23
  }
23
24
 
24
- static styles = css`
25
- :host {
26
- display: inline-flex;
27
- justify-content: center;
28
- align-items: center;
29
- width: calc(16px * var(--sf));
30
- height: calc(16px * var(--sf));
31
- }
32
-
33
- svg {
34
- width: 100%;
35
- height: 100%;
36
- fill: var(--icon-color, currentColor);
37
- }
38
-
39
- path {
40
- fill: var(--icon-color, currentColor);
41
- }
42
-
43
- .icon-container {
44
- display: flex;
45
- justify-content: center;
46
- align-items: center;
47
- width: calc(16px * var(--sf));
48
- height: calc(16px * var(--sf));
49
- }
50
-
51
- /* Notes style color variable for future implementation */
52
- :host {
53
- --notes-style-color: #ffb6b9;
54
- }
55
- `;
25
+ static styles = unsafeCSS(styles);
56
26
 
57
27
  // Load all SVGs from `x Icon/` as raw strings at build time (Vite)
58
28
  // The keys will be the file base names (without extension), lowercased.
@@ -1 +1,306 @@
1
- // here should be an input component
1
+ // ds-input.ts
2
+ // Input component for text and other input types
3
+
4
+ import { LitElement, html, css } from "lit";
5
+ import "./ds-text";
6
+
7
+ export class Input extends LitElement {
8
+ static properties = {
9
+ type: { type: String, reflect: true },
10
+ name: { type: String, reflect: true },
11
+ value: { type: String },
12
+ placeholder: { type: String },
13
+ placeholderKey: { type: String, attribute: "placeholder-key" },
14
+ label: { type: String },
15
+ labelKey: { type: String, attribute: "label-key" },
16
+ disabled: { type: Boolean, reflect: true },
17
+ readonly: { type: Boolean, reflect: true },
18
+ required: { type: Boolean, reflect: true },
19
+ autofocus: { type: Boolean },
20
+ autocomplete: { type: String },
21
+ pattern: { type: String },
22
+ minlength: { type: Number },
23
+ maxlength: { type: Number },
24
+ min: { type: String },
25
+ max: { type: String },
26
+ step: { type: String },
27
+ variant: { type: String, reflect: true },
28
+ error: { type: String },
29
+ errorKey: { type: String, attribute: "error-key" },
30
+ _focused: { type: Boolean, state: true },
31
+ };
32
+
33
+ declare type:
34
+ | "text"
35
+ | "password"
36
+ | "email"
37
+ | "number"
38
+ | "tel"
39
+ | "url"
40
+ | "search"
41
+ | "date"
42
+ | "time"
43
+ | "datetime-local";
44
+ declare name: string;
45
+ declare value: string;
46
+ declare placeholder: string;
47
+ declare placeholderKey: string;
48
+ declare label: string;
49
+ declare labelKey: string;
50
+ declare disabled: boolean;
51
+ declare readonly: boolean;
52
+ declare required: boolean;
53
+ declare autofocus: boolean;
54
+ declare autocomplete: string;
55
+ declare pattern: string;
56
+ declare minlength: number;
57
+ declare maxlength: number;
58
+ declare min: string;
59
+ declare max: string;
60
+ declare step: string;
61
+ declare variant: "default" | "filled" | "outlined";
62
+ declare error: string;
63
+ declare errorKey: string;
64
+ declare _focused: boolean;
65
+
66
+ constructor() {
67
+ super();
68
+ this.type = "text";
69
+ this.name = "";
70
+ this.value = "";
71
+ this.placeholder = "";
72
+ this.placeholderKey = "";
73
+ this.label = "";
74
+ this.labelKey = "";
75
+ this.disabled = false;
76
+ this.readonly = false;
77
+ this.required = false;
78
+ this.autofocus = false;
79
+ this.autocomplete = "off";
80
+ this.pattern = "";
81
+ this.minlength = 0;
82
+ this.maxlength = 0;
83
+ this.min = "";
84
+ this.max = "";
85
+ this.step = "";
86
+ this.variant = "default";
87
+ this.error = "";
88
+ this.errorKey = "";
89
+ this._focused = false;
90
+ }
91
+
92
+ static styles = css`
93
+ :host {
94
+ display: block;
95
+ width: 100%;
96
+ }
97
+
98
+ .input-wrapper {
99
+ display: flex;
100
+ flex-direction: column;
101
+ gap: calc(var(--025) * var(--sf, 1));
102
+ width: 100%;
103
+ }
104
+
105
+ label {
106
+ font-family: var(--typeface-regular);
107
+ font-size: calc(12px * var(--sf, 1));
108
+ color: var(--text-color-secondary);
109
+ }
110
+
111
+ .input-container {
112
+ position: relative;
113
+ display: flex;
114
+ align-items: center;
115
+ width: 100%;
116
+ }
117
+
118
+ input {
119
+ width: 100%;
120
+ height: calc(var(--1) * var(--sf, 1));
121
+ padding: 0 calc(var(--025) * var(--sf, 1));
122
+ font-family: var(--typeface-regular);
123
+ font-size: calc(14px * var(--sf, 1));
124
+ color: var(--text-color-primary);
125
+ background-color: var(--input-background, transparent);
126
+ border: 1px solid var(--input-border-color, var(--border-color, #ccc));
127
+ border-radius: calc(var(--025) * var(--sf, 1));
128
+ outline: none;
129
+ transition:
130
+ border-color 0.2s ease,
131
+ box-shadow 0.2s ease;
132
+ box-sizing: border-box;
133
+ }
134
+
135
+ input::placeholder {
136
+ color: var(--text-color-tertiary, #999);
137
+ }
138
+
139
+ input:focus {
140
+ border-color: var(--accent-color, #007aff);
141
+ box-shadow: 0 0 0 2px var(--input-focus-ring, rgba(0, 122, 255, 0.2));
142
+ }
143
+
144
+ input:disabled {
145
+ opacity: 0.5;
146
+ cursor: not-allowed;
147
+ background-color: var(--input-disabled-background, #f5f5f5);
148
+ }
149
+
150
+ input:read-only {
151
+ background-color: var(--input-readonly-background, #fafafa);
152
+ }
153
+
154
+ :host([variant="filled"]) input {
155
+ background-color: var(
156
+ --input-filled-background,
157
+ var(--surface-color-secondary, #f5f5f5)
158
+ );
159
+ border: none;
160
+ border-bottom: 2px solid var(--border-color, #ccc);
161
+ border-radius: calc(var(--025) * var(--sf, 1))
162
+ calc(var(--025) * var(--sf, 1)) 0 0;
163
+ }
164
+
165
+ :host([variant="filled"]) input:focus {
166
+ border-bottom-color: var(--accent-color, #007aff);
167
+ box-shadow: none;
168
+ }
169
+
170
+ :host([variant="outlined"]) input {
171
+ background-color: transparent;
172
+ border: 2px solid var(--border-color, #ccc);
173
+ }
174
+
175
+ :host([variant="outlined"]) input:focus {
176
+ border-color: var(--accent-color, #007aff);
177
+ }
178
+
179
+ .error-message {
180
+ font-family: var(--typeface-regular);
181
+ font-size: calc(12px * var(--sf, 1));
182
+ color: var(--error-color, #ff3b30);
183
+ margin-top: calc(var(--025) * var(--sf, 1));
184
+ }
185
+
186
+ :host([required]) label::after {
187
+ content: " *";
188
+ color: var(--error-color, #ff3b30);
189
+ }
190
+
191
+ /* Error state */
192
+ input.has-error {
193
+ border-color: var(--error-color, #ff3b30);
194
+ }
195
+
196
+ input.has-error:focus {
197
+ box-shadow: 0 0 0 2px rgba(255, 59, 48, 0.2);
198
+ }
199
+ `;
200
+
201
+ private _handleInput(e: Event): void {
202
+ const target = e.target as HTMLInputElement;
203
+ this.value = target.value;
204
+ this.dispatchEvent(
205
+ new CustomEvent("input-change", {
206
+ detail: { value: this.value, name: this.name },
207
+ bubbles: true,
208
+ })
209
+ );
210
+ }
211
+
212
+ private _handleFocus(): void {
213
+ this._focused = true;
214
+ this.dispatchEvent(new CustomEvent("input-focus", { bubbles: true }));
215
+ }
216
+
217
+ private _handleBlur(): void {
218
+ this._focused = false;
219
+ this.dispatchEvent(new CustomEvent("input-blur", { bubbles: true }));
220
+ }
221
+
222
+ /**
223
+ * Focus the input element
224
+ */
225
+ focus(): void {
226
+ const input = this.shadowRoot?.querySelector("input");
227
+ input?.focus();
228
+ }
229
+
230
+ /**
231
+ * Blur the input element
232
+ */
233
+ blur(): void {
234
+ const input = this.shadowRoot?.querySelector("input");
235
+ input?.blur();
236
+ }
237
+
238
+ /**
239
+ * Select all text in the input
240
+ */
241
+ select(): void {
242
+ const input = this.shadowRoot?.querySelector("input");
243
+ input?.select();
244
+ }
245
+
246
+ render() {
247
+ const hasError = Boolean(this.error || this.errorKey);
248
+
249
+ return html`
250
+ <div class="input-wrapper">
251
+ ${this.label || this.labelKey
252
+ ? html`
253
+ <label for="input">
254
+ ${this.labelKey
255
+ ? html`<ds-text .key=${this.labelKey}></ds-text>`
256
+ : this.label}
257
+ </label>
258
+ `
259
+ : null}
260
+
261
+ <div class="input-container">
262
+ <input
263
+ id="input"
264
+ .type=${this.type}
265
+ .name=${this.name}
266
+ .value=${this.value}
267
+ .placeholder=${this.placeholder}
268
+ ?disabled=${this.disabled}
269
+ ?readonly=${this.readonly}
270
+ ?required=${this.required}
271
+ ?autofocus=${this.autofocus}
272
+ autocomplete=${this.autocomplete}
273
+ pattern=${this.pattern || ""}
274
+ minlength=${this.minlength || ""}
275
+ maxlength=${this.maxlength || ""}
276
+ min=${this.min}
277
+ max=${this.max}
278
+ step=${this.step}
279
+ class=${hasError ? "has-error" : ""}
280
+ @input=${this._handleInput}
281
+ @focus=${this._handleFocus}
282
+ @blur=${this._handleBlur}
283
+ />
284
+ </div>
285
+
286
+ ${hasError
287
+ ? html`
288
+ <div class="error-message">
289
+ ${this.errorKey
290
+ ? html`<ds-text .key=${this.errorKey}></ds-text>`
291
+ : this.error}
292
+ </div>
293
+ `
294
+ : null}
295
+ </div>
296
+ `;
297
+ }
298
+ }
299
+
300
+ customElements.define("ds-input", Input);
301
+
302
+ declare global {
303
+ interface HTMLElementTagNameMap {
304
+ "ds-input": Input;
305
+ }
306
+ }
@@ -0,0 +1,52 @@
1
+ import { LitElement, html, unsafeCSS } from "lit";
2
+ import styles from "./styles/ds-pagedots.css?inline";
3
+
4
+ /**
5
+ * Page dots indicator component for carousels and pagination.
6
+ *
7
+ * Usage:
8
+ * - <ds-pagedots count="3" active="0"></ds-pagedots>
9
+ */
10
+ export class Pagedots extends LitElement {
11
+ static properties = {
12
+ /** Number of dots to display */
13
+ count: { type: Number, reflect: true },
14
+ /** Index of the active dot (0-based) */
15
+ active: { type: Number, reflect: true },
16
+ };
17
+
18
+ declare count: number;
19
+ declare active: number;
20
+
21
+ constructor() {
22
+ super();
23
+ this.count = 3;
24
+ this.active = 0;
25
+ }
26
+
27
+ static styles = unsafeCSS(styles);
28
+
29
+ render() {
30
+ const dots = Array.from({ length: this.count }, (_, i) => i);
31
+ return html`
32
+ ${dots.map(
33
+ (index) => html`
34
+ <span
35
+ class="dot ${index === this.active ? "active" : ""}"
36
+ role="button"
37
+ aria-label="Slide ${index + 1}"
38
+ aria-current="${index === this.active ? "true" : "false"}"
39
+ ></span>
40
+ `
41
+ )}
42
+ `;
43
+ }
44
+ }
45
+
46
+ customElements.define("ds-pagedots", Pagedots);
47
+
48
+ declare global {
49
+ interface HTMLElementTagNameMap {
50
+ "ds-pagedots": Pagedots;
51
+ }
52
+ }