Packages
noora
0.85.0
0.85.0
0.84.1
0.84.0
0.83.2
0.83.1
0.83.0
0.82.7
0.82.6
0.82.5
0.82.4
0.82.3
0.82.2
0.82.1
0.82.0
0.81.4
0.81.3
0.81.2
0.81.1
0.81.0
0.80.1
0.80.0
0.79.1
0.79.0
0.78.1
0.78.0
0.77.4
0.77.3
0.77.2
0.77.1
0.77.0
0.76.0
0.75.0
0.74.0
0.73.0
0.72.0
0.71.0
0.70.0
0.69.1
0.69.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.2
0.64.1
0.64.0
0.63.2
0.63.1
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.0
0.54.0
0.53.1
0.53.0
0.52.1
0.52.0
0.51.0
0.50.1
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.3
0.44.2
0.44.1
0.44.0
0.43.0
0.42.0
0.41.0
0.40.6
0.40.5
0.40.4
0.40.3
0.40.2
0.40.1
0.40.0
0.39.1
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.1
0.32.0
0.31.0
0.30.0
0.29.2
0.29.1
0.29.0
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.0
0.1.0
0.1.0-rc.2
0.1.0-rc.1
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
A component library for Phoenix LiveView applications
Current section
Files
Jump to
Current section
Files
js/web-components/Badge.js
import { LitElement, css, html, unsafeCSS } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
import badgeStyles from "../../css/badge.css";
import badgeContract from "../../components/badge.json";
import {
contractAttribute,
contractProperties,
initializeContractDefaults,
resolveContractValue,
} from "./Contract.js";
const appearanceAttribute = contractAttribute(badgeContract, "appearance");
const colorAttribute = contractAttribute(badgeContract, "color");
const sizeAttribute = contractAttribute(badgeContract, "size");
export class NooraBadge extends LitElement {
static properties = {
...contractProperties(badgeContract),
_hasIcon: { state: true },
};
static styles = [
unsafeCSS(badgeStyles),
css`
slot[name="icon"]::slotted(svg) {
width: 100%;
height: 100%;
pointer-events: none;
}
`,
];
constructor() {
super();
initializeContractDefaults(this, badgeContract);
this._hasIcon = false;
}
updated() {
this.#synchronizeIconState(
this.renderRoot.querySelector('slot[name="icon"]'),
);
}
render() {
const showDot = this.dot && !this._hasIcon;
const showIcon = this._hasIcon || showDot;
return html`
<span
class=${badgeContract.className}
part="badge"
data-style=${this.#appearance()}
data-color=${this.#color()}
data-size=${this.#size()}
?data-disabled=${this.disabled}
?data-dot=${showDot}
?data-icon=${this._hasIcon}
?data-icon-only=${this.iconOnly}
aria-label=${ifDefined(this._ariaLabel)}
>
<span data-part="icon" part="icon" ?hidden=${!showIcon}>
<slot name="icon" @slotchange=${this.#handleIconSlotChange}></slot>
${showDot ? this.#dot() : null}
</span>
<span data-part="label" part="label" ?hidden=${this.iconOnly}>
<slot>${this.label}</slot>
</span>
</span>
`;
}
#appearance() {
return resolveContractValue(this.appearance, appearanceAttribute);
}
#color() {
return resolveContractValue(this.color, colorAttribute);
}
#dot() {
if (this.#size() === "small") {
return html`
<svg
aria-hidden="true"
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
>
<rect x="4" y="4" width="4" height="4" rx="1" fill="#FDFDFD"></rect>
</svg>
`;
}
return html`
<svg
aria-hidden="true"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
>
<rect
x="5"
y="5"
width="6"
height="6"
rx="1.33333"
fill="currentColor"
></rect>
</svg>
`;
}
#handleIconSlotChange(event) {
this.#synchronizeIconState(event.currentTarget);
}
#size() {
return resolveContractValue(this.size, sizeAttribute);
}
#synchronizeIconState(slot) {
const hasIcon = slot.assignedElements({ flatten: true }).length > 0;
if (hasIcon !== this._hasIcon) {
this._hasIcon = hasIcon;
}
}
}
export function registerNooraBadge() {
if (!customElements.get(badgeContract.tagName)) {
customElements.define(badgeContract.tagName, NooraBadge);
}
}