@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
157 lines (156 loc) • 6.42 kB
JavaScript
/*!
* All material copyright ESRI, All Rights Reserved, unless otherwise specified.
* See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
* v1.5.0-next.4
*/
import { Fragment, h } from "@stencil/core";
import { connectConditionalSlotComponent, disconnectConditionalSlotComponent } from "../../utils/conditionalSlot";
import { slotChangeGetAssignedElements, slotChangeHasAssignedElement } from "../../utils/dom";
import { CSS, SLOTS } from "./resources";
/**
* @slot - A slot for adding custom content. This content will appear between any leading and trailing panels added to the component, such as a map.
* @slot header - A slot for adding header content. This content will be positioned at the top of the component.
* @slot footer - A slot for adding footer content. This content will be positioned at the bottom of the component.
* @slot panel-start - A slot for adding the starting `calcite-shell-panel`.
* @slot panel-end - A slot for adding the ending `calcite-shell-panel`.
* @slot panel-top - A slot for adding the top `calcite-shell-center-row`.
* @slot panel-bottom - A slot for adding the bottom `calcite-shell-center-row`.
* @slot center-row - [Deprecated] Use the `"panel-bottom"` slot instead. A slot for adding the bottom `calcite-shell-center-row`.
* @slot modals - A slot for adding `calcite-modal` components. When placed in this slot, the modal position will be constrained to the extent of the shell.
* @slot alerts - A slot for adding `calcite-alert` components. When placed in this slot, the alert position will be constrained to the extent of the shell.
*/
export class Shell {
constructor() {
// --------------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------------
this.handleHeaderSlotChange = (event) => {
this.hasHeader = !!slotChangeHasAssignedElement(event);
};
this.handleFooterSlotChange = (event) => {
this.hasFooter = !!slotChangeHasAssignedElement(event);
};
this.handleAlertsSlotChange = (event) => {
this.hasAlerts = !!slotChangeHasAssignedElement(event);
slotChangeGetAssignedElements(event)?.map((el) => {
if (el.nodeName === "CALCITE-ALERT") {
el.slottedInShell = true;
}
});
};
this.handleModalsSlotChange = (event) => {
this.hasModals = !!slotChangeHasAssignedElement(event);
slotChangeGetAssignedElements(event)?.map((el) => {
if (el.nodeName === "CALCITE-MODAL") {
el.slottedInShell = true;
}
});
};
this.contentBehind = false;
this.hasHeader = false;
this.hasFooter = false;
this.hasAlerts = false;
this.hasModals = false;
}
// --------------------------------------------------------------------------
//
// Lifecycle
//
// --------------------------------------------------------------------------
connectedCallback() {
connectConditionalSlotComponent(this);
}
disconnectedCallback() {
disconnectConditionalSlotComponent(this);
}
// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------
renderHeader() {
return (h("div", { hidden: !this.hasHeader }, h("slot", { key: "header", name: SLOTS.header, onSlotchange: this.handleHeaderSlotChange })));
}
renderFooter() {
return (h("div", { class: CSS.footer, hidden: !this.hasFooter, key: "footer" }, h("slot", { name: SLOTS.footer, onSlotchange: this.handleFooterSlotChange })));
}
renderAlerts() {
return (h("div", { hidden: !this.hasAlerts }, h("slot", { key: "alerts", name: SLOTS.alerts, onSlotchange: this.handleAlertsSlotChange })));
}
renderModals() {
return (h("div", { hidden: !this.hasModals }, h("slot", { key: "modals", name: SLOTS.modals, onSlotchange: this.handleModalsSlotChange })));
}
renderContent() {
const defaultSlotNode = h("slot", { key: "default-slot" });
const deprecatedCenterRowSlotNode = (h("slot", { key: "center-row-slot", name: SLOTS.centerRow }));
const panelBottomSlotNode = h("slot", { key: "panel-bottom-slot", name: SLOTS.panelBottom });
const panelTopSlotNode = h("slot", { key: "panel-top-slot", name: SLOTS.panelTop });
const contentContainerKey = "content-container";
const content = !!this.contentBehind
? [
h("div", { class: {
[CSS.content]: true,
[CSS.contentBehind]: true
}, key: contentContainerKey }, defaultSlotNode),
h("div", { class: CSS.contentBehindCenterContent }, panelTopSlotNode, panelBottomSlotNode, deprecatedCenterRowSlotNode)
]
: [
h("div", { class: CSS.content, key: contentContainerKey }, panelTopSlotNode, defaultSlotNode, panelBottomSlotNode, deprecatedCenterRowSlotNode)
];
return content;
}
renderMain() {
return (h("div", { class: CSS.main }, h("slot", { name: SLOTS.panelStart }), this.renderContent(), h("slot", { name: SLOTS.panelEnd })));
}
renderPositionedSlots() {
return (h("div", { class: CSS.positionedSlotWrapper }, this.renderAlerts(), this.renderModals()));
}
render() {
return (h(Fragment, null, this.renderHeader(), this.renderMain(), this.renderFooter(), this.renderPositionedSlots()));
}
static get is() { return "calcite-shell"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["shell.scss"]
};
}
static get styleUrls() {
return {
"$": ["shell.css"]
};
}
static get properties() {
return {
"contentBehind": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Positions the center content behind any `calcite-shell-panel`s."
},
"attribute": "content-behind",
"reflect": true,
"defaultValue": "false"
}
};
}
static get states() {
return {
"hasHeader": {},
"hasFooter": {},
"hasAlerts": {},
"hasModals": {}
};
}
static get elementRef() { return "el"; }
}