calcite-radio-button.cjs.entry.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. 'use strict';
  7. Object.defineProperty(exports, '__esModule', { value: true });
  8. const index = require('./index-5c65e149.js');
  9. const guid = require('./guid-8b6d6cb4.js');
  10. const dom = require('./dom-9ac0341c.js');
  11. const label = require('./label-165fc611.js');
  12. const form = require('./form-11926121.js');
  13. const array = require('./array-f1fe66d8.js');
  14. const interactive = require('./interactive-e294111f.js');
  15. const CSS = {
  16. container: "container"
  17. };
  18. const radioButtonCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host{display:block;cursor:pointer}:host .container{position:relative;outline:2px solid transparent;outline-offset:2px}:host .radio{cursor:pointer;border-radius:9999px;background-color:var(--calcite-ui-foreground-1);-webkit-transition-property:all;transition-property:all;-webkit-transition-duration:150ms;transition-duration:150ms;-webkit-transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);-webkit-box-shadow:inset 0 0 0 1px var(--calcite-ui-border-input);box-shadow:inset 0 0 0 1px var(--calcite-ui-border-input)}:host([hovered]) .radio,:host(:not([checked])[focused]:not([disabled])) .radio{-webkit-box-shadow:inset 0 0 0 2px var(--calcite-ui-brand);box-shadow:inset 0 0 0 2px var(--calcite-ui-brand)}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}:host([disabled]) .radio{cursor:default;opacity:var(--calcite-ui-opacity-disabled)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}:host([hovered][disabled]) .radio{-webkit-box-shadow:inset 0 0 0 1px var(--calcite-ui-border-input);box-shadow:inset 0 0 0 1px var(--calcite-ui-border-input)}:host([scale=s]){--calcite-radio-size:var(--calcite-font-size--2)}:host([scale=m]){--calcite-radio-size:var(--calcite-font-size--1)}:host([scale=l]){--calcite-radio-size:var(--calcite-font-size-0)}.radio{height:var(--calcite-radio-size);max-width:var(--calcite-radio-size);min-width:var(--calcite-radio-size)}:host([scale=s][checked]) .radio,:host([hovered][scale=s][checked][disabled]) .radio{-webkit-box-shadow:inset 0 0 0 4px var(--calcite-ui-brand);box-shadow:inset 0 0 0 4px var(--calcite-ui-brand)}:host([scale=s][focused][checked]:not([disabled])) .radio{-webkit-box-shadow:inset 0 0 0 4px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand);box-shadow:inset 0 0 0 4px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand)}:host([scale=m][checked]) .radio,:host([hovered][scale=m][checked][disabled]) .radio{-webkit-box-shadow:inset 0 0 0 5px var(--calcite-ui-brand);box-shadow:inset 0 0 0 5px var(--calcite-ui-brand)}:host([scale=m][focused][checked]:not([disabled])) .radio{-webkit-box-shadow:inset 0 0 0 5px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand);box-shadow:inset 0 0 0 5px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand)}:host([scale=l][checked]) .radio,:host([hovered][scale=l][checked][disabled]) .radio{-webkit-box-shadow:inset 0 0 0 6px var(--calcite-ui-brand);box-shadow:inset 0 0 0 6px var(--calcite-ui-brand)}:host([scale=l][focused][checked]:not([disabled])) .radio{-webkit-box-shadow:inset 0 0 0 6px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand);box-shadow:inset 0 0 0 6px var(--calcite-ui-brand), 0 0 0 2px var(--calcite-ui-foreground-1), 0 0 0 4px var(--calcite-ui-brand)}@media (forced-colors: active){:host([checked]) .radio::after,:host([checked][disabled]) .radio::after{content:\"\";width:var(--calcite-radio-size);height:var(--calcite-radio-size);background-color:windowText;display:block}}::slotted(input[slot=hidden-form-input]){bottom:0 !important;left:0 !important;margin:0 !important;opacity:0 !important;outline:none !important;padding:0 !important;position:absolute !important;right:0 !important;top:0 !important;-webkit-transform:none !important;transform:none !important;-webkit-appearance:none !important;z-index:-1 !important}";
  19. const RadioButton = class {
  20. constructor(hostRef) {
  21. index.registerInstance(this, hostRef);
  22. this.calciteInternalRadioButtonBlur = index.createEvent(this, "calciteInternalRadioButtonBlur", 7);
  23. this.calciteRadioButtonChange = index.createEvent(this, "calciteRadioButtonChange", 7);
  24. this.calciteInternalRadioButtonCheckedChange = index.createEvent(this, "calciteInternalRadioButtonCheckedChange", 7);
  25. this.calciteInternalRadioButtonFocus = index.createEvent(this, "calciteInternalRadioButtonFocus", 7);
  26. //--------------------------------------------------------------------------
  27. //
  28. // Properties
  29. //
  30. //--------------------------------------------------------------------------
  31. /** The checked state of the radio button. */
  32. this.checked = false;
  33. /** The disabled state of the radio button. */
  34. this.disabled = false;
  35. /**
  36. * The focused state of the radio button.
  37. * @internal
  38. */
  39. this.focused = false;
  40. /** The radio button's hidden status. When a radio button is hidden it is not focusable or checkable. */
  41. this.hidden = false;
  42. /**
  43. * The hovered state of the radio button.
  44. * @internal
  45. */
  46. this.hovered = false;
  47. /** Requires that a value is selected for the radio button group before the parent form will submit. */
  48. this.required = false;
  49. /** The scale (size) of the radio button. `scale` is passed as a property automatically from `calcite-radio-button-group`. */
  50. this.scale = "m";
  51. //--------------------------------------------------------------------------
  52. //
  53. // Private Methods
  54. //
  55. //--------------------------------------------------------------------------
  56. this.selectItem = (items, selectedIndex) => {
  57. items[selectedIndex].click();
  58. };
  59. this.queryButtons = () => {
  60. return Array.from(this.rootNode.querySelectorAll("calcite-radio-button:not([hidden])")).filter((radioButton) => radioButton.name === this.name);
  61. };
  62. this.isDefaultSelectable = () => {
  63. const radioButtons = this.queryButtons();
  64. return !radioButtons.some((radioButton) => radioButton.checked) && radioButtons[0] === this.el;
  65. };
  66. this.check = () => {
  67. if (this.disabled) {
  68. return;
  69. }
  70. this.uncheckAllRadioButtonsInGroup();
  71. this.checked = true;
  72. this.calciteRadioButtonChange.emit();
  73. this.setFocus();
  74. };
  75. this.clickHandler = () => {
  76. this.check();
  77. };
  78. this.setContainerEl = (el) => {
  79. this.containerEl = el;
  80. };
  81. this.handleKeyDown = (event) => {
  82. const keys = ["ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", " "];
  83. const key = event.key;
  84. const { el } = this;
  85. if (keys.indexOf(key) === -1) {
  86. return;
  87. }
  88. if (key === " ") {
  89. this.check();
  90. return;
  91. }
  92. let adjustedKey = key;
  93. if (dom.getElementDir(el) === "rtl") {
  94. if (key === "ArrowRight") {
  95. adjustedKey = "ArrowLeft";
  96. }
  97. if (key === "ArrowLeft") {
  98. adjustedKey = "ArrowRight";
  99. }
  100. }
  101. const radioButtons = Array.from(this.rootNode.querySelectorAll("calcite-radio-button:not([hidden]")).filter((radioButton) => radioButton.name === this.name);
  102. let currentIndex = 0;
  103. const radioButtonsLength = radioButtons.length;
  104. radioButtons.some((item, index) => {
  105. if (item.checked) {
  106. currentIndex = index;
  107. return true;
  108. }
  109. });
  110. switch (adjustedKey) {
  111. case "ArrowLeft":
  112. case "ArrowUp":
  113. event.preventDefault();
  114. this.selectItem(radioButtons, array.getRoundRobinIndex(Math.max(currentIndex - 1, -1), radioButtonsLength));
  115. return;
  116. case "ArrowRight":
  117. case "ArrowDown":
  118. event.preventDefault();
  119. this.selectItem(radioButtons, array.getRoundRobinIndex(currentIndex + 1, radioButtonsLength));
  120. return;
  121. default:
  122. return;
  123. }
  124. };
  125. this.onContainerBlur = () => {
  126. this.focused = false;
  127. this.calciteInternalRadioButtonBlur.emit();
  128. };
  129. this.onContainerFocus = () => {
  130. if (!this.disabled) {
  131. this.focused = true;
  132. this.calciteInternalRadioButtonFocus.emit();
  133. }
  134. };
  135. }
  136. checkedChanged(newChecked) {
  137. if (newChecked) {
  138. this.uncheckOtherRadioButtonsInGroup();
  139. }
  140. this.calciteInternalRadioButtonCheckedChange.emit(newChecked);
  141. }
  142. nameChanged() {
  143. this.checkLastRadioButton();
  144. }
  145. //--------------------------------------------------------------------------
  146. //
  147. // Public Methods
  148. //
  149. //--------------------------------------------------------------------------
  150. /** Sets focus on the component. */
  151. async setFocus() {
  152. if (!this.disabled) {
  153. dom.focusElement(this.containerEl);
  154. }
  155. }
  156. onLabelClick(event) {
  157. if (!this.disabled && !this.hidden) {
  158. this.uncheckOtherRadioButtonsInGroup();
  159. const label = event.currentTarget;
  160. const radioButton = label.for
  161. ? this.rootNode.querySelector(`calcite-radio-button[id="${label.for}"]`)
  162. : label.querySelector(`calcite-radio-button[name="${this.name}"]`);
  163. if (radioButton) {
  164. radioButton.checked = true;
  165. radioButton.focused = true;
  166. }
  167. this.calciteRadioButtonChange.emit();
  168. this.setFocus();
  169. }
  170. }
  171. checkLastRadioButton() {
  172. const radioButtons = this.queryButtons();
  173. const checkedRadioButtons = radioButtons.filter((radioButton) => radioButton.checked);
  174. if ((checkedRadioButtons === null || checkedRadioButtons === void 0 ? void 0 : checkedRadioButtons.length) > 1) {
  175. const lastCheckedRadioButton = checkedRadioButtons[checkedRadioButtons.length - 1];
  176. checkedRadioButtons
  177. .filter((checkedRadioButton) => checkedRadioButton !== lastCheckedRadioButton)
  178. .forEach((checkedRadioButton) => {
  179. checkedRadioButton.checked = false;
  180. checkedRadioButton.emitCheckedChange();
  181. });
  182. }
  183. }
  184. /** @internal */
  185. async emitCheckedChange() {
  186. this.calciteInternalRadioButtonCheckedChange.emit();
  187. }
  188. uncheckAllRadioButtonsInGroup() {
  189. const radioButtons = this.queryButtons();
  190. radioButtons.forEach((radioButton) => {
  191. if (radioButton.checked) {
  192. radioButton.checked = false;
  193. radioButton.focused = false;
  194. }
  195. });
  196. }
  197. uncheckOtherRadioButtonsInGroup() {
  198. const radioButtons = this.queryButtons();
  199. const otherRadioButtons = radioButtons.filter((radioButton) => radioButton.guid !== this.guid);
  200. otherRadioButtons.forEach((otherRadioButton) => {
  201. if (otherRadioButton.checked) {
  202. otherRadioButton.checked = false;
  203. otherRadioButton.focused = false;
  204. }
  205. });
  206. }
  207. getTabIndex() {
  208. if (this.disabled) {
  209. return undefined;
  210. }
  211. return this.checked || this.isDefaultSelectable() ? 0 : -1;
  212. }
  213. //--------------------------------------------------------------------------
  214. //
  215. // Event Listeners
  216. //
  217. //--------------------------------------------------------------------------
  218. mouseenter() {
  219. this.hovered = true;
  220. }
  221. mouseleave() {
  222. this.hovered = false;
  223. }
  224. //--------------------------------------------------------------------------
  225. //
  226. // Lifecycle
  227. //
  228. //--------------------------------------------------------------------------
  229. connectedCallback() {
  230. this.rootNode = this.el.getRootNode();
  231. this.guid = this.el.id || `calcite-radio-button-${guid.guid()}`;
  232. if (this.name) {
  233. this.checkLastRadioButton();
  234. }
  235. label.connectLabel(this);
  236. form.connectForm(this);
  237. }
  238. componentDidLoad() {
  239. if (this.focused && !this.disabled) {
  240. this.setFocus();
  241. }
  242. }
  243. disconnectedCallback() {
  244. label.disconnectLabel(this);
  245. form.disconnectForm(this);
  246. }
  247. componentDidRender() {
  248. interactive.updateHostInteraction(this);
  249. }
  250. // --------------------------------------------------------------------------
  251. //
  252. // Render Methods
  253. //
  254. // --------------------------------------------------------------------------
  255. render() {
  256. const tabIndex = this.getTabIndex();
  257. return (index.h(index.Host, { onClick: this.clickHandler, onKeyDown: this.handleKeyDown }, index.h("div", { "aria-checked": dom.toAriaBoolean(this.checked), "aria-label": label.getLabelText(this), class: CSS.container, onBlur: this.onContainerBlur, onFocus: this.onContainerFocus, ref: this.setContainerEl, role: "radio", tabIndex: tabIndex }, index.h("div", { class: "radio" })), index.h(form.HiddenFormInputSlot, { component: this })));
  258. }
  259. get el() { return index.getElement(this); }
  260. static get watchers() { return {
  261. "checked": ["checkedChanged"],
  262. "name": ["nameChanged"]
  263. }; }
  264. };
  265. RadioButton.style = radioButtonCss;
  266. exports.calcite_radio_button = RadioButton;