import { attr, godown, htmlSlot, styles } from "@godown/element"; import { type PropertyValueMap, type TemplateResult, css, html } from "lit"; import { property, query, state } from "lit/decorators.js"; import { GlobalStyle, scopePrefix } from "../../internal/global-style.js"; import { Ranger } from "sharekit"; const protoName = "typewriter"; const cssScope = scopePrefix(protoName); /** * {@linkcode Typewriter} renders a typewriter effect to text. * * @category effect */ @godown(protoName) @styles(css` :host { ${cssScope}--cursor-width: .05em; } :host, :host([contents]) [part="root"] { display: inline-block; } i { border-right: var(${cssScope}--cursor-width) solid; margin-left: 0.02em; animation: s 1.5s steps(1) infinite; } @keyframes s { 0% { border-color: currentColor; } 50% { border-color: transparent; } } slot { display: none; } `) class Typewriter extends GlobalStyle { /** * Raw text. */ @property() content = ""; /** * If true, hide the cursor */ @property({ type: Boolean }) ended = false; /** * Maximum random time. */ @property({ type: Number }) max = 100; /** * Minimum random time. */ @property({ type: Number }) min = 50; /** * Fixed time. */ @property({ type: Number }) delay = 0; /** * The index at the beginning. */ @property({ type: Number }) index = 0; @state() contentInternal = ""; protected timeoutID: number; @query("i") protected _i: HTMLElement; protected _ranger: Ranger; /** * {@linkcode Typewriter.content} length. */ get len(): number { return this.content.length; } protected render(): TemplateResult<1> { return html`