Итак, я работаю над очень маленьким веб-компонентом, который станет частью гораздо большей системы проектирования.
Я немного новичок в использовании веб-компонентов, но я знаю, что этот конкретный веб-компонент может использоваться много-много раз в одном макете.
Этот веб-компонент контролирует, насколько вертикальное пространство для размещения любых дочерних компонентов, которые передаются в него.
Анатомия компонента довольно проста:
import { LitElement, html, css, unsafeCSS, property, customElement } from 'lit-element';
export const spacingAmounts = {
'x-small': css`4px`,
'small': css`8px`,
'medium': css`12px`,
'large': css`16px`,
'x-large': css`20px`,
'2x-large': css`30px`,
'3x-large': css`40px`,
'4x-large': css`60px`,
'5x-large': css`90px`,
'6x-large': css`120px`,
};
const createSpacingStyleRules = (direction: 'top' | 'bottom') => {
return Object.keys(spacingAmounts).map(s => {
const amount = spacingAmounts[s];
return css`
:host([${unsafeCSS(direction)}="${unsafeCSS(s)}"]) {
margin-${unsafeCSS(direction)}: ${unsafeCSS(amount)};
}
`;
});
};
@customElement('gu-vertical-space')
export class GuVerticalSpace extends LitElement {
@property() top: string;
@property() bottom: string;
static get styles() {
const styles = [
css`
:host {
display: block;
}
`,
// ----------------------------------------------------------
// @TODO:
// test if it's better performance wise to either:
//
// 1 - generate a verbose list of static styles for
// each instance of gu-vertical-space
// or
// 2 - generate a tiny amount of styles on the fly,
// based on property inputs...
// ----------------------------------------------------------
// ...createSpacingStyleRules('top'),
// ...createSpacingStyleRules('bottom'),
];
return styles;
}
render() {
const styles = [];
if (this.top) {
styles.push(css`
:host([top="${unsafeCSS(this.top)}"]) {
margin-top: ${spacingAmounts[this.top]}
}
`);
}
if (this.bottom) {
styles.push(css`
:host([bottom="${unsafeCSS(this.bottom)}"]) {
margin-bottom: ${spacingAmounts[this.bottom]}
}
`);
}
return html`
<style>${styles}</style>
<slot></slot>
`;
}
}
Здесь есть два подхода для сопоставления предопределенных величин полей с верхней или нижней частью хоста веб-компонента.
В настоящее время активный подход состоит в том, чтобы просто динамически генерировать блок <style>
внутри функции рендеринга, который содержит любые величины полей, определяемые свойствами ввода "top" или "bottom".
Другой подход, который я рассматриваю (хотя и закомментирован), - статически генерировать огромный список правил стилей - таким образом, избегая необходимости генерировать какие-либо вещи стиля динамического c внутри рендера ( ) функция, которая может быть анти-паттерном - если я правильно понимаю документы с освещенным элементом .
Может быть, мне не хватает более элегантного подхода? Я склоняюсь к нынешнему подходу, просто потому, что его легче понять - но любопытно, что думают другие!