From a34f31751f7990bfdb9b141929b4b0c30a32502b Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Wed, 11 Oct 2023 10:28:05 -0400 Subject: [PATCH] Move `spread` directive to framework library --- framework/src/index.ts | 1 + framework/src/lib/directives/spread.ts | 44 +++++++++++++++++++++++++ studio-frontend/src/app/icon.element.ts | 18 ++-------- 3 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 framework/src/lib/directives/spread.ts diff --git a/framework/src/index.ts b/framework/src/index.ts index 0eb37f9..49b1fa1 100644 --- a/framework/src/index.ts +++ b/framework/src/index.ts @@ -1 +1,2 @@ export * from "./lib/decorators/on"; +export { default as spread } from "./lib/directives/spread"; diff --git a/framework/src/lib/directives/spread.ts b/framework/src/lib/directives/spread.ts new file mode 100644 index 0000000..4802a68 --- /dev/null +++ b/framework/src/lib/directives/spread.ts @@ -0,0 +1,44 @@ +import { ElementPart, nothing } from "lit"; +import { directive, Directive } from "lit/directive.js"; + +interface Stringable { + toString(): string; +} + +/** + * A simple implementation of React's spread operator (`...`) for Lit. Assigns + * each `{ [key]: value }` entry in the provided object as an HTML attribute to + * the element it's invoked on. + * + * React: + * @example + * ```jsx + * export default (props) =>
+ * ``` + * + * Lit: + * @example + * ```typescript + * export class FooElement extends LitElement { + * props: Record = {}; + * override render = () => html`
` + * } + * ``` + * + * @note + * The object entries are assigned as HTML _attributes_, not _properties_, so + * each enumerable value in the provided object must have a meaningnful + * `toString()` implementation. + */ +export default directive(class Spread extends Directive { + override render(_: Record) { + return nothing; + } + + override update(part: ElementPart, [attrs]: [Record]) { + for (let [key, value] of Object.entries(attrs)) { + part.element.setAttribute(key, value.toString()); + } + return part; + } +}); diff --git a/studio-frontend/src/app/icon.element.ts b/studio-frontend/src/app/icon.element.ts index 5ed1409..5099b4c 100644 --- a/studio-frontend/src/app/icon.element.ts +++ b/studio-frontend/src/app/icon.element.ts @@ -1,7 +1,7 @@ +import { spread } from "@storyteller/framework"; import { match } from "@storyteller/utility"; -import { ElementPart, LitElement, TemplateResult, html, nothing, unsafeCSS } from "lit"; +import { LitElement, TemplateResult, html, nothing, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { Directive, directive } from "lit/directive.js"; import { unsafeSVG } from "lit/directives/unsafe-svg.js"; import fasCircleInfo from "@fortawesome/fontawesome-pro/svgs/solid/circle-info.svg?raw"; @@ -59,17 +59,3 @@ function renderSvg(iconId: string) { `; } - -// TODO: Definitely move this -const spread = directive(class extends Directive { - override render(_: Record) { - return nothing; - } - - override update(part: ElementPart, [attrs]: [Record]) { - for (let [key, value] of Object.entries(attrs)) { - part.element.setAttribute(key, value); - } - return part; - } -});