block-section.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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, Prop, h, Host } from "@stencil/core";
  7. import { getElementDir, toAriaBoolean } from "../../utils/dom";
  8. import { CSS, ICONS, TEXT } from "./resources";
  9. import { guid } from "../../utils/guid";
  10. /**
  11. * @slot - A slot for adding content to the block section.
  12. */
  13. export class BlockSection {
  14. constructor() {
  15. /**
  16. * When true, the block's section content will be displayed.
  17. */
  18. this.open = false;
  19. /**
  20. * This property determines the look of the section toggle.
  21. * If the value is "switch", a toggle-switch will be displayed.
  22. * If the value is "button", a clickable header is displayed.
  23. */
  24. this.toggleDisplay = "button";
  25. this.guid = guid();
  26. // --------------------------------------------------------------------------
  27. //
  28. // Private Methods
  29. //
  30. // --------------------------------------------------------------------------
  31. this.handleHeaderKeyDown = (event) => {
  32. if (event.key === " " || event.key === "Enter") {
  33. this.toggleSection();
  34. event.preventDefault();
  35. event.stopPropagation();
  36. }
  37. };
  38. this.toggleSection = () => {
  39. this.open = !this.open;
  40. this.calciteBlockSectionToggle.emit();
  41. };
  42. }
  43. // --------------------------------------------------------------------------
  44. //
  45. // Render Methods
  46. //
  47. // --------------------------------------------------------------------------
  48. renderStatusIcon() {
  49. var _a;
  50. const { status } = this;
  51. const statusIcon = (_a = ICONS[status]) !== null && _a !== void 0 ? _a : false;
  52. const statusIconClasses = {
  53. [CSS.statusIcon]: true,
  54. [CSS.valid]: status == "valid",
  55. [CSS.invalid]: status == "invalid"
  56. };
  57. return !!statusIcon ? (h("calcite-icon", { class: statusIconClasses, icon: statusIcon, scale: "s" })) : null;
  58. }
  59. render() {
  60. const { el, intlCollapse, intlExpand, open, text, toggleDisplay } = this;
  61. const dir = getElementDir(el);
  62. const arrowIcon = open
  63. ? ICONS.menuOpen
  64. : dir === "rtl"
  65. ? ICONS.menuClosedLeft
  66. : ICONS.menuClosedRight;
  67. const toggleLabel = open ? intlCollapse || TEXT.collapse : intlExpand || TEXT.expand;
  68. const { guid } = this;
  69. const regionId = `${guid}-region`;
  70. const buttonId = `${guid}-button`;
  71. const headerNode = toggleDisplay === "switch" ? (h("div", { "aria-controls": regionId, "aria-label": toggleLabel, class: {
  72. [CSS.toggle]: true,
  73. [CSS.toggleSwitch]: true
  74. }, id: buttonId, onClick: this.toggleSection, onKeyDown: this.handleHeaderKeyDown, tabIndex: 0, title: toggleLabel },
  75. h("div", { class: CSS.toggleSwitchContent },
  76. h("span", { class: CSS.toggleSwitchText }, text)),
  77. h("calcite-switch", { checked: open, label: toggleLabel, scale: "s", tabIndex: -1 }),
  78. this.renderStatusIcon())) : (h("button", { "aria-controls": regionId, "aria-label": toggleLabel, class: {
  79. [CSS.sectionHeader]: true,
  80. [CSS.toggle]: true
  81. }, id: buttonId, name: toggleLabel, onClick: this.toggleSection },
  82. h("calcite-icon", { icon: arrowIcon, scale: "s" }),
  83. h("span", { class: CSS.sectionHeaderText }, text),
  84. this.renderStatusIcon()));
  85. return (h(Host, null,
  86. headerNode,
  87. h("section", { "aria-expanded": toAriaBoolean(open), "aria-labelledby": buttonId, class: CSS.content, hidden: !open, id: regionId },
  88. h("slot", null))));
  89. }
  90. static get is() { return "calcite-block-section"; }
  91. static get encapsulation() { return "shadow"; }
  92. static get originalStyleUrls() { return {
  93. "$": ["block-section.scss"]
  94. }; }
  95. static get styleUrls() { return {
  96. "$": ["block-section.css"]
  97. }; }
  98. static get properties() { return {
  99. "intlCollapse": {
  100. "type": "string",
  101. "mutable": false,
  102. "complexType": {
  103. "original": "string",
  104. "resolved": "string",
  105. "references": {}
  106. },
  107. "required": false,
  108. "optional": true,
  109. "docs": {
  110. "tags": [],
  111. "text": "Tooltip used for the toggle when expanded."
  112. },
  113. "attribute": "intl-collapse",
  114. "reflect": false
  115. },
  116. "intlExpand": {
  117. "type": "string",
  118. "mutable": false,
  119. "complexType": {
  120. "original": "string",
  121. "resolved": "string",
  122. "references": {}
  123. },
  124. "required": false,
  125. "optional": true,
  126. "docs": {
  127. "tags": [],
  128. "text": "Tooltip used for the toggle when collapsed."
  129. },
  130. "attribute": "intl-expand",
  131. "reflect": false
  132. },
  133. "open": {
  134. "type": "boolean",
  135. "mutable": true,
  136. "complexType": {
  137. "original": "boolean",
  138. "resolved": "boolean",
  139. "references": {}
  140. },
  141. "required": false,
  142. "optional": false,
  143. "docs": {
  144. "tags": [],
  145. "text": "When true, the block's section content will be displayed."
  146. },
  147. "attribute": "open",
  148. "reflect": true,
  149. "defaultValue": "false"
  150. },
  151. "status": {
  152. "type": "string",
  153. "mutable": false,
  154. "complexType": {
  155. "original": "Status",
  156. "resolved": "\"idle\" | \"invalid\" | \"valid\"",
  157. "references": {
  158. "Status": {
  159. "location": "import",
  160. "path": "../interfaces"
  161. }
  162. }
  163. },
  164. "required": false,
  165. "optional": true,
  166. "docs": {
  167. "tags": [],
  168. "text": "BlockSection status. Adds indicator to show valid or invalid status."
  169. },
  170. "attribute": "status",
  171. "reflect": true
  172. },
  173. "text": {
  174. "type": "string",
  175. "mutable": false,
  176. "complexType": {
  177. "original": "string",
  178. "resolved": "string",
  179. "references": {}
  180. },
  181. "required": false,
  182. "optional": false,
  183. "docs": {
  184. "tags": [],
  185. "text": "Text displayed in the button."
  186. },
  187. "attribute": "text",
  188. "reflect": false
  189. },
  190. "toggleDisplay": {
  191. "type": "string",
  192. "mutable": false,
  193. "complexType": {
  194. "original": "BlockSectionToggleDisplay",
  195. "resolved": "\"button\" | \"switch\"",
  196. "references": {
  197. "BlockSectionToggleDisplay": {
  198. "location": "import",
  199. "path": "./interfaces"
  200. }
  201. }
  202. },
  203. "required": false,
  204. "optional": false,
  205. "docs": {
  206. "tags": [],
  207. "text": "This property determines the look of the section toggle.\nIf the value is \"switch\", a toggle-switch will be displayed.\nIf the value is \"button\", a clickable header is displayed."
  208. },
  209. "attribute": "toggle-display",
  210. "reflect": true,
  211. "defaultValue": "\"button\""
  212. }
  213. }; }
  214. static get events() { return [{
  215. "method": "calciteBlockSectionToggle",
  216. "name": "calciteBlockSectionToggle",
  217. "bubbles": true,
  218. "cancelable": true,
  219. "composed": true,
  220. "docs": {
  221. "tags": [],
  222. "text": "Emitted when the header has been clicked."
  223. },
  224. "complexType": {
  225. "original": "any",
  226. "resolved": "any",
  227. "references": {}
  228. }
  229. }]; }
  230. static get elementRef() { return "el"; }
  231. }