checkbox.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
  5. import { i as inheritAriaAttributes, e as renderHiddenInput } from './helpers.js';
  6. import { c as createColorClasses, h as hostContext } from './theme.js';
  7. import { b as getIonMode } from './ionic-global.js';
  8. const checkboxIosCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:50%;--border-width:0.125rem;--border-style:solid;--border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.23);--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--size:min(1.375rem, 55.836px);--checkmark-width:1.5px}:host(.checkbox-disabled){opacity:0.3}";
  9. const IonCheckboxIosStyle0 = checkboxIosCss;
  10. const checkboxMdCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:calc(var(--size) * .125);--border-width:2px;--border-style:solid;--border-color:rgb(var(--ion-text-color-rgb, 0, 0, 0), 0.6);--checkmark-width:3;--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--transition:background 180ms cubic-bezier(0.4, 0, 0.2, 1);--size:18px}.checkbox-icon path{stroke-dasharray:30;stroke-dashoffset:30}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{stroke-dashoffset:0;-webkit-transition:stroke-dashoffset 90ms linear 90ms;transition:stroke-dashoffset 90ms linear 90ms}:host(.checkbox-disabled) .label-text-wrapper{opacity:0.38}:host(.checkbox-disabled) .native-wrapper{opacity:0.63}";
  11. const IonCheckboxMdStyle0 = checkboxMdCss;
  12. const Checkbox = /*@__PURE__*/ proxyCustomElement(class Checkbox extends HTMLElement {
  13. constructor() {
  14. super();
  15. this.__registerHost();
  16. this.__attachShadow();
  17. this.ionChange = createEvent(this, "ionChange", 7);
  18. this.ionFocus = createEvent(this, "ionFocus", 7);
  19. this.ionBlur = createEvent(this, "ionBlur", 7);
  20. this.inputId = `ion-cb-${checkboxIds++}`;
  21. this.inputLabelId = `${this.inputId}-lbl`;
  22. this.helperTextId = `${this.inputId}-helper-text`;
  23. this.errorTextId = `${this.inputId}-error-text`;
  24. this.inheritedAttributes = {};
  25. /**
  26. * Sets the checked property and emits
  27. * the ionChange event. Use this to update the
  28. * checked state in response to user-generated
  29. * actions such as a click.
  30. */
  31. this.setChecked = (state) => {
  32. const isChecked = (this.checked = state);
  33. this.ionChange.emit({
  34. checked: isChecked,
  35. value: this.value,
  36. });
  37. };
  38. this.toggleChecked = (ev) => {
  39. ev.preventDefault();
  40. this.setFocus();
  41. this.setChecked(!this.checked);
  42. this.indeterminate = false;
  43. };
  44. this.onFocus = () => {
  45. this.ionFocus.emit();
  46. };
  47. this.onBlur = () => {
  48. this.ionBlur.emit();
  49. };
  50. this.onKeyDown = (ev) => {
  51. if (ev.key === ' ') {
  52. ev.preventDefault();
  53. if (!this.disabled) {
  54. this.toggleChecked(ev);
  55. }
  56. }
  57. };
  58. this.onClick = (ev) => {
  59. if (this.disabled) {
  60. return;
  61. }
  62. this.toggleChecked(ev);
  63. };
  64. /**
  65. * Stops propagation when the display label is clicked,
  66. * otherwise, two clicks will be triggered.
  67. */
  68. this.onDivLabelClick = (ev) => {
  69. ev.stopPropagation();
  70. };
  71. this.color = undefined;
  72. this.name = this.inputId;
  73. this.checked = false;
  74. this.indeterminate = false;
  75. this.disabled = false;
  76. this.errorText = undefined;
  77. this.helperText = undefined;
  78. this.value = 'on';
  79. this.labelPlacement = 'start';
  80. this.justify = undefined;
  81. this.alignment = undefined;
  82. this.required = false;
  83. }
  84. componentWillLoad() {
  85. this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
  86. }
  87. /** @internal */
  88. async setFocus() {
  89. if (this.focusEl) {
  90. this.focusEl.focus();
  91. }
  92. }
  93. getHintTextID() {
  94. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  95. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  96. return errorTextId;
  97. }
  98. if (helperText) {
  99. return helperTextId;
  100. }
  101. return undefined;
  102. }
  103. /**
  104. * Responsible for rendering helper text and error text.
  105. * This element should only be rendered if hint text is set.
  106. */
  107. renderHintText() {
  108. const { helperText, errorText, helperTextId, errorTextId } = this;
  109. /**
  110. * undefined and empty string values should
  111. * be treated as not having helper/error text.
  112. */
  113. const hasHintText = !!helperText || !!errorText;
  114. if (!hasHintText) {
  115. return;
  116. }
  117. return (h("div", { class: "checkbox-bottom" }, h("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), h("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
  118. }
  119. render() {
  120. const { color, checked, disabled, el, getSVGPath, indeterminate, inheritedAttributes, inputId, justify, labelPlacement, name, value, alignment, required, } = this;
  121. const mode = getIonMode(this);
  122. const path = getSVGPath(mode, indeterminate);
  123. const hasLabelContent = el.textContent !== '';
  124. renderHiddenInput(true, el, name, checked ? value : '', disabled);
  125. // The host element must have a checkbox role to ensure proper VoiceOver
  126. // support in Safari for accessibility.
  127. return (h(Host, { key: '26cbe7220e555107200e9b5deeae754aa534a80b', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, class: createColorClasses(color, {
  128. [mode]: true,
  129. 'in-item': hostContext('ion-item', el),
  130. 'checkbox-checked': checked,
  131. 'checkbox-disabled': disabled,
  132. 'checkbox-indeterminate': indeterminate,
  133. interactive: true,
  134. [`checkbox-justify-${justify}`]: justify !== undefined,
  135. [`checkbox-alignment-${alignment}`]: alignment !== undefined,
  136. [`checkbox-label-placement-${labelPlacement}`]: true,
  137. }), onClick: this.onClick }, h("label", { key: 'f025cec5ff08e8be4487b9cc0324616ca5dfae2a', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: 'dc53f7e4e240dc2e18556e6350df2b5c3169f553', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, onFocus: () => this.onFocus(), onBlur: () => this.onBlur(), ref: (focusEl) => (this.focusEl = focusEl), required: required }, inheritedAttributes)), h("div", { key: 'a625e9b50c3b617de8bbbfd624d772454fecaf2d', class: {
  138. 'label-text-wrapper': true,
  139. 'label-text-wrapper-hidden': !hasLabelContent,
  140. }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '87d1a90691327945f4343406706e4ab27f453844' }), this.renderHintText()), h("div", { key: 'b57fed8cdecee4df1ef0d57f157267ee77fac653', class: "native-wrapper" }, h("svg", { key: 'd472a06ec6c8b74dfb651415d2236db8080f6805', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container" }, path)))));
  141. }
  142. getSVGPath(mode, indeterminate) {
  143. let path = indeterminate ? (h("path", { d: "M6 12L18 12", part: "mark" })) : (h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
  144. if (mode === 'md') {
  145. path = indeterminate ? (h("path", { d: "M2 12H22", part: "mark" })) : (h("path", { d: "M1.73,12.91 8.1,19.28 22.79,4.59", part: "mark" }));
  146. }
  147. return path;
  148. }
  149. get el() { return this; }
  150. static get style() { return {
  151. ios: IonCheckboxIosStyle0,
  152. md: IonCheckboxMdStyle0
  153. }; }
  154. }, [33, "ion-checkbox", {
  155. "color": [513],
  156. "name": [1],
  157. "checked": [1028],
  158. "indeterminate": [1028],
  159. "disabled": [4],
  160. "errorText": [1, "error-text"],
  161. "helperText": [1, "helper-text"],
  162. "value": [8],
  163. "labelPlacement": [1, "label-placement"],
  164. "justify": [1],
  165. "alignment": [1],
  166. "required": [4],
  167. "setFocus": [64]
  168. }]);
  169. let checkboxIds = 0;
  170. function defineCustomElement() {
  171. if (typeof customElements === "undefined") {
  172. return;
  173. }
  174. const components = ["ion-checkbox"];
  175. components.forEach(tagName => { switch (tagName) {
  176. case "ion-checkbox":
  177. if (!customElements.get(tagName)) {
  178. customElements.define(tagName, Checkbox);
  179. }
  180. break;
  181. } });
  182. }
  183. export { Checkbox as C, defineCustomElement as d };