{"mappings":"AACA,cAAc,uBAAuB,sBAAiC;AAGtE,SAAS,mBAAgC;AACzC,SAAS,cAAc;;;;;;AAUvB,cA8BM,mBAAmB,YAAY;;;;CAInC,AACA;;;;CAKA,AACA;;;;CAKA,AACA;;;;CAKA,AACA;;;;CAKA,AACA;;;;CAKA,AACA;CAEA,AACA;CAEA,UAAU;CAEV,UACU,IAAI;CACd,UAAU,SAAS;;;;CAKnB,IAAI;CAIJ,UAAU,UAAU,eAAe;CAenC;CAKA,UAAU;CAOV,UAAU,QAAQ,mBAAmB;CAMrC,MAAM;CAcN;CAIA;;AAKF,eAAe;AACf,SAAS","names":[],"sources":["../../../../src/web-components/typewriter/component.ts"],"sourcesContent":["import { attr, godown, htmlSlot, styles } from \"@godown/element\";\nimport { type PropertyValueMap, type TemplateResult, css, html } from \"lit\";\nimport { property, query, state } from \"lit/decorators.js\";\n\nimport { GlobalStyle, scopePrefix } from \"../../internal/global-style.js\";\nimport { Ranger } from \"sharekit\";\n\nconst protoName = \"typewriter\";\nconst cssScope = scopePrefix(protoName);\n\n/**\n * {@linkcode Typewriter} renders a typewriter effect to text.\n *\n * @category effect\n */\n@godown(protoName)\n@styles(css`\n  :host {\n    ${cssScope}--cursor-width: .05em;\n  }\n\n  :host,\n  :host([contents]) [part=\"root\"] {\n    display: inline-block;\n  }\n\n  i {\n    border-right: var(${cssScope}--cursor-width) solid;\n    margin-left: 0.02em;\n    animation: s 1.5s steps(1) infinite;\n  }\n\n  @keyframes s {\n    0% {\n      border-color: currentColor;\n    }\n    50% {\n      border-color: transparent;\n    }\n  }\n\n  slot {\n    display: none;\n  }\n`)\nclass Typewriter extends GlobalStyle {\n  /**\n   * Raw text.\n   */\n  @property()\n  content = \"\";\n\n  /**\n   * If true, hide the cursor\n   */\n  @property({ type: Boolean })\n  ended = false;\n\n  /**\n   * Maximum random time.\n   */\n  @property({ type: Number })\n  max = 100;\n\n  /**\n   * Minimum random time.\n   */\n  @property({ type: Number })\n  min = 50;\n\n  /**\n   * Fixed time.\n   */\n  @property({ type: Number })\n  delay = 0;\n\n  /**\n   * The index at the beginning.\n   */\n  @property({ type: Number })\n  index = 0;\n\n  @state()\n  contentInternal = \"\";\n\n  protected timeoutID: number;\n\n  @query(\"i\")\n  protected _i: HTMLElement;\n  protected _ranger: Ranger;\n\n  /**\n   * {@linkcode Typewriter.content} length.\n   */\n  get len(): number {\n    return this.content.length;\n  }\n\n  protected render(): TemplateResult<1> {\n    return html`\n      <div\n        part=\"root\"\n        ${attr(this.observedRecord)}\n      >\n        ${htmlSlot()} ${this.contentInternal}\n        <i\n          part=\"cursor\"\n          ?hidden=\"${this.ended}\"\n        ></i>\n      </div>\n    `;\n  }\n\n  connectedCallback(): void {\n    super.connectedCallback();\n    this._ranger = new Ranger(this.min, this.max);\n  }\n\n  protected firstUpdated(): void {\n    this.content ||= this._slot?.assignedNodes()[0]?.textContent.trim() || \"\";\n    if (!this.ended && this.len) {\n      this.write();\n    }\n  }\n\n  protected updated(changedProperties: PropertyValueMap<this>): void {\n    if (changedProperties.has(\"index\")) {\n      this.dispatchCustomEvent(this.index === this.len ? \"done\" : \"write\", this.contentInternal);\n    }\n  }\n\n  write(at: number = this.index): void {\n    this.contentInternal = this.content.slice(0, at + 1);\n    const timeout = this.delay || this._ranger.random();\n    this.timeoutID = this.timeouts.add(\n      setTimeout(() => {\n        const nx = at + 1;\n        if (nx <= this.len) {\n          this.index = nx;\n          this.write();\n        }\n      }, timeout),\n    );\n  }\n\n  stop(): void {\n    clearTimeout(this.timeoutID);\n  }\n\n  end(): void {\n    this.ended = true;\n  }\n}\n\nexport default Typewriter;\nexport { Typewriter };\n"],"version":3,"file":"component.d.ts"}