ExamplesPlaygroundReference Source

coral-spectrum/coral-component-shell/src/scripts/Shell.js

  1. /**
  2. * Copyright 2019 Adobe. All rights reserved.
  3. * This file is licensed to you under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License. You may obtain a copy
  5. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. *
  7. * Unless required by applicable law or agreed to in writing, software distributed under
  8. * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
  9. * OF ANY KIND, either express or implied. See the License for the specific language
  10. * governing permissions and limitations under the License.
  11. */
  12.  
  13. import {BaseComponent} from '../../../coral-base-component';
  14. import {Collection} from '../../../coral-collection';
  15.  
  16. const CLASSNAME = '_coral-Shell';
  17.  
  18. /**
  19. @class Coral.Shell
  20. @classdesc The Shell base component to be used with its family for console like applications. See examples for how to
  21. integrate all Shell sub components.
  22. @htmltag coral-shell
  23. @extends {HTMLElement}
  24. @extends {BaseComponent}
  25. */
  26. class Shell extends BaseComponent(HTMLElement) {
  27. /** @ignore */
  28. constructor() {
  29. super();
  30.  
  31. // Prepare templates
  32. this._elements = {
  33. // Fetch or create the content zone elements
  34. header: this.querySelector('coral-shell-header') || document.createElement('coral-shell-header'),
  35. content: this.querySelector('coral-shell-content') || document.createElement('coral-shell-content')
  36. };
  37. }
  38.  
  39. /**
  40. The menu collection.
  41.  
  42. @type {Collection}
  43. @readonly
  44. */
  45. get menus() {
  46. // Construct the collection on first request:
  47. if (!this._menus) {
  48. this._menus = new Collection({
  49. host: this,
  50. itemTagName: 'coral-shell-menu'
  51. });
  52. }
  53.  
  54. return this._menus;
  55. }
  56.  
  57. /**
  58. The shell header zone.
  59.  
  60. @type {ShellHeader}
  61. @contentzone
  62. */
  63. get header() {
  64. return this._getContentZone(this._elements.header);
  65. }
  66.  
  67. set header(value) {
  68. this._setContentZone('header', value, {
  69. handle: 'header',
  70. tagName: 'coral-shell-header',
  71. insert: function (header) {
  72. this.insertBefore(header, this.firstChild);
  73. }
  74. });
  75. }
  76.  
  77. /**
  78. The shell content zone.
  79.  
  80. @type {ShellContent}
  81. @contentzone
  82. */
  83. get content() {
  84. return this._getContentZone(this._elements.content);
  85. }
  86.  
  87. set content(value) {
  88. this._setContentZone('content', value, {
  89. handle: 'content',
  90. tagName: 'coral-shell-content',
  91. insert: function (content) {
  92. this.appendChild(content);
  93. }
  94. });
  95. }
  96.  
  97. get _contentZones() {
  98. return {
  99. 'coral-shell-header': 'header',
  100. 'coral-shell-content': 'content'
  101. };
  102. }
  103.  
  104. /** @ignore */
  105. render() {
  106. super.render();
  107.  
  108. this.classList.add(CLASSNAME);
  109.  
  110. const header = this._elements.header;
  111. const menus = this.menus.getAll();
  112. const content = this._elements.content;
  113.  
  114. // If the the content zone is not provided, we need to make sure that it holds all children
  115. if (!content.parentNode) {
  116. // Remove header
  117. if (header.parentNode) {
  118. header.parentNode.removeChild(header);
  119. }
  120.  
  121. // Remove menus
  122. this.menus.clear();
  123.  
  124. // Move the rest into content
  125. while (this.firstChild) {
  126. content.appendChild(this.firstChild);
  127. }
  128. }
  129.  
  130. // Call the content zone insert
  131. this.header = header;
  132. menus.forEach((menu) => this.menus.add(menu));
  133. this.content = content;
  134. }
  135. }
  136.  
  137. export default Shell;