@jack-henry/jh-elements 2.0.0-beta.8

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 (39) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +26 -0
  3. package/README.md +13 -0
  4. package/components/badge/badge.js +73 -0
  5. package/components/button/button.js +953 -0
  6. package/components/card/card.js +333 -0
  7. package/components/checkbox/checkbox.js +601 -0
  8. package/components/checkbox-group/checkbox-group.js +241 -0
  9. package/components/divider/divider.js +91 -0
  10. package/components/icon/icon.js +96 -0
  11. package/components/input/input.js +1245 -0
  12. package/components/input-email/input-email.js +18 -0
  13. package/components/input-password/input-password.js +153 -0
  14. package/components/input-search/input-search.js +41 -0
  15. package/components/input-telephone/input-telephone.js +18 -0
  16. package/components/input-textarea/input-textarea.js +374 -0
  17. package/components/input-url/input-url.js +31 -0
  18. package/components/list-group/list-group.js +103 -0
  19. package/components/list-item/list-item.js +350 -0
  20. package/components/menu/menu.js +60 -0
  21. package/components/notification/notification.js +327 -0
  22. package/components/progress/progress.js +417 -0
  23. package/components/radio/radio.js +422 -0
  24. package/components/radio-group/radio-group.js +400 -0
  25. package/components/switch/switch.js +316 -0
  26. package/components/table/table.js +367 -0
  27. package/components/table-data-cell/table-data-cell.js +107 -0
  28. package/components/table-header-cell/table-header-cell.js +321 -0
  29. package/components/table-row/table-row.js +52 -0
  30. package/components/tag/tag.js +422 -0
  31. package/components/tag-group/tag-group.js +57 -0
  32. package/components/toast/toast.js +172 -0
  33. package/components/toast-controller/toast-controller.js +122 -0
  34. package/components/tooltip/tooltip.js +498 -0
  35. package/custom-elements.json +6864 -0
  36. package/index.d.ts +69 -0
  37. package/jsconfig.json +9 -0
  38. package/package.json +52 -0
  39. package/utils/themeProvider.js +32 -0
