@orange-halo/components 1.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 +186 -0
- package/dist/base.d.ts +30 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +78 -0
- package/dist/base.js.map +1 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/oh-accordion.d.ts +47 -0
- package/dist/oh-accordion.d.ts.map +1 -0
- package/dist/oh-accordion.js +387 -0
- package/dist/oh-accordion.js.map +1 -0
- package/dist/oh-alert.d.ts +48 -0
- package/dist/oh-alert.d.ts.map +1 -0
- package/dist/oh-alert.js +343 -0
- package/dist/oh-alert.js.map +1 -0
- package/dist/oh-badge.d.ts +38 -0
- package/dist/oh-badge.d.ts.map +1 -0
- package/dist/oh-badge.js +176 -0
- package/dist/oh-badge.js.map +1 -0
- package/dist/oh-breadcrumb.d.ts +39 -0
- package/dist/oh-breadcrumb.d.ts.map +1 -0
- package/dist/oh-breadcrumb.js +277 -0
- package/dist/oh-breadcrumb.js.map +1 -0
- package/dist/oh-button.d.ts +62 -0
- package/dist/oh-button.d.ts.map +1 -0
- package/dist/oh-button.figma.d.ts +2 -0
- package/dist/oh-button.figma.d.ts.map +1 -0
- package/dist/oh-button.figma.js +20 -0
- package/dist/oh-button.figma.js.map +1 -0
- package/dist/oh-button.js +490 -0
- package/dist/oh-button.js.map +1 -0
- package/dist/oh-card.d.ts +44 -0
- package/dist/oh-card.d.ts.map +1 -0
- package/dist/oh-card.js +340 -0
- package/dist/oh-card.js.map +1 -0
- package/dist/oh-checkbox-group.d.ts +39 -0
- package/dist/oh-checkbox-group.d.ts.map +1 -0
- package/dist/oh-checkbox-group.figma.d.ts +2 -0
- package/dist/oh-checkbox-group.figma.d.ts.map +1 -0
- package/dist/oh-checkbox-group.figma.js +24 -0
- package/dist/oh-checkbox-group.figma.js.map +1 -0
- package/dist/oh-checkbox-group.js +309 -0
- package/dist/oh-checkbox-group.js.map +1 -0
- package/dist/oh-checkbox.d.ts +50 -0
- package/dist/oh-checkbox.d.ts.map +1 -0
- package/dist/oh-checkbox.js +315 -0
- package/dist/oh-checkbox.js.map +1 -0
- package/dist/oh-cluster.d.ts +38 -0
- package/dist/oh-cluster.d.ts.map +1 -0
- package/dist/oh-cluster.js +141 -0
- package/dist/oh-cluster.js.map +1 -0
- package/dist/oh-container.d.ts +38 -0
- package/dist/oh-container.d.ts.map +1 -0
- package/dist/oh-container.js +116 -0
- package/dist/oh-container.js.map +1 -0
- package/dist/oh-drawer.d.ts +66 -0
- package/dist/oh-drawer.d.ts.map +1 -0
- package/dist/oh-drawer.js +284 -0
- package/dist/oh-drawer.js.map +1 -0
- package/dist/oh-footer.d.ts +40 -0
- package/dist/oh-footer.d.ts.map +1 -0
- package/dist/oh-footer.js +112 -0
- package/dist/oh-footer.js.map +1 -0
- package/dist/oh-grid.d.ts +40 -0
- package/dist/oh-grid.d.ts.map +1 -0
- package/dist/oh-grid.js +168 -0
- package/dist/oh-grid.js.map +1 -0
- package/dist/oh-hero.d.ts +28 -0
- package/dist/oh-hero.d.ts.map +1 -0
- package/dist/oh-hero.js +242 -0
- package/dist/oh-hero.js.map +1 -0
- package/dist/oh-icon.d.ts +44 -0
- package/dist/oh-icon.d.ts.map +1 -0
- package/dist/oh-icon.js +321 -0
- package/dist/oh-icon.js.map +1 -0
- package/dist/oh-input.d.ts +56 -0
- package/dist/oh-input.d.ts.map +1 -0
- package/dist/oh-input.figma.d.ts +2 -0
- package/dist/oh-input.figma.d.ts.map +1 -0
- package/dist/oh-input.figma.js +36 -0
- package/dist/oh-input.figma.js.map +1 -0
- package/dist/oh-input.js +320 -0
- package/dist/oh-input.js.map +1 -0
- package/dist/oh-link.d.ts +45 -0
- package/dist/oh-link.d.ts.map +1 -0
- package/dist/oh-link.js +392 -0
- package/dist/oh-link.js.map +1 -0
- package/dist/oh-modal.d.ts +54 -0
- package/dist/oh-modal.d.ts.map +1 -0
- package/dist/oh-modal.js +450 -0
- package/dist/oh-modal.js.map +1 -0
- package/dist/oh-navbar.d.ts +49 -0
- package/dist/oh-navbar.d.ts.map +1 -0
- package/dist/oh-navbar.js +185 -0
- package/dist/oh-navbar.js.map +1 -0
- package/dist/oh-progress.d.ts +56 -0
- package/dist/oh-progress.d.ts.map +1 -0
- package/dist/oh-progress.js +299 -0
- package/dist/oh-progress.js.map +1 -0
- package/dist/oh-radio-group.d.ts +43 -0
- package/dist/oh-radio-group.d.ts.map +1 -0
- package/dist/oh-radio-group.figma.d.ts +2 -0
- package/dist/oh-radio-group.figma.d.ts.map +1 -0
- package/dist/oh-radio-group.figma.js +22 -0
- package/dist/oh-radio-group.figma.js.map +1 -0
- package/dist/oh-radio-group.js +324 -0
- package/dist/oh-radio-group.js.map +1 -0
- package/dist/oh-radio.d.ts +50 -0
- package/dist/oh-radio.d.ts.map +1 -0
- package/dist/oh-radio.js +314 -0
- package/dist/oh-radio.js.map +1 -0
- package/dist/oh-select.d.ts +82 -0
- package/dist/oh-select.d.ts.map +1 -0
- package/dist/oh-select.js +638 -0
- package/dist/oh-select.js.map +1 -0
- package/dist/oh-skip-link.d.ts +37 -0
- package/dist/oh-skip-link.d.ts.map +1 -0
- package/dist/oh-skip-link.js +145 -0
- package/dist/oh-skip-link.js.map +1 -0
- package/dist/oh-stack.d.ts +36 -0
- package/dist/oh-stack.d.ts.map +1 -0
- package/dist/oh-stack.js +112 -0
- package/dist/oh-stack.js.map +1 -0
- package/dist/oh-tabs.d.ts +85 -0
- package/dist/oh-tabs.d.ts.map +1 -0
- package/dist/oh-tabs.js +417 -0
- package/dist/oh-tabs.js.map +1 -0
- package/dist/oh-toggle.d.ts +51 -0
- package/dist/oh-toggle.d.ts.map +1 -0
- package/dist/oh-toggle.js +219 -0
- package/dist/oh-toggle.js.map +1 -0
- package/dist/styles/typography.d.ts +15 -0
- package/dist/styles/typography.d.ts.map +1 -0
- package/dist/styles/typography.js +235 -0
- package/dist/styles/typography.js.map +1 -0
- package/package.json +140 -0
package/dist/oh-radio.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* oh-radio
|
|
3
|
+
*
|
|
4
|
+
* A chunky, playful radio button with hand-crafted feel.
|
|
5
|
+
* Matches the inset/pressed aesthetic of oh-input.
|
|
6
|
+
*
|
|
7
|
+
* DESIGN DECISIONS:
|
|
8
|
+
* ─────────────────
|
|
9
|
+
* 1. CHUNKY & TACTILE
|
|
10
|
+
* - Thick 2.5px border
|
|
11
|
+
* - Inset shadow when unchecked (pressed into page)
|
|
12
|
+
* - Fully circular (radio = circle)
|
|
13
|
+
*
|
|
14
|
+
* 2. CHECKED STATE
|
|
15
|
+
* - Filled dot in center
|
|
16
|
+
* - Primary color ring
|
|
17
|
+
* - Shadow shifts to feel "activated"
|
|
18
|
+
*
|
|
19
|
+
* 3. ACCESSIBILITY
|
|
20
|
+
* - Native radio hidden but accessible
|
|
21
|
+
* - Label always required
|
|
22
|
+
* - Focus ring matches input
|
|
23
|
+
* - Works in radio groups via name attribute
|
|
24
|
+
*
|
|
25
|
+
* @element oh-radio
|
|
26
|
+
*/
|
|
27
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
28
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
30
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
31
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
32
|
+
};
|
|
33
|
+
import { html, css } from "lit";
|
|
34
|
+
import { customElement, property } from "lit/decorators.js";
|
|
35
|
+
import { OhElement, baseStyles } from "./base.js";
|
|
36
|
+
let OhRadio = class OhRadio extends OhElement {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.checked = false;
|
|
40
|
+
this.label = "";
|
|
41
|
+
this.name = "";
|
|
42
|
+
this.value = "";
|
|
43
|
+
this.error = false;
|
|
44
|
+
this.errorMessage = "";
|
|
45
|
+
/**
|
|
46
|
+
* Force a visual state (for documentation/Figma sync only)
|
|
47
|
+
* Values: 'hover' | 'focus'
|
|
48
|
+
*/
|
|
49
|
+
this.forceState = "default";
|
|
50
|
+
}
|
|
51
|
+
static { this.styles = [
|
|
52
|
+
baseStyles,
|
|
53
|
+
css `
|
|
54
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
55
|
+
ORANGE HALO RADIO
|
|
56
|
+
Chunky • Tactile • Playful
|
|
57
|
+
═══════════════════════════════════════════════════════════════ */
|
|
58
|
+
|
|
59
|
+
:host {
|
|
60
|
+
display: inline-block;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.radio-wrapper {
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
align-items: flex-start;
|
|
66
|
+
gap: var(--oh-spacing-3);
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Hide native radio but keep it accessible */
|
|
71
|
+
.native-radio {
|
|
72
|
+
position: absolute;
|
|
73
|
+
width: 1px;
|
|
74
|
+
height: 1px;
|
|
75
|
+
padding: 0;
|
|
76
|
+
margin: -1px;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
clip: rect(0, 0, 0, 0);
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
border: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
84
|
+
CUSTOM RADIO CIRCLE
|
|
85
|
+
═══════════════════════════════════════════════════════════════ */
|
|
86
|
+
|
|
87
|
+
.radio-circle {
|
|
88
|
+
position: relative;
|
|
89
|
+
width: 24px;
|
|
90
|
+
height: 24px;
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
|
|
93
|
+
/* Chunky border, fully circular */
|
|
94
|
+
border: var(--oh-input-base-border-width) solid var(--oh-color-border-emphasis);
|
|
95
|
+
border-radius: var(--oh-radius-full);
|
|
96
|
+
|
|
97
|
+
/* Offset shadow like primary button */
|
|
98
|
+
background-color: var(--oh-color-surface-base);
|
|
99
|
+
box-shadow: 3px 3px 0 0 var(--oh-shadow-secondary);
|
|
100
|
+
|
|
101
|
+
transition:
|
|
102
|
+
transform var(--oh-motion-snappy) var(--oh-motion-ease-playful),
|
|
103
|
+
box-shadow var(--oh-motion-snappy) var(--oh-motion-ease-playful),
|
|
104
|
+
background-color var(--oh-motion-quick) ease,
|
|
105
|
+
border-color var(--oh-motion-quick) ease;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Inner dot (hidden by default) */
|
|
109
|
+
.radio-circle::after {
|
|
110
|
+
content: '';
|
|
111
|
+
position: absolute;
|
|
112
|
+
top: 50%;
|
|
113
|
+
left: 50%;
|
|
114
|
+
width: 10px;
|
|
115
|
+
height: 10px;
|
|
116
|
+
background-color: var(--oh-color-text-on-brand);
|
|
117
|
+
border-radius: var(--oh-radius-full);
|
|
118
|
+
transform: translate(-50%, -50%) scale(0);
|
|
119
|
+
transition: transform var(--oh-motion-snappy) var(--oh-motion-ease-playful);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
123
|
+
STATES
|
|
124
|
+
═══════════════════════════════════════════════════════════════ */
|
|
125
|
+
|
|
126
|
+
/* Hover: lift up-left, shadow grows */
|
|
127
|
+
.radio-wrapper:hover .radio-circle {
|
|
128
|
+
border-color: var(--oh-color-border-hover);
|
|
129
|
+
transform: translate(-1px, -1px);
|
|
130
|
+
box-shadow: 4px 4px 0 0 var(--oh-shadow-secondary);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Active: press down-right, shadow shrinks */
|
|
134
|
+
.radio-wrapper:active .radio-circle {
|
|
135
|
+
transform: translate(1px, 1px);
|
|
136
|
+
box-shadow: 1px 1px 0 0 var(--oh-shadow-secondary);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Checked: primary color with warm shadow */
|
|
140
|
+
.native-radio:checked + .radio-circle {
|
|
141
|
+
background-color: var(--oh-color-brand-primary);
|
|
142
|
+
border-color: var(--oh-color-brand-primary);
|
|
143
|
+
box-shadow: 3px 3px 0 0 var(--oh-shadow-primary);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.native-radio:checked + .radio-circle::after {
|
|
147
|
+
transform: translate(-50%, -50%) scale(1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Checked + Hover */
|
|
151
|
+
.radio-wrapper:hover .native-radio:checked + .radio-circle {
|
|
152
|
+
background-color: var(--oh-color-brand-primary-hover);
|
|
153
|
+
border-color: var(--oh-color-brand-primary-hover);
|
|
154
|
+
transform: translate(-1px, -1px);
|
|
155
|
+
box-shadow: 4px 4px 0 0 var(--oh-shadow-primary);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Checked + Active */
|
|
159
|
+
.radio-wrapper:active .native-radio:checked + .radio-circle {
|
|
160
|
+
background-color: var(--oh-color-brand-primary-active);
|
|
161
|
+
transform: translate(1px, 1px);
|
|
162
|
+
box-shadow: 1px 1px 0 0 var(--oh-shadow-primary);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Focus: underline the label (accessible indicator) */
|
|
166
|
+
.native-radio:focus-visible ~ .label {
|
|
167
|
+
text-decoration: underline;
|
|
168
|
+
text-underline-offset: var(--oh-spacing-1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
172
|
+
LABEL
|
|
173
|
+
═══════════════════════════════════════════════════════════════ */
|
|
174
|
+
|
|
175
|
+
.label {
|
|
176
|
+
font-family: var(--oh-font-family-sans);
|
|
177
|
+
font-size: var(--oh-font-size-lg);
|
|
178
|
+
line-height: var(--oh-font-line-height-normal);
|
|
179
|
+
color: var(--oh-color-text-primary);
|
|
180
|
+
user-select: none;
|
|
181
|
+
padding-top: 0; /* Align with radio */
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
185
|
+
ERROR STATE
|
|
186
|
+
═══════════════════════════════════════════════════════════════ */
|
|
187
|
+
|
|
188
|
+
:host([error]) .radio-circle {
|
|
189
|
+
border-color: var(--oh-color-feedback-error);
|
|
190
|
+
box-shadow: 3px 3px 0 0 var(--oh-shadow-error);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:host([error]) .radio-wrapper:hover .radio-circle {
|
|
194
|
+
border-color: var(--oh-color-feedback-error-hover);
|
|
195
|
+
box-shadow: 4px 4px 0 0 var(--oh-shadow-error);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.error-message {
|
|
199
|
+
display: flex;
|
|
200
|
+
align-items: center;
|
|
201
|
+
gap: var(--oh-spacing-2);
|
|
202
|
+
font-family: var(--oh-font-family-sans);
|
|
203
|
+
font-size: var(--oh-font-size-base);
|
|
204
|
+
color: var(--oh-color-feedback-error);
|
|
205
|
+
margin-top: var(--oh-spacing-1);
|
|
206
|
+
margin-left: calc(24px + var(--oh-spacing-3)); /* Align with label */
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.error-icon {
|
|
210
|
+
flex-shrink: 0;
|
|
211
|
+
width: var(--oh-spacing-4);
|
|
212
|
+
height: var(--oh-spacing-4);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
216
|
+
REDUCED MOTION
|
|
217
|
+
═══════════════════════════════════════════════════════════════ */
|
|
218
|
+
|
|
219
|
+
@media (prefers-reduced-motion: reduce) {
|
|
220
|
+
.radio-circle,
|
|
221
|
+
.radio-circle::after {
|
|
222
|
+
transition-duration: 0.01ms !important;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
227
|
+
FORCED STATES (for Figma Sync / documentation)
|
|
228
|
+
═══════════════════════════════════════════════════════════════ */
|
|
229
|
+
|
|
230
|
+
/* Forced Hover - Unchecked */
|
|
231
|
+
:host([force-state="hover"]) .radio-circle {
|
|
232
|
+
border-color: var(--oh-color-border-hover);
|
|
233
|
+
transform: translate(-1px, -1px);
|
|
234
|
+
box-shadow: 4px 4px 0 0 var(--oh-shadow-secondary);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* Forced Focus - Unchecked */
|
|
238
|
+
:host([force-state="focus"]) .label {
|
|
239
|
+
text-decoration: underline;
|
|
240
|
+
text-underline-offset: var(--oh-spacing-1);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* Forced Hover - Checked */
|
|
244
|
+
:host([force-state="hover"][checked]) .radio-circle {
|
|
245
|
+
background-color: var(--oh-color-brand-primary-hover);
|
|
246
|
+
border-color: var(--oh-color-brand-primary-hover);
|
|
247
|
+
transform: translate(-1px, -1px);
|
|
248
|
+
box-shadow: 4px 4px 0 0 var(--oh-shadow-primary);
|
|
249
|
+
}
|
|
250
|
+
`,
|
|
251
|
+
]; }
|
|
252
|
+
_handleChange(event) {
|
|
253
|
+
const target = event.target;
|
|
254
|
+
this.checked = target.checked;
|
|
255
|
+
this.emit("oh-change", { checked: this.checked, value: this.value });
|
|
256
|
+
}
|
|
257
|
+
render() {
|
|
258
|
+
const inputId = `oh-radio-${this.name}-${this.value || Math.random().toString(36).substr(2, 9)}`;
|
|
259
|
+
return html `
|
|
260
|
+
<div>
|
|
261
|
+
<label class="radio-wrapper" for=${inputId}>
|
|
262
|
+
<input
|
|
263
|
+
type="radio"
|
|
264
|
+
class="native-radio"
|
|
265
|
+
id=${inputId}
|
|
266
|
+
name=${this.name}
|
|
267
|
+
.value=${this.value}
|
|
268
|
+
.checked=${this.checked}
|
|
269
|
+
aria-invalid=${this.error ? "true" : "false"}
|
|
270
|
+
@change=${this._handleChange}
|
|
271
|
+
/>
|
|
272
|
+
<span class="radio-circle" part="circle"></span>
|
|
273
|
+
<span class="label" part="label">${this.label}</span>
|
|
274
|
+
</label>
|
|
275
|
+
${this.error && this.errorMessage
|
|
276
|
+
? html `
|
|
277
|
+
<div class="error-message" part="error" role="alert">
|
|
278
|
+
<svg class="error-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
279
|
+
<path fill-rule="evenodd" 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" clip-rule="evenodd" />
|
|
280
|
+
</svg>
|
|
281
|
+
${this.errorMessage}
|
|
282
|
+
</div>
|
|
283
|
+
`
|
|
284
|
+
: ""}
|
|
285
|
+
</div>
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
__decorate([
|
|
290
|
+
property({ type: Boolean, reflect: true })
|
|
291
|
+
], OhRadio.prototype, "checked", void 0);
|
|
292
|
+
__decorate([
|
|
293
|
+
property({ type: String })
|
|
294
|
+
], OhRadio.prototype, "label", void 0);
|
|
295
|
+
__decorate([
|
|
296
|
+
property({ type: String })
|
|
297
|
+
], OhRadio.prototype, "name", void 0);
|
|
298
|
+
__decorate([
|
|
299
|
+
property({ type: String })
|
|
300
|
+
], OhRadio.prototype, "value", void 0);
|
|
301
|
+
__decorate([
|
|
302
|
+
property({ type: Boolean, reflect: true })
|
|
303
|
+
], OhRadio.prototype, "error", void 0);
|
|
304
|
+
__decorate([
|
|
305
|
+
property({ type: String })
|
|
306
|
+
], OhRadio.prototype, "errorMessage", void 0);
|
|
307
|
+
__decorate([
|
|
308
|
+
property({ type: String, reflect: true, attribute: "force-state" })
|
|
309
|
+
], OhRadio.prototype, "forceState", void 0);
|
|
310
|
+
OhRadio = __decorate([
|
|
311
|
+
customElement("oh-radio")
|
|
312
|
+
], OhRadio);
|
|
313
|
+
export { OhRadio };
|
|
314
|
+
//# sourceMappingURL=oh-radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oh-radio.js","sourceRoot":"","sources":["../src/oh-radio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* oh-select
|
|
3
|
+
*
|
|
4
|
+
* A chunky, playful dropdown select with hand-crafted feel.
|
|
5
|
+
* Custom-styled dropdown (not native) for full visual control.
|
|
6
|
+
*
|
|
7
|
+
* DESIGN DECISIONS:
|
|
8
|
+
* ─────────────────
|
|
9
|
+
* 1. CHUNKY & TACTILE
|
|
10
|
+
* - Thick 2.5px border
|
|
11
|
+
* - Offset shadow (sticker effect like button)
|
|
12
|
+
* - 10px border radius
|
|
13
|
+
* - Solid warm fills
|
|
14
|
+
*
|
|
15
|
+
* 2. DROPDOWN PANEL
|
|
16
|
+
* - Appears below trigger with shadow
|
|
17
|
+
* - Options have hover/focus states
|
|
18
|
+
* - Selected option highlighted
|
|
19
|
+
* - Smooth open/close animation
|
|
20
|
+
*
|
|
21
|
+
* 3. ACCESSIBILITY
|
|
22
|
+
* - role="combobox" with proper ARIA
|
|
23
|
+
* - Keyboard navigation (arrows, enter, escape, home, end)
|
|
24
|
+
* - Type-ahead search
|
|
25
|
+
* - Focus management
|
|
26
|
+
* - Label always required
|
|
27
|
+
*
|
|
28
|
+
* @element oh-select
|
|
29
|
+
*/
|
|
30
|
+
import { OhElement } from "./base.js";
|
|
31
|
+
export interface SelectOption {
|
|
32
|
+
label: string;
|
|
33
|
+
value: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class OhSelect extends OhElement {
|
|
36
|
+
static styles: import("lit").CSSResult[];
|
|
37
|
+
label: string;
|
|
38
|
+
placeholder: string;
|
|
39
|
+
name: string;
|
|
40
|
+
options: SelectOption[];
|
|
41
|
+
value: string;
|
|
42
|
+
required: boolean;
|
|
43
|
+
helperText: string;
|
|
44
|
+
errorText: string;
|
|
45
|
+
private _open;
|
|
46
|
+
private _highlightedIndex;
|
|
47
|
+
private _focused;
|
|
48
|
+
private _trigger;
|
|
49
|
+
private _listbox;
|
|
50
|
+
private _labelId;
|
|
51
|
+
private _listboxId;
|
|
52
|
+
private _errorId;
|
|
53
|
+
private _typeaheadBuffer;
|
|
54
|
+
private _typeaheadTimeout;
|
|
55
|
+
private get _selectedOption();
|
|
56
|
+
private _open_dropdown;
|
|
57
|
+
private _close_dropdown;
|
|
58
|
+
private _toggle_dropdown;
|
|
59
|
+
private _selectOption;
|
|
60
|
+
private _handleTriggerClick;
|
|
61
|
+
private _handleTriggerKeydown;
|
|
62
|
+
private _handleTypeahead;
|
|
63
|
+
private _highlightNext;
|
|
64
|
+
private _highlightPrevious;
|
|
65
|
+
private _highlightFirst;
|
|
66
|
+
private _highlightLast;
|
|
67
|
+
private _scrollToHighlighted;
|
|
68
|
+
private _handleOptionClick;
|
|
69
|
+
private _handleOptionMouseenter;
|
|
70
|
+
private _handleFocus;
|
|
71
|
+
private _handleBlur;
|
|
72
|
+
private _handleClickOutside;
|
|
73
|
+
connectedCallback(): void;
|
|
74
|
+
disconnectedCallback(): void;
|
|
75
|
+
render(): import("lit").TemplateResult<1>;
|
|
76
|
+
}
|
|
77
|
+
declare global {
|
|
78
|
+
interface HTMLElementTagNameMap {
|
|
79
|
+
"oh-select": OhSelect;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=oh-select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oh-select.d.ts","sourceRoot":"","sources":["../src/oh-select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,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,4BA+PpB;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,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAuB;IAEhD,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,cAAc;IAQtB,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;IAQ1B,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,MAAM;CAyGP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
|