checkbox.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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. import { Component, Element, Event, h, Host, Method, Prop } from "@stencil/core";
  7. import { guid } from "../../utils/guid";
  8. import { HiddenFormInputSlot } from "../../utils/form";
  9. import { connectLabel, disconnectLabel, getLabelText } from "../../utils/label";
  10. import { connectForm, disconnectForm } from "../../utils/form";
  11. import { updateHostInteraction } from "../../utils/interactive";
  12. import { toAriaBoolean } from "../../utils/dom";
  13. export class Checkbox {
  14. constructor() {
  15. //--------------------------------------------------------------------------
  16. //
  17. // Properties
  18. //
  19. //--------------------------------------------------------------------------
  20. /** The checked state of the checkbox. */
  21. this.checked = false;
  22. /** True if the checkbox is disabled */
  23. this.disabled = false;
  24. /**
  25. * The hovered state of the checkbox.
  26. * @internal
  27. */
  28. this.hovered = false;
  29. /**
  30. * True if the checkbox is initially indeterminate,
  31. * which is independent from its checked state
  32. * https://css-tricks.com/indeterminate-checkboxes/
  33. * */
  34. this.indeterminate = false;
  35. /**
  36. * When true, makes the component required for form-submission.
  37. *
  38. * @internal
  39. */
  40. this.required = false;
  41. /** specify the scale of the checkbox, defaults to m */
  42. this.scale = "m";
  43. //--------------------------------------------------------------------------
  44. //
  45. // Private Properties
  46. //
  47. //--------------------------------------------------------------------------
  48. this.checkedPath = "M5.5 12L2 8.689l.637-.636L5.5 10.727l8.022-7.87.637.637z";
  49. this.indeterminatePath = "M13 8v1H3V8z";
  50. //--------------------------------------------------------------------------
  51. //
  52. // Private Methods
  53. //
  54. //--------------------------------------------------------------------------
  55. this.getPath = () => this.indeterminate ? this.indeterminatePath : this.checked ? this.checkedPath : "";
  56. this.toggle = () => {
  57. if (!this.disabled) {
  58. this.checked = !this.checked;
  59. this.setFocus();
  60. this.indeterminate = false;
  61. this.calciteCheckboxChange.emit();
  62. }
  63. };
  64. this.keyDownHandler = (event) => {
  65. if (event.key === " " || event.key === "Enter") {
  66. this.toggle();
  67. event.preventDefault();
  68. }
  69. };
  70. this.clickHandler = () => {
  71. this.toggle();
  72. };
  73. //--------------------------------------------------------------------------
  74. //
  75. // Event Listeners
  76. //
  77. //--------------------------------------------------------------------------
  78. this.onToggleBlur = () => {
  79. this.calciteInternalCheckboxBlur.emit(false);
  80. };
  81. this.onToggleFocus = () => {
  82. this.calciteInternalCheckboxFocus.emit(true);
  83. };
  84. this.onLabelClick = () => {
  85. this.toggle();
  86. };
  87. }
  88. //--------------------------------------------------------------------------
  89. //
  90. // Public Methods
  91. //
  92. //--------------------------------------------------------------------------
  93. /** Sets focus on the component. */
  94. async setFocus() {
  95. var _a;
  96. (_a = this.toggleEl) === null || _a === void 0 ? void 0 : _a.focus();
  97. }
  98. //--------------------------------------------------------------------------
  99. //
  100. // Lifecycle
  101. //
  102. //--------------------------------------------------------------------------
  103. connectedCallback() {
  104. this.guid = this.el.id || `calcite-checkbox-${guid()}`;
  105. connectLabel(this);
  106. connectForm(this);
  107. }
  108. disconnectedCallback() {
  109. disconnectLabel(this);
  110. disconnectForm(this);
  111. }
  112. componentDidRender() {
  113. updateHostInteraction(this);
  114. }
  115. // --------------------------------------------------------------------------
  116. //
  117. // Render Methods
  118. //
  119. // --------------------------------------------------------------------------
  120. render() {
  121. return (h(Host, { onClick: this.clickHandler, onKeyDown: this.keyDownHandler },
  122. h("div", { "aria-checked": toAriaBoolean(this.checked), "aria-label": getLabelText(this), class: "toggle", onBlur: this.onToggleBlur, onFocus: this.onToggleFocus, ref: (toggleEl) => (this.toggleEl = toggleEl), role: "checkbox", tabIndex: this.disabled ? undefined : 0 },
  123. h("svg", { class: "check-svg", viewBox: "0 0 16 16" },
  124. h("path", { d: this.getPath() })),
  125. h("slot", null)),
  126. h(HiddenFormInputSlot, { component: this })));
  127. }
  128. static get is() { return "calcite-checkbox"; }
  129. static get encapsulation() { return "shadow"; }
  130. static get originalStyleUrls() { return {
  131. "$": ["checkbox.scss"]
  132. }; }
  133. static get styleUrls() { return {
  134. "$": ["checkbox.css"]
  135. }; }
  136. static get properties() { return {
  137. "checked": {
  138. "type": "boolean",
  139. "mutable": true,
  140. "complexType": {
  141. "original": "boolean",
  142. "resolved": "boolean",
  143. "references": {}
  144. },
  145. "required": false,
  146. "optional": false,
  147. "docs": {
  148. "tags": [],
  149. "text": "The checked state of the checkbox."
  150. },
  151. "attribute": "checked",
  152. "reflect": true,
  153. "defaultValue": "false"
  154. },
  155. "disabled": {
  156. "type": "boolean",
  157. "mutable": false,
  158. "complexType": {
  159. "original": "boolean",
  160. "resolved": "boolean",
  161. "references": {}
  162. },
  163. "required": false,
  164. "optional": false,
  165. "docs": {
  166. "tags": [],
  167. "text": "True if the checkbox is disabled"
  168. },
  169. "attribute": "disabled",
  170. "reflect": true,
  171. "defaultValue": "false"
  172. },
  173. "guid": {
  174. "type": "string",
  175. "mutable": true,
  176. "complexType": {
  177. "original": "string",
  178. "resolved": "string",
  179. "references": {}
  180. },
  181. "required": false,
  182. "optional": false,
  183. "docs": {
  184. "tags": [],
  185. "text": "The id attribute of the checkbox. When omitted, a globally unique identifier is used."
  186. },
  187. "attribute": "guid",
  188. "reflect": true
  189. },
  190. "hovered": {
  191. "type": "boolean",
  192. "mutable": true,
  193. "complexType": {
  194. "original": "boolean",
  195. "resolved": "boolean",
  196. "references": {}
  197. },
  198. "required": false,
  199. "optional": false,
  200. "docs": {
  201. "tags": [{
  202. "name": "internal",
  203. "text": undefined
  204. }],
  205. "text": "The hovered state of the checkbox."
  206. },
  207. "attribute": "hovered",
  208. "reflect": true,
  209. "defaultValue": "false"
  210. },
  211. "indeterminate": {
  212. "type": "boolean",
  213. "mutable": true,
  214. "complexType": {
  215. "original": "boolean",
  216. "resolved": "boolean",
  217. "references": {}
  218. },
  219. "required": false,
  220. "optional": false,
  221. "docs": {
  222. "tags": [],
  223. "text": "True if the checkbox is initially indeterminate,\nwhich is independent from its checked state\nhttps://css-tricks.com/indeterminate-checkboxes/"
  224. },
  225. "attribute": "indeterminate",
  226. "reflect": true,
  227. "defaultValue": "false"
  228. },
  229. "label": {
  230. "type": "string",
  231. "mutable": false,
  232. "complexType": {
  233. "original": "string",
  234. "resolved": "string",
  235. "references": {}
  236. },
  237. "required": false,
  238. "optional": true,
  239. "docs": {
  240. "tags": [{
  241. "name": "internal",
  242. "text": undefined
  243. }],
  244. "text": "The label of the checkbox input"
  245. },
  246. "attribute": "label",
  247. "reflect": false
  248. },
  249. "name": {
  250. "type": "any",
  251. "mutable": false,
  252. "complexType": {
  253. "original": "any",
  254. "resolved": "any",
  255. "references": {}
  256. },
  257. "required": false,
  258. "optional": false,
  259. "docs": {
  260. "tags": [],
  261. "text": "The name of the checkbox input"
  262. },
  263. "attribute": "name",
  264. "reflect": true
  265. },
  266. "required": {
  267. "type": "boolean",
  268. "mutable": false,
  269. "complexType": {
  270. "original": "boolean",
  271. "resolved": "boolean",
  272. "references": {}
  273. },
  274. "required": false,
  275. "optional": false,
  276. "docs": {
  277. "tags": [{
  278. "name": "internal",
  279. "text": undefined
  280. }],
  281. "text": "When true, makes the component required for form-submission."
  282. },
  283. "attribute": "required",
  284. "reflect": true,
  285. "defaultValue": "false"
  286. },
  287. "scale": {
  288. "type": "string",
  289. "mutable": false,
  290. "complexType": {
  291. "original": "Scale",
  292. "resolved": "\"l\" | \"m\" | \"s\"",
  293. "references": {
  294. "Scale": {
  295. "location": "import",
  296. "path": "../interfaces"
  297. }
  298. }
  299. },
  300. "required": false,
  301. "optional": false,
  302. "docs": {
  303. "tags": [],
  304. "text": "specify the scale of the checkbox, defaults to m"
  305. },
  306. "attribute": "scale",
  307. "reflect": true,
  308. "defaultValue": "\"m\""
  309. },
  310. "value": {
  311. "type": "any",
  312. "mutable": false,
  313. "complexType": {
  314. "original": "any",
  315. "resolved": "any",
  316. "references": {}
  317. },
  318. "required": false,
  319. "optional": false,
  320. "docs": {
  321. "tags": [],
  322. "text": "The value of the checkbox input"
  323. },
  324. "attribute": "value",
  325. "reflect": false
  326. }
  327. }; }
  328. static get events() { return [{
  329. "method": "calciteInternalCheckboxBlur",
  330. "name": "calciteInternalCheckboxBlur",
  331. "bubbles": true,
  332. "cancelable": true,
  333. "composed": true,
  334. "docs": {
  335. "tags": [{
  336. "name": "internal",
  337. "text": undefined
  338. }],
  339. "text": "Emitted when the checkbox is blurred"
  340. },
  341. "complexType": {
  342. "original": "any",
  343. "resolved": "any",
  344. "references": {}
  345. }
  346. }, {
  347. "method": "calciteCheckboxChange",
  348. "name": "calciteCheckboxChange",
  349. "bubbles": true,
  350. "cancelable": true,
  351. "composed": true,
  352. "docs": {
  353. "tags": [],
  354. "text": "Emitted when the checkbox checked status changes"
  355. },
  356. "complexType": {
  357. "original": "any",
  358. "resolved": "any",
  359. "references": {}
  360. }
  361. }, {
  362. "method": "calciteInternalCheckboxFocus",
  363. "name": "calciteInternalCheckboxFocus",
  364. "bubbles": true,
  365. "cancelable": true,
  366. "composed": true,
  367. "docs": {
  368. "tags": [{
  369. "name": "internal",
  370. "text": undefined
  371. }],
  372. "text": "Emitted when the checkbox is focused"
  373. },
  374. "complexType": {
  375. "original": "any",
  376. "resolved": "any",
  377. "references": {}
  378. }
  379. }]; }
  380. static get methods() { return {
  381. "setFocus": {
  382. "complexType": {
  383. "signature": "() => Promise<void>",
  384. "parameters": [],
  385. "references": {
  386. "Promise": {
  387. "location": "global"
  388. }
  389. },
  390. "return": "Promise<void>"
  391. },
  392. "docs": {
  393. "text": "Sets focus on the component.",
  394. "tags": []
  395. }
  396. }
  397. }; }
  398. static get elementRef() { return "el"; }
  399. }