@@ -0,0 +1,422 @@
1
+ // SPDX-FileCopyrightText: 2025 Jack Henry
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { LitElement, css, html } from 'lit';
6
+
7
+ let id = 0;
8
+
9
+ /**
10
+ * @cssprop --jh-radio-opacity-disabled - The radio opacity when disabled. Defaults to `--jh-opacity-disabled`.
11
+ * @cssprop --jh-radio-input-border-radius - The radio and status mark border-radius.
12
+ * Defaults to `--jh-border-radius-circle`.
13
+ * @cssprop --jh-radio-color-focus - The radio outline when it receives keyboard focus. Defaults to `--jh-border-focus-color`.
14
+ * @cssprop --jh-radio-helper-color-text - The helper-text text color. Defaults to `--jh-color-content-secondary-enabled`.
15
+ * @cssprop --jh-radio-label-color-text - The label text color. Defaults to `--jh-color-content-primary-enabled`.
16
+ * @cssprop --jh-radio-input-color-background-unselected-enabled - The radio background-color when unselected.
17
+ * Defaults to `--jh-color-container-primary-enabled`.
18
+ * @cssprop --jh-radio-input-color-border-unselected-enabled - The radio border-color when unselected.
19
+ * Defaults to `--jh-border-control-color`.
20
+ * @cssprop --jh-radio-input-color-background-unselected-focus - The radio background-color when unselected and focused. Defaults to `--jh-color-container-primary-enabled`.
21
+ * @cssprop --jh-radio-input-color-border-unselected-focus - The radio border-color when unselected and focused.
22
+ * Defaults to `--jh-color-content-brand-hover`.
23
+ * @cssprop --jh-radio-input-color-background-unselected-hover - The radio background-color when unselected and hovered.
24
+ * Defaults to `--jh-color-container-primary-enabled`.
25
+ * @cssprop --jh-radio-input-color-border-unselected-hover - The radio border-color when unselected and hovered.
26
+ * Defaults to `--jh-color-content-brand-hover`.
27
+ * @cssprop --jh-radio-input-color-background-unselected-active - The radio background-color when unselected and active.
28
+ * Defaults to `--jh-color-container-primary-enabled`.
29
+ * @cssprop --jh-radio-input-color-border-unselected-active - The radio border-color when unselected and active.
30
+ * Defaults to `--jh-color-content-brand-active`.
31
+ * @cssprop --jh-radio-input-color-background-unselected-disabled - The radio background-color when unselected and disabled.
32
+ * Defaults to `--jh-color-container-primary-enabled`.
33
+ * @cssprop --jh-radio-input-color-border-unselected-disabled - The radio border-color when unselected and disabled.
34
+ * Defaults to `--jh-border-control-color`.
35
+ * @cssprop --jh-radio-input-color-background-selected-enabled - The radio background-color when selected.
36
+ * Defaults to `--jh-color-container-primary-enabled`.
37
+ * @cssprop --jh-radio-input-color-border-selected-enabled - The radio border-color when selected.
38
+ * Defaults to `--jh-border-control-color`.
39
+ * @cssprop --jh-radio-status-color-background-selected-enabled- The status mark color when selected.
40
+ * Defaults to `--jh-color-content-brand-enabled`.
41
+ * @cssprop --jh-radio-input-color-background-selected-focus - The radio background-color when selected and focused. Defaults to `--jh-color-container-primary-enabled`.
42
+ * @cssprop --jh-radio-input-color-border-selected-focus - The radio border-color when selected and focused.
43
+ * Defaults to `--jh-color-content-brand-hover`.
44
+ * @cssprop --jh-radio-status-color-background-selected-focus - The status mark color when selected and focused.
45
+ * Defaults to `--jh-color-content-brand-hover`.
46
+ * @cssprop --jh-radio-input-color-background-selected-hover - The radio background-color when selected and hovered. Defaults to `--jh-color-container-primary-enabled`.
47
+ * @cssprop --jh-radio-input-color-border-selected-hover - The radio border-color when selected and hovered.
48
+ * Defaults to `--jh-color-content-brand-hover`.
49
+ * @cssprop --jh-radio-status-color-background-selected-hover - The status mark color when selected and hovered.
50
+ * Defaults to `--jh-color-content-brand-hover`.
51
+ * @cssprop --jh-radio-input-color-background-selected-active - The background-color when selected and active.
52
+ * Defaults to `--jh-color-container-primary-enabled`.
53
+ * @cssprop --jh-radio-input-color-border-selected-active - The border-color when selected and active.
54
+ * Defaults to `--jh-color-content-brand-active`.
55
+ * @cssprop --jh-radio-status-color-background-selected-active - The status mark color when selected and active.
56
+ * Defaults to `--jh-color-content-brand-active`.
57
+ * @cssprop --jh-radio-input-color-background-selected-disabled - The background-color when selected and disabled.
58
+ * Defaults to `--jh-color-container-primary-enabled`.
59
+ * @cssprop --jh-radio-input-color-border-selected-disabled - The border-color when selected and disabled.
60
+ * Defaults to `--jh-border-control-color`.
61
+ * @cssprop --jh-radio-status-color-background-selected-disabled - The status mark color when selected and disabled. Defaults to `--jh-color-content-brand-enabled`.
62
+ *
63
+ * @event jh-change - Dispatched when the state of the radio has changed.
64
+ *
65
+ * @customElement jh-radio */
66
+
67
+ export class JhRadio extends LitElement {
68
+
69
+ /** @type {?Number} */
70
+ #id;
71
+ /** @type {ElementInternals} */
72
+ #internals;
73
+
74
+ static get styles() {
75
+ return css`
76
+ :host {
77
+ font-family: var(--jh-font-body-regular-1-font-family);
78
+ font-weight: var(--jh-font-body-regular-1-font-weight);
79
+ font-size: var(--jh-font-body-regular-1-font-size);
80
+ line-height: var(--jh-font-body-regular-1-line-height);
81
+ display: inline-flex;
82
+ position: relative;
83
+ }
84
+ span {
85
+ box-sizing: border-box;
86
+ display: block;
87
+ }
88
+ .radio {
89
+ border-color: var(
90
+ --jh-radio-input-color-border-unselected-enabled,
91
+ var(--jh-border-control-color)
92
+ );
93
+ border-style: var(--jh-border-control-style);
94
+ border-width: var(--jh-border-control-width);
95
+ background-color: var(
96
+ --jh-radio-input-color-background-unselected-enabled,
97
+ var(--jh-color-container-primary-enabled)
98
+ );
99
+ border-radius: var(
100
+ --jh-radio-input-border-radius,
101
+ var(--jh-border-radius-circle)
102
+ );
103
+ width: var(--jh-dimension-500);
104
+ height: var(--jh-dimension-500);
105
+ position: relative;
106
+ }
107
+ :host(:hover) {
108
+ cursor: pointer;
109
+ }
110
+ :host(:focus) {
111
+ outline: none;
112
+ }
113
+ :host(:focus-visible) .radio {
114
+ outline-color: var(
115
+ --jh-radio-color-focus,
116
+ var(--jh-border-focus-color)
117
+ );
118
+ outline-style: var(--jh-border-focus-style);
119
+ outline-width: var(--jh-border-focus-width);
120
+ outline-offset: 1px;
121
+ background-color: var(
122
+ --jh-radio-input-color-background-unselected-focus,
123
+ var(--jh-color-container-primary-enabled)
124
+ );
125
+ border-color: var(
126
+ --jh-radio-input-color-border-unselected-focus,
127
+ var(--jh-color-content-brand-hover)
128
+ );
129
+ }
130
+ :host .radio:hover {
131
+ background-color: var(
132
+ --jh-radio-input-color-background-unselected-hover,
133
+ var(--jh-color-container-primary-enabled)
134
+ );
135
+ border-color: var(
136
+ --jh-radio-input-color-border-unselected-hover,
137
+ var(--jh-color-content-brand-hover)
138
+ );
139
+ }
140
+ :host .radio:active {
141
+ background-color: var(
142
+ --jh-radio-input-color-background-unselected-active,
143
+ var(--jh-color-container-primary-enabled)
144
+ );
145
+ border-color: var(
146
+ --jh-radio-input-color-border-unselected-active,
147
+ var(--jh-color-content-brand-active)
148
+ );
149
+ }
150
+ :host([disabled]) .radio {
151
+ background-color: var(
152
+ --jh-radio-input-color-background-unselected-disabled,
153
+ var(--jh-color-container-primary-enabled)
154
+ );
155
+ border-color: var(
156
+ --jh-radio-input-color-border-unselected-disabled,
157
+ var(--jh-border-control-color)
158
+ );
159
+ }
160
+ :host([checked]) .radio {
161
+ background-color: var(
162
+ --jh-radio-input-color-background-selected-enabled,
163
+ var(--jh-color-container-primary-enabled)
164
+ );
165
+ border-color: var(
166
+ --jh-radio-input-color-border-selected-enabled,
167
+ var(--jh-border-control-color)
168
+ );
169
+ }
170
+ :host([checked]:focus-visible) .radio {
171
+ background-color: var(
172
+ --jh-radio-input-color-background-selected-focus,
173
+ var(--jh-color-container-primary-enabled)
174
+ );
175
+ border-color: var(
176
+ --jh-radio-input-color-border-selected-focus,
177
+ var(--jh-color-content-brand-hover)
178
+ );
179
+ }
180
+ :host([checked]) .radio:hover {
181
+ background-color: var(
182
+ --jh-radio-input-color-background-selected-hover,
183
+ var(--jh-color-container-primary-enabled)
184
+ );
185
+ border-color: var(
186
+ --jh-radio-input-color-border-selected-hover,
187
+ var(--jh-color-content-brand-hover)
188
+ );
189
+ }
190
+ :host([checked]) .radio:active {
191
+ background-color: var(
192
+ --jh-radio-input-color-background-selected-active,
193
+ var(--jh-color-container-primary-enabled)
194
+ );
195
+ border-color: var(
196
+ --jh-radio-input-color-border-selected-active,
197
+ var(--jh-color-content-brand-active)
198
+ );
199
+ }
200
+ :host([checked][disabled]) .radio {
201
+ background-color: var(
202
+ --jh-radio-input-color-background-selected-disabled,
203
+ var(--jh-color-container-primary-enabled)
204
+ );
205
+ border-color: var(
206
+ --jh-radio-input-color-border-selected-disabled,
207
+ var(--jh-border-control-color)
208
+ );
209
+ }
210
+ :host([checked]) .radio::before {
211
+ background-color: var(
212
+ --jh-radio-status-color-background-selected-enabled,
213
+ var(--jh-color-content-brand-enabled)
214
+ );
215
+ border-radius: var(
216
+ --jh-radio-input-border-radius,
217
+ var(--jh-border-radius-circle)
218
+ );
219
+ width: var(--jh-dimension-300);
220
+ height: var(--jh-dimension-300);
221
+ content: '';
222
+ position: absolute;
223
+ top: 3px;
224
+ left: 3px;
225
+ }
226
+ :host([checked]:focus-visible) .radio::before {
227
+ background-color: var(
228
+ --jh-radio-status-color-background-selected-focus,
229
+ var(--jh-color-content-brand-hover)
230
+ );
231
+ }
232
+ :host([checked]) .radio:hover::before {
233
+ background-color: var(
234
+ --jh-radio-status-color-background-selected-hover,
235
+ var(--jh-color-content-brand-hover)
236
+ );
237
+ }
238
+ :host([checked]) .radio:active::before {
239
+ background-color: var(
240
+ --jh-radio-status-color-background-selected-active,
241
+ var(--jh-color-content-brand-active)
242
+ );
243
+ }
244
+ :host([checked][disabled]) .radio::before {
245
+ background-color: var(
246
+ --jh-radio-status-color-background-selected-disabled,
247
+ var(--jh-color-content-brand-enabled)
248
+ );
249
+ }
250
+ .label-container {
251
+ margin-left: var(--jh-dimension-200);
252
+ flex: 1;
253
+ }
254
+ .label-text,
255
+ .helper-text {
256
+ word-break: break-word;
257
+ }
258
+ .label-text {
259
+ color: var(
260
+ --jh-radio-label-color-text,
261
+ var(--jh-color-content-primary-enabled)
262
+ );
263
+ }
264
+ .helper-text {
265
+ color: var(
266
+ --jh-radio-helper-color-text,
267
+ var(--jh-color-content-secondary-enabled)
268
+ );
269
+ font-family: var(--jh-font-helper-regular-font-family);
270
+ font-weight: var(--jh-font-helper-regular-font-weight);
271
+ font-size: var(--jh-font-helper-regular-font-size);
272
+ line-height: var(--jh-font-helper-regular-line-height);
273
+ margin: 0;
274
+ }
275
+ :host([disabled]) {
276
+ opacity: var(--jh-radio-opacity-disabled, var(--jh-opacity-disabled));
277
+ cursor: default;
278
+ }
279
+ :host([disabled]:focus-visible) .radio {
280
+ outline: none;
281
+ }
282
+ `;
283
+ }
284
+
285
+ static get properties() {
286
+ return {
287
+ /** Sets an `aria-label` to assist screen reader users when no visible label is present. */
288
+ accessibleLabel: {
289
+ type: String,
290
+ attribute: 'accessible-label',
291
+ },
292
+ /** Sets the selected or 'checked' state on the radio. */
293
+ checked: {
294
+ type: Boolean,
295
+ reflect: true,
296
+ },
297
+ /** Disables the radio and prevents all user interactions. May cause radio to be ignored by assistive technologies(AT). */
298
+ disabled: {
299
+ type: Boolean,
300
+ reflect: true,
301
+ },
302
+ /**
303
+ * Provides additional context or guidance for using the radio. For `helper-text` to be displayed, the `label` property must also be set.
304
+ */
305
+ helperText: {
306
+ type: String,
307
+ attribute: 'helper-text',
308
+ },
309
+ /**
310
+ * Sets the value of the data to be collected when selected.
311
+ */
312
+ label: {
313
+ type: String,
314
+ },
315
+ /** Sets the value of the radio. */
316
+ value: {
317
+ type: String,
318
+ },
319
+ };
320
+ }
321
+
322
+ constructor() {
323
+ super();
324
+ this.#internals = this.attachInternals();
325
+ this.#internals.role = 'radio';
326
+ /** @type {?string} */
327
+ this.accessibleLabel = null;
328
+ /** @type {?boolean} */
329
+ this.checked = false;
330
+ /** @type {?boolean} */
331
+ this.disabled = false;
332
+ /** @type {?string} */
333
+ this.helperText = null;
334
+ /** @type {?string} */
335
+ this.label = null;
336
+ /** @type {?string} */
337
+ this.value = null;
338
+
339
+ this.addEventListener('click', this.#handleClick);
340
+ this.addEventListener('keydown', this.#handleKeydown);
341
+ }
342
+
343
+ connectedCallback() {
344
+ super.connectedCallback();
345
+ this.#id = id++;
346
+ this.setAttribute('tabindex', '0');
347
+ this.setAttribute('aria-checked', `${this.checked}`);
348
+ if (this.accessibleLabel) {
349
+ this.setAttribute('aria-label', `${this.accessibleLabel}`);
350
+ }
351
+ if (this.helperText) {
352
+ this.setAttribute('aria-describedby', `radio-helper-text-${this.#id}`);
353
+ }
354
+
355
+ let observer = new MutationObserver(this.#updateArias.bind(this));
356
+ let options = {
357
+ attributes: true,
358
+ };
359
+ observer.observe(this, options);
360
+ }
361
+
362
+ #updateArias(mutations) {
363
+ for (const mutation of mutations) {
364
+ if (mutation.attributeName === 'checked') {
365
+ this.setAttribute('aria-checked', `${this.checked}`);
366
+ }
367
+ if (mutation.attributeName === 'disabled') {
368
+ this.setAttribute('aria-disabled', `${this.disabled}`);
369
+ }
370
+ if (mutation.attributeName === 'accessible-label') {
371
+ this.setAttribute('aria-label', `${this.accessibleLabel}`);
372
+ }
373
+ }
374
+ }
375
+
376
+ #handleClick() {
377
+ if (this.disabled) return;
378
+ if (this.checked) return;
379
+
380
+ this.checked = true;
381
+ const options = {
382
+ bubbles: true,
383
+ composed: true,
384
+ cancelable: true,
385
+ };
386
+ this.dispatchEvent(new CustomEvent('jh-change', options));
387
+ }
388
+
389
+ #handleKeydown(e) {
390
+ if (e.code === 'Space') {
391
+ this.#handleClick();
392
+ }
393
+ }
394
+
395
+ render() {
396
+ let helperText;
397
+ let label;
398
+
399
+ if (this.helperText) {
400
+ helperText = html`
401
+ <p class="helper-text" id="radio-helper-text-${this.#id}">
402
+ ${this.helperText}
403
+ </p>
404
+ `;
405
+ }
406
+
407
+ if (this.label) {
408
+ label = html`
409
+ <span class="label-container">
410
+ <span class="label-text">${this.label}</span>
411
+ ${helperText}
412
+ </span>
413
+ `;
414
+ }
415
+
416
+ return html`
417
+ <span class="radio" aria-hidden="true"></span>
418
+ ${label}
419
+ `;
420
+ }
421
+ }
422
+ customElements.define('jh-radio', JhRadio);