@scania/tegel
Version:
Tegel Design System
344 lines (343 loc) • 13.8 kB
JavaScript
import { h, Host } from "@stencil/core";
import generateUniqueId from "../../utils/generateUniqueId";
import hasSlot from "../../utils/hasSlot";
/**
* @slot header - Slot for the Card header.
* @slot subheader - Slot for the Card subheader.
* @slot thumbnail - Slot for the Card thumbnail.
* @slot body - Slot for the body section of the Card.
* @slot body-image - Slot for the body section of the Card, used for image.
* @slot actions - Slot for the bottom section of the Card, used for buttons .
*/
export class TdsCard {
constructor() {
/** Variant of the Card based on the theme used. */
this.modeVariant = null;
/** Placement of the header */
this.imagePlacement = 'below-header';
/** Divider for the body */
this.bodyDivider = false;
/** Makes the Card clickable. */
this.clickable = false;
this.stretch = false;
/** ID for the Card, must be unique.
*
* **NOTE**: If you're listening for Card events, you need to set this ID yourself to identify the Card,
* as the default ID is random and will be different every time.
*/
this.cardId = generateUniqueId();
/**
* Enables expandable behaviour.
* When true, clicking the header toggles content visibility.
*/
this.expandable = false;
/**
* Tracks the current expanded state when expandable is enabled.
*/
this.expanded = false;
this.toggleExpand = () => {
if (this.expandable) {
this.expanded = !this.expanded;
}
};
this.handleClick = () => {
this.tdsClick.emit({
cardId: this.cardId,
});
};
this.getCardHeader = () => {
const usesHeaderSlot = hasSlot('header', this.host);
const usesSubheaderSlot = hasSlot('subheader', this.host);
const usesThumbnailSlot = hasSlot('thumbnail', this.host);
return (h("div", { class: { 'card-header': true, 'expandable': this.expandable, 'expanded': this.expanded } }, usesThumbnailSlot && h("slot", { name: "thumbnail" }), h("div", { class: "header-subheader", id: `header-${this.cardId}` }, this.header && h("span", { class: "header" }, this.header), usesHeaderSlot && h("slot", { name: "header" }), this.subheader && h("span", { class: "subheader" }, this.subheader), usesSubheaderSlot && h("slot", { name: "subheader" })), this.expandable && (h("tds-button", { type: "button", variant: "ghost", size: "sm", "tds-aria-label": "Toggle card content", "aria-expanded": this.expanded ? 'true' : 'false', onClick: this.toggleExpand }, h("tds-icon", { slot: "icon", size: "16px", name: "chevron_down", svgTitle: "Chevron Down", class: { rotated: this.expanded } })))));
};
this.getCardContent = () => {
const usesBodySlot = hasSlot('body', this.host);
const usesBodyImageSlot = hasSlot('body-image', this.host);
const usesActionsSlot = hasSlot('actions', this.host);
const bodyId = `body-${this.cardId}`;
return (h("div", { class: { stretch: this.stretch }, "aria-describedby": usesBodySlot ? bodyId : null }, this.imagePlacement === 'below-header' && this.getCardHeader(), h("div", { class: "card-body", id: bodyId }, usesBodyImageSlot && h("slot", { name: "body-image" }), this.bodyImg && h("img", { class: "card-body-img", src: this.bodyImg, alt: this.bodyImgAlt }), this.imagePlacement === 'above-header' && this.getCardHeader(), this.bodyDivider && h("tds-divider", null), usesBodySlot && h("slot", { name: "body" })), usesActionsSlot && h("slot", { name: `actions` })));
};
}
render() {
const cardStyle = {
card: true,
clickable: this.clickable,
[this.imagePlacement]: !this.stretch,
[`${this.imagePlacement}-stretch`]: this.stretch,
};
const ariaLabel = this.header ? this.header : `Card ${this.cardId}`;
return (h(Host, { key: 'a02da4f8704ad22664fec6ba0b97421094e4cda0', class: { [`tds-mode-variant-${this.modeVariant}`]: !!this.modeVariant } }, this.clickable ? (h("button", { class: cardStyle, onClick: this.handleClick, "aria-label": ariaLabel, "aria-describedby": `header-${this.cardId}` }, this.getCardContent())) : (h("div", { class: cardStyle }, this.getCardContent()))));
}
static get is() { return "tds-card"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["card.scss"]
};
}
static get styleUrls() {
return {
"$": ["card.css"]
};
}
static get properties() {
return {
"modeVariant": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'primary' | 'secondary' | null",
"resolved": "\"primary\" | \"secondary\" | null",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Variant of the Card based on the theme used."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "mode-variant",
"defaultValue": "null"
},
"imagePlacement": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'above-header' | 'below-header'",
"resolved": "\"above-header\" | \"below-header\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Placement of the header"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "image-placement",
"defaultValue": "'below-header'"
},
"header": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Text in the header"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "header"
},
"subheader": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Subheader text in the header"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "subheader"
},
"bodyImg": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Body image src"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "body-img"
},
"bodyImgAlt": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Alt text for the body image"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "body-img-alt"
},
"bodyDivider": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Divider for the body"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "body-divider",
"defaultValue": "false"
},
"clickable": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Makes the Card clickable."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "clickable",
"defaultValue": "false"
},
"stretch": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "stretch",
"defaultValue": "false"
},
"cardId": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "ID for the Card, must be unique.\n\n**NOTE**: If you're listening for Card events, you need to set this ID yourself to identify the Card,\nas the default ID is random and will be different every time."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "card-id",
"defaultValue": "generateUniqueId()"
},
"expandable": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Enables expandable behaviour.\nWhen true, clicking the header toggles content visibility."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "expandable",
"defaultValue": "false"
},
"expanded": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Tracks the current expanded state when expandable is enabled."
},
"getter": false,
"setter": false,
"reflect": true,
"attribute": "expanded",
"defaultValue": "false"
}
};
}
static get events() {
return [{
"method": "tdsClick",
"name": "tdsClick",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Sends unique Card identifier when the Card is clicked, if clickable=true"
},
"complexType": {
"original": "{\n cardId: string;\n }",
"resolved": "{ cardId: string; }",
"references": {}
}
}];
}
static get elementRef() { return "host"; }
}