@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
280 lines (279 loc) • 9.11 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 { h } from "@stencil/core";
import { connectConditionalSlotComponent, disconnectConditionalSlotComponent } from "../../utils/conditionalSlot";
import { getSlotted, toAriaBoolean } from "../../utils/dom";
import { connectLocalized, disconnectLocalized } from "../../utils/locale";
import { connectMessages, disconnectMessages, setUpMessages, updateMessages } from "../../utils/t9n";
import { CSS, SLOTS } from "./resources";
/**
* Cards do not include a grid or bounding container
* - cards will expand to fit the width of their container
*/
/**
* @slot - A slot for adding subheader/description content.
* @slot thumbnail - A slot for adding a thumbnail to the component.
* @slot title - A slot for adding a title.
* @slot subtitle - A slot for adding a subtitle or short summary.
* @slot footer-start - A slot for adding a leading footer.
* @slot footer-end - A slot for adding a trailing footer.
*/
export class Card {
constructor() {
//--------------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------------
this.cardSelectClick = () => {
this.selectCard();
};
this.cardSelectKeyDown = (event) => {
switch (event.key) {
case " ":
case "Enter":
this.selectCard();
event.preventDefault();
break;
}
};
this.loading = false;
this.selected = false;
this.selectable = false;
this.thumbnailPosition = "block-start";
this.messages = undefined;
this.messageOverrides = undefined;
this.effectiveLocale = undefined;
this.defaultMessages = undefined;
}
onMessagesChange() {
/* wired up by t9n util */
}
// --------------------------------------------------------------------------
//
// Lifecycle
//
// --------------------------------------------------------------------------
connectedCallback() {
connectConditionalSlotComponent(this);
connectLocalized(this);
connectMessages(this);
}
disonnectedCallback() {
disconnectConditionalSlotComponent(this);
disconnectLocalized(this);
disconnectMessages(this);
}
async componentWillLoad() {
await setUpMessages(this);
}
render() {
const thumbnailInline = this.thumbnailPosition.startsWith("inline");
const thumbnailStart = this.thumbnailPosition.endsWith("start");
return (h("div", { class: { "calcite-card-container": true, inline: thumbnailInline } }, this.loading ? (h("div", { class: "calcite-card-loader-container" }, h("calcite-loader", { label: this.messages.loading }))) : null, thumbnailStart && this.renderThumbnail(), h("section", { "aria-busy": toAriaBoolean(this.loading), class: { [CSS.container]: true } }, this.selectable ? this.renderCheckbox() : null, this.renderHeader(), h("div", { class: "card-content" }, h("slot", null)), this.renderFooter()), !thumbnailStart && this.renderThumbnail()));
}
effectiveLocaleChange() {
updateMessages(this, this.effectiveLocale);
}
selectCard() {
this.selected = !this.selected;
this.calciteCardSelect.emit();
}
renderThumbnail() {
return getSlotted(this.el, SLOTS.thumbnail) ? (h("section", { class: CSS.thumbnailWrapper }, h("slot", { name: SLOTS.thumbnail }))) : null;
}
renderCheckbox() {
return (h("calcite-label", { class: CSS.checkboxWrapper, onClick: this.cardSelectClick, onKeyDown: this.cardSelectKeyDown }, h("calcite-checkbox", { checked: this.selected, label: this.messages.select })));
}
renderHeader() {
const { el } = this;
const title = getSlotted(el, SLOTS.title);
const subtitle = getSlotted(el, SLOTS.subtitle);
const hasHeader = title || subtitle;
return hasHeader ? (h("header", { class: CSS.header }, h("slot", { name: SLOTS.title }), h("slot", { name: SLOTS.subtitle }))) : null;
}
renderFooter() {
const { el } = this;
const startFooter = getSlotted(el, SLOTS.footerStart);
const endFooter = getSlotted(el, SLOTS.footerEnd);
const hasFooter = startFooter || endFooter;
return hasFooter ? (h("footer", { class: CSS.footer }, h("slot", { name: SLOTS.footerStart }), h("slot", { name: SLOTS.footerEnd }))) : null;
}
static get is() { return "calcite-card"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["card.scss"]
};
}
static get styleUrls() {
return {
"$": ["card.css"]
};
}
static get assetsDirs() { return ["assets"]; }
static get properties() {
return {
"loading": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, a busy indicator is displayed."
},
"attribute": "loading",
"reflect": true,
"defaultValue": "false"
},
"selected": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, the component is selected."
},
"attribute": "selected",
"reflect": true,
"defaultValue": "false"
},
"selectable": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "When `true`, the component is selectable."
},
"attribute": "selectable",
"reflect": true,
"defaultValue": "false"
},
"thumbnailPosition": {
"type": "string",
"mutable": false,
"complexType": {
"original": "LogicalFlowPosition",
"resolved": "\"block-end\" | \"block-start\" | \"inline-end\" | \"inline-start\"",
"references": {
"LogicalFlowPosition": {
"location": "import",
"path": "../interfaces"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets the placement of the thumbnail defined in the `thumbnail` slot."
},
"attribute": "thumbnail-position",
"reflect": true,
"defaultValue": "\"block-start\""
},
"messages": {
"type": "unknown",
"mutable": true,
"complexType": {
"original": "CardMessages",
"resolved": "{ select: string; deselect: string; loading: string; }",
"references": {
"CardMessages": {
"location": "import",
"path": "./assets/card/t9n"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "internal",
"text": undefined
}],
"text": "Made into a prop for testing purposes only"
}
},
"messageOverrides": {
"type": "unknown",
"mutable": true,
"complexType": {
"original": "Partial<CardMessages>",
"resolved": "{ select?: string; deselect?: string; loading?: string; }",
"references": {
"Partial": {
"location": "global"
},
"CardMessages": {
"location": "import",
"path": "./assets/card/t9n"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Use this property to override individual strings used by the component."
}
}
};
}
static get states() {
return {
"effectiveLocale": {},
"defaultMessages": {}
};
}
static get events() {
return [{
"method": "calciteCardSelect",
"name": "calciteCardSelect",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Fires when `selectable` is `true` and the component is selected."
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}];
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "messageOverrides",
"methodName": "onMessagesChange"
}, {
"propName": "effectiveLocale",
"methodName": "effectiveLocaleChange"
}];
}
}