@chiralkit/design-system 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/chiralkit-ds/chiralkit-ds.css +1 -0
- package/dist/chiralkit-ds/chiralkit-ds.esm.js +1 -0
- package/dist/chiralkit-ds/index.esm.js +1 -0
- package/dist/chiralkit-ds/p-038fa008.entry.js +1 -0
- package/dist/chiralkit-ds/p-2fdc1012.entry.js +1 -0
- package/dist/chiralkit-ds/p-306ec33b.entry.js +1 -0
- package/dist/chiralkit-ds/p-3f704698.entry.js +1 -0
- package/dist/chiralkit-ds/p-41081d22.entry.js +1 -0
- package/dist/chiralkit-ds/p-7d7e5aac.entry.js +1 -0
- package/dist/chiralkit-ds/p-84b801f8.entry.js +1 -0
- package/dist/chiralkit-ds/p-a28c71b4.entry.js +1 -0
- package/dist/chiralkit-ds/p-be84312f.entry.js +1 -0
- package/dist/chiralkit-ds/p-c8015fe6.entry.js +1 -0
- package/dist/chiralkit-ds/p-d36a6bea.entry.js +1 -0
- package/dist/chiralkit-ds/p-e-glNjK6.js +2 -0
- package/dist/chiralkit-ds/p-f0f9ff61.entry.js +1 -0
- package/dist/cjs/chiralkit-ds.cjs.js +24 -0
- package/dist/cjs/ds-badge.cjs.entry.js +18 -0
- package/dist/cjs/ds-button.cjs.entry.js +26 -0
- package/dist/cjs/ds-card.cjs.entry.js +17 -0
- package/dist/cjs/ds-checkbox.cjs.entry.js +67 -0
- package/dist/cjs/ds-code-block.cjs.entry.js +39 -0
- package/dist/cjs/ds-dialog.cjs.entry.js +67 -0
- package/dist/cjs/ds-input.cjs.entry.js +50 -0
- package/dist/cjs/ds-loader.cjs.entry.js +26 -0
- package/dist/cjs/ds-select.cjs.entry.js +85 -0
- package/dist/cjs/ds-tabs.cjs.entry.js +138 -0
- package/dist/cjs/ds-textarea.cjs.entry.js +50 -0
- package/dist/cjs/ds-tooltip.cjs.entry.js +233 -0
- package/dist/cjs/index-mMvyq7U_.js +2018 -0
- package/dist/cjs/index.cjs.js +10 -0
- package/dist/cjs/loader.cjs.js +12 -0
- package/dist/collection/collection-manifest.json +24 -0
- package/dist/collection/components/ds-badge/ds-badge.css +36 -0
- package/dist/collection/components/ds-badge/ds-badge.js +93 -0
- package/dist/collection/components/ds-button/ds-button.css +66 -0
- package/dist/collection/components/ds-button/ds-button.js +197 -0
- package/dist/collection/components/ds-card/ds-card.css +12 -0
- package/dist/collection/components/ds-card/ds-card.js +68 -0
- package/dist/collection/components/ds-checkbox/ds-checkbox.css +22 -0
- package/dist/collection/components/ds-checkbox/ds-checkbox.js +339 -0
- package/dist/collection/components/ds-code-block/ds-code-block.css +65 -0
- package/dist/collection/components/ds-code-block/ds-code-block.js +162 -0
- package/dist/collection/components/ds-dialog/ds-dialog.css +30 -0
- package/dist/collection/components/ds-dialog/ds-dialog.js +313 -0
- package/dist/collection/components/ds-input/ds-input.css +38 -0
- package/dist/collection/components/ds-input/ds-input.js +353 -0
- package/dist/collection/components/ds-loader/ds-loader.css +94 -0
- package/dist/collection/components/ds-loader/ds-loader.js +149 -0
- package/dist/collection/components/ds-select/ds-select.css +69 -0
- package/dist/collection/components/ds-select/ds-select.js +235 -0
- package/dist/collection/components/ds-tabs/ds-tabs.css +59 -0
- package/dist/collection/components/ds-tabs/ds-tabs.js +248 -0
- package/dist/collection/components/ds-textarea/ds-textarea.css +41 -0
- package/dist/collection/components/ds-textarea/ds-textarea.js +342 -0
- package/dist/collection/components/ds-tooltip/ds-tooltip.css +31 -0
- package/dist/collection/components/ds-tooltip/ds-tooltip.js +318 -0
- package/dist/collection/components.js +2 -0
- package/dist/collection/index.js +1 -0
- package/dist/components/ds-badge.d.ts +11 -0
- package/dist/components/ds-badge.js +1 -0
- package/dist/components/ds-button.d.ts +11 -0
- package/dist/components/ds-button.js +1 -0
- package/dist/components/ds-card.d.ts +11 -0
- package/dist/components/ds-card.js +1 -0
- package/dist/components/ds-checkbox.d.ts +11 -0
- package/dist/components/ds-checkbox.js +1 -0
- package/dist/components/ds-code-block.d.ts +11 -0
- package/dist/components/ds-code-block.js +1 -0
- package/dist/components/ds-dialog.d.ts +11 -0
- package/dist/components/ds-dialog.js +1 -0
- package/dist/components/ds-input.d.ts +11 -0
- package/dist/components/ds-input.js +1 -0
- package/dist/components/ds-loader.d.ts +11 -0
- package/dist/components/ds-loader.js +1 -0
- package/dist/components/ds-select.d.ts +11 -0
- package/dist/components/ds-select.js +1 -0
- package/dist/components/ds-tabs.d.ts +11 -0
- package/dist/components/ds-tabs.js +1 -0
- package/dist/components/ds-textarea.d.ts +11 -0
- package/dist/components/ds-textarea.js +1 -0
- package/dist/components/ds-tooltip.d.ts +11 -0
- package/dist/components/ds-tooltip.js +1 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/p-DDUZow8F.js +1 -0
- package/dist/components/p-ZsYP0VBq.js +1 -0
- package/dist/components/p-k0ywxWpC.js +1 -0
- package/dist/esm/chiralkit-ds.js +20 -0
- package/dist/esm/ds-badge.entry.js +16 -0
- package/dist/esm/ds-button.entry.js +24 -0
- package/dist/esm/ds-card.entry.js +15 -0
- package/dist/esm/ds-checkbox.entry.js +65 -0
- package/dist/esm/ds-code-block.entry.js +37 -0
- package/dist/esm/ds-dialog.entry.js +65 -0
- package/dist/esm/ds-input.entry.js +48 -0
- package/dist/esm/ds-loader.entry.js +24 -0
- package/dist/esm/ds-select.entry.js +83 -0
- package/dist/esm/ds-tabs.entry.js +136 -0
- package/dist/esm/ds-textarea.entry.js +48 -0
- package/dist/esm/ds-tooltip.entry.js +231 -0
- package/dist/esm/index-e-glNjK6.js +2008 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/loader.js +10 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/layouts/app-shell.css +84 -0
- package/dist/tests/a11y.js +55 -0
- package/dist/types/Users/alex/projects/MyGitHub/chiralkit/packages/design-system/.stencil/tests/a11y.d.ts +17 -0
- package/dist/types/components/ds-badge/ds-badge.d.ts +54 -0
- package/dist/types/components/ds-button/ds-button.d.ts +75 -0
- package/dist/types/components/ds-card/ds-card.d.ts +53 -0
- package/dist/types/components/ds-checkbox/ds-checkbox.d.ts +94 -0
- package/dist/types/components/ds-code-block/ds-code-block.d.ts +83 -0
- package/dist/types/components/ds-dialog/ds-dialog.d.ts +148 -0
- package/dist/types/components/ds-input/ds-input.d.ts +104 -0
- package/dist/types/components/ds-loader/ds-loader.d.ts +64 -0
- package/dist/types/components/ds-select/ds-select.d.ts +123 -0
- package/dist/types/components/ds-tabs/ds-tabs.d.ts +155 -0
- package/dist/types/components/ds-textarea/ds-textarea.d.ts +93 -0
- package/dist/types/components/ds-tooltip/ds-tooltip.d.ts +26 -0
- package/dist/types/components.d.ts +3068 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/stencil-public-runtime.d.ts +1861 -0
- package/docs.json +2112 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +78 -0
- package/react/components/ds-badge.tsx +25 -0
- package/react/components/ds-button.tsx +25 -0
- package/react/components/ds-card.tsx +25 -0
- package/react/components/ds-checkbox.tsx +25 -0
- package/react/components/ds-code-block.tsx +25 -0
- package/react/components/ds-dialog.tsx +31 -0
- package/react/components/ds-input.tsx +25 -0
- package/react/components/ds-loader.tsx +25 -0
- package/react/components/ds-select.tsx +25 -0
- package/react/components/ds-tabs.tsx +25 -0
- package/react/components/ds-textarea.tsx +25 -0
- package/react/components/ds-tooltip.tsx +25 -0
- package/react/components.ts +162 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { h, Host, } from "@stencil/core";
|
|
2
|
+
/**
|
|
3
|
+
* ## Accessibility
|
|
4
|
+
*
|
|
5
|
+
* **Category:** form-field
|
|
6
|
+
* **APG pattern:** N/A — native element. This wraps a native `<input>`;
|
|
7
|
+
* there is no WAI-ARIA APG pattern for a plain text input because the
|
|
8
|
+
* browser already implements it natively. Reference:
|
|
9
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
|
|
10
|
+
*
|
|
11
|
+
* **Keyboard interactions:**
|
|
12
|
+
* - Tab: moves focus to the native `<input>` (shadow DOM does not
|
|
13
|
+
* interrupt tab order).
|
|
14
|
+
* - Printable characters: insert at the caret position (native).
|
|
15
|
+
* - Backspace / Delete: native editing.
|
|
16
|
+
* - Arrow keys: move the caret within the value (native); for
|
|
17
|
+
* `type="number"` Up/Down step the numeric value (native).
|
|
18
|
+
* - Enter: on `type="search"` may submit the enclosing form (native);
|
|
19
|
+
* no custom handling.
|
|
20
|
+
* - Escape: no native meaning for a text input.
|
|
21
|
+
*
|
|
22
|
+
* **ARIA:**
|
|
23
|
+
* - Roles used: none explicit — the native `<input>` supplies its
|
|
24
|
+
* implicit role (`textbox`, `searchbox`, etc. depending on `type`).
|
|
25
|
+
* - State attributes: `disabled` (native attribute, not `aria-disabled`),
|
|
26
|
+
* `aria-invalid` (from the `invalid` prop), `aria-required` (from the
|
|
27
|
+
* `required` prop), `aria-describedby` (from the `describedBy` prop,
|
|
28
|
+
* expected to reference a light-DOM node id — typically a hint or
|
|
29
|
+
* error message rendered by the consumer alongside the field).
|
|
30
|
+
* - Labeling strategy: `aria-label` set from the `label` prop onto the
|
|
31
|
+
* internal `<input>`. This is the **canonical, recommended** mode —
|
|
32
|
+
* explicit and independent of DOM structure. Consumers MUST pass
|
|
33
|
+
* `label` (or otherwise give the field an accessible name) — an
|
|
34
|
+
* `<input>` with no accessible name is a WCAG failure (axe rule
|
|
35
|
+
* `label`). Wrapping the host in a light-DOM `<label>` (e.g.
|
|
36
|
+
* `<label>Email <ds-input></ds-input></label>`) also produces an
|
|
37
|
+
* accessible name in Chromium via flattened-tree resolution — the
|
|
38
|
+
* same secondary mode documented on `ds-select`, verified in this
|
|
39
|
+
* component's e2e tests. Setting `aria-label` directly on the
|
|
40
|
+
* `<ds-input>` host does NOT work: shadow-DOM attribute forwarding
|
|
41
|
+
* would be required — use the `label` prop instead.
|
|
42
|
+
*
|
|
43
|
+
* **Focus:**
|
|
44
|
+
* - On mount: nothing auto-focuses.
|
|
45
|
+
* - On value change: focus remains on the native `<input>`.
|
|
46
|
+
* - Focus indicator: the browser default `:focus-visible` ring is kept
|
|
47
|
+
* on purpose — a themed focus ring using `--ds-color-focus` is a
|
|
48
|
+
* future decision once the DS ships a shared focus utility. Not
|
|
49
|
+
* overridden by `ds-input.css`.
|
|
50
|
+
*
|
|
51
|
+
* **Motion:**
|
|
52
|
+
* - Animations: none.
|
|
53
|
+
* - Reduced-motion behavior: N/A — no animation to collapse.
|
|
54
|
+
*
|
|
55
|
+
* **Contrast:**
|
|
56
|
+
* - Text: inherits `color: inherit` / `currentColor`; ratio depends on
|
|
57
|
+
* the consumer's theme, not verified in isolation here.
|
|
58
|
+
* - Border: `color-mix(in oklch, currentColor 22%, transparent)`,
|
|
59
|
+
* matching `ds-select` — inherits whatever contrast the host page
|
|
60
|
+
* sets. WCAG 1.4.11 (3:1 non-text) is the consumer's responsibility
|
|
61
|
+
* in themes that override the surface.
|
|
62
|
+
*
|
|
63
|
+
* **Screen reader announcement:**
|
|
64
|
+
* - Rendered state: announces the `label` prop text as the accessible
|
|
65
|
+
* name, followed by the browser/AT's role announcement for the
|
|
66
|
+
* input type ("edit text", "search text", "password", "phone
|
|
67
|
+
* number", "email"…). When `required=true` the announcement
|
|
68
|
+
* includes "required"; when `invalid=true` it includes "invalid".
|
|
69
|
+
* - State change: on value edit, AT typically echoes the typed
|
|
70
|
+
* character (native input behavior); no `aria-live` added, per the
|
|
71
|
+
* spec's guidance against live-region overuse.
|
|
72
|
+
*
|
|
73
|
+
* **Consumer contract:**
|
|
74
|
+
* - `placeholder` is a hint, not a label. It disappears on focus in
|
|
75
|
+
* most browsers and is not reliably announced by every AT — always
|
|
76
|
+
* pair with `label`.
|
|
77
|
+
* - For `type="password"` in a real form, pair with a light-DOM
|
|
78
|
+
* `<input type="hidden">` or a form-associated ancestor that gives
|
|
79
|
+
* the browser's password manager an `autocomplete` hint. This
|
|
80
|
+
* component intentionally does not expose `autocomplete` in v1;
|
|
81
|
+
* consumers that need it can render a native `<input>` for that
|
|
82
|
+
* field until the prop is added.
|
|
83
|
+
* - When `invalid=true`, pair with a `describedBy` id that points at
|
|
84
|
+
* a visible error message; `aria-invalid` alone gives the AT the
|
|
85
|
+
* status but not the reason.
|
|
86
|
+
*/
|
|
87
|
+
export class DsInput {
|
|
88
|
+
inputEl;
|
|
89
|
+
value;
|
|
90
|
+
name;
|
|
91
|
+
type = "text";
|
|
92
|
+
placeholder;
|
|
93
|
+
disabled = false;
|
|
94
|
+
required = false;
|
|
95
|
+
invalid = false;
|
|
96
|
+
describedBy;
|
|
97
|
+
label;
|
|
98
|
+
size = "md";
|
|
99
|
+
dsInput;
|
|
100
|
+
watchValue(newValue) {
|
|
101
|
+
if (this.inputEl && this.inputEl.value !== (newValue ?? "")) {
|
|
102
|
+
this.inputEl.value = newValue ?? "";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
componentDidLoad() {
|
|
106
|
+
if (this.inputEl && this.value !== undefined) {
|
|
107
|
+
this.inputEl.value = this.value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
onInput = (event) => {
|
|
111
|
+
const value = event.target.value;
|
|
112
|
+
this.dsInput.emit(value);
|
|
113
|
+
};
|
|
114
|
+
render() {
|
|
115
|
+
const cls = `ds-input ds-input--${this.size}`;
|
|
116
|
+
return (h(Host, { key: 'efce39c6ecfb8dda71577e7fb7b285ddc16287f5' }, h("input", { key: '5f6ad573f20e6eca20f42aa96c8acdf386508d1c', class: cls, type: this.type, name: this.name, placeholder: this.placeholder, disabled: this.disabled, "aria-label": this.label, "aria-required": this.required ? "true" : undefined, "aria-invalid": this.invalid ? "true" : undefined, "aria-describedby": this.describedBy, ref: (el) => (this.inputEl = el), onInput: this.onInput })));
|
|
117
|
+
}
|
|
118
|
+
static get is() { return "ds-input"; }
|
|
119
|
+
static get encapsulation() { return "shadow"; }
|
|
120
|
+
static get originalStyleUrls() {
|
|
121
|
+
return {
|
|
122
|
+
"$": ["ds-input.css"]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
static get styleUrls() {
|
|
126
|
+
return {
|
|
127
|
+
"$": ["ds-input.css"]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
static get properties() {
|
|
131
|
+
return {
|
|
132
|
+
"value": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"mutable": false,
|
|
135
|
+
"complexType": {
|
|
136
|
+
"original": "string",
|
|
137
|
+
"resolved": "string | undefined",
|
|
138
|
+
"references": {}
|
|
139
|
+
},
|
|
140
|
+
"required": false,
|
|
141
|
+
"optional": true,
|
|
142
|
+
"docs": {
|
|
143
|
+
"tags": [],
|
|
144
|
+
"text": ""
|
|
145
|
+
},
|
|
146
|
+
"getter": false,
|
|
147
|
+
"setter": false,
|
|
148
|
+
"reflect": false,
|
|
149
|
+
"attribute": "value"
|
|
150
|
+
},
|
|
151
|
+
"name": {
|
|
152
|
+
"type": "string",
|
|
153
|
+
"mutable": false,
|
|
154
|
+
"complexType": {
|
|
155
|
+
"original": "string",
|
|
156
|
+
"resolved": "string | undefined",
|
|
157
|
+
"references": {}
|
|
158
|
+
},
|
|
159
|
+
"required": false,
|
|
160
|
+
"optional": true,
|
|
161
|
+
"docs": {
|
|
162
|
+
"tags": [],
|
|
163
|
+
"text": ""
|
|
164
|
+
},
|
|
165
|
+
"getter": false,
|
|
166
|
+
"setter": false,
|
|
167
|
+
"reflect": false,
|
|
168
|
+
"attribute": "name"
|
|
169
|
+
},
|
|
170
|
+
"type": {
|
|
171
|
+
"type": "string",
|
|
172
|
+
"mutable": false,
|
|
173
|
+
"complexType": {
|
|
174
|
+
"original": "| \"text\"\n | \"email\"\n | \"password\"\n | \"search\"\n | \"tel\"\n | \"url\"\n | \"number\"",
|
|
175
|
+
"resolved": "\"email\" | \"number\" | \"password\" | \"search\" | \"tel\" | \"text\" | \"url\"",
|
|
176
|
+
"references": {}
|
|
177
|
+
},
|
|
178
|
+
"required": false,
|
|
179
|
+
"optional": false,
|
|
180
|
+
"docs": {
|
|
181
|
+
"tags": [],
|
|
182
|
+
"text": ""
|
|
183
|
+
},
|
|
184
|
+
"getter": false,
|
|
185
|
+
"setter": false,
|
|
186
|
+
"reflect": false,
|
|
187
|
+
"attribute": "type",
|
|
188
|
+
"defaultValue": "\"text\""
|
|
189
|
+
},
|
|
190
|
+
"placeholder": {
|
|
191
|
+
"type": "string",
|
|
192
|
+
"mutable": false,
|
|
193
|
+
"complexType": {
|
|
194
|
+
"original": "string",
|
|
195
|
+
"resolved": "string | undefined",
|
|
196
|
+
"references": {}
|
|
197
|
+
},
|
|
198
|
+
"required": false,
|
|
199
|
+
"optional": true,
|
|
200
|
+
"docs": {
|
|
201
|
+
"tags": [],
|
|
202
|
+
"text": ""
|
|
203
|
+
},
|
|
204
|
+
"getter": false,
|
|
205
|
+
"setter": false,
|
|
206
|
+
"reflect": false,
|
|
207
|
+
"attribute": "placeholder"
|
|
208
|
+
},
|
|
209
|
+
"disabled": {
|
|
210
|
+
"type": "boolean",
|
|
211
|
+
"mutable": false,
|
|
212
|
+
"complexType": {
|
|
213
|
+
"original": "boolean",
|
|
214
|
+
"resolved": "boolean",
|
|
215
|
+
"references": {}
|
|
216
|
+
},
|
|
217
|
+
"required": false,
|
|
218
|
+
"optional": false,
|
|
219
|
+
"docs": {
|
|
220
|
+
"tags": [],
|
|
221
|
+
"text": ""
|
|
222
|
+
},
|
|
223
|
+
"getter": false,
|
|
224
|
+
"setter": false,
|
|
225
|
+
"reflect": false,
|
|
226
|
+
"attribute": "disabled",
|
|
227
|
+
"defaultValue": "false"
|
|
228
|
+
},
|
|
229
|
+
"required": {
|
|
230
|
+
"type": "boolean",
|
|
231
|
+
"mutable": false,
|
|
232
|
+
"complexType": {
|
|
233
|
+
"original": "boolean",
|
|
234
|
+
"resolved": "boolean",
|
|
235
|
+
"references": {}
|
|
236
|
+
},
|
|
237
|
+
"required": false,
|
|
238
|
+
"optional": false,
|
|
239
|
+
"docs": {
|
|
240
|
+
"tags": [],
|
|
241
|
+
"text": ""
|
|
242
|
+
},
|
|
243
|
+
"getter": false,
|
|
244
|
+
"setter": false,
|
|
245
|
+
"reflect": false,
|
|
246
|
+
"attribute": "required",
|
|
247
|
+
"defaultValue": "false"
|
|
248
|
+
},
|
|
249
|
+
"invalid": {
|
|
250
|
+
"type": "boolean",
|
|
251
|
+
"mutable": false,
|
|
252
|
+
"complexType": {
|
|
253
|
+
"original": "boolean",
|
|
254
|
+
"resolved": "boolean",
|
|
255
|
+
"references": {}
|
|
256
|
+
},
|
|
257
|
+
"required": false,
|
|
258
|
+
"optional": false,
|
|
259
|
+
"docs": {
|
|
260
|
+
"tags": [],
|
|
261
|
+
"text": ""
|
|
262
|
+
},
|
|
263
|
+
"getter": false,
|
|
264
|
+
"setter": false,
|
|
265
|
+
"reflect": false,
|
|
266
|
+
"attribute": "invalid",
|
|
267
|
+
"defaultValue": "false"
|
|
268
|
+
},
|
|
269
|
+
"describedBy": {
|
|
270
|
+
"type": "string",
|
|
271
|
+
"mutable": false,
|
|
272
|
+
"complexType": {
|
|
273
|
+
"original": "string",
|
|
274
|
+
"resolved": "string | undefined",
|
|
275
|
+
"references": {}
|
|
276
|
+
},
|
|
277
|
+
"required": false,
|
|
278
|
+
"optional": true,
|
|
279
|
+
"docs": {
|
|
280
|
+
"tags": [],
|
|
281
|
+
"text": ""
|
|
282
|
+
},
|
|
283
|
+
"getter": false,
|
|
284
|
+
"setter": false,
|
|
285
|
+
"reflect": false,
|
|
286
|
+
"attribute": "described-by"
|
|
287
|
+
},
|
|
288
|
+
"label": {
|
|
289
|
+
"type": "string",
|
|
290
|
+
"mutable": false,
|
|
291
|
+
"complexType": {
|
|
292
|
+
"original": "string",
|
|
293
|
+
"resolved": "string | undefined",
|
|
294
|
+
"references": {}
|
|
295
|
+
},
|
|
296
|
+
"required": false,
|
|
297
|
+
"optional": true,
|
|
298
|
+
"docs": {
|
|
299
|
+
"tags": [],
|
|
300
|
+
"text": ""
|
|
301
|
+
},
|
|
302
|
+
"getter": false,
|
|
303
|
+
"setter": false,
|
|
304
|
+
"reflect": false,
|
|
305
|
+
"attribute": "label"
|
|
306
|
+
},
|
|
307
|
+
"size": {
|
|
308
|
+
"type": "string",
|
|
309
|
+
"mutable": false,
|
|
310
|
+
"complexType": {
|
|
311
|
+
"original": "\"md\" | \"lg\"",
|
|
312
|
+
"resolved": "\"lg\" | \"md\"",
|
|
313
|
+
"references": {}
|
|
314
|
+
},
|
|
315
|
+
"required": false,
|
|
316
|
+
"optional": false,
|
|
317
|
+
"docs": {
|
|
318
|
+
"tags": [],
|
|
319
|
+
"text": ""
|
|
320
|
+
},
|
|
321
|
+
"getter": false,
|
|
322
|
+
"setter": false,
|
|
323
|
+
"reflect": false,
|
|
324
|
+
"attribute": "size",
|
|
325
|
+
"defaultValue": "\"md\""
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
static get events() {
|
|
330
|
+
return [{
|
|
331
|
+
"method": "dsInput",
|
|
332
|
+
"name": "dsInput",
|
|
333
|
+
"bubbles": true,
|
|
334
|
+
"cancelable": true,
|
|
335
|
+
"composed": true,
|
|
336
|
+
"docs": {
|
|
337
|
+
"tags": [],
|
|
338
|
+
"text": ""
|
|
339
|
+
},
|
|
340
|
+
"complexType": {
|
|
341
|
+
"original": "string",
|
|
342
|
+
"resolved": "string",
|
|
343
|
+
"references": {}
|
|
344
|
+
}
|
|
345
|
+
}];
|
|
346
|
+
}
|
|
347
|
+
static get watchers() {
|
|
348
|
+
return [{
|
|
349
|
+
"propName": "value",
|
|
350
|
+
"methodName": "watchValue"
|
|
351
|
+
}];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
color: currentColor;
|
|
4
|
+
line-height: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.ds-loader {
|
|
8
|
+
display: block;
|
|
9
|
+
width: 40px;
|
|
10
|
+
height: 40px;
|
|
11
|
+
color: inherit;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.ds-loader--sm {
|
|
15
|
+
width: 16px;
|
|
16
|
+
height: 16px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.ds-loader--md {
|
|
20
|
+
width: 40px;
|
|
21
|
+
height: 40px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ds-loader--lg {
|
|
25
|
+
width: 120px;
|
|
26
|
+
height: 120px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ds-loader__half {
|
|
30
|
+
transform-box: view-box;
|
|
31
|
+
transform-origin: 50% 50%;
|
|
32
|
+
animation: ds-loader-swing 1.4s cubic-bezier(0.6, 0, 0.4, 1) infinite;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.ds-loader__half--b {
|
|
36
|
+
animation-name: ds-loader-swing-mirror;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ds-loader__mirror {
|
|
40
|
+
transform-box: view-box;
|
|
41
|
+
transform-origin: 50% 50%;
|
|
42
|
+
transform: scaleX(-1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.ds-loader--speed-slow .ds-loader__half {
|
|
46
|
+
animation-duration: 2.2s;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ds-loader--speed-fast .ds-loader__half {
|
|
50
|
+
animation-duration: 0.9s;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@keyframes ds-loader-swing {
|
|
54
|
+
0% {
|
|
55
|
+
transform: rotate(180deg);
|
|
56
|
+
}
|
|
57
|
+
50% {
|
|
58
|
+
transform: rotate(0deg);
|
|
59
|
+
}
|
|
60
|
+
100% {
|
|
61
|
+
transform: rotate(180deg);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes ds-loader-swing-mirror {
|
|
66
|
+
0% {
|
|
67
|
+
transform: rotate(-180deg);
|
|
68
|
+
}
|
|
69
|
+
50% {
|
|
70
|
+
transform: rotate(0deg);
|
|
71
|
+
}
|
|
72
|
+
100% {
|
|
73
|
+
transform: rotate(-180deg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@media (prefers-reduced-motion: reduce) {
|
|
78
|
+
.ds-loader__half,
|
|
79
|
+
.ds-loader__half--b {
|
|
80
|
+
animation: ds-loader-pulse 2s ease-in-out infinite;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@keyframes ds-loader-pulse {
|
|
84
|
+
0%,
|
|
85
|
+
100% {
|
|
86
|
+
opacity: 0.4;
|
|
87
|
+
transform: rotate(0deg);
|
|
88
|
+
}
|
|
89
|
+
50% {
|
|
90
|
+
opacity: 1;
|
|
91
|
+
transform: rotate(0deg);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { h, Host } from "@stencil/core";
|
|
2
|
+
/**
|
|
3
|
+
* ## Accessibility
|
|
4
|
+
*
|
|
5
|
+
* **Category:** static-display (indeterminate progress indicator)
|
|
6
|
+
* **APG pattern:** N/A — the loader is a passive presence indicator, not a
|
|
7
|
+
* `progressbar` (no measurable value). Uses `role="status"` per WAI-ARIA
|
|
8
|
+
* live-region semantics for indeterminate loading states.
|
|
9
|
+
*
|
|
10
|
+
* **Keyboard interactions:**
|
|
11
|
+
* - Tab: N/A — not focusable.
|
|
12
|
+
* - Enter: N/A.
|
|
13
|
+
* - Escape: N/A.
|
|
14
|
+
* - Arrow keys: N/A.
|
|
15
|
+
* - Printable characters: N/A.
|
|
16
|
+
*
|
|
17
|
+
* **ARIA:**
|
|
18
|
+
* - Roles used: `role="status"` on the host — an implicit polite live
|
|
19
|
+
* region ARIA lists as valid for "advisory information" including
|
|
20
|
+
* in-progress operations. The inner `<svg>` is decorative and carries
|
|
21
|
+
* `aria-hidden="true"` + `focusable="false"` so it never becomes a
|
|
22
|
+
* parallel target for screen readers.
|
|
23
|
+
* - State attributes: none. The loader has no state changes to announce
|
|
24
|
+
* beyond its own presence; the polite live region on mount is the
|
|
25
|
+
* announcement.
|
|
26
|
+
* - Labeling strategy: `aria-label` from the `label` prop (default
|
|
27
|
+
* "Loading"). Consumers pass a more specific string when the context
|
|
28
|
+
* warrants ("Loading ceremonies", "Signing in", …).
|
|
29
|
+
*
|
|
30
|
+
* **Focus:**
|
|
31
|
+
* - On mount: nothing auto-focuses.
|
|
32
|
+
* - On activate/open: N/A — not interactive.
|
|
33
|
+
* - On close/deactivate: N/A.
|
|
34
|
+
* - Focus indicator: N/A — the host is not focusable.
|
|
35
|
+
*
|
|
36
|
+
* **Motion:**
|
|
37
|
+
* - Animations: two mirrored halves of the logo path oscillate
|
|
38
|
+
* symmetrically around the visual center, meeting at the ring midpoint
|
|
39
|
+
* and separating again. Cycle 1.4s by default (`speed="normal"`);
|
|
40
|
+
* `speed="slow"` = 2.2s, `speed="fast"` = 0.9s.
|
|
41
|
+
* - Reduced-motion behavior: `@media (prefers-reduced-motion: reduce)`
|
|
42
|
+
* collapses both halves to a static rendering with a slow opacity
|
|
43
|
+
* pulse (2s ease-in-out). No rotation, no lateral movement.
|
|
44
|
+
*
|
|
45
|
+
* **Contrast:**
|
|
46
|
+
* - Text: N/A — the visible surface is the SVG stroke, not text.
|
|
47
|
+
* - Non-text: stroke inherits `currentColor` from the host. Consumers are
|
|
48
|
+
* responsible for confirming the stroke against its background meets
|
|
49
|
+
* the ≥ 3:1 non-text contrast threshold (WCAG 1.4.11) where the loader
|
|
50
|
+
* conveys state (e.g. distinguishing "still loading" from "idle").
|
|
51
|
+
*
|
|
52
|
+
* **Screen reader announcement:**
|
|
53
|
+
* - Rendered state: the polite live region announces the label
|
|
54
|
+
* (e.g. "Loading") when the loader mounts.
|
|
55
|
+
* - State change: N/A — the loader itself has no state that changes.
|
|
56
|
+
* Consumers unmount the loader when the awaited work completes; that
|
|
57
|
+
* removal is silent, which is the intended behavior (the arriving
|
|
58
|
+
* content is the announcement).
|
|
59
|
+
*/
|
|
60
|
+
export class DsLoader {
|
|
61
|
+
size = "md";
|
|
62
|
+
label = "Loading";
|
|
63
|
+
speed = "normal";
|
|
64
|
+
render() {
|
|
65
|
+
const cls = [
|
|
66
|
+
"ds-loader",
|
|
67
|
+
`ds-loader--${this.size}`,
|
|
68
|
+
`ds-loader--speed-${this.speed}`,
|
|
69
|
+
].join(" ");
|
|
70
|
+
return (h(Host, { key: 'd7017e7e3c970e27bffa30c193abd937c5ec13cd', role: "status", "aria-label": this.label }, h("svg", { key: '9eb10695249bc4c833b6347d38226fdc37d4be7d', class: cls, viewBox: "-48 -48 96 96", "aria-hidden": "true", focusable: "false" }, h("g", { key: '711ee60648593d216687087c5b2145ec25120bc5', class: "ds-loader__half ds-loader__half--a" }, h("path", { key: '9efdc31104b6037a57d7bdc802303938f7285666', d: LOGO_PATH_D, fill: "none", stroke: "currentColor", "stroke-width": "14", "stroke-linecap": "round", "stroke-linejoin": "round" })), h("g", { key: 'fcbeefc154e0e9db5b0378f77dafa3f9c0162e92', class: "ds-loader__half ds-loader__half--b" }, h("g", { key: '790b3ec1c4b262352cc383ab6b9f7d5cbb77474b', class: "ds-loader__mirror" }, h("path", { key: '694713be37532568852b2de2530cc50c1ff3b8de', d: LOGO_PATH_D, fill: "none", stroke: "currentColor", "stroke-width": "14", "stroke-linecap": "round", "stroke-linejoin": "round" }))))));
|
|
71
|
+
}
|
|
72
|
+
static get is() { return "ds-loader"; }
|
|
73
|
+
static get encapsulation() { return "shadow"; }
|
|
74
|
+
static get originalStyleUrls() {
|
|
75
|
+
return {
|
|
76
|
+
"$": ["ds-loader.css"]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
static get styleUrls() {
|
|
80
|
+
return {
|
|
81
|
+
"$": ["ds-loader.css"]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
static get properties() {
|
|
85
|
+
return {
|
|
86
|
+
"size": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"mutable": false,
|
|
89
|
+
"complexType": {
|
|
90
|
+
"original": "\"sm\" | \"md\" | \"lg\"",
|
|
91
|
+
"resolved": "\"lg\" | \"md\" | \"sm\"",
|
|
92
|
+
"references": {}
|
|
93
|
+
},
|
|
94
|
+
"required": false,
|
|
95
|
+
"optional": false,
|
|
96
|
+
"docs": {
|
|
97
|
+
"tags": [],
|
|
98
|
+
"text": ""
|
|
99
|
+
},
|
|
100
|
+
"getter": false,
|
|
101
|
+
"setter": false,
|
|
102
|
+
"reflect": false,
|
|
103
|
+
"attribute": "size",
|
|
104
|
+
"defaultValue": "\"md\""
|
|
105
|
+
},
|
|
106
|
+
"label": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"mutable": false,
|
|
109
|
+
"complexType": {
|
|
110
|
+
"original": "string",
|
|
111
|
+
"resolved": "string",
|
|
112
|
+
"references": {}
|
|
113
|
+
},
|
|
114
|
+
"required": false,
|
|
115
|
+
"optional": false,
|
|
116
|
+
"docs": {
|
|
117
|
+
"tags": [],
|
|
118
|
+
"text": ""
|
|
119
|
+
},
|
|
120
|
+
"getter": false,
|
|
121
|
+
"setter": false,
|
|
122
|
+
"reflect": false,
|
|
123
|
+
"attribute": "label",
|
|
124
|
+
"defaultValue": "\"Loading\""
|
|
125
|
+
},
|
|
126
|
+
"speed": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"mutable": false,
|
|
129
|
+
"complexType": {
|
|
130
|
+
"original": "\"slow\" | \"normal\" | \"fast\"",
|
|
131
|
+
"resolved": "\"fast\" | \"normal\" | \"slow\"",
|
|
132
|
+
"references": {}
|
|
133
|
+
},
|
|
134
|
+
"required": false,
|
|
135
|
+
"optional": false,
|
|
136
|
+
"docs": {
|
|
137
|
+
"tags": [],
|
|
138
|
+
"text": ""
|
|
139
|
+
},
|
|
140
|
+
"getter": false,
|
|
141
|
+
"setter": false,
|
|
142
|
+
"reflect": false,
|
|
143
|
+
"attribute": "speed",
|
|
144
|
+
"defaultValue": "\"normal\""
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const LOGO_PATH_D = "M14.09 -27.22 L13.04 -28.53 L11.94 -29.76 L10.78 -30.92 L9.57 -32.01 L8.30 -33.02 L7.00 -33.95 L5.65 -34.80 L4.27 -35.57 L2.85 -36.25 L1.40 -36.84 L-0.07 -37.35 L-1.56 -37.76 L-3.07 -38.08 L-4.59 -38.31 L-6.13 -38.45 L-7.66 -38.50 L-9.20 -38.45 L-10.73 -38.31 L-12.25 -38.08 L-13.76 -37.76 L-15.25 -37.35 L-16.73 -36.84 L-18.17 -36.25 L-19.59 -35.57 L-20.97 -34.80 L-22.32 -33.95 L-23.63 -33.02 L-24.89 -32.01 L-26.10 -30.92 L-27.26 -29.76 L-28.37 -28.53 L-29.41 -27.22 L-30.40 -25.86 L-31.32 -24.42 L-32.17 -22.93 L-32.95 -21.39 L-33.66 -19.79 L-34.30 -18.15 L-34.86 -16.46 L-35.34 -14.73 L-35.74 -12.97 L-36.06 -11.18 L-36.29 -9.35 L-36.44 -7.51 L-36.50 -5.65 L-36.48 -3.77 L-36.37 -1.89 L-36.18 0 L-35.90 1.89 L-35.53 3.77 L-35.07 5.65 L-34.53 7.51 L-33.90 9.35 L-33.18 11.18 L-32.39 12.97 L-31.51 14.73 L-30.55 16.46 L-29.51 18.15 L-28.40 19.79 L-27.21 21.39 L-25.95 22.93 L-24.61 24.42 L-23.22 25.86 L-21.75 27.22 L-20.23 28.53 L-18.64 29.76 L-17.00 30.92 L-15.31 32.01 L-13.57 33.02 L-11.79 33.95 L-9.96 34.80 L-8.10 35.57 L-6.20 36.25 L-4.28 36.84 L-2.33 37.35 L-0.35 37.76 L1.63 38.08 L3.64 38.31 L5.65 38.45 L7.66 38.50 L9.68 38.45 L11.69 38.31 L13.69 38.08 L15.68 37.76 L17.65 37.35 L19.60 36.84 L21.53 36.25 L23.42 35.57 L25.28 34.80 L27.11 33.95 L28.89 33.02 L30.63 32.01 L32.32 30.92 L33.96 29.76 L35.55 28.53 L37.07 27.22";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
position: relative;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.ds-select {
|
|
7
|
+
font-family: var(--ds-font-family);
|
|
8
|
+
font-size: var(--ds-font-size-md);
|
|
9
|
+
background-color: transparent;
|
|
10
|
+
color: inherit;
|
|
11
|
+
border: 1px solid color-mix(in oklch, currentColor 22%, transparent);
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
-webkit-appearance: none;
|
|
14
|
+
appearance: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* The caret is drawn on a ::after pseudo-element of :host rather than as a
|
|
19
|
+
* background-image/mask-image on .ds-select itself. mask-image masks the
|
|
20
|
+
* ENTIRE painted box of the element it's applied to (text, border, and all)
|
|
21
|
+
* -- it is not layered behind content the way background-image is. Applying
|
|
22
|
+
* it directly to the <select> would clip away the option text and border,
|
|
23
|
+
* leaving only the tiny caret shape visible. Confirmed empirically before
|
|
24
|
+
* writing this. Using a dedicated pseudo-element keeps the mask contained to
|
|
25
|
+
* just the caret glyph while background-color: currentColor makes it track
|
|
26
|
+
* the host's inherited color (fixing the original bug where the SVG's own
|
|
27
|
+
* currentColor resolved to black inside the isolated background-image
|
|
28
|
+
* context).
|
|
29
|
+
*/
|
|
30
|
+
:host::after {
|
|
31
|
+
content: "";
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 50%;
|
|
34
|
+
right: var(--ds-spacing-sm);
|
|
35
|
+
width: 12px;
|
|
36
|
+
height: 12px;
|
|
37
|
+
transform: translateY(-50%);
|
|
38
|
+
background-color: currentColor;
|
|
39
|
+
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'><path d='M2.5 4.5L6 8L9.5 4.5' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
|
|
40
|
+
mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'><path d='M2.5 4.5L6 8L9.5 4.5' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
|
|
41
|
+
-webkit-mask-repeat: no-repeat;
|
|
42
|
+
mask-repeat: no-repeat;
|
|
43
|
+
-webkit-mask-position: center;
|
|
44
|
+
mask-position: center;
|
|
45
|
+
-webkit-mask-size: contain;
|
|
46
|
+
mask-size: contain;
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ds-select:disabled {
|
|
51
|
+
opacity: 0.5;
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:host(:has(.ds-select:disabled))::after {
|
|
56
|
+
opacity: 0.5;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ds-select--md {
|
|
60
|
+
border-radius: var(--ds-radius-sm);
|
|
61
|
+
padding: var(--ds-spacing-sm) var(--ds-spacing-lg);
|
|
62
|
+
padding-right: calc(var(--ds-spacing-lg) + var(--ds-spacing-lg));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.ds-select--lg {
|
|
66
|
+
border-radius: var(--ds-radius-md);
|
|
67
|
+
padding: var(--ds-spacing-md) var(--ds-spacing-xl);
|
|
68
|
+
padding-right: calc(var(--ds-spacing-xl) + var(--ds-spacing-lg));
|
|
69
|
+
}
|