button.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
  5. import { h as hasShadowDom, i as inheritAriaAttributes } from './helpers.js';
  6. import { a as printIonWarning } from './index4.js';
  7. import { o as openURL, c as createColorClasses, h as hostContext } from './theme.js';
  8. import { b as getIonMode } from './ionic-global.js';
  9. import { d as defineCustomElement$1 } from './ripple-effect.js';
  10. const buttonIosCss = ":host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:14px;--padding-top:13px;--padding-bottom:13px;--padding-start:1em;--padding-end:1em;--transition:background-color, opacity 100ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:3.1em;font-size:min(1rem, 48px);font-weight:500;letter-spacing:0}:host(.button-solid){--background-activated:var(--ion-color-primary-shade, #004acd);--background-focused:var(--ion-color-primary-shade, #004acd);--background-hover:var(--ion-color-primary-tint, #1a65eb);--background-activated-opacity:1;--background-focused-opacity:1;--background-hover-opacity:1}:host(.button-outline){--border-radius:14px;--border-width:1px;--border-style:solid;--background-activated:var(--ion-color-primary, #0054e9);--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;--color-activated:var(--ion-color-primary-contrast, #fff)}:host(.button-clear){--background-activated:transparent;--background-activated-opacity:0;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;font-size:min(1.0625rem, 51px);font-weight:normal}:host(.in-buttons){font-size:clamp(17px, 1.0625rem, 21.08px);font-weight:400}:host(.button-large){--border-radius:16px;--padding-top:17px;--padding-start:1em;--padding-end:1em;--padding-bottom:17px;min-height:3.1em;font-size:min(1.25rem, 60px)}:host(.button-small){--border-radius:6px;--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:min(0.8125rem, 39px)}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-strong){font-weight:600}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.125em, 60px);min-height:clamp(30px, 2.125em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 1.125em, 43.02px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(12.1394px, 1.308125em, 40.1856px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 0.9em, 43.056px)}:host(.button-outline.ion-focused.ion-color) .button-native,:host(.button-clear.ion-focused.ion-color) .button-native{color:var(--ion-color-base)}:host(.button-outline.ion-focused.ion-color) .button-native::after,:host(.button-clear.ion-focused.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-shade)}@media (any-hover: hover){:host(.button-clear:not(.ion-activated):hover),:host(.button-outline:not(.ion-activated):hover){opacity:0.6}:host(.button-clear.ion-color:hover) .button-native,:host(.button-outline.ion-color:hover) .button-native{color:var(--ion-color-base)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:transparent}:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-tint)}:host(:hover.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color):not(.ion-activated)) .button-native::after{background:#fff;opacity:0.1}}:host(.button-clear.ion-activated){opacity:0.4}:host(.button-outline.ion-activated.ion-color) .button-native{color:var(--ion-color-contrast)}:host(.button-outline.ion-activated.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-activated) .button-native::after{background:var(--ion-color-shade)}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--color));color:var(--ion-toolbar-background, var(--background), var(--ion-color-primary-contrast, #fff))}";
  11. const IonButtonIosStyle0 = buttonIosCss;
  12. const buttonMdCss = ":host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:4px;--padding-top:8px;--padding-bottom:8px;--padding-start:1.1em;--padding-end:1.1em;--transition:box-shadow 280ms cubic-bezier(.4, 0, .2, 1),\n background-color 15ms linear,\n color 15ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:36px;font-size:0.875rem;font-weight:500;letter-spacing:0.06em;text-transform:uppercase}:host(.button-solid){--background-activated:transparent;--background-hover:var(--ion-color-primary-contrast, #fff);--background-focused:var(--ion-color-primary-contrast, #fff);--background-activated-opacity:0;--background-focused-opacity:.24;--background-hover-opacity:.08;--box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12)}:host(.button-solid.ion-activated){--box-shadow:0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12)}:host(.button-outline){--border-width:2px;--border-style:solid;--box-shadow:none;--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-outline.ion-activated.ion-color) .button-native{background:transparent}:host(.button-clear){--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-large){--padding-top:14px;--padding-start:1em;--padding-end:1em;--padding-bottom:14px;min-height:2.8em;font-size:1.25rem}:host(.button-small){--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:0.8125rem}:host(.button-strong){font-weight:bold}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.86em, 60px);min-height:clamp(30px, 2.86em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.104px, 1.6em, 43.008px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(13.002px, 1.23125em, 40.385px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.008px, 1.4em, 43.008px)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color.ion-focused) .button-native::after,:host(.button-outline.ion-color.ion-focused) .button-native::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-background, var(--color));color:var(--ion-toolbar-color, var(--background), var(--ion-color-primary-contrast, #fff))}";
  13. const IonButtonMdStyle0 = buttonMdCss;
  14. const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement {
  15. constructor() {
  16. super();
  17. this.__registerHost();
  18. this.__attachShadow();
  19. this.ionFocus = createEvent(this, "ionFocus", 7);
  20. this.ionBlur = createEvent(this, "ionBlur", 7);
  21. this.inItem = false;
  22. this.inListHeader = false;
  23. this.inToolbar = false;
  24. this.formButtonEl = null;
  25. this.formEl = null;
  26. this.inheritedAttributes = {};
  27. this.handleClick = (ev) => {
  28. const { el } = this;
  29. if (this.type === 'button') {
  30. openURL(this.href, ev, this.routerDirection, this.routerAnimation);
  31. }
  32. else if (hasShadowDom(el)) {
  33. this.submitForm(ev);
  34. }
  35. };
  36. this.onFocus = () => {
  37. this.ionFocus.emit();
  38. };
  39. this.onBlur = () => {
  40. this.ionBlur.emit();
  41. };
  42. this.slotChanged = () => {
  43. /**
  44. * Ensures that the 'has-icon-only' class is properly added
  45. * or removed from `ion-button` when manipulating the
  46. * `icon-only` slot.
  47. *
  48. * Without this, the 'has-icon-only' class is only checked
  49. * or added when `ion-button` component first renders.
  50. */
  51. this.isCircle = this.hasIconOnly;
  52. };
  53. this.isCircle = false;
  54. this.color = undefined;
  55. this.buttonType = 'button';
  56. this.disabled = false;
  57. this.expand = undefined;
  58. this.fill = undefined;
  59. this.routerDirection = 'forward';
  60. this.routerAnimation = undefined;
  61. this.download = undefined;
  62. this.href = undefined;
  63. this.rel = undefined;
  64. this.shape = undefined;
  65. this.size = undefined;
  66. this.strong = false;
  67. this.target = undefined;
  68. this.type = 'button';
  69. this.form = undefined;
  70. }
  71. disabledChanged() {
  72. const { disabled } = this;
  73. if (this.formButtonEl) {
  74. this.formButtonEl.disabled = disabled;
  75. }
  76. }
  77. /**
  78. * This is responsible for rendering a hidden native
  79. * button element inside the associated form. This allows
  80. * users to submit a form by pressing "Enter" when a text
  81. * field inside of the form is focused. The native button
  82. * rendered inside of `ion-button` is in the Shadow DOM
  83. * and therefore does not participate in form submission
  84. * which is why the following code is necessary.
  85. */
  86. renderHiddenButton() {
  87. const formEl = (this.formEl = this.findForm());
  88. if (formEl) {
  89. const { formButtonEl } = this;
  90. /**
  91. * If the form already has a rendered form button
  92. * then do not append a new one again.
  93. */
  94. if (formButtonEl !== null && formEl.contains(formButtonEl)) {
  95. return;
  96. }
  97. // Create a hidden native button inside of the form
  98. const newFormButtonEl = (this.formButtonEl = document.createElement('button'));
  99. newFormButtonEl.type = this.type;
  100. newFormButtonEl.style.display = 'none';
  101. // Only submit if the button is not disabled.
  102. newFormButtonEl.disabled = this.disabled;
  103. formEl.appendChild(newFormButtonEl);
  104. }
  105. }
  106. componentWillLoad() {
  107. this.inToolbar = !!this.el.closest('ion-buttons');
  108. this.inListHeader = !!this.el.closest('ion-list-header');
  109. this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
  110. this.inheritedAttributes = inheritAriaAttributes(this.el);
  111. }
  112. get hasIconOnly() {
  113. return !!this.el.querySelector('[slot="icon-only"]');
  114. }
  115. get rippleType() {
  116. const hasClearFill = this.fill === undefined || this.fill === 'clear';
  117. // If the button is in a toolbar, has a clear fill (which is the default)
  118. // and only has an icon we use the unbounded "circular" ripple effect
  119. if (hasClearFill && this.hasIconOnly && this.inToolbar) {
  120. return 'unbounded';
  121. }
  122. return 'bounded';
  123. }
  124. /**
  125. * Finds the form element based on the provided `form` selector
  126. * or element reference provided.
  127. */
  128. findForm() {
  129. const { form } = this;
  130. if (form instanceof HTMLFormElement) {
  131. return form;
  132. }
  133. if (typeof form === 'string') {
  134. // Check if the string provided is a form id.
  135. const el = document.getElementById(form);
  136. if (el) {
  137. if (el instanceof HTMLFormElement) {
  138. return el;
  139. }
  140. else {
  141. /**
  142. * The developer specified a string for the form attribute, but the
  143. * element with that id is not a form element.
  144. */
  145. printIonWarning(`[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is attached to a <form> element.`, this.el);
  146. return null;
  147. }
  148. }
  149. else {
  150. /**
  151. * The developer specified a string for the form attribute, but the
  152. * element with that id could not be found in the DOM.
  153. */
  154. printIonWarning(`[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is correct and the form is rendered in the DOM.`, this.el);
  155. return null;
  156. }
  157. }
  158. if (form !== undefined) {
  159. /**
  160. * The developer specified a HTMLElement for the form attribute,
  161. * but the element is not a HTMLFormElement.
  162. * This will also catch if the developer tries to pass in null
  163. * as the form attribute.
  164. */
  165. printIonWarning(`[ion-button] - The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.`, this.el);
  166. return null;
  167. }
  168. /**
  169. * If the form element is not set, the button may be inside
  170. * of a form element. Query the closest form element to the button.
  171. */
  172. return this.el.closest('form');
  173. }
  174. submitForm(ev) {
  175. // this button wants to specifically submit a form
  176. // climb up the dom to see if we're in a <form>
  177. // and if so, then use JS to submit it
  178. if (this.formEl && this.formButtonEl) {
  179. ev.preventDefault();
  180. this.formButtonEl.click();
  181. }
  182. }
  183. render() {
  184. const mode = getIonMode(this);
  185. const { buttonType, type, disabled, rel, target, size, href, color, expand, hasIconOnly, shape, strong, inheritedAttributes, } = this;
  186. const finalSize = size === undefined && this.inItem ? 'small' : size;
  187. const TagType = href === undefined ? 'button' : 'a';
  188. const attrs = TagType === 'button'
  189. ? { type }
  190. : {
  191. download: this.download,
  192. href,
  193. rel,
  194. target,
  195. };
  196. let fill = this.fill;
  197. /**
  198. * We check both undefined and null to
  199. * work around https://github.com/ionic-team/stencil/issues/3586.
  200. */
  201. if (fill == null) {
  202. fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
  203. }
  204. /**
  205. * We call renderHiddenButton in the render function to account
  206. * for any properties being set async. For example, changing the
  207. * "type" prop from "button" to "submit" after the component has
  208. * loaded would warrant the hidden button being added to the
  209. * associated form.
  210. */
  211. {
  212. type !== 'button' && this.renderHiddenButton();
  213. }
  214. return (h(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses(color, {
  215. [mode]: true,
  216. [buttonType]: true,
  217. [`${buttonType}-${expand}`]: expand !== undefined,
  218. [`${buttonType}-${finalSize}`]: finalSize !== undefined,
  219. [`${buttonType}-${shape}`]: shape !== undefined,
  220. [`${buttonType}-${fill}`]: true,
  221. [`${buttonType}-strong`]: strong,
  222. 'in-toolbar': hostContext('ion-toolbar', this.el),
  223. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  224. 'in-buttons': hostContext('ion-buttons', this.el),
  225. 'button-has-icon-only': hasIconOnly,
  226. 'button-disabled': disabled,
  227. 'ion-activatable': true,
  228. 'ion-focusable': true,
  229. }) }, h(TagType, Object.assign({ key: 'b7c2a46fb994024841219316f4089335fa463d84' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '3e07a5c9f86836f9fbaefc6c617bdde6eb6f70cd', class: "button-inner" }, h("slot", { key: '41c08ae09aed16faaa57707d229ff75d97f0731c', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: 'ab8b749e4572884cc04970a7594466b4a24c886e', name: "start" }), h("slot", { key: '397f7ff48ea45e82029414be95d29ae86e12c3a9' }), h("slot", { key: '9a5627713002e8be3738d392b616f6e951b70e12', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: '105566543ceda102474edab7ca8a44c7e71af589', type: this.rippleType }))));
  230. }
  231. get el() { return this; }
  232. static get watchers() { return {
  233. "disabled": ["disabledChanged"]
  234. }; }
  235. static get style() { return {
  236. ios: IonButtonIosStyle0,
  237. md: IonButtonMdStyle0
  238. }; }
  239. }, [33, "ion-button", {
  240. "color": [513],
  241. "buttonType": [1025, "button-type"],
  242. "disabled": [516],
  243. "expand": [513],
  244. "fill": [1537],
  245. "routerDirection": [1, "router-direction"],
  246. "routerAnimation": [16],
  247. "download": [1],
  248. "href": [1],
  249. "rel": [1],
  250. "shape": [513],
  251. "size": [513],
  252. "strong": [4],
  253. "target": [1],
  254. "type": [1],
  255. "form": [1],
  256. "isCircle": [32]
  257. }, undefined, {
  258. "disabled": ["disabledChanged"]
  259. }]);
  260. function defineCustomElement() {
  261. if (typeof customElements === "undefined") {
  262. return;
  263. }
  264. const components = ["ion-button", "ion-ripple-effect"];
  265. components.forEach(tagName => { switch (tagName) {
  266. case "ion-button":
  267. if (!customElements.get(tagName)) {
  268. customElements.define(tagName, Button);
  269. }
  270. break;
  271. case "ion-ripple-effect":
  272. if (!customElements.get(tagName)) {
  273. defineCustomElement$1();
  274. }
  275. break;
  276. } });
  277. }
  278. export { Button as B, defineCustomElement as d };