@jack-henry/jh-elements 2.0.0-beta.14 → 2.0.0-beta.15

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 (36) hide show
  1. package/NOTICE +1 -1
  2. package/README.md +2 -2
  3. package/components/badge/badge.js +4 -4
  4. package/components/button/button.js +8 -13
  5. package/components/card/card.js +4 -4
  6. package/components/checkbox/checkbox.js +19 -31
  7. package/components/checkbox-group/checkbox-group.js +12 -20
  8. package/components/divider/divider.js +5 -5
  9. package/components/element/element.js +94 -0
  10. package/components/icon/icon.js +14 -12
  11. package/components/input/input.js +63 -64
  12. package/components/input-email/input-email.js +1 -1
  13. package/components/input-password/input-password.js +3 -12
  14. package/components/input-search/input-search.js +1 -1
  15. package/components/input-telephone/input-telephone.js +1 -1
  16. package/components/input-textarea/input-textarea.js +4 -13
  17. package/components/input-url/input-url.js +1 -1
  18. package/components/list-group/list-group.js +6 -13
  19. package/components/list-item/list-item.js +131 -143
  20. package/components/menu/menu.js +5 -8
  21. package/components/notification/notification.js +5 -15
  22. package/components/progress/progress.js +62 -56
  23. package/components/radio/radio.js +8 -21
  24. package/components/radio-group/radio-group.js +16 -31
  25. package/components/select/select.js +51 -30
  26. package/components/switch/switch.js +9 -22
  27. package/components/table/table.js +7 -14
  28. package/components/table-data-cell/table-data-cell.js +5 -8
  29. package/components/table-header-cell/table-header-cell.js +14 -24
  30. package/components/table-row/table-row.js +5 -8
  31. package/components/tag/tag.js +5 -10
  32. package/components/tag-group/tag-group.js +5 -7
  33. package/components/toast/toast.js +5 -14
  34. package/components/tooltip/tooltip.js +8 -9
  35. package/custom-elements.json +338 -226
  36. package/package.json +3 -3
@@ -2,13 +2,12 @@
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
 
5
- import { LitElement, css, html } from 'lit';
5
+ import { css, html } from 'lit';
6
6
  import { ifDefined } from 'lit/directives/if-defined.js';
7
+ import { JhElement } from '../element/element.js';
7
8
  import '../button/button.js';
8
9
  import '@jack-henry/jh-icons/icons-wc/icon-circle-xmark.js';
9
10
 
10
- let id = 0;
11
-
12
11
  /**
13
12
  * @cssprop --jh-input-label-color-text - The label text color. Defaults to `--jh-color-content-primary-enabled`.
14
13
  * @cssprop --jh-input-field-color-background - The input field background-color when in an editable state. This property does not apply when the component is set to `readonly`. Defaults to `--jh-color-container-primary-enabled`.
@@ -42,26 +41,22 @@ let id = 0;
42
41
  * @cssprop --jh-input-value-color-text - The value text color. Defaults to `jh-color-content-primary-enabled`.
43
42
  * @cssprop --jh-input-error-color-text - The error message text color. Defaults to `jh-color-content-negative-enabled`.
44
43
  *
45
- * @event jh-select - Dispatched when text is selected. Event payload contains the selected text, the starting index of the selection, and the ending index of the selection. These values can be accessed via `e.detail.selected`, `e.detail.selectionStart`, and `e.detail.selectionEnd`.
46
- * @event jh-change - Dispatched when the value of the input has changed and input loses focus. Event payload includes the value of the input and can be accessed via `e.detail.value`. Payload also includes the raw/unformatted value when an input mask is applied and can be accessed via `e.detail.rawValue`.
47
- * @event jh-input - Dispatched when the value of the input has changed. Event payload includes the value of the input and can be accessed via `e.detail.value`. Payload also includes the raw/unformatted value when an input mask is applied and can be accessed via `e.detail.rawValue`.
48
- * @event jh-maxlength - Dispatched when the `maxlength` property is set and it's value is reached.
49
- * @event jh-input:clear-button-click - Dispatched when the clear button is activated. Event payload contains the previous value of the input field before it was cleared and can be accessed via `e.detail.previousValue`.
44
+ * @event jh-select - Dispatched when text is selected. Event payload contains the selected text, the starting index of the selection, and the ending index of the selection. These values can be accessed via `e.detail.state.selected`, `e.detail.state.selectionStart`, and `e.detail.state.selectionEnd`.
45
+ * @event jh-change - Dispatched when the value of the input has changed and input loses focus. Event payload includes the value of the input and can be accessed via `e.detail.state.value`. Payload also includes the raw/unformatted value when an input mask is applied and can be accessed via `e.detail.state.rawValue`. Payload also includes the `maxlength` and `minlength` values and can be accessed via `e.detail.reference.maxlength` and `e.detail.reference.minlength` as well as the `pattern` value and can be accessed via `e.detail.reference.pattern`.
46
+ * @event jh-input - Dispatched when the value of the input has changed. Event payload includes the value of the input and can be accessed via `e.detail.state.value`. Payload also includes the raw/unformatted value when an input mask is applied and can be accessed via `e.detail.state.rawValue`. Payload also includes the `maxlength` and `minlength` values and can be accessed via `e.detail.reference.maxlength` and `e.detail.reference.minlength` as well as the `pattern` value and can be accessed via `e.detail.reference.pattern`.
47
+ * @event jh-maxlength - Dispatched when the `maxlength` property is set and it's value is reached. Event payload includes the `maxlength` value and can be accessed via `e.detail.reference.maxlength`.
48
+ * @event jh-input:clear-button-click - Dispatched when the clear button is activated. Event payload contains the previous value of the input field before it was cleared and can be accessed via `e.detail.state.previousValue`. Payload also contains the method used to activate the clear button (mouse or keyboard) and can be accessed via `e.detail.reference.clearMethod`.
50
49
  * @slot jh-input-left - Use to insert an element on the left side of the input field, such as an icon or button.
51
50
  * @slot jh-input-right - Use to insert an element on the right side of the input field, such as an icon or button.
52
51
  * @slot jh-input-clear-button - Use to insert an icon within the clear button.
53
52
  *
54
53
  * @customElement jh-input
55
54
  */
