/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import module = require('module');
import {html, css, unsafeCSS, LitElement, TemplateResult, CSSResult} from 'lit';
import {customElement, property} from 'lit/decorators';
import {unsafeHTML} from 'lit/directives/unsafe-html';
import {until} from 'lit/directives/until';
import {Sizes, States, MarkupIdentifiers} from '../Enum/IconTypes';
import Icons = require('../Icons');
import 'TYPO3/CMS/Backend/Element/SpinnerElement';
const iconUnifyModifier = 0.86;
const iconSize = (identifier: CSSResult, size: number) => css`
:host([size=${identifier}]),
:host([raw]) .icon-size-${identifier} {
font-size: ${size}px;
}
`;
/**
* Module: TYPO3/CMS/Backend/Element/IconElement
*
* @example
*
*/
@customElement('typo3-backend-icon')
export class IconElement extends LitElement {
@property({type: String}) identifier: string;
@property({type: String, reflect: true}) size: Sizes = Sizes.default;
@property({type: String}) state: States = States.default;
@property({type: String}) overlay: string = null;
@property({type: String}) markup: MarkupIdentifiers = MarkupIdentifiers.inline;
/**
* @internal Usage of `raw` attribute is discouraged due to security implications.
*
* The `raw` attribute value will be rendered unescaped into DOM as raw html (.innerHTML = raw).
* That means it is the responsibility of the callee to ensure the HTML string does not contain
* user supplied strings.
* This attribute should therefore only be used to preserve backwards compatibility,
* and must not be used in new code or with user supplied strings.
* Use `identifier` attribute if ever possible instead.
*/
@property({type: String}) raw?: string = null;
static styles = [
css`
:host {
display: flex;
font-size: 1em;
width: 1em;
height: 1em;
line-height: 0;
}
typo3-backend-spinner {
font-size: 1em;
}
.icon {
position: relative;
display: block;
overflow: hidden;
white-space: nowrap;
height: 1em;
width: 1em;
line-height: 1;
}
.icon svg,
.icon img {
display: block;
height: 1em;
width: 1em;
transform: translate3d(0, 0, 0);
}
.icon * {
display: block;
line-height: inherit;
}
.icon-markup {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.icon-overlay {
position: absolute;
bottom: 0;
right: 0;
font-size: 0.6875em;
text-align: center;
}
.icon-color {
fill: currentColor;
}
.icon-state-disabled .icon-markup {
opacity: .5;
}
.icon-unify {
font-size: ${iconUnifyModifier}em;
line-height: ${1 / iconUnifyModifier};
}
.icon-spin .icon-markup {
animation: icon-spin 2s infinite linear;
}
@keyframes icon-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`,
iconSize(unsafeCSS(Sizes.small), 16),
iconSize(unsafeCSS(Sizes.default), 32),
iconSize(unsafeCSS(Sizes.large), 48),
iconSize(unsafeCSS(Sizes.mega), 64),
];
public render(): TemplateResult {
if (this.raw) {
return html`${unsafeHTML(this.raw)}`;
}
if (!this.identifier) {
return html``;
}
const icon = Icons.getIcon(this.identifier, this.size, this.overlay, this.state, this.markup)
.then((markup: string) => {
return html`
${unsafeHTML(markup)}
`;
});
return html`${until(icon, html``)}`;
}
}