tab.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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.97
  5. */
  6. import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client/index.js';
  7. import { g as guid } from './guid.js';
  8. import { n as nodeListToArray } from './dom.js';
  9. const tabCss = "@keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in-down{0%{opacity:0;transform:translate3D(0, -5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;transform:translate3D(0, 5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-scale{0%{opacity:0;transform:scale3D(0.95, 0.95, 1)}100%{opacity: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;animation-fill-mode:both;animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{animation-name:in}.calcite-animate__in-down{animation-name:in-down}.calcite-animate__in-up{animation-name:in-up}.calcite-animate__in-scale{animation-name:in-scale}@media (prefers-reduced-motion: reduce){:root{--calcite-internal-duration-factor:0.01}}:root{--calcite-floating-ui-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host([selected]) section,:host([selected]) .container{display:block}:host{display:none;block-size:100%;inline-size:100%}:host([selected]){display:block;block-size:100%;inline-size:100%;overflow:auto}section,.container{display:none;block-size:100%;inline-size:100%}:host([scale=s]){padding-block:0.25rem;font-size:var(--calcite-font-size--2);line-height:1rem}:host([scale=m]){padding-block:0.5rem;font-size:var(--calcite-font-size--1);line-height:1rem}:host([scale=l]){padding-block:0.75rem;font-size:var(--calcite-font-size-0);line-height:1.25rem}";
  10. const Tab = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
  11. constructor() {
  12. super();
  13. this.__registerHost();
  14. this.__attachShadow();
  15. this.calciteInternalTabRegister = createEvent(this, "calciteInternalTabRegister", 6);
  16. /**
  17. * When `true`, the component's contents are selected.
  18. *
  19. * Only one tab can be selected within the `calcite-tabs` parent.
  20. *
  21. * @deprecated Use `selected` instead.
  22. */
  23. this.active = false;
  24. /**
  25. * When `true`, the component's contents are selected.
  26. *
  27. * Only one tab can be selected within the `calcite-tabs` parent.
  28. */
  29. this.selected = false;
  30. /**
  31. * @internal
  32. */
  33. this.scale = "m";
  34. this.guid = `calcite-tab-title-${guid()}`;
  35. }
  36. activeHandler(value) {
  37. this.selected = value;
  38. }
  39. selectedHandler(value) {
  40. this.active = value;
  41. }
  42. //--------------------------------------------------------------------------
  43. //
  44. // Lifecycle
  45. //
  46. //--------------------------------------------------------------------------
  47. render() {
  48. const id = this.el.id || this.guid;
  49. return (h(Host, { "aria-labelledby": this.labeledBy, id: id }, h("div", { class: "container", role: "tabpanel", tabIndex: this.selected ? 0 : -1 }, h("section", null, h("slot", null)))));
  50. }
  51. connectedCallback() {
  52. this.parentTabsEl = this.el.closest("calcite-tabs");
  53. const isSelected = this.selected || this.active;
  54. if (isSelected) {
  55. this.activeHandler(isSelected);
  56. this.selectedHandler(isSelected);
  57. }
  58. }
  59. componentDidLoad() {
  60. this.calciteInternalTabRegister.emit();
  61. }
  62. componentWillRender() {
  63. var _a;
  64. this.scale = (_a = this.parentTabsEl) === null || _a === void 0 ? void 0 : _a.scale;
  65. }
  66. disconnectedCallback() {
  67. var _a;
  68. // Dispatching to body in order to be listened by other elements that are still connected to the DOM.
  69. (_a = document.body) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent("calciteTabUnregister", {
  70. detail: this.el
  71. }));
  72. }
  73. //--------------------------------------------------------------------------
  74. //
  75. // Event Listeners
  76. //
  77. //--------------------------------------------------------------------------
  78. internalTabChangeHandler(event) {
  79. const targetTabsEl = event
  80. .composedPath()
  81. .find((el) => el.tagName === "CALCITE-TABS");
  82. // to allow `<calcite-tabs>` to be nested we need to make sure this
  83. // `calciteTabChange` event was actually fired from a within the same
  84. // `<calcite-tabs>` that is the a parent of this tab.
  85. if (targetTabsEl !== this.parentTabsEl) {
  86. return;
  87. }
  88. if (this.tab) {
  89. this.selected = this.tab === event.detail.tab;
  90. }
  91. else {
  92. this.getTabIndex().then((index) => {
  93. this.selected = index === event.detail.tab;
  94. });
  95. }
  96. event.stopPropagation();
  97. }
  98. //--------------------------------------------------------------------------
  99. //
  100. // Public Methods
  101. //
  102. //--------------------------------------------------------------------------
  103. /**
  104. * Returns the index of the component item within the tab array.
  105. */
  106. async getTabIndex() {
  107. return Array.prototype.indexOf.call(nodeListToArray(this.el.parentElement.children).filter((el) => el.matches("calcite-tab")), this.el);
  108. }
  109. //--------------------------------------------------------------------------
  110. //
  111. // Private Methods
  112. //
  113. //--------------------------------------------------------------------------
  114. /**
  115. * @param tabIds
  116. * @param titleIds
  117. * @internal
  118. */
  119. async updateAriaInfo(tabIds = [], titleIds = []) {
  120. this.labeledBy = titleIds[tabIds.indexOf(this.el.id)] || null;
  121. }
  122. get el() { return this; }
  123. static get watchers() { return {
  124. "active": ["activeHandler"],
  125. "selected": ["selectedHandler"]
  126. }; }
  127. static get style() { return tabCss; }
  128. }, [1, "calcite-tab", {
  129. "tab": [513],
  130. "active": [1540],
  131. "selected": [1540],
  132. "scale": [1537],
  133. "labeledBy": [32],
  134. "getTabIndex": [64],
  135. "updateAriaInfo": [64]
  136. }, [[16, "calciteInternalTabChange", "internalTabChangeHandler"]]]);
  137. function defineCustomElement() {
  138. if (typeof customElements === "undefined") {
  139. return;
  140. }
  141. const components = ["calcite-tab"];
  142. components.forEach(tagName => { switch (tagName) {
  143. case "calcite-tab":
  144. if (!customElements.get(tagName)) {
  145. customElements.define(tagName, Tab);
  146. }
  147. break;
  148. } });
  149. }
  150. defineCustomElement();
  151. export { Tab as T, defineCustomElement as d };