@jack-henry/jh-elements 2.0.0-beta.13 → 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 (37) 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 +106 -52
  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 +72 -74
  12. package/components/input-email/input-email.js +1 -1
  13. package/components/input-password/input-password.js +10 -19
  14. package/components/input-search/input-search.js +2 -2
  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 +19 -21
  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 +21 -29
  28. package/components/table-data-cell/table-data-cell.js +7 -9
  29. package/components/table-header-cell/table-header-cell.js +15 -25
  30. package/components/table-row/table-row.js +5 -8
  31. package/components/tag/tag.js +12 -14
  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 +350 -215
  36. package/jsconfig.json +1 -1
  37. package/package.json +11 -15
package/NOTICE CHANGED
@@ -1,5 +1,5 @@
1
1
  ===========================================================
2
- Jack Henry Design System
2
+ Forge Design System
3
3
  Copyright 2025 Jack Henry
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -6,8 +6,8 @@ SPDX-License-Identifier: Apache-2.0
6
6
 
7
7
  ## @jack-henry/jh-elements
8
8
 
9
- Contains Jack Henry's web component library. To get started, visit our documentation sites.
9
+ Contains the Forge Design System web component library. To get started, visit our documentation sites.
10
10
 
11
- * [Jackhenry.design](https://jackhenry.design) focuses on introducing the underlying concepts of the Design System, usage guidelines, and a style guide.
11
+ * [Jackhenry.design](https://jackhenry.design) focuses on introducing the underlying concepts of the design system, usage guidelines, and a style guide.
12
12
  * [Storybook](https://main--68f8e6a25b256d0ef89b13e6.chromatic.com/?path=/docs/welcome-about-jh--docs) focuses on technical implementations and considerations
13
13
  for engineers including author guidance and a playground where you can test drive our components.
@@ -2,8 +2,9 @@
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
 
8
9
  /**
9
10
  * @cssprop --jh-badge-border-radius - The badge border radius. Defaults to `--jh-border-radius-pill`.
@@ -12,7 +13,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
12
13
  *
13
14
  * @customElement jh-badge
14
15
  */
15
- export class JhBadge extends LitElement {
16
+ export class JhBadge extends JhElement {
16
17
  static get styles() {
17
18
  return css`
18
19
  :host {
@@ -70,5 +71,4 @@ export class JhBadge extends LitElement {
70
71
  `;
71
72
  }
72
73
  }
73
- customElements.define('jh-badge', JhBadge);
74
-
74
+ JhBadge.register('jh-badge', JhBadge);
@@ -2,8 +2,9 @@
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 '../progress/progress.js';
8
9
 
9
10
  /**
@@ -102,20 +103,18 @@ import '../progress/progress.js';
102
103
  * @cssprop --jh-button-border-radius - The button container border-radius. Defaults to `--jh-border-radius-100`.
103
104
  * @cssprop --jh-button-opacity-disabled - The button container opacity when disabled. Defaults to `--jh-opacity-disabled`.
104
105
  * @cssprop --jh-button-color-focus - The button container outline when it receives keyboard focus. Defaults to `--jh-border-focus-color`.
105
- * @cssprop --jh-button-size - The button width when no label is set, and the button height. Button width and height defaults to `--jh-dimension-1000` when `size="small"`, `--jh-dimension-1200` when `size="medium"`, and `--jh-dimension-1400` when `size="large"`.
106
+ * @cssprop --jh-button-size - The button width of single icon buttons, and the button height. Button width and height defaults to `--jh-dimension-600` when `size="x-small"`,`--jh-dimension-800` when `size="small"`, `--jh-dimension-1000` when `size="medium"`, and `--jh-dimension-1200` when `size="large"`.
106
107
  *
107
- * @slot jh-button-icon - Use to insert an icon.
108
+ * @slot jh-button-icon-left - Use to insert an icon on the left side of the button and for single icon buttons.
109
+ * @slot jh-button-icon-right - Use to insert an icon on the right side of the button and for single icon buttons.
108
110
  * @customElement jh-button
109
111
  */
110
- export class JhButton extends LitElement {
112
+ export class JhButton extends JhElement {
111
113
  /** @ignore */
112
114
  static get formAssociated() {
113
115
  return true;
114
116
  }
115
117
 
116
- /** @type {ElementInternals} */
117
- #internals;
118
-
119
118
  /** @type {?string} */
120
119
  #value;
121
120
 
@@ -156,6 +155,7 @@ export class JhButton extends LitElement {
156
155
  display: flex;
157
156
  justify-content: center;
158
157
  align-items: center;
158
+ gap: var(--jh-dimension-200);
159
159
  }
160
160
  button:focus,
161
161
  a:focus {
@@ -179,17 +179,21 @@ export class JhButton extends LitElement {
179
179
  pointer-events: none;
180
180
  }
181
181
  /* Size styling ('medium' is default) */
182
+ :host([size='x-small']) button,
183
+ :host([size='x-small']) a {
184
+ height: var(--jh-button-size, var(--jh-dimension-600));
185
+ }
182
186
  :host([size='small']) button,
183
187
  :host([size='small']) a {
184
- height: var(--jh-button-size, var(--jh-dimension-1000));
188
+ height: var(--jh-button-size, var(--jh-dimension-800));
185
189
  }
186
190
  :host([size='medium']) button,
187
191
  :host([size='medium']) a {
188
- height: var(--jh-button-size, var(--jh-dimension-1200));
192
+ height: var(--jh-button-size, var(--jh-dimension-1000));
189
193
  }
190
194
  :host([size='large']) button,
191
195
  :host([size='large']) a {
192
- height: var(--jh-button-size, var(--jh-dimension-1400));
196
+ height: var(--jh-button-size, var(--jh-dimension-1200));
193
197
  }
194
198
  /* appearance='primary' ('secondary' is default) */
195
199
  :host([appearance='primary']) button,
@@ -687,33 +691,28 @@ export class JhButton extends LitElement {
687
691
  var(--jh-color-content-on-negative-enabled)
688
692
  );
689
693
  }
690
- /* Icon-related Type option styling */
691
- :host([icon-position='before'][label]) ::slotted(*) {
692
- margin-right: var(--jh-dimension-200);
694
+
695
+ /* Single icon styling */
696
+ :host button.single-icon,
697
+ :host a.single-icon {
698
+ padding: 0;
693
699
  }
694
- :host([icon-position='after'][label]) ::slotted(*) {
695
- margin-left: var(--jh-dimension-200);
700
+ :host([size='x-small']) button.single-icon,
701
+ :host([size='x-small']) a.single-icon {
702
+ width: var(--jh-button-size, var(--jh-dimension-600));
696
703
  }
697
- :host([icon-position='after']) .content-wrapper {
698
- flex-direction: row-reverse;
704
+ :host([size='small']) button.single-icon,
705
+ :host([size='small']) a.single-icon {
706
+ width: var(--jh-button-size, var(--jh-dimension-800));
699
707
  }
700
- /* Icon only styling */
701
- :host(:not([label])[size='small']) button,
702
- :host(:not([label])[size='small']) a {
708
+ :host([size='medium']) button.single-icon,
709
+ :host([size='medium']) a.single-icon {
703
710
  width: var(--jh-button-size, var(--jh-dimension-1000));
704
711
  }
705
- :host(:not([label])[size='medium']) button,
706
- :host(:not([label])[size='medium']) a {
712
+ :host([size='large']) button.single-icon,
713
+ :host([size='large']) a.single-icon {
707
714
  width: var(--jh-button-size, var(--jh-dimension-1200));
708
715
  }
709
- :host(:not([label])[size='large']) button,
710
- :host(:not([label])[size='large']) a {
711
- width: var(--jh-button-size, var(--jh-dimension-1400));
712
- }
713
- :host(:not([label])) button,
714
- :host(:not([label])) a {
715
- padding: 0;
716
- }
717
716
  /* Block styling */
718
717
  :host([block]) {
719
718
  display: block;
@@ -721,6 +720,8 @@ export class JhButton extends LitElement {
721
720
  }
722
721
  :host(:not([label])[block]) button,
723
722
  :host(:not([label])[block]) a,
723
+ :host([block]) button.single-icon,
724
+ :host([block]) a.single-icon,
724
725
  :host([block]) button,
725
726
  :host([block]) a {
726
727
  width: 100%;
@@ -759,12 +760,6 @@ export class JhButton extends LitElement {
759
760
  href: {
760
761
  type: String,
761
762
  },
762
- /** Sets location of icon in relation to the label. */
763
- iconPosition: {
764
- type: String,
765
- attribute: 'icon-position',
766
- reflect: true,
767
- },
768
763
  /** Displays a progress indicator. */
769
764
  pending: {
770
765
  type: Boolean,
@@ -795,15 +790,21 @@ export class JhButton extends LitElement {
795
790
  value: {
796
791
  type: String,
797
792
  },
793
+ _hasLeftSlotContent: {
794
+ type: Boolean,
795
+ state: true,
796
+ },
797
+ _hasRightSlotContent: {
798
+ type: Boolean,
799
+ state: true,
800
+ },
798
801
  };
799
802
  }
800
803
 
801
804
  constructor() {
802
805
  super();
803
806
  /** @type {ElementInternals} */
804
- this.#internals = this.attachInternals();
805
- /** @type {ElementInternals} */
806
- this.#internals.form;
807
+ this.internals.form;
807
808
  /** @type {'true'|'false'} */
808
809
  this.accessibleDisabled = null;
809
810
  /** @type {?string} */
@@ -816,15 +817,13 @@ export class JhButton extends LitElement {
816
817
  this.disabled = false;
817
818
  /** @type {?string} */
818
819
  this.href = null;
819
- /** @type {'before'|'after'} */
820
- this.iconPosition = 'before';
821
820
  /** @type {?boolean} */
822
821
  this.pending = false;
823
822
  /** @type {?string} */
824
823
  this.label = null;
825
824
  /** @type {?string} */
826
825
  this.name = null;
827
- /** @type {'small'|'medium'|'large'} */
826
+ /** @type {'x-small'|'small'|'medium'|'large'} */
828
827
  this.size = 'medium';
829
828
  /** @type {?boolean} */
830
829
  this.submit = false;
@@ -832,6 +831,10 @@ export class JhButton extends LitElement {
832
831
  this.target = null;
833
832
  /** @type {?string} */
834
833
  this.value = null;
834
+ /** @type {boolean} */
835
+ this._hasLeftSlotContent = false;
836
+ /** @type {boolean} */
837
+ this._hasRightSlotContent = false;
835
838
 
836
839
  this.addEventListener('click', this.#onClick);
837
840
  this.addEventListener('keydown', this.#handleKeydown);
@@ -846,7 +849,7 @@ export class JhButton extends LitElement {
846
849
  const oldValue = this.#value;
847
850
  if (newValue !== oldValue) {
848
851
  this.#value = newValue;
849
- this.#internals.setFormValue(newValue);
852
+ this.internals.setFormValue(newValue);
850
853
  }
851
854
  this.requestUpdate('value', oldValue);
852
855
  }
@@ -856,6 +859,19 @@ export class JhButton extends LitElement {
856
859
  new ResizeObserver(this.#cacheButtonDimensions.bind(this)).observe(this);
857
860
  }
858
861
 
862
+ //if button size changes, adjust the size of the icons accordingly.
863
+ updated(changedProperties) {
864
+ if (changedProperties.has('size')) {
865
+ const iconSize = this.size === 'x-small' ? 'x-small' : 'medium';
866
+ const slots = this.shadowRoot.querySelectorAll('slot');
867
+ slots.forEach(slot => {
868
+ const icon = slot?.assignedElements({flatten: true})[0];
869
+ if (icon) {
870
+ icon.setAttribute('size', iconSize);
871
+ }
872
+ });
873
+ }
874
+ }
859
875
  #cacheButtonDimensions() {
860
876
  const { width } = this.getBoundingClientRect();
861
877
 
@@ -868,8 +884,8 @@ export class JhButton extends LitElement {
868
884
 
869
885
  #onClick(event) {
870
886
  //If I'm a submit button in a form and I'm not disabled submit the form
871
- if (this.submit && this.#internals.form && !this.disabled) {
872
- this.#internals.form.requestSubmit();
887
+ if (this.submit && this.internals.form && !this.disabled) {
888
+ this.internals.form.requestSubmit();
873
889
  }
874
890
  }
875
891
 
@@ -883,11 +899,43 @@ export class JhButton extends LitElement {
883
899
  }
884
900
  }
885
901
 
886
- #handleSlotChange() {
887
- this.firstElementChild.setAttribute('aria-hidden', 'true');
888
- this.firstElementChild.setAttribute('size', 'medium');
902
+ #handleSlotChange(e) {
903
+
904
+ let newSlottedElement = e.target.assignedElements()[0];
905
+ let slot = e.target;
906
+
907
+ if (slot.name !== 'jh-button-icon-left' && slot.name !== 'jh-button-icon-right') {
908
+ return;
909
+ }
910
+
911
+ // Set icon size
912
+ if (newSlottedElement?.tagName.startsWith('JH-ICON')) {
913
+ newSlottedElement.setAttribute('aria-hidden', 'true');
914
+
915
+ if (this.size === 'x-small') {
916
+ newSlottedElement.setAttribute('size', 'x-small');
917
+ } else {
918
+ newSlottedElement.setAttribute('size', 'medium');
919
+ }
920
+ }
921
+
922
+ if (slot.name === 'jh-button-icon-left') {
923
+ this._hasLeftSlotContent = this.#checkSlotContent(slot);
924
+ }
925
+ if (slot.name === 'jh-button-icon-right') {
926
+ this._hasRightSlotContent = this.#checkSlotContent(slot);
927
+ }
889
928
  }
890
929
 
930
+ #checkSlotContent(slot) {
931
+ // Slotted and fallback elements
932
+ const slottedElements = slot.assignedElements({ flatten: true });
933
+ if (slottedElements.length > 0) {
934
+ return true;
935
+ }
936
+ return false;
937
+ }
938
+
891
939
  #renderButtonContent(pending, label) {
892
940
  let buttonContent;
893
941
  let buttonLabel;
@@ -898,15 +946,19 @@ export class JhButton extends LitElement {
898
946
 
899
947
  if (pending && !this.disabled) {
900
948
  buttonContent = html`
901
- <jh-progress type="circular" indeterminate></jh-progress>
949
+ <jh-progress type="circular" indeterminate size=${this.size === 'x-small' ? 'small' : 'medium'}></jh-progress>
902
950
  `;
903
951
  } else {
904
952
  buttonContent = html`
905
953
  <slot
906
- name="jh-button-icon"
954
+ name="jh-button-icon-left"
907
955
  @slotchange=${this.#handleSlotChange}
908
956
  ></slot>
909
957
  ${buttonLabel}
958
+ <slot
959
+ name="jh-button-icon-right"
960
+ @slotchange=${this.#handleSlotChange}
961
+ ></slot>
910
962
  `;
911
963
  }
912
964
 
@@ -916,6 +968,7 @@ export class JhButton extends LitElement {
916
968
  render() {
917
969
  const buttonContent = this.#renderButtonContent(this.pending, this.label);
918
970
  let ariaDisabled;
971
+ let singleIconClass = !this.label && (this._hasLeftSlotContent !== this._hasRightSlotContent) ? 'single-icon' : null;
919
972
 
920
973
  if (this.accessibleDisabled !== 'false') {
921
974
  ariaDisabled = this.accessibleDisabled;
@@ -924,6 +977,7 @@ export class JhButton extends LitElement {
924
977
  if (this.href) {
925
978
  return html`
926
979
  <a
980
+ class=${ifDefined(singleIconClass)}
927
981
  tabindex="0"
928
982
  aria-disabled=${ifDefined(ariaDisabled)}
929
983
  aria-label=${ifDefined(this.accessibleLabel)}
@@ -937,6 +991,7 @@ export class JhButton extends LitElement {
937
991
  } else {
938
992
  return html`
939
993
  <button
994
+ class=${ifDefined(singleIconClass)}
940
995
  tabindex="0"
941
996
  aria-disabled=${ifDefined(ariaDisabled)}
942
997
  aria-label=${ifDefined(this.accessibleLabel)}
@@ -949,5 +1004,4 @@ export class JhButton extends LitElement {
949
1004
  }
950
1005
  }
951
1006
  }
952
-
953
- customElements.define('jh-button', JhButton);
1007
+ JhButton.register('jh-button', JhButton);
@@ -2,8 +2,9 @@
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 '../divider/divider.js';
8
9
 
9
10
  /**
@@ -31,7 +32,7 @@ import '../divider/divider.js';
31
32
  * @slot jh-card-footer - Use to insert card footer content.
32
33
  * @customElement jh-card
33
34
  */
34
- export class JhCard extends LitElement {
35
+ export class JhCard extends JhElement {
35
36
  static get styles() {
36
37
  return css`
37
38
  :host {
@@ -341,5 +342,4 @@ export class JhCard extends LitElement {
341
342
  `;
342
343
  }
343
344
  }
344
-
345
- customElements.define('jh-card', JhCard);
345
+ JhCard.register('jh-card', JhCard);
@@ -2,10 +2,9 @@
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
-
8
- let id = 0;
7
+ import { JhElement } from '../element/element.js';
9
8
 
10
9
  /**
11
10
  * @cssprop --jh-checkbox-opacity-disabled - The checkbox opacity when disabled. Defaults to `--jh-opacity-disabled`.
@@ -54,22 +53,19 @@ let id = 0;
54
53
  * @cssprop --jh-checkbox-input-color-border-indeterminate-disabled - The checkbox border-color when indeterminate and disabled. Defaults to `--jh-color-content-brand-enabled`.
55
54
  * @cssprop --jh-checkbox-status-color-border-indeterminate-disabled - The checkbox color when indeterminate status mark when disabled. Defaults to `--jh-color-content-on-brand-enabled`.
56
55
  *
57
- * @event jh-change - Dispatched when the state of the checkbox has changed.
56
+ * @event jh-change - Dispatched when the state of the checkbox has changed. Event payload includes the `checked` state of the checkbox and can be accessed via `e.detail.state.checked`.
58
57
  *
59
58
  * @customElement jh-checkbox
60
59
  */
61
- export class JhCheckbox extends LitElement {
60
+ export class JhCheckbox extends JhElement {
62
61
  static get formAssociated() {
63
62
  return true;
64
63
  }
64
+
65
65
  /** @type {?Boolean} */
66
66
  #checked;
67
- /** @type {?Number} */
68
- #id;
69
67
  /** @type {?Boolean} */
70
68
  #indeterminate;
71
- /** @type {ElementInternals} */
72
- #internals;
73
69
  /** @type {?string} */
74
70
  #value;
75
71
 
@@ -456,7 +452,6 @@ export class JhCheckbox extends LitElement {
456
452
 
457
453
  constructor() {
458
454
  super();
459
- this.#internals = this.attachInternals();
460
455
  /** @type {?boolean} */
461
456
  this.checked = false;
462
457
  /** @type {?boolean} */
@@ -475,22 +470,17 @@ export class JhCheckbox extends LitElement {
475
470
  this.accessibleLabel = null;
476
471
  }
477
472
 
478
- connectedCallback() {
479
- super.connectedCallback();
480
- this.#id = id++;
481
- }
482
-
483
473
  /**
484
474
  * Returns the checkbox's parent form element.
485
475
  * @type {?HTMLFormElement}
486
476
  */
487
477
  get form() {
488
- return this.#internals.form;
478
+ return this.internals.form;
489
479
  }
490
480
 
491
481
  /** @ignore */
492
482
  get validity() {
493
- return this.#internals.validity;
483
+ return this.internals.validity;
494
484
  }
495
485
 
496
486
  /** @type {?string} */
@@ -537,20 +527,19 @@ export class JhCheckbox extends LitElement {
537
527
 
538
528
  #updateFormValue(value, checked, indeterminate) {
539
529
  if (!indeterminate) {
540
- this.#internals.setFormValue(checked ? value || 'on' : null);
541
- } else this.#internals.setFormValue(null);
530
+ this.internals.setFormValue(checked ? value || 'on' : null);
531
+ } else this.internals.setFormValue(null);
542
532
  }
543
533
 
544
534
  #handleChange(e) {
545
535
  this.checked = e.target.checked;
546
536
  this.indeterminate = false;
547
537
  this.#updateFormValue(this.value, this.checked, this.indeterminate);
548
- const options = {
549
- bubbles: true,
550
- composed: true,
551
- cancelable: true,
552
- };
553
- this.dispatchEvent(new CustomEvent('jh-change', options));
538
+ this.dispatchCustomEvent('jh-change', {
539
+ state: {
540
+ checked: this.checked,
541
+ },
542
+ });
554
543
  }
555
544
 
556
545
  render() {
@@ -559,7 +548,7 @@ export class JhCheckbox extends LitElement {
559
548
 
560
549
  if (this.helperText) {
561
550
  helperText = html`
562
- <p class="helper-text" id="checkbox-helper-text-${this.#id}">
551
+ <p class="helper-text" id="checkbox-helper-text-${this.uniqueId}">
563
552
  ${this.helperText}
564
553
  </p>
565
554
  `;
@@ -568,7 +557,7 @@ export class JhCheckbox extends LitElement {
568
557
  if (this.label) {
569
558
  label = html`
570
559
  <div class="label-container">
571
- <label class="label-text" for="checkbox-label-${this.#id}">
560
+ <label class="label-text" for="checkbox-label-${this.uniqueId}">
572
561
  ${this.label}
573
562
  </label>
574
563
  ${helperText}
@@ -587,9 +576,9 @@ export class JhCheckbox extends LitElement {
587
576
  aria-label=${ifDefined(this.accessibleLabel)}
588
577
  value=${ifDefined(this.value)}
589
578
  name=${ifDefined(this.name)}
590
- id=${ifDefined(this.label ? `checkbox-label-${this.#id}` : null)}
579
+ id=${ifDefined(this.label ? `checkbox-label-${this.uniqueId}` : null)}
591
580
  aria-describedby=${ifDefined(
592
- this.helperText ? `checkbox-helper-text-${this.#id}` : null
581
+ this.helperText ? `checkbox-helper-text-${this.uniqueId}` : null
593
582
  )}
594
583
  />
595
584
  <span aria-hidden="true"></span>
@@ -597,5 +586,4 @@ export class JhCheckbox extends LitElement {
597
586
  `;
598
587
  }
599
588
  }
600
-
601
- customElements.define('jh-checkbox', JhCheckbox);
589
+ JhCheckbox.register('jh-checkbox', JhCheckbox);
@@ -2,10 +2,10 @@
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
- let id = 0;
9
9
  /**
10
10
  *
11
11
  * @cssprop --jh-checkbox-group-label-color-text - The label text color. Defaults to `--jh-color-content-primary-enabled`.
@@ -23,10 +23,7 @@ let id = 0;
23
23
  *
24
24
  * @customElement jh-checkbox-group
25
25
  */
26
- export class JhCheckboxGroup extends LitElement {
27
- /** @type {?Number} */
28
- #id;
29
-
26
+ export class JhCheckboxGroup extends JhElement {
30
27
  static get styles() {
31
28
  return css`
32
29
  :host {
@@ -211,11 +208,6 @@ export class JhCheckboxGroup extends LitElement {
211
208
  this.showIndicator = false;
212
209
  }
213
210
 
214
- connectedCallback() {
215
- super.connectedCallback();
216
- this.#id = id++;
217
- }
218
-
219
211
  firstUpdated() {
220
212
  const slot = this.renderRoot?.querySelector('slot');
221
213
  this.#syncDisabledToChildren();
@@ -239,13 +231,13 @@ export class JhCheckboxGroup extends LitElement {
239
231
 
240
232
  #getAriaDescribedBy() {
241
233
  if (this.errorText && this.invalid && this.helperText && this.label) {
242
- return `checkbox-group-error-${this.#id} checkbox-group-helper-${
243
- this.#id
234
+ return `checkbox-group-error-${this.uniqueId} checkbox-group-helper-${
235
+ this.uniqueId
244
236
  }`;
245
237
  } else if (this.errorText && this.invalid) {
246
- return `checkbox-group-error-${this.#id}`;
238
+ return `checkbox-group-error-${this.uniqueId}`;
247
239
  } else if (this.helperText && this.label) {
248
- return `checkbox-group-helper-${this.#id}`;
240
+ return `checkbox-group-helper-${this.uniqueId}`;
249
241
  }
250
242
  }
251
243
 
@@ -264,24 +256,24 @@ export class JhCheckboxGroup extends LitElement {
264
256
  }
265
257
 
266
258
  if (this.helperText) {
267
- helperText = html`<p class="helper-text" id="checkbox-group-helper-${this.#id}">${this.helperText}</p>`;
259
+ helperText = html`<p class="helper-text" id="checkbox-group-helper-${this.uniqueId}">${this.helperText}</p>`;
268
260
  }
269
261
 
270
262
  if (this.label) {
271
263
  label = html`
272
- <legend class="label" for="checkbox-group-label-${this.#id}">
264
+ <legend class="label" for="checkbox-group-label-${this.uniqueId}">
273
265
  ${this.label}${indicator}
274
266
  </legend>
275
267
  ${helperText}`;
276
268
  }
277
269
 
278
270
  if (this.invalid && this.errorText) {
279
- errorText = html`<p class="error-text" id="checkbox-group-error-${this.#id}">${this.errorText}</p>`;
271
+ errorText = html`<p class="error-text" id="checkbox-group-error-${this.uniqueId}">${this.errorText}</p>`;
280
272
  }
281
273
 
282
274
  return html`
283
275
  <fieldset
284
- id=${ifDefined(this.label ? `checkbox-group-label-${this.#id}` : null)}
276
+ id=${ifDefined(this.label ? `checkbox-group-label-${this.uniqueId}` : null)}
285
277
  aria-describedby=${ifDefined(this.#getAriaDescribedBy())}
286
278
  ?required=${this.required}
287
279
  aria-invalid=${ifDefined(this.invalid ? 'true' : null)}
@@ -294,4 +286,4 @@ export class JhCheckboxGroup extends LitElement {
294
286
  `;
295
287
  }
296
288
  }
297
- customElements.define('jh-checkbox-group', JhCheckboxGroup);
289
+ JhCheckboxGroup.register('jh-checkbox-group', JhCheckboxGroup);
@@ -2,7 +2,8 @@
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
 
5
- import { LitElement, css } from 'lit';
5
+ import { css } from 'lit';
6
+ import { JhElement } from '../element/element.js';
6
7
 
7
8
  /**
8
9
  * @cssprop --jh-divider-border-width - The divider width. Defaults to `--jh-border-decorative-width`.
@@ -11,7 +12,7 @@ import { LitElement, css } from 'lit';
11
12
  * @cssprop --jh-divider-space-inset - The divider margin-left. Defaults to `0`.
12
13
  * @customElement jh-divider
13
14
  */
14
- export class JhDivider extends LitElement {
15
+ export class JhDivider extends JhElement {
15
16
  static get styles() {
16
17
  return css`
17
18
  :host {
@@ -67,7 +68,7 @@ export class JhDivider extends LitElement {
67
68
  margin-left: var(--inset, var(--jh-divider-space-inset));
68
69
  }
69
70
  `
70
- }
71
+ }
71
72
 
72
73
  static get properties() {
73
74
  return {
@@ -87,5 +88,4 @@ export class JhDivider extends LitElement {
87
88
  this.inset = null;
88
89
  }
89
90
  }
90
-
91
- customElements.define('jh-divider', JhDivider);
91
+ JhDivider.register('jh-divider', JhDivider);