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

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.
@@ -102,9 +102,10 @@ import '../progress/progress.js';
102
102
  * @cssprop --jh-button-border-radius - The button container border-radius. Defaults to `--jh-border-radius-100`.
103
103
  * @cssprop --jh-button-opacity-disabled - The button container opacity when disabled. Defaults to `--jh-opacity-disabled`.
104
104
  * @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"`.
105
+ * @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
106
  *
107
- * @slot jh-button-icon - Use to insert an icon.
107
+ * @slot jh-button-icon-left - Use to insert an icon on the left side of the button and for single icon buttons.
108
+ * @slot jh-button-icon-right - Use to insert an icon on the right side of the button and for single icon buttons.
108
109
  * @customElement jh-button
109
110
  */
110
111
  export class JhButton extends LitElement {
@@ -156,6 +157,7 @@ export class JhButton extends LitElement {
156
157
  display: flex;
157
158
  justify-content: center;
158
159
  align-items: center;
160
+ gap: var(--jh-dimension-200);
159
161
  }
160
162
  button:focus,
161
163
  a:focus {
@@ -179,17 +181,21 @@ export class JhButton extends LitElement {
179
181
  pointer-events: none;
180
182
  }
181
183
  /* Size styling ('medium' is default) */
184
+ :host([size='x-small']) button,
185
+ :host([size='x-small']) a {
186
+ height: var(--jh-button-size, var(--jh-dimension-600));
187
+ }
182
188
  :host([size='small']) button,
183
189
  :host([size='small']) a {
184
- height: var(--jh-button-size, var(--jh-dimension-1000));
190
+ height: var(--jh-button-size, var(--jh-dimension-800));
185
191
  }
186
192
  :host([size='medium']) button,
187
193
  :host([size='medium']) a {
188
- height: var(--jh-button-size, var(--jh-dimension-1200));
194
+ height: var(--jh-button-size, var(--jh-dimension-1000));
189
195
  }
190
196
  :host([size='large']) button,
191
197
  :host([size='large']) a {
192
- height: var(--jh-button-size, var(--jh-dimension-1400));
198
+ height: var(--jh-button-size, var(--jh-dimension-1200));
193
199
  }
194
200
  /* appearance='primary' ('secondary' is default) */
195
201
  :host([appearance='primary']) button,
@@ -687,33 +693,28 @@ export class JhButton extends LitElement {
687
693
  var(--jh-color-content-on-negative-enabled)
688
694
  );
689
695
  }
690
- /* Icon-related Type option styling */
691
- :host([icon-position='before'][label]) ::slotted(*) {
692
- margin-right: var(--jh-dimension-200);
696
+
697
+ /* Single icon styling */
698
+ :host button.single-icon,
699
+ :host a.single-icon {
700
+ padding: 0;
693
701
  }
694
- :host([icon-position='after'][label]) ::slotted(*) {
695
- margin-left: var(--jh-dimension-200);
702
+ :host([size='x-small']) button.single-icon,
703
+ :host([size='x-small']) a.single-icon {
704
+ width: var(--jh-button-size, var(--jh-dimension-600));
696
705
  }
697
- :host([icon-position='after']) .content-wrapper {
698
- flex-direction: row-reverse;
706
+ :host([size='small']) button.single-icon,
707
+ :host([size='small']) a.single-icon {
708
+ width: var(--jh-button-size, var(--jh-dimension-800));
699
709
  }
700
- /* Icon only styling */
701
- :host(:not([label])[size='small']) button,
702
- :host(:not([label])[size='small']) a {
710
+ :host([size='medium']) button.single-icon,
711
+ :host([size='medium']) a.single-icon {
703
712
  width: var(--jh-button-size, var(--jh-dimension-1000));
704
713
  }
705
- :host(:not([label])[size='medium']) button,
706
- :host(:not([label])[size='medium']) a {
714
+ :host([size='large']) button.single-icon,
715
+ :host([size='large']) a.single-icon {
707
716
  width: var(--jh-button-size, var(--jh-dimension-1200));
708
717
  }
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
718
  /* Block styling */
718
719
  :host([block]) {
719
720
  display: block;
@@ -721,6 +722,8 @@ export class JhButton extends LitElement {
721
722
  }
722
723
  :host(:not([label])[block]) button,
723
724
  :host(:not([label])[block]) a,
725
+ :host([block]) button.single-icon,
726
+ :host([block]) a.single-icon,
724
727
  :host([block]) button,
725
728
  :host([block]) a {
726
729
  width: 100%;
@@ -759,12 +762,6 @@ export class JhButton extends LitElement {
759
762
  href: {
760
763
  type: String,
761
764
  },
762
- /** Sets location of icon in relation to the label. */
763
- iconPosition: {
764
- type: String,
765
- attribute: 'icon-position',
766
- reflect: true,
767
- },
768
765
  /** Displays a progress indicator. */
769
766
  pending: {
770
767
  type: Boolean,
@@ -795,6 +792,14 @@ export class JhButton extends LitElement {
795
792
  value: {
796
793
  type: String,
797
794
  },
795
+ _hasLeftSlotContent: {
796
+ type: Boolean,
797
+ state: true,
798
+ },
799
+ _hasRightSlotContent: {
800
+ type: Boolean,
801
+ state: true,
802
+ },
798
803
  };
799
804
  }
800
805
 
@@ -816,15 +821,13 @@ export class JhButton extends LitElement {
816
821
  this.disabled = false;
817
822
  /** @type {?string} */
818
823
  this.href = null;
819
- /** @type {'before'|'after'} */
820
- this.iconPosition = 'before';
821
824
  /** @type {?boolean} */
822
825
  this.pending = false;
823
826
  /** @type {?string} */
824
827
  this.label = null;
825
828
  /** @type {?string} */
826
829
  this.name = null;
827
- /** @type {'small'|'medium'|'large'} */
830
+ /** @type {'x-small'|'small'|'medium'|'large'} */
828
831
  this.size = 'medium';
829
832
  /** @type {?boolean} */
830
833
  this.submit = false;
@@ -832,6 +835,10 @@ export class JhButton extends LitElement {
832
835
  this.target = null;
833
836
  /** @type {?string} */
834
837
  this.value = null;
838
+ /** @type {boolean} */
839
+ this._hasLeftSlotContent = false;
840
+ /** @type {boolean} */
841
+ this._hasRightSlotContent = false;
835
842
 
836
843
  this.addEventListener('click', this.#onClick);
837
844
  this.addEventListener('keydown', this.#handleKeydown);
@@ -856,6 +863,19 @@ export class JhButton extends LitElement {
856
863
  new ResizeObserver(this.#cacheButtonDimensions.bind(this)).observe(this);
857
864
  }
858
865
 
866
+ //if button size changes, adjust the size of the icons accordingly.
867
+ updated(changedProperties) {
868
+ if (changedProperties.has('size')) {
869
+ const iconSize = this.size === 'x-small' ? 'x-small' : 'medium';
870
+ const slots = this.shadowRoot.querySelectorAll('slot');
871
+ slots.forEach(slot => {
872
+ const icon = slot?.assignedElements({flatten: true})[0];
873
+ if (icon) {
874
+ icon.setAttribute('size', iconSize);
875
+ }
876
+ });
877
+ }
878
+ }
859
879
  #cacheButtonDimensions() {
860
880
  const { width } = this.getBoundingClientRect();
861
881
 
@@ -883,11 +903,43 @@ export class JhButton extends LitElement {
883
903
  }
884
904
  }
885
905
 
886
- #handleSlotChange() {
887
- this.firstElementChild.setAttribute('aria-hidden', 'true');
888
- this.firstElementChild.setAttribute('size', 'medium');
906
+ #handleSlotChange(e) {
907
+
908
+ let newSlottedElement = e.target.assignedElements()[0];
909
+ let slot = e.target;
910
+
911
+ if (slot.name !== 'jh-button-icon-left' && slot.name !== 'jh-button-icon-right') {
912
+ return;
913
+ }
914
+
915
+ // Set icon size
916
+ if (newSlottedElement?.tagName.startsWith('JH-ICON')) {
917
+ newSlottedElement.setAttribute('aria-hidden', 'true');
918
+
919
+ if (this.size === 'x-small') {
920
+ newSlottedElement.setAttribute('size', 'x-small');
921
+ } else {
922
+ newSlottedElement.setAttribute('size', 'medium');
923
+ }
924
+ }
925
+
926
+ if (slot.name === 'jh-button-icon-left') {
927
+ this._hasLeftSlotContent = this.#checkSlotContent(slot);
928
+ }
929
+ if (slot.name === 'jh-button-icon-right') {
930
+ this._hasRightSlotContent = this.#checkSlotContent(slot);
931
+ }
889
932
  }
890
933
 
934
+ #checkSlotContent(slot) {
935
+ // Slotted and fallback elements
936
+ const slottedElements = slot.assignedElements({ flatten: true });
937
+ if (slottedElements.length > 0) {
938
+ return true;
939
+ }
940
+ return false;
941
+ }
942
+
891
943
  #renderButtonContent(pending, label) {
892
944
  let buttonContent;
893
945
  let buttonLabel;
@@ -898,15 +950,19 @@ export class JhButton extends LitElement {
898
950
 
899
951
  if (pending && !this.disabled) {
900
952
  buttonContent = html`
901
- <jh-progress type="circular" indeterminate></jh-progress>
953
+ <jh-progress type="circular" indeterminate size=${this.size === 'x-small' ? 'small' : 'medium'}></jh-progress>
902
954
  `;
903
955
  } else {
904
956
  buttonContent = html`
905
957
  <slot
906
- name="jh-button-icon"
958
+ name="jh-button-icon-left"
907
959
  @slotchange=${this.#handleSlotChange}
908
960
  ></slot>
909
961
  ${buttonLabel}
962
+ <slot
963
+ name="jh-button-icon-right"
964
+ @slotchange=${this.#handleSlotChange}
965
+ ></slot>
910
966
  `;
911
967
  }
912
968
 
@@ -916,6 +972,7 @@ export class JhButton extends LitElement {
916
972
  render() {
917
973
  const buttonContent = this.#renderButtonContent(this.pending, this.label);
918
974
  let ariaDisabled;
975
+ let singleIconClass = !this.label && (this._hasLeftSlotContent !== this._hasRightSlotContent) ? 'single-icon' : null;
919
976
 
920
977
  if (this.accessibleDisabled !== 'false') {
921
978
  ariaDisabled = this.accessibleDisabled;
@@ -924,6 +981,7 @@ export class JhButton extends LitElement {
924
981
  if (this.href) {
925
982
  return html`
926
983
  <a
984
+ class=${ifDefined(singleIconClass)}
927
985
  tabindex="0"
928
986
  aria-disabled=${ifDefined(ariaDisabled)}
929
987
  aria-label=${ifDefined(this.accessibleLabel)}
@@ -937,6 +995,7 @@ export class JhButton extends LitElement {
937
995
  } else {
938
996
  return html`
939
997
  <button
998
+ class=${ifDefined(singleIconClass)}
940
999
  tabindex="0"
941
1000
  aria-disabled=${ifDefined(ariaDisabled)}
942
1001
  aria-label=${ifDefined(this.accessibleLabel)}