56
- export class JhInput extends LitElement {
55
+ export class JhInput extends JhElement {
57
56
  static get formAssociated() {
58
57
  return true;
59
58
  }
60
59
 
61
- /** @type {ElementInternals} */
62
- #internals;
63
- /** @type {?number} */
64
- #id;
65
60
  /** @type {?string} */
66
61
  #value;
67
62
  /** @type {string} */
@@ -413,6 +408,8 @@ export class JhInput extends LitElement {
413
408
  minlength: { type: String },
414
409
  /** Sets a name for the input control. */
415
410
  name: { type: String },
411
+ /** Sets the pattern attribute on the input field. */
412
+ pattern: { type: String },
416
413
  /** Prevents users from changing the input value. Removes all slotted content. */
417
414
  readonly: { type: Boolean },
418
415
  /** Indicates a value is required. */
@@ -432,7 +429,6 @@ export class JhInput extends LitElement {
432
429
 
433
430
  constructor() {
434
431
  super();
435
- this.#internals = this.attachInternals();
436
432
  /** @type {?string} */
437
433
  this.accessibleLabel = null;
438
434
  /** @type {?string} */
@@ -465,6 +461,8 @@ export class JhInput extends LitElement {
465
461
  this.minlength = null;
466
462
  /** @type {?string} */
467
463
  this.name = null;
464
+ /** @type {?string} */
465
+ this.pattern = null;
468
466
  /** @type {boolean} */
469
467
  this.readonly = false;
470
468
  /** @type {boolean} */
@@ -483,12 +481,11 @@ export class JhInput extends LitElement {
483
481
 
484
482
  connectedCallback() {
485
483
  super.connectedCallback();
486
- this.#id = id++;
487
484
  this.#captureMaskIndexes();
488
485
  let observer = new MutationObserver(this.#captureMaskIndexes.bind(this));
489
486
  observer.observe(this, { attributeFilter: ['input-mask'] });
490
487
  this.addEventListener('jh-select', this.#setSelection);
491
- }
488
+ }
492
489
 
493
490
  disconnectedCallback() {
494
491
  super.disconnectedCallback();
@@ -497,10 +494,6 @@ export class JhInput extends LitElement {
497
494
  }
498
495
  }
499
496
 
500
- get uniqueId() {
501
- return this.#id;
502
- }
503
-
504
497
  firstUpdated() {
505
498
  // attach event listeners to show/hide clear button
506
499
  if (this.showClearButton) {
@@ -617,7 +610,7 @@ export class JhInput extends LitElement {
617
610
 
618
611
  /** @ignore */
619
612
  get form() {
620
- return this.#internals.form;
613
+ return this.internals.form;
621
614
  }
622
615
 
623
616
  get value() {
@@ -628,22 +621,11 @@ export class JhInput extends LitElement {
628
621
  const oldValue = this.#value;
629
622
  if (newValue !== oldValue) {
630
623
  this.#value = newValue;
631
- this.#internals.setFormValue(this.#value);
624
+ this.internals.setFormValue(this.#value);
632
625
  }
633
626
  this.requestUpdate('value', oldValue);
634
627
  }
635
628
 
636
- #dispatch(eventName, details) {
637
- this.dispatchEvent(
638
- new CustomEvent(eventName, {
639
- detail: details,
640
- bubbles: true,
641
- cancelable: true,
642
- composed: true,
643
- })
644
- );
645
- }
646
-
647
629
  _handleInput(e) {
648
630
  this.value = e.target.value;
649
631
  let inputType = e.inputType;
@@ -655,7 +637,13 @@ export class JhInput extends LitElement {
655
637
  this.#applyInputMask(e);
656
638
  }
657
639
  } else {
658
- this.#dispatch('jh-input', { value: this.value });
640
+ this.dispatchCustomEvent('jh-input', {
641
+ reference: {
642
+ 'maxlength': this.maxlength,
643
+ 'minlength': this.minlength,
644
+ 'pattern': this.pattern,
645
+ }
646
+ } );
659
647
  }
660
648
  }
661
649
 
@@ -997,9 +985,15 @@ export class JhInput extends LitElement {
997
985
  this.value = formattedResult.join('');
998
986
 
999
987
  // Dispatch a custom event with the formatted and raw values
1000
- this.#dispatch('jh-input', {
1001
- 'value': this.value,
1002
- 'rawValue': this.#rawValue
988
+ this.dispatchCustomEvent('jh-input', {
989
+ state: {
990
+ 'rawValue': this.#rawValue || null
991
+ },
992
+ reference: {
993
+ 'maxlength': this.maxlength,
994
+ 'minlength': this.minlength,
995
+ 'pattern': this.pattern,
996
+ }
1003
997
  });
1004
998
  }
1005
999
 
@@ -1082,15 +1076,16 @@ export class JhInput extends LitElement {
1082
1076
  }
1083
1077
 
1084
1078
  _handleChange() {
1085
- let payload = {
1086
- 'value': this.value,
1087
- }
1088
-
1089
- if (this.inputMask) {
1090
- payload.rawValue = this.#rawValue;
1091
- }
1092
-
1093
- this.#dispatch('jh-change', payload);
1079
+ this.dispatchCustomEvent('jh-change', {
1080
+ state: {
1081
+ 'rawValue': this.#rawValue || null
1082
+ },
1083
+ reference: {
1084
+ 'minlength': this.minlength,
1085
+ 'maxlength': this.maxlength,
1086
+ 'pattern': this.pattern,
1087
+ }
1088
+ });
1094
1089
  }
1095
1090
 
1096
1091
  _handleSelect(e) {
@@ -1101,35 +1096,38 @@ export class JhInput extends LitElement {
1101
1096
 
1102
1097
  // ensure selected string present before dispatching event. Can be empty due to caret positioning when user attempts to delete fixed char.
1103
1098
  if (selectedString) {
1104
- this.#dispatch('jh-select', {
1105
- selected: selectedString,
1106
- selectionStart: e.target.selectionStart,
1107
- selectionEnd: e.target.selectionEnd
1099
+ this.dispatchCustomEvent('jh-select', {
1100
+ state: {
1101
+ 'selection': selectedString,
1102
+ 'selectionStart': e.target.selectionStart,
1103
+ 'selectionEnd': e.target.selectionEnd
1104
+ }
1108
1105
  });
1109
1106
  }
1110
1107
  }
1111
1108
 
1112
1109
  _handleMaxlength() {
1113
- this.#dispatch('jh-maxlength');
1110
+ this.dispatchCustomEvent('jh-maxlength', {
1111
+ reference: {
1112
+ 'maxlength': this.maxlength
1113
+ }
1114
+ });
1114
1115
  }
1115
1116
 
1116
- _handleClearButtonClick() {
1117
+ _handleClearButtonClick(e) {
1117
1118
  let previousValue = this.value;
1118
1119
  // clear input value
1119
1120
  this.value = '';
1120
1121
  // focus input field
1121
1122
  this.shadowRoot.querySelector('input').focus();
1122
- // dispatch clear event
1123
- this.dispatchEvent(
1124
- new CustomEvent('jh-input:clear-button-click', {
1125
- detail: {
1126
- 'previousValue': previousValue
1127
- },
1128
- bubbles: true,
1129
- cancelable: true,
1130
- composed: true,
1131
- })
1132
- );
1123
+ this.dispatchCustomEvent('jh-input:clear-button-click', {
1124
+ state: {
1125
+ 'previousValue': previousValue,
1126
+ },
1127
+ reference: {
1128
+ 'clearMethod': e.pointerType === 'mouse' ? 'mouse' : 'keyboard'
1129
+ }
1130
+ });
1133
1131
  }
1134
1132
 
1135
1133
  _handleSlotChange(e) {
@@ -1292,6 +1290,7 @@ export class JhInput extends LitElement {
1292
1290
  maxlength=${ifDefined(this.maxlength === '' ? null : this.maxlength)}
1293
1291
  minlength=${ifDefined(this.minlength === '' ? null : this.minlength)}
1294
1292
  name=${ifDefined(this.name === '' ? null : this.name)}
1293
+ pattern=${ifDefined(this.pattern === '' ? null : this.pattern)}
1295
1294
  ?readonly=${this.readonly}
1296
1295
  ?required=${this.required}
1297
1296
  type="text"
@@ -1319,4 +1318,4 @@ export class JhInput extends LitElement {
1319
1318
  }
1320
1319
  }
1321
1320
 
1322
- customElements.define('jh-input', JhInput);
1321
+ JhInput.register('jh-input', JhInput);
@@ -14,4 +14,4 @@ export class JhInputEmail extends JhInput {
14
14
  this.inputmode = 'email';
15
15
  }
16
16
  }
17
- customElements.define('jh-input-email', JhInputEmail);
17
+ JhInputEmail.register('jh-input-email', JhInputEmail);
@@ -16,10 +16,6 @@ let id = 0;
16
16
  * @customElement jh-input-password
17
17
  */
18
18
  export class JhInputPassword extends JhInput {
19
-
20
- /** @type {?number} */
21
- #id;
22
-
23
19
  static get properties() {
24
20
  return {
25
21
  /** Unmasks the input field value when set. */
@@ -47,12 +43,7 @@ export class JhInputPassword extends JhInput {
47
43
  this.passwordVisible = false;
48
44
  }
49
45
 
50
- connectedCallback() {
51
- super.connectedCallback();
52
- this.#id = id++;
53
- }
54
-
55
- renderInput() {
46
+ renderInput() {
56
47
  let describedby;
57
48
 
58
49
  if (this.helperText || (this.errorText && this.invalid)) {
@@ -68,7 +59,7 @@ renderInput() {
68
59
  <div class="input-wrapper">
69
60
  ${leftSlot}
70
61
  <input
71
- id="jh-input-${this.#id}"
62
+ id="jh-input-${this.uniqueId}"
72
63
  aria-describedby=${describedby}
73
64
  aria-invalid=${ifDefined(this.invalid ? 'true' : null)}
74
65
  aria-label=${ifDefined(
@@ -160,4 +151,4 @@ renderInput() {
160
151
  this.passwordVisible = !this.passwordVisible;
161
152
  }
162
153
  }
163
- customElements.define('jh-input-password', JhInputPassword);
154
+ JhInputPassword.register('jh-input-password', JhInputPassword);
@@ -41,4 +41,4 @@ export class JhInputSearch extends JhInput {
41
41
  `;
42
42
  }
43
43
  }
44
- customElements.define('jh-input-search', JhInputSearch);
44
+ JhInputSearch.register('jh-input-search', JhInputSearch);
@@ -15,4 +15,4 @@ export class JhInputTelephone extends JhInput {
15
15
  inputEl.setAttribute('type', 'tel');
16
16
  }
17
17
  }
18
- customElements.define('jh-input-telephone', JhInputTelephone);
18
+ JhInputTelephone.register('jh-input-telephone', JhInputTelephone);
@@ -6,18 +6,14 @@ import { css, html } from 'lit';
6
6
  import { ifDefined } from 'lit/directives/if-defined.js';
7
7
  import { JhInput } from '../input/input.js';
8
8
 
9
- let id = 0;
10
-
11
9
  /**
12
10
  * @cssprop --jh-input-textarea-field-dimension-min-height - The input field minimum height. Defaults to `--jh-dimension-2000` when `size='small'`, `--jh-dimension-2200` when `size='medium'`, and `--jh-dimension-2400` when `size='large'`.
13
11
  *
14
- * @event jh-change - Dispatched when the value of the input has changed and input loses focus. Event payload includes the value of the input and can be accessed via `e.detail.value`.
15
- * @event jh-input - Dispatched when the value of the input has changed. Event payload includes the value of the input and can be accessed via `e.detail.value`.
12
+ * @event jh-change - Dispatched when the value of the input has changed and input loses focus. Event payload includes the value of the input and can be accessed via `e.detail.state.value`.
13
+ * @event jh-input - Dispatched when the value of the input has changed. Event payload includes the value of the input and can be accessed via `e.detail.state.value`.
16
14
  * @customElement jh-input-textarea
17
15
  */
18
16
  export class JhInputTextarea extends JhInput {
19
- /** @type {?number} */
20
- #id;
21
17
  /** @type {?ResizeObserver} */
22
18
  #resizeObserver;
23
19
 
@@ -195,11 +191,6 @@ export class JhInputTextarea extends JhInput {
195
191
  this.wrap = null;
196
192
  }
197
193
 
198
- connectedCallback() {
199
- super.connectedCallback();
200
- this.#id = id++;
201
- }
202
-
203
194
  disconnectedCallback() {
204
195
  super.disconnectedCallback();
205
196
  if (this.#resizeObserver) {
@@ -244,7 +235,7 @@ export class JhInputTextarea extends JhInput {
244
235
  renderInput() {
245
236
  return html`
246
237
  <textarea
247
- id="jh-input-${this.#id}"
238
+ id="jh-input-${this.uniqueId}"
248
239
  aria-describedby=${this._getDescribedby()}
249
240
  aria-invalid=${ifDefined(this.invalid ? 'true' : null)}
250
241
  aria-label=${ifDefined(this.accessibleLabel === '' ? null : this.accessibleLabel)}
@@ -268,4 +259,4 @@ export class JhInputTextarea extends JhInput {
268
259
  `
269
260
  }
270
261
  }
271
- customElements.define('jh-input-textarea', JhInputTextarea);
262
+ JhInputTextarea.register('jh-input-textarea', JhInputTextarea);
@@ -28,4 +28,4 @@ export class JhInputUrl extends JhInput {
28
28
  inputEl.setAttribute('type', 'url');
29
29
  }
30
30
  }
31
- customElements.define('jh-input-url', JhInputUrl);
31
+ JhInputUrl.register('jh-input-url', JhInputUrl);
@@ -2,7 +2,8 @@
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
 
5
- import { LitElement, css, html } from 'lit';
5
+ import { css, html } from 'lit';
6
+ import { JhElement } from '../element/element.js';
6
7
  import { ifDefined } from 'lit/directives/if-defined.js';
7
8
 
8
9
  let id = 0;
@@ -19,10 +20,7 @@ let id = 0;
19
20
  * @slot default - Use to insert `<jh-list-item>` component(s).
20
21
  * @customElement jh-list-group
21
22
  */
22
- export class JhListGroup extends LitElement {
23
- /** @type {?Number} */
24
- #id;
25
-
23
+ export class JhListGroup extends JhElement {
26
24
  static get styles() {
27
25
  return css`
28
26
  :host {
@@ -76,22 +74,17 @@ export class JhListGroup extends LitElement {
76
74
  this.accessibleLabel = null;
77
75
  }
78
76
 
79
- connectedCallback() {
80
- super.connectedCallback();
81
- this.#id = id++;
82
- }
83
-
84
77
  render() {
85
78
  return html`
86
79
  ${this.label
87
- ? html`<div class="subheader" id="list-group-labelledby-${this.#id}">
80
+ ? html`<div class="subheader" id="list-group-labelledby-${this.uniqueId}">
88
81
  ${this.label}
89
82
  </div>`
90
83
  : null}
91
84
  <div
92
85
  role="group"
93
86
  aria-labelledby=${ifDefined(
94
- this.label ? `list-group-labelledby-${this.#id}` : null
87
+ this.label ? `list-group-labelledby-${this.uniqueId}` : null
95
88
  )}
96
89
  aria-label=${ifDefined(this.accessibleLabel)}
97
90
  >
@@ -100,4 +93,4 @@ export class JhListGroup extends LitElement {
100
93
  `;
101
94
  }
102
95
  }
103
- customElements.define('jh-list-group', JhListGroup);
96
+ JhListGroup.register('jh-list-group', JhListGroup);