@orange-halo/components 2.1.0 → 3.0.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/custom-elements.json +968 -362
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +1 -2
- package/dist/base.js.map +1 -1
- package/dist/index.d.ts +4 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/oh-accordion.d.ts +53 -8
- package/dist/oh-accordion.d.ts.map +1 -1
- package/dist/oh-accordion.js +99 -29
- package/dist/oh-accordion.js.map +1 -1
- package/dist/oh-alert.d.ts +26 -8
- package/dist/oh-alert.d.ts.map +1 -1
- package/dist/oh-alert.js +96 -36
- package/dist/oh-alert.js.map +1 -1
- package/dist/oh-badge.d.ts +32 -13
- package/dist/oh-badge.d.ts.map +1 -1
- package/dist/oh-badge.js +38 -19
- package/dist/oh-badge.js.map +1 -1
- package/dist/oh-breadcrumb.d.ts +39 -12
- package/dist/oh-breadcrumb.d.ts.map +1 -1
- package/dist/oh-breadcrumb.js +66 -25
- package/dist/oh-breadcrumb.js.map +1 -1
- package/dist/oh-button.d.ts +49 -23
- package/dist/oh-button.d.ts.map +1 -1
- package/dist/oh-button.figma.js +1 -3
- package/dist/oh-button.figma.js.map +1 -1
- package/dist/oh-button.js +133 -82
- package/dist/oh-button.js.map +1 -1
- package/dist/oh-card.d.ts +47 -19
- package/dist/oh-card.d.ts.map +1 -1
- package/dist/oh-card.js +143 -96
- package/dist/oh-card.js.map +1 -1
- package/dist/oh-checkbox-group.d.ts +56 -12
- package/dist/oh-checkbox-group.d.ts.map +1 -1
- package/dist/oh-checkbox-group.figma.js +4 -6
- package/dist/oh-checkbox-group.figma.js.map +1 -1
- package/dist/oh-checkbox-group.js +114 -49
- package/dist/oh-checkbox-group.js.map +1 -1
- package/dist/oh-checkbox.d.ts +54 -17
- package/dist/oh-checkbox.d.ts.map +1 -1
- package/dist/oh-checkbox.js +117 -60
- package/dist/oh-checkbox.js.map +1 -1
- package/dist/oh-cluster.d.ts +19 -14
- package/dist/oh-cluster.d.ts.map +1 -1
- package/dist/oh-cluster.js +19 -19
- package/dist/oh-cluster.js.map +1 -1
- package/dist/oh-container.d.ts +19 -16
- package/dist/oh-container.d.ts.map +1 -1
- package/dist/oh-container.js +21 -23
- package/dist/oh-container.js.map +1 -1
- package/dist/oh-drawer.d.ts +28 -11
- package/dist/oh-drawer.d.ts.map +1 -1
- package/dist/oh-drawer.js +52 -24
- package/dist/oh-drawer.js.map +1 -1
- package/dist/oh-footer.d.ts +37 -18
- package/dist/oh-footer.d.ts.map +1 -1
- package/dist/oh-footer.js +38 -19
- package/dist/oh-footer.js.map +1 -1
- package/dist/oh-grid.d.ts +27 -14
- package/dist/oh-grid.d.ts.map +1 -1
- package/dist/oh-grid.js +28 -21
- package/dist/oh-grid.js.map +1 -1
- package/dist/oh-icon.d.ts +21 -5
- package/dist/oh-icon.d.ts.map +1 -1
- package/dist/oh-icon.js +27 -9
- package/dist/oh-icon.js.map +1 -1
- package/dist/oh-input.d.ts +110 -21
- package/dist/oh-input.d.ts.map +1 -1
- package/dist/oh-input.figma.js +2 -2
- package/dist/oh-input.figma.js.map +1 -1
- package/dist/oh-input.js +227 -71
- package/dist/oh-input.js.map +1 -1
- package/dist/oh-link.d.ts +42 -19
- package/dist/oh-link.d.ts.map +1 -1
- package/dist/oh-link.js +83 -38
- package/dist/oh-link.js.map +1 -1
- package/dist/oh-modal.d.ts +35 -6
- package/dist/oh-modal.d.ts.map +1 -1
- package/dist/oh-modal.js +90 -39
- package/dist/oh-modal.js.map +1 -1
- package/dist/oh-navbar.d.ts +42 -19
- package/dist/oh-navbar.d.ts.map +1 -1
- package/dist/oh-navbar.js +44 -20
- package/dist/oh-navbar.js.map +1 -1
- package/dist/oh-progress.d.ts +26 -7
- package/dist/oh-progress.d.ts.map +1 -1
- package/dist/oh-progress.js +35 -14
- package/dist/oh-progress.js.map +1 -1
- package/dist/oh-radio-group.d.ts +55 -13
- package/dist/oh-radio-group.d.ts.map +1 -1
- package/dist/oh-radio-group.figma.js +2 -2
- package/dist/oh-radio-group.figma.js.map +1 -1
- package/dist/oh-radio-group.js +122 -51
- package/dist/oh-radio-group.js.map +1 -1
- package/dist/oh-radio.d.ts +55 -17
- package/dist/oh-radio.d.ts.map +1 -1
- package/dist/oh-radio.js +120 -61
- package/dist/oh-radio.js.map +1 -1
- package/dist/oh-select.d.ts +59 -16
- package/dist/oh-select.d.ts.map +1 -1
- package/dist/oh-select.js +141 -69
- package/dist/oh-select.js.map +1 -1
- package/dist/oh-skip-link.d.ts +33 -15
- package/dist/oh-skip-link.d.ts.map +1 -1
- package/dist/oh-skip-link.js +43 -32
- package/dist/oh-skip-link.js.map +1 -1
- package/dist/oh-stack.d.ts +17 -14
- package/dist/oh-stack.d.ts.map +1 -1
- package/dist/oh-stack.js +18 -20
- package/dist/oh-stack.js.map +1 -1
- package/dist/oh-tabs.d.ts +55 -30
- package/dist/oh-tabs.d.ts.map +1 -1
- package/dist/oh-tabs.js +100 -76
- package/dist/oh-tabs.js.map +1 -1
- package/dist/oh-textarea.d.ts +129 -0
- package/dist/oh-textarea.d.ts.map +1 -0
- package/dist/oh-textarea.js +401 -0
- package/dist/oh-textarea.js.map +1 -0
- package/dist/oh-toggle.d.ts +45 -12
- package/dist/oh-toggle.d.ts.map +1 -1
- package/dist/oh-toggle.js +84 -34
- package/dist/oh-toggle.js.map +1 -1
- package/dist/styles/typography.js +1 -1
- package/package.json +7 -7
- package/dist/oh-hero.d.ts +0 -33
- package/dist/oh-hero.d.ts.map +0 -1
- package/dist/oh-hero.js +0 -246
- package/dist/oh-hero.js.map +0 -1
package/dist/oh-radio.js
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* oh-radio
|
|
3
3
|
*
|
|
4
|
-
* A chunky, playful radio button with hand-crafted feel.
|
|
5
|
-
* Matches the inset/pressed aesthetic of oh-input.
|
|
6
|
-
*
|
|
7
4
|
* DESIGN DECISIONS:
|
|
8
5
|
* ─────────────────
|
|
9
|
-
* 1.
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
6
|
+
* 1. LOOK FROM TOKENS
|
|
7
|
+
* - Border: stroke.control in color.border.emphasis
|
|
8
|
+
* - Circular: shape.pill
|
|
9
|
+
* - Shadow: offset by elevation.offset.* in elevation.color.secondary; hover and
|
|
10
|
+
* press move the circle by lift.hoverSm / lift.pressSm
|
|
13
11
|
*
|
|
14
12
|
* 2. CHECKED STATE
|
|
15
|
-
* - Filled dot in
|
|
16
|
-
*
|
|
17
|
-
* - Shadow shifts to feel "activated"
|
|
13
|
+
* - Filled with color.brand.primary, a centre dot in color.text.onBrand,
|
|
14
|
+
* and the shadow in elevation.color.primary
|
|
18
15
|
*
|
|
19
16
|
* 3. ACCESSIBILITY
|
|
20
|
-
* -
|
|
17
|
+
* - A native radio, visually hidden but focusable and announced
|
|
21
18
|
* - Label always required
|
|
22
|
-
* - Focus
|
|
23
|
-
* -
|
|
24
|
-
*
|
|
25
|
-
* @element oh-radio
|
|
19
|
+
* - Focus underlines the label (a solid indicator)
|
|
20
|
+
* - Two oh-radios with the same name don't form a group (each native
|
|
21
|
+
* radio is in its own shadow root): use oh-radio-group for a set
|
|
26
22
|
*/
|
|
27
23
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
28
24
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -33,6 +29,44 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
33
29
|
import { html, css, nothing } from "lit";
|
|
34
30
|
import { customElement, property, state } from "lit/decorators.js";
|
|
35
31
|
import { OhElement, baseStyles } from "./base.js";
|
|
32
|
+
/**
|
|
33
|
+
* A single radio button with its label.
|
|
34
|
+
*
|
|
35
|
+
* **Use it for** a one-off radio you manage yourself. **For a set of
|
|
36
|
+
* choices, use `oh-radio-group`.** Each `oh-radio` keeps its native radio
|
|
37
|
+
* inside its own shadow root, so two of them with the same `name` don't form
|
|
38
|
+
* a group: checking one doesn't uncheck the other, and arrow keys don't move
|
|
39
|
+
* between them. `oh-radio-group` renders the whole set in one place, with
|
|
40
|
+
* arrow-key navigation and one label for the group. For an independent
|
|
41
|
+
* on/off choice use `oh-checkbox`.
|
|
42
|
+
*
|
|
43
|
+
* **States:** unchecked, checked, hover, active, focus, error (set `error-text`).
|
|
44
|
+
*
|
|
45
|
+
* **Behaviour:** clicking the circle or label checks it. Checking sets
|
|
46
|
+
* `checked` and fires `oh-change`. The native radio sits in the shadow
|
|
47
|
+
* root, so it doesn't submit with a native form.
|
|
48
|
+
*
|
|
49
|
+
* **Accessibility:** a real native radio, visually hidden, carries the role
|
|
50
|
+
* and state; the drawn circle is decoration. Always set `label`: it's the
|
|
51
|
+
* radio's name. Focus underlines the label. The error message shows under
|
|
52
|
+
* the radio with an icon, sets `aria-invalid` and is linked with
|
|
53
|
+
* `aria-describedby`; it's announced (`role="alert"`) only when it appears
|
|
54
|
+
* after first render.
|
|
55
|
+
*
|
|
56
|
+
* **Look:** set by tokens — `stroke.control` in `color.border.emphasis`
|
|
57
|
+
* (border), `shape.pill` (circle), `typography.control.*` (label),
|
|
58
|
+
* `elevation.offset.*` and `elevation.color.secondary` (shadow), `lift.hoverSm` /
|
|
59
|
+
* `lift.pressSm` (movement on hover and press), `color.border.hover`
|
|
60
|
+
* (hover), `color.brand.primary` (and its hover and active tokens),
|
|
61
|
+
* `color.text.onBrand` and `elevation.color.primary` (checked),
|
|
62
|
+
* `color.feedback.error` and `elevation.color.error` (error).
|
|
63
|
+
*
|
|
64
|
+
* @element oh-radio
|
|
65
|
+
* @fires oh-change - The radio was checked. detail: { checked, value }
|
|
66
|
+
* @csspart circle - The drawn radio circle
|
|
67
|
+
* @csspart label - The label text
|
|
68
|
+
* @csspart error - The error message
|
|
69
|
+
*/
|
|
36
70
|
let OhRadio = class OhRadio extends OhElement {
|
|
37
71
|
constructor() {
|
|
38
72
|
super(...arguments);
|
|
@@ -40,8 +74,11 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
40
74
|
this.label = "";
|
|
41
75
|
this.name = "";
|
|
42
76
|
this.value = "";
|
|
43
|
-
|
|
44
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Error shown with the control and linked to it. Setting it puts the
|
|
79
|
+
* control in its error state; clear it to leave that state.
|
|
80
|
+
*/
|
|
81
|
+
this.errorText = "";
|
|
45
82
|
/**
|
|
46
83
|
* Force a visual state (for documentation/Figma sync only)
|
|
47
84
|
* Values: 'hover' | 'focus'
|
|
@@ -58,11 +95,6 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
58
95
|
static { this.styles = [
|
|
59
96
|
baseStyles,
|
|
60
97
|
css `
|
|
61
|
-
/* ═══════════════════════════════════════════════════════════════
|
|
62
|
-
ORANGE HALO RADIO
|
|
63
|
-
Chunky • Tactile • Playful
|
|
64
|
-
═══════════════════════════════════════════════════════════════ */
|
|
65
|
-
|
|
66
98
|
:host {
|
|
67
99
|
display: inline-block;
|
|
68
100
|
}
|
|
@@ -96,25 +128,26 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
96
128
|
width: 24px;
|
|
97
129
|
height: 24px;
|
|
98
130
|
flex-shrink: 0;
|
|
99
|
-
|
|
100
|
-
/*
|
|
131
|
+
|
|
132
|
+
/* Border: stroke.control in color.border.emphasis; circular (shape.pill) */
|
|
101
133
|
border: var(--oh-stroke-control) solid var(--oh-color-border-emphasis);
|
|
102
134
|
border-radius: var(--oh-shape-pill);
|
|
103
|
-
|
|
104
|
-
/* Offset shadow
|
|
135
|
+
|
|
136
|
+
/* Offset shadow: elevation.offset.md in elevation.color.secondary */
|
|
105
137
|
background-color: var(--oh-color-surface-base);
|
|
106
|
-
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
138
|
+
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
139
|
+
0 0 var(--oh-elevation-color-secondary);
|
|
140
|
+
|
|
141
|
+
transition:
|
|
142
|
+
transform var(--oh-motion-snappy) var(--oh-motion-ease-emphasized),
|
|
143
|
+
box-shadow var(--oh-motion-snappy) var(--oh-motion-ease-emphasized),
|
|
111
144
|
background-color var(--oh-motion-quick) ease,
|
|
112
145
|
border-color var(--oh-motion-quick) ease;
|
|
113
146
|
}
|
|
114
147
|
|
|
115
148
|
/* Inner dot (hidden by default) */
|
|
116
149
|
.radio-circle::after {
|
|
117
|
-
content:
|
|
150
|
+
content: "";
|
|
118
151
|
position: absolute;
|
|
119
152
|
top: 50%;
|
|
120
153
|
left: 50%;
|
|
@@ -123,31 +156,35 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
123
156
|
background-color: var(--oh-color-text-on-brand);
|
|
124
157
|
border-radius: var(--oh-shape-pill);
|
|
125
158
|
transform: translate(-50%, -50%) scale(0);
|
|
126
|
-
transition: transform var(--oh-motion-snappy)
|
|
159
|
+
transition: transform var(--oh-motion-snappy)
|
|
160
|
+
var(--oh-motion-ease-emphasized);
|
|
127
161
|
}
|
|
128
162
|
|
|
129
163
|
/* ═══════════════════════════════════════════════════════════════
|
|
130
164
|
STATES
|
|
131
165
|
═══════════════════════════════════════════════════════════════ */
|
|
132
166
|
|
|
133
|
-
/* Hover: lift
|
|
167
|
+
/* Hover: moves by lift.hoverSm; shadow offset elevation.offset.lg */
|
|
134
168
|
.radio-wrapper:hover .radio-circle {
|
|
135
169
|
border-color: var(--oh-color-border-hover);
|
|
136
170
|
transform: translate(var(--oh-lift-hover-sm), var(--oh-lift-hover-sm));
|
|
137
|
-
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
171
|
+
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
172
|
+
0 0 var(--oh-elevation-color-secondary);
|
|
138
173
|
}
|
|
139
174
|
|
|
140
|
-
/* Active:
|
|
175
|
+
/* Active: moves by lift.pressSm; shadow offset elevation.offset.xs */
|
|
141
176
|
.radio-wrapper:active .radio-circle {
|
|
142
177
|
transform: translate(var(--oh-lift-press-sm), var(--oh-lift-press-sm));
|
|
143
|
-
box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
|
|
178
|
+
box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
|
|
179
|
+
0 0 var(--oh-elevation-color-secondary);
|
|
144
180
|
}
|
|
145
181
|
|
|
146
|
-
/* Checked: primary color
|
|
182
|
+
/* Checked: color.brand.primary fill, elevation.color.primary shadow */
|
|
147
183
|
.native-radio:checked + .radio-circle {
|
|
148
184
|
background-color: var(--oh-color-brand-primary);
|
|
149
185
|
border-color: var(--oh-color-brand-primary);
|
|
150
|
-
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
186
|
+
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
187
|
+
0 0 var(--oh-elevation-color-primary);
|
|
151
188
|
}
|
|
152
189
|
|
|
153
190
|
.native-radio:checked + .radio-circle::after {
|
|
@@ -159,14 +196,16 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
159
196
|
background-color: var(--oh-color-brand-primary-hover);
|
|
160
197
|
border-color: var(--oh-color-brand-primary-hover);
|
|
161
198
|
transform: translate(var(--oh-lift-hover-sm), var(--oh-lift-hover-sm));
|
|
162
|
-
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
199
|
+
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
200
|
+
0 0 var(--oh-elevation-color-primary);
|
|
163
201
|
}
|
|
164
202
|
|
|
165
203
|
/* Checked + Active */
|
|
166
204
|
.radio-wrapper:active .native-radio:checked + .radio-circle {
|
|
167
205
|
background-color: var(--oh-color-brand-primary-active);
|
|
168
206
|
transform: translate(var(--oh-lift-press-sm), var(--oh-lift-press-sm));
|
|
169
|
-
box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
|
|
207
|
+
box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
|
|
208
|
+
0 0 var(--oh-elevation-color-primary);
|
|
170
209
|
}
|
|
171
210
|
|
|
172
211
|
/* Focus: underline the label (accessible indicator) */
|
|
@@ -192,14 +231,16 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
192
231
|
ERROR STATE
|
|
193
232
|
═══════════════════════════════════════════════════════════════ */
|
|
194
233
|
|
|
195
|
-
:host([
|
|
234
|
+
:host([data-invalid]) .radio-circle {
|
|
196
235
|
border-color: var(--oh-color-feedback-error);
|
|
197
|
-
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
236
|
+
box-shadow: var(--oh-elevation-offset-md) var(--oh-elevation-offset-md)
|
|
237
|
+
0 0 var(--oh-elevation-color-error);
|
|
198
238
|
}
|
|
199
239
|
|
|
200
|
-
:host([
|
|
240
|
+
:host([data-invalid]) .radio-wrapper:hover .radio-circle {
|
|
201
241
|
border-color: var(--oh-color-feedback-error-hover);
|
|
202
|
-
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
242
|
+
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
243
|
+
0 0 var(--oh-elevation-color-error);
|
|
203
244
|
}
|
|
204
245
|
|
|
205
246
|
.error-message {
|
|
@@ -238,7 +279,8 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
238
279
|
:host([force-state="hover"]) .radio-circle {
|
|
239
280
|
border-color: var(--oh-color-border-hover);
|
|
240
281
|
transform: translate(var(--oh-lift-hover-sm), var(--oh-lift-hover-sm));
|
|
241
|
-
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
282
|
+
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
283
|
+
0 0 var(--oh-elevation-color-secondary);
|
|
242
284
|
}
|
|
243
285
|
|
|
244
286
|
/* Forced Focus - Unchecked */
|
|
@@ -252,7 +294,8 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
252
294
|
background-color: var(--oh-color-brand-primary-hover);
|
|
253
295
|
border-color: var(--oh-color-brand-primary-hover);
|
|
254
296
|
transform: translate(var(--oh-lift-hover-sm), var(--oh-lift-hover-sm));
|
|
255
|
-
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
297
|
+
box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
|
|
298
|
+
0 0 var(--oh-elevation-color-primary);
|
|
256
299
|
}
|
|
257
300
|
`,
|
|
258
301
|
]; }
|
|
@@ -261,9 +304,14 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
261
304
|
this.checked = target.checked;
|
|
262
305
|
this.emit("oh-change", { checked: this.checked, value: this.value });
|
|
263
306
|
}
|
|
307
|
+
updated(changed) {
|
|
308
|
+
// Styling hook for the error state (data-invalid on the host)
|
|
309
|
+
if (changed.has("errorText"))
|
|
310
|
+
this.toggleAttribute("data-invalid", !!this.errorText);
|
|
311
|
+
}
|
|
264
312
|
willUpdate(changed) {
|
|
265
|
-
if (this.hasUpdated &&
|
|
266
|
-
this._announceError = !!
|
|
313
|
+
if (this.hasUpdated && changed.has("errorText")) {
|
|
314
|
+
this._announceError = !!this.errorText;
|
|
267
315
|
}
|
|
268
316
|
}
|
|
269
317
|
render() {
|
|
@@ -278,20 +326,34 @@ let OhRadio = class OhRadio extends OhElement {
|
|
|
278
326
|
name=${this.name}
|
|
279
327
|
.value=${this.value}
|
|
280
328
|
.checked=${this.checked}
|
|
281
|
-
aria-invalid=${this.
|
|
282
|
-
aria-describedby=${this.
|
|
329
|
+
aria-invalid=${this.errorText ? "true" : "false"}
|
|
330
|
+
aria-describedby=${this.errorText ? this._errorId : nothing}
|
|
283
331
|
@change=${this._handleChange}
|
|
284
332
|
/>
|
|
285
333
|
<span class="radio-circle" part="circle"></span>
|
|
286
334
|
<span class="label" part="label">${this.label}</span>
|
|
287
335
|
</label>
|
|
288
|
-
${this.
|
|
336
|
+
${this.errorText
|
|
289
337
|
? html `
|
|
290
|
-
<div
|
|
291
|
-
|
|
292
|
-
|
|
338
|
+
<div
|
|
339
|
+
id=${this._errorId}
|
|
340
|
+
class="error-message"
|
|
341
|
+
part="error"
|
|
342
|
+
role=${this._announceError ? "alert" : nothing}
|
|
343
|
+
>
|
|
344
|
+
<svg
|
|
345
|
+
class="error-icon"
|
|
346
|
+
viewBox="0 0 20 20"
|
|
347
|
+
fill="currentColor"
|
|
348
|
+
aria-hidden="true"
|
|
349
|
+
>
|
|
350
|
+
<path
|
|
351
|
+
fill-rule="evenodd"
|
|
352
|
+
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z"
|
|
353
|
+
clip-rule="evenodd"
|
|
354
|
+
/>
|
|
293
355
|
</svg>
|
|
294
|
-
${this.
|
|
356
|
+
${this.errorText}
|
|
295
357
|
</div>
|
|
296
358
|
`
|
|
297
359
|
: ""}
|
|
@@ -312,11 +374,8 @@ __decorate([
|
|
|
312
374
|
property({ type: String })
|
|
313
375
|
], OhRadio.prototype, "value", void 0);
|
|
314
376
|
__decorate([
|
|
315
|
-
property({ type:
|
|
316
|
-
], OhRadio.prototype, "
|
|
317
|
-
__decorate([
|
|
318
|
-
property({ type: String })
|
|
319
|
-
], OhRadio.prototype, "errorMessage", void 0);
|
|
377
|
+
property({ type: String, attribute: "error-text" })
|
|
378
|
+
], OhRadio.prototype, "errorText", void 0);
|
|
320
379
|
__decorate([
|
|
321
380
|
property({ type: String, reflect: true, attribute: "force-state" })
|
|
322
381
|
], OhRadio.prototype, "forceState", void 0);
|
package/dist/oh-radio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oh-radio.js","sourceRoot":"","sources":["../src/oh-radio.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"oh-radio.js","sourceRoot":"","sources":["../src/oh-radio.ts"],"names":[],"mappings":"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"}
|
package/dist/oh-select.d.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* oh-select
|
|
3
3
|
*
|
|
4
|
-
* A
|
|
5
|
-
*
|
|
4
|
+
* A custom dropdown select (not a native <select>), so the trigger and the
|
|
5
|
+
* list can be styled with tokens.
|
|
6
6
|
*
|
|
7
7
|
* DESIGN DECISIONS:
|
|
8
8
|
* ─────────────────
|
|
9
|
-
* 1.
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* 1. TRIGGER
|
|
10
|
+
* - A <button role="combobox">, with the same tokens as the other
|
|
11
|
+
* controls: stroke.control border in color.border.emphasis,
|
|
12
|
+
* shape.control corners, an outset shadow offset by
|
|
13
|
+
* elevation.offset.lg in elevation.color.secondary
|
|
14
|
+
* - Hover and press move it by lift.hoverMd / lift.pressSm, like oh-button
|
|
14
15
|
*
|
|
15
16
|
* 2. DROPDOWN PANEL
|
|
16
|
-
* -
|
|
17
|
-
*
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
17
|
+
* - A listbox below the trigger, on color.surface.highlight with
|
|
18
|
+
* shape.container corners
|
|
19
|
+
* - The highlighted option is underlined; the selected option is marked
|
|
20
|
+
* in color.brand.primary and set in typography.emphasis.fontWeight
|
|
21
|
+
* - Opens and closes with a transition (none under reduced motion)
|
|
20
22
|
*
|
|
21
23
|
* 3. ACCESSIBILITY
|
|
22
|
-
* - role="combobox" with
|
|
23
|
-
*
|
|
24
|
+
* - role="combobox" with aria-expanded, aria-controls and
|
|
25
|
+
* aria-activedescendant; focus stays on the trigger
|
|
26
|
+
* - Keyboard navigation (arrows, Enter, Space, Escape, Home, End, Tab)
|
|
24
27
|
* - Type-ahead search
|
|
25
|
-
* - Focus management
|
|
26
28
|
* - Label always required
|
|
27
|
-
*
|
|
28
|
-
* @element oh-select
|
|
29
29
|
*/
|
|
30
30
|
import { type PropertyValues } from "lit";
|
|
31
31
|
import { OhElement } from "./base.js";
|
|
@@ -33,6 +33,48 @@ export interface SelectOption {
|
|
|
33
33
|
label: string;
|
|
34
34
|
value: string;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* A dropdown for choosing one option from a list.
|
|
38
|
+
*
|
|
39
|
+
* **Use it for** one choice from a list too long to show every option.
|
|
40
|
+
* **Don't use it for** a few options (use `oh-radio-group`, which shows them
|
|
41
|
+
* all), several choices (use `oh-checkbox-group`) or free text (use
|
|
42
|
+
* `oh-input` with `suggestions`).
|
|
43
|
+
*
|
|
44
|
+
* **Parts:** a trigger showing the selected option's label (or
|
|
45
|
+
* `placeholder`), and a list of `options` (`{ label, value }`). One size.
|
|
46
|
+
* **States:** rest, hover, active, focus, open, error (set `error-text`),
|
|
47
|
+
* required.
|
|
48
|
+
*
|
|
49
|
+
* **Behaviour:** click the trigger, or press Enter, Space or an arrow key,
|
|
50
|
+
* to open the list. Arrow keys, Home and End move the highlight, Enter or
|
|
51
|
+
* Space selects, Escape and Tab close, and clicking outside closes. Typing
|
|
52
|
+
* letters jumps to a matching option (and selects it while the list is
|
|
53
|
+
* closed). Selecting sets `value`, returns focus to the trigger and fires
|
|
54
|
+
* `oh-change`. It isn't form-associated: it doesn't submit with a native
|
|
55
|
+
* form, so read `value` or listen for `oh-change`. It has no `disabled`
|
|
56
|
+
* property.
|
|
57
|
+
*
|
|
58
|
+
* **Accessibility:** the trigger is a `combobox` controlling a `listbox`,
|
|
59
|
+
* with `aria-activedescendant` for the highlighted option, so focus stays
|
|
60
|
+
* on the trigger. Always set `label`: it names the trigger and the list.
|
|
61
|
+
* The error shows after the label and before the trigger, with an icon, sets
|
|
62
|
+
* `aria-invalid` and is linked with `aria-describedby`; it's announced
|
|
63
|
+
* (`role="alert"`) only when it appears after first render. Focus is a
|
|
64
|
+
* solid underline on the trigger text.
|
|
65
|
+
*
|
|
66
|
+
* **Look:** set by tokens — `stroke.control` in `color.border.emphasis`
|
|
67
|
+
* (border), `shape.control` (trigger corners), `shape.container` (list
|
|
68
|
+
* corners), `typography.control.*` (type), `elevation.offset.*` and
|
|
69
|
+
* `elevation.color.secondary` (shadow), `lift.hoverMd` / `lift.pressSm` (movement
|
|
70
|
+
* on hover and press), `color.border.hover` (hover), `focus.ringColor` and
|
|
71
|
+
* `color.surface.highlight` (open), `color.surface.hover` and
|
|
72
|
+
* `color.brand.primary` (selected option), `color.feedback.error` and
|
|
73
|
+
* `elevation.color.error` (error).
|
|
74
|
+
*
|
|
75
|
+
* @element oh-select
|
|
76
|
+
* @fires oh-change - An option was selected. detail: { value }
|
|
77
|
+
*/
|
|
36
78
|
export declare class OhSelect extends OhElement {
|
|
37
79
|
static styles: import("lit").CSSResult[];
|
|
38
80
|
label: string;
|
|
@@ -51,6 +93,7 @@ export declare class OhSelect extends OhElement {
|
|
|
51
93
|
private _labelId;
|
|
52
94
|
private _listboxId;
|
|
53
95
|
private _errorId;
|
|
96
|
+
private _helperId;
|
|
54
97
|
private _typeaheadBuffer;
|
|
55
98
|
private _typeaheadTimeout;
|
|
56
99
|
private get _selectedOption();
|
package/dist/oh-select.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oh-select.d.ts","sourceRoot":"","sources":["../src/oh-select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBACa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"oh-select.d.ts","sourceRoot":"","sources":["../src/oh-select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,qBACa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,4BAqQpB;IAGF,KAAK,SAAM;IAGX,WAAW,SAAsB;IAGjC,IAAI,SAAM;IAGV,OAAO,EAAE,YAAY,EAAE,CAAM;IAG7B,KAAK,SAAM;IAGX,QAAQ,UAAS;IAGjB,UAAU,SAAM;IAGhB,SAAS,SAAM;IAGf,OAAO,CAAC,KAAK,CAAS;IAGtB,OAAO,CAAC,iBAAiB,CAAM;IAG/B,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,QAAQ,CAAqB;IAGrC,OAAO,CAAC,QAAQ,CAAoB;IAEpC,OAAO,CAAC,QAAQ,CAAgE;IAChF,OAAO,CAAC,UAAU,CAAkE;IACpF,OAAO,CAAC,QAAQ,CAAgE;IAChF,OAAO,CAAC,SAAS,CAAiE;IAClF,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAuB;IAEhD,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,qBAAqB;IAqE7B,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,mBAAmB,CAIzB;IAEO,iBAAiB;IAKjB,oBAAoB;IAK7B;;;;OAIG;IAEH,OAAO,CAAC,cAAc,CAAS;IAE/B,UAAU,CAAC,OAAO,EAAE,cAAc;IAMlC,MAAM;CAoIP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
|