tile-select.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  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, Prop, Listen, Watch, State, Method } from "@stencil/core";
  7. import { guid } from "../../utils/guid";
  8. import { CSS } from "./resources";
  9. import { updateHostInteraction } from "../../utils/interactive";
  10. /**
  11. * @slot - A slot for adding custom content.
  12. */
  13. export class TileSelect {
  14. constructor() {
  15. //--------------------------------------------------------------------------
  16. //
  17. // Properties
  18. //
  19. //--------------------------------------------------------------------------
  20. /** The checked state of the tile select. */
  21. this.checked = false;
  22. /** The disabled state of the tile select. */
  23. this.disabled = false;
  24. /** The hidden state of the tile select. */
  25. this.hidden = false;
  26. /** Display an interactive radio or checkbox. */
  27. this.inputEnabled = false;
  28. /** The side of the tile that the radio or checkbox appears on when inputEnabled is true. */
  29. this.inputAlignment = "start";
  30. /** The selection mode of the tile select: radio (single) or checkbox (multiple). */
  31. this.type = "radio";
  32. /** specify the width of the tile, defaults to auto */
  33. this.width = "auto";
  34. this.guid = `calcite-tile-select-${guid()}`;
  35. //--------------------------------------------------------------------------
  36. //
  37. // State
  38. //
  39. //--------------------------------------------------------------------------
  40. /** The focused state of the tile-select. */
  41. this.focused = false;
  42. }
  43. checkedChanged(newChecked) {
  44. this.input.checked = newChecked;
  45. }
  46. nameChanged(newName) {
  47. this.input.name = newName;
  48. }
  49. //--------------------------------------------------------------------------
  50. //
  51. // Public Methods
  52. //
  53. //--------------------------------------------------------------------------
  54. /** Sets focus on the component. */
  55. async setFocus() {
  56. this.input.setFocus();
  57. }
  58. //--------------------------------------------------------------------------
  59. //
  60. // Event Listeners
  61. //
  62. //--------------------------------------------------------------------------
  63. checkboxChangeHandler(event) {
  64. const checkbox = event.target;
  65. if (checkbox === this.input) {
  66. this.checked = checkbox.checked;
  67. }
  68. event.stopPropagation();
  69. this.calciteTileSelectChange.emit();
  70. }
  71. checkboxFocusBlurHandler(event) {
  72. const checkbox = event.target;
  73. if (checkbox === this.input) {
  74. this.focused = event.detail;
  75. }
  76. event.stopPropagation();
  77. }
  78. radioButtonChangeHandler(event) {
  79. const radioButton = event.target;
  80. if (radioButton === this.input) {
  81. this.checked = radioButton.checked;
  82. }
  83. event.stopPropagation();
  84. this.calciteTileSelectChange.emit();
  85. }
  86. radioButtonCheckedChangeHandler(event) {
  87. const radioButton = event.target;
  88. if (radioButton === this.input) {
  89. this.checked = radioButton.checked;
  90. }
  91. event.stopPropagation();
  92. }
  93. radioButtonFocusBlurHandler(event) {
  94. const radioButton = event.target;
  95. if (radioButton === this.input) {
  96. this.focused = radioButton.focused;
  97. }
  98. event.stopPropagation();
  99. }
  100. click(event) {
  101. const target = event.target;
  102. const targets = ["calcite-tile", "calcite-tile-select"];
  103. if (targets.includes(target.localName)) {
  104. this.input.click();
  105. }
  106. }
  107. mouseenter() {
  108. if (this.input.localName === "calcite-radio-button") {
  109. this.input.hovered = true;
  110. }
  111. if (this.input.localName === "calcite-checkbox") {
  112. this.input.hovered = true;
  113. }
  114. }
  115. mouseleave() {
  116. if (this.input.localName === "calcite-radio-button") {
  117. this.input.hovered = false;
  118. }
  119. if (this.input.localName === "calcite-checkbox") {
  120. this.input.hovered = false;
  121. }
  122. }
  123. //--------------------------------------------------------------------------
  124. //
  125. // Lifecycle
  126. //
  127. //--------------------------------------------------------------------------
  128. connectedCallback() {
  129. this.renderInput();
  130. }
  131. disconnectedCallback() {
  132. this.input.parentNode.removeChild(this.input);
  133. }
  134. componentDidRender() {
  135. updateHostInteraction(this);
  136. }
  137. // --------------------------------------------------------------------------
  138. //
  139. // Render Methods
  140. //
  141. // --------------------------------------------------------------------------
  142. renderInput() {
  143. this.input = document.createElement(this.type === "radio" ? "calcite-radio-button" : "calcite-checkbox");
  144. this.input.checked = this.checked;
  145. this.input.disabled = this.disabled;
  146. this.input.hidden = this.hidden;
  147. this.input.id = this.guid;
  148. this.input.label = this.heading || this.name || "";
  149. if (this.name) {
  150. this.input.name = this.name;
  151. }
  152. if (this.value) {
  153. this.input.value = this.value != null ? this.value.toString() : "";
  154. }
  155. this.el.insertAdjacentElement("beforeend", this.input);
  156. }
  157. render() {
  158. const { checked, description, disabled, focused, heading, icon, inputAlignment, inputEnabled, width } = this;
  159. return (h("div", { class: {
  160. checked,
  161. container: true,
  162. [CSS.description]: Boolean(description),
  163. [CSS.descriptionOnly]: Boolean(!heading && !icon && description),
  164. disabled,
  165. focused,
  166. [CSS.heading]: Boolean(heading),
  167. [CSS.headingOnly]: heading && !icon && !description,
  168. [CSS.icon]: Boolean(icon),
  169. [CSS.iconOnly]: !heading && icon && !description,
  170. [CSS.inputAlignmentEnd]: inputAlignment === "end",
  171. [CSS.inputAlignmentStart]: inputAlignment === "start",
  172. [CSS.inputEnabled]: inputEnabled,
  173. [CSS.largeVisual]: heading && icon && !description,
  174. [CSS.widthAuto]: width === "auto",
  175. [CSS.widthFull]: width === "full"
  176. } },
  177. h("calcite-tile", { active: checked, description: description, embed: true, heading: heading, icon: icon }),
  178. h("slot", null)));
  179. }
  180. static get is() { return "calcite-tile-select"; }
  181. static get encapsulation() { return "shadow"; }
  182. static get originalStyleUrls() { return {
  183. "$": ["tile-select.scss"]
  184. }; }
  185. static get styleUrls() { return {
  186. "$": ["tile-select.css"]
  187. }; }
  188. static get properties() { return {
  189. "checked": {
  190. "type": "boolean",
  191. "mutable": true,
  192. "complexType": {
  193. "original": "boolean",
  194. "resolved": "boolean",
  195. "references": {}
  196. },
  197. "required": false,
  198. "optional": false,
  199. "docs": {
  200. "tags": [],
  201. "text": "The checked state of the tile select."
  202. },
  203. "attribute": "checked",
  204. "reflect": true,
  205. "defaultValue": "false"
  206. },
  207. "description": {
  208. "type": "string",
  209. "mutable": false,
  210. "complexType": {
  211. "original": "string",
  212. "resolved": "string",
  213. "references": {}
  214. },
  215. "required": false,
  216. "optional": true,
  217. "docs": {
  218. "tags": [],
  219. "text": "The description text that appears beneath the heading of the tile."
  220. },
  221. "attribute": "description",
  222. "reflect": true
  223. },
  224. "disabled": {
  225. "type": "boolean",
  226. "mutable": false,
  227. "complexType": {
  228. "original": "boolean",
  229. "resolved": "boolean",
  230. "references": {}
  231. },
  232. "required": false,
  233. "optional": false,
  234. "docs": {
  235. "tags": [],
  236. "text": "The disabled state of the tile select."
  237. },
  238. "attribute": "disabled",
  239. "reflect": true,
  240. "defaultValue": "false"
  241. },
  242. "heading": {
  243. "type": "string",
  244. "mutable": false,
  245. "complexType": {
  246. "original": "string",
  247. "resolved": "string",
  248. "references": {}
  249. },
  250. "required": false,
  251. "optional": true,
  252. "docs": {
  253. "tags": [],
  254. "text": "The heading text that appears between the icon and description of the tile."
  255. },
  256. "attribute": "heading",
  257. "reflect": true
  258. },
  259. "hidden": {
  260. "type": "boolean",
  261. "mutable": false,
  262. "complexType": {
  263. "original": "boolean",
  264. "resolved": "boolean",
  265. "references": {}
  266. },
  267. "required": false,
  268. "optional": false,
  269. "docs": {
  270. "tags": [],
  271. "text": "The hidden state of the tile select."
  272. },
  273. "attribute": "hidden",
  274. "reflect": true,
  275. "defaultValue": "false"
  276. },
  277. "icon": {
  278. "type": "string",
  279. "mutable": false,
  280. "complexType": {
  281. "original": "string",
  282. "resolved": "string",
  283. "references": {}
  284. },
  285. "required": false,
  286. "optional": true,
  287. "docs": {
  288. "tags": [],
  289. "text": "The icon that appears at the top of the tile."
  290. },
  291. "attribute": "icon",
  292. "reflect": true
  293. },
  294. "name": {
  295. "type": "any",
  296. "mutable": false,
  297. "complexType": {
  298. "original": "any",
  299. "resolved": "any",
  300. "references": {}
  301. },
  302. "required": false,
  303. "optional": false,
  304. "docs": {
  305. "tags": [],
  306. "text": "The name of the tile select. This name will appear in form submissions as either a radio or checkbox identifier based on the `type` property."
  307. },
  308. "attribute": "name",
  309. "reflect": true
  310. },
  311. "inputEnabled": {
  312. "type": "boolean",
  313. "mutable": false,
  314. "complexType": {
  315. "original": "boolean",
  316. "resolved": "boolean",
  317. "references": {}
  318. },
  319. "required": false,
  320. "optional": false,
  321. "docs": {
  322. "tags": [],
  323. "text": "Display an interactive radio or checkbox."
  324. },
  325. "attribute": "input-enabled",
  326. "reflect": true,
  327. "defaultValue": "false"
  328. },
  329. "inputAlignment": {
  330. "type": "string",
  331. "mutable": false,
  332. "complexType": {
  333. "original": "Extract<\"end\" | \"start\", Alignment>",
  334. "resolved": "\"end\" | \"start\"",
  335. "references": {
  336. "Extract": {
  337. "location": "global"
  338. },
  339. "Alignment": {
  340. "location": "import",
  341. "path": "../interfaces"
  342. }
  343. }
  344. },
  345. "required": false,
  346. "optional": false,
  347. "docs": {
  348. "tags": [],
  349. "text": "The side of the tile that the radio or checkbox appears on when inputEnabled is true."
  350. },
  351. "attribute": "input-alignment",
  352. "reflect": true,
  353. "defaultValue": "\"start\""
  354. },
  355. "type": {
  356. "type": "string",
  357. "mutable": false,
  358. "complexType": {
  359. "original": "TileSelectType",
  360. "resolved": "\"checkbox\" | \"radio\"",
  361. "references": {
  362. "TileSelectType": {
  363. "location": "import",
  364. "path": "./interfaces"
  365. }
  366. }
  367. },
  368. "required": false,
  369. "optional": false,
  370. "docs": {
  371. "tags": [],
  372. "text": "The selection mode of the tile select: radio (single) or checkbox (multiple)."
  373. },
  374. "attribute": "type",
  375. "reflect": true,
  376. "defaultValue": "\"radio\""
  377. },
  378. "value": {
  379. "type": "any",
  380. "mutable": false,
  381. "complexType": {
  382. "original": "any",
  383. "resolved": "any",
  384. "references": {}
  385. },
  386. "required": false,
  387. "optional": true,
  388. "docs": {
  389. "tags": [],
  390. "text": "The value of the tile select. This value will appear in form submissions when this tile select is checked."
  391. },
  392. "attribute": "value",
  393. "reflect": false
  394. },
  395. "width": {
  396. "type": "string",
  397. "mutable": false,
  398. "complexType": {
  399. "original": "Extract<\"auto\" | \"full\", Width>",
  400. "resolved": "\"auto\" | \"full\"",
  401. "references": {
  402. "Extract": {
  403. "location": "global"
  404. },
  405. "Width": {
  406. "location": "import",
  407. "path": "../interfaces"
  408. }
  409. }
  410. },
  411. "required": false,
  412. "optional": false,
  413. "docs": {
  414. "tags": [],
  415. "text": "specify the width of the tile, defaults to auto"
  416. },
  417. "attribute": "width",
  418. "reflect": true,
  419. "defaultValue": "\"auto\""
  420. }
  421. }; }
  422. static get states() { return {
  423. "focused": {}
  424. }; }
  425. static get events() { return [{
  426. "method": "calciteTileSelectChange",
  427. "name": "calciteTileSelectChange",
  428. "bubbles": true,
  429. "cancelable": true,
  430. "composed": true,
  431. "docs": {
  432. "tags": [],
  433. "text": "Emits a custom change event. For checkboxes, it emits when the checkbox is checked or unchecked. For radios it only emits when it is checked."
  434. },
  435. "complexType": {
  436. "original": "any",
  437. "resolved": "any",
  438. "references": {}
  439. }
  440. }]; }
  441. static get methods() { return {
  442. "setFocus": {
  443. "complexType": {
  444. "signature": "() => Promise<void>",
  445. "parameters": [],
  446. "references": {
  447. "Promise": {
  448. "location": "global"
  449. }
  450. },
  451. "return": "Promise<void>"
  452. },
  453. "docs": {
  454. "text": "Sets focus on the component.",
  455. "tags": []
  456. }
  457. }
  458. }; }
  459. static get elementRef() { return "el"; }
  460. static get watchers() { return [{
  461. "propName": "checked",
  462. "methodName": "checkedChanged"
  463. }, {
  464. "propName": "name",
  465. "methodName": "nameChanged"
  466. }]; }
  467. static get listeners() { return [{
  468. "name": "calciteCheckboxChange",
  469. "method": "checkboxChangeHandler",
  470. "target": undefined,
  471. "capture": false,
  472. "passive": false
  473. }, {
  474. "name": "calciteInternalCheckboxFocus",
  475. "method": "checkboxFocusBlurHandler",
  476. "target": undefined,
  477. "capture": false,
  478. "passive": false
  479. }, {
  480. "name": "calciteInternalCheckboxBlur",
  481. "method": "checkboxFocusBlurHandler",
  482. "target": undefined,
  483. "capture": false,
  484. "passive": false
  485. }, {
  486. "name": "calciteRadioButtonChange",
  487. "method": "radioButtonChangeHandler",
  488. "target": undefined,
  489. "capture": false,
  490. "passive": false
  491. }, {
  492. "name": "calciteInternalRadioButtonCheckedChange",
  493. "method": "radioButtonCheckedChangeHandler",
  494. "target": undefined,
  495. "capture": false,
  496. "passive": false
  497. }, {
  498. "name": "calciteInternalRadioButtonFocus",
  499. "method": "radioButtonFocusBlurHandler",
  500. "target": undefined,
  501. "capture": false,
  502. "passive": false
  503. }, {
  504. "name": "calciteInternalRadioButtonBlur",
  505. "method": "radioButtonFocusBlurHandler",
  506. "target": undefined,
  507. "capture": false,
  508. "passive": false
  509. }, {
  510. "name": "click",
  511. "method": "click",
  512. "target": undefined,
  513. "capture": false,
  514. "passive": false
  515. }, {
  516. "name": "mouseenter",
  517. "method": "mouseenter",
  518. "target": undefined,
  519. "capture": false,
  520. "passive": true
  521. }, {
  522. "name": "mouseleave",
  523. "method": "mouseleave",
  524. "target": undefined,
  525. "capture": false,
  526. "passive": true
  527. }]; }
  528. }