@postnord/web-components
Version:
PostNord Web Components
393 lines (392 loc) • 15.7 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { Host, h } from "@stencil/core";
import { arrow_right, open_in_new } from "pn-design-assets/pn-assets/icons.js";
import { ripple, uuidv4 } from "../../../index";
/**
* The card component is more than just a navigational element.
* It is a flexible component that can be used as a product item, a clickable link card, etc...
*
* Setting the `href` prop will transform the entire `pn-card` into a clickable element.
* If you need content to be interactable inside the card, do not use the `href` prop.
*
* @slot - The default slot is the primary content of the card. This is the same area where the `text` prop is located.
* @slot image - Set a custom image/svg/illustration. Simply use an `img` tag with the slot "image".
* @slot tags - Add `pn-tags` that will be positioned above the `label` and `overline` if used.
* @slot header - The header content, same area that the `label` and `overline` props will appear.
* @slot navigation - This slot is intended for one or more `pn-button` components.
* Only use **without** the `href` prop. Having both at the same time makes the component inaccessible.
*/
export class PnCard {
constructor() {
this.visibleOutline = false;
this.label = undefined;
this.labelTag = 'h3';
this.overline = undefined;
this.text = undefined;
this.cardId = null;
this.horizontal = false;
this.reverse = false;
this.aspectRatio = '';
this.href = undefined;
this.hrefLabel = undefined;
this.target = undefined;
this.rel = 'noopener noreferrer';
this.icon = null;
}
id = `pn-card-${uuidv4()}`;
idTitle = `${this.id}-title`;
hostElement;
watchCardId() {
const id = this.cardId || this.id;
this.idTitle = `${id}-title`;
}
/** Emitted when you click on the card link (if you use the `href` prop). */
pnCard;
componentWillLoad() {
this.watchCardId();
}
isExternal() {
return this.target === '_blank';
}
showTitle() {
return !!this.label;
}
showHref() {
return !!this.href && (this.hrefLabel || this.showTitle());
}
getTitleId() {
return this.hrefLabel ? null : this.idTitle;
}
getLabelledby() {
return this.hrefLabel ? null : this.showTitle() ? this.idTitle : null;
}
getIcon() {
if (!!this.icon)
return this.icon;
return this.isExternal() ? open_in_new : arrow_right;
}
getHeadingTag() {
const tags = ['h2', 'h3', 'h4', 'h5', 'h6', 'p'];
return tags.includes(this.labelTag) ? this.labelTag : 'h3';
}
handleFocus({ type, target }) {
this.visibleOutline = type === 'focus' && target.matches(':focus-visible');
}
handleClick(event) {
ripple(event, this.hostElement, '.pn-card');
this.pnCard.emit({ click: event });
}
render() {
const TitleTag = this.getHeadingTag();
return (h(Host, { key: '4c1a897e5b6fd69663aa076de44231cbde9b85b1' }, h("article", { key: 'a93fb7255cd352eed29814f010f0111eebcf0d46', id: this.cardId, class: "pn-card", "data-link": !!this.href, "data-horizontal": this.horizontal, "data-reverse": this.reverse, "data-focus": this.visibleOutline }, h("div", { key: '1861f3a85267df00d8d974ed2f014fb097288d4c', class: "pn-card-image" }, h("picture", { key: 'd0acfe747efd63762ddb0dd7cbe67baadb7ad4e1', class: "pn-card-picture", style: { '--pn-card-aspect-ratio': this.aspectRatio || 'unset' } }, h("slot", { key: 'e8360ba8b54d5ad376b549189102eb6412fb6a3e', name: "image" }))), h("div", { key: '1b613813ac38d257cd2c64cb3e7f053950b8d58a', class: "pn-card-content" }, h("header", { key: '4048f0f93b62c71f3caa553ba0f217064f1f8b80', class: "pn-card-header" }, h("div", { key: '071f1f13e492909e27aa4fb860c8ba3a9e88efc4', class: "pn-card-tags" }, h("slot", { key: 'bb4ad165fc8443b55784fcad35d8733f89e34b55', name: "tags" })), !!this.overline && h("p", { key: 'c75cfc0045739d7dfa4c2c6aef79dd57d64ccbc1', class: "pn-card-label-overline" }, this.overline), !!this.label && (h(TitleTag, { key: 'e65289e4307c08f8c92e9b83b3981cd8413a63d4', id: this.getTitleId(), class: "pn-card-label" }, this.label)), h("slot", { key: 'd901c192ed2e029f9b2a0a7df421d6c008f80ea6', name: "header" })), h("section", { key: 'da99e7c8a01924e670a9cbee424ac899870c1a8f', class: "pn-card-section" }, !!this.text && h("p", { key: 'c27938d4704111825dca3ab621133bdd99e401f0', class: "pn-card-section-paragraph" }, this.text), h("slot", { key: '6dfd91ac2b404b23522812c22247d01c5da6a557' })), h("nav", { key: '10252f1454848d360a727c2a85b9ab5461d73b0b', class: "pn-card-navigation" }, this.showHref() && (h("a", { key: '82640b1972e9f740694a5c135857e8b3c87e7a2b', class: "pn-card-link", href: this.href, target: this.target, rel: this.rel, "aria-labelledby": this.getLabelledby(), onClick: event => this.handleClick(event), onFocus: event => this.handleFocus(event), onBlur: event => this.handleFocus(event) }, this.hrefLabel, h("pn-icon", { key: '50d3021b2f7f2722426f5299fea249b596e8f28b', color: "blue700", icon: this.getIcon() }))), h("slot", { key: 'be97f6fc934ccd5f55fb577028c52757ada6c128', name: "navigation" }))))));
}
static get is() { return "pn-card"; }
static get originalStyleUrls() {
return {
"$": ["pn-card.scss"]
};
}
static get styleUrls() {
return {
"$": ["pn-card.css"]
};
}
static get properties() {
return {
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Headline of the card. Will act as label for the link if there is no `href-label` set."
},
"attribute": "label",
"reflect": false
},
"labelTag": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p'",
"resolved": "\"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"p\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The label HTML tag. Default is `h3`."
},
"attribute": "label-tag",
"reflect": false,
"defaultValue": "'h3'"
},
"overline": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Set a smaller text above the `label` text."
},
"attribute": "overline",
"reflect": false
},
"text": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Text content of the card."
},
"attribute": "text",
"reflect": false
},
"cardId": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Set a HTML id for the card. Optional and not required."
},
"attribute": "card-id",
"reflect": false,
"defaultValue": "null"
},
"horizontal": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Features"
}],
"text": "Uee the horizontal card layout."
},
"attribute": "horizontal",
"reflect": false,
"defaultValue": "false"
},
"reverse": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Features"
}],
"text": "Reverse the order of which the image will wrap."
},
"attribute": "reverse",
"reflect": false,
"defaultValue": "false"
},
"aspectRatio": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | '3/3' | '16/9'",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "see",
"text": "{@link https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio CSS documentation.}"
}, {
"name": "category",
"text": "Features"
}],
"text": "Select image aspect ratio. Example: '3/3', '16/9'."
},
"attribute": "aspect-ratio",
"reflect": false,
"defaultValue": "''"
},
"href": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Href"
}],
"text": "The card link."
},
"attribute": "href",
"reflect": false
},
"hrefLabel": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Href"
}],
"text": "The link text."
},
"attribute": "href-label",
"reflect": false
},
"target": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Href"
}],
"text": "The target attribute of the link."
},
"attribute": "target",
"reflect": false
},
"rel": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Href"
}],
"text": "The rel attribute of the link."
},
"attribute": "rel",
"reflect": false,
"defaultValue": "'noopener noreferrer'"
},
"icon": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Href"
}],
"text": "The link icon. Defaults to `arrow_right` or `open_in_new` if `target=\"_blank\"`."
},
"attribute": "icon",
"reflect": false,
"defaultValue": "null"
}
};
}
static get states() {
return {
"visibleOutline": {}
};
}
static get events() {
return [{
"method": "pnCard",
"name": "pnCard",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when you click on the card link (if you use the `href` prop)."
},
"complexType": {
"original": "{ click: MouseEvent }",
"resolved": "{ click: MouseEvent; }",
"references": {
"MouseEvent": {
"location": "global",
"id": "global::MouseEvent"
}
}
}
}];
}
static get elementRef() { return "hostElement"; }
static get watchers() {
return [{
"propName": "cardId",
"methodName": "watchCardId"
}];
}
}
//# sourceMappingURL=pn-card.js.map