UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

271 lines (270 loc) 8.03 kB
import { t as e } from "../../_plugin-vue_export-helper-BTgDAbhb.js"; import { MOTION_TEXT_ANIMATION_MODES as t, MOTION_TEXT_SPEEDS as n, MOTION_TEXT_TIMING_PRESETS as r } from "./motion-text-constants.js"; import { Fragment as i, Transition as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createTextVNode as l, normalizeClass as u, normalizeStyle as d, openBlock as f, renderList as p, renderSlot as m, toDisplayString as h, withCtx as g } from "vue"; //#region components/motion_text/motion_text.vue var _ = { compatConfig: { MODE: 3 }, name: "DtMotionText", inheritAttrs: !1, props: { text: { type: String, default: "" }, animationMode: { type: String, default: "gradient-in", validator: (e) => t.includes(e) }, speed: { type: String, default: "md", validator: (e) => n.includes(e) }, autoStart: { type: Boolean, default: !0 }, loop: { type: Boolean, default: !1 }, respectsReducedMotion: { type: Boolean, default: !0 }, screenReaderText: { type: String, default: "" } }, emits: [ "start", "complete", "progress", "pause", "resume" ], data() { return { words: [], visibleWordCount: 0, visibleCharsPerWord: [], isAnimating: !1, isPaused: !1, isLooped: !1, animationTimeouts: [], prefersReducedMotion: !1, animationKey: 0 }; }, computed: { timing() { return r[this.speed]; }, componentStyles() { return { "--d-motion-text-duration": `${this.timing.duration}ms`, "--d-motion-text-char-duration": `${this.timing.duration}ms`, "--d-motion-text-word-duration": `${this.timing.duration * 2}ms` }; }, isStaticAnimationMode() { return this.animationMode === "gradient-sweep" || this.animationMode === "shimmer"; }, motionTextClasses() { return [ "d-motion-text", `d-motion-text--${this.animationMode}`, { "d-motion-text--animating": this.isAnimating, "d-motion-text--paused": this.isPaused, "d-motion-text--looped": this.isLooped }, this.$attrs.class ]; } }, watch: { text() { this.reset(), this.initializeContent(); }, loop: { handler(e) { this.isLooped = e; }, immediate: !0 } }, mounted() { this.checkReducedMotion(), this.initializeContent(); }, beforeUnmount() { this.clearTimeouts(); }, methods: { processTextToChars(e) { let t = [], n = (e, r = 0) => { if (e.nodeType === Node.TEXT_NODE) { let n = e.textContent?.match(/\S+\s*/g) || []; return t.push(...n.map((e, t) => ({ text: e, chars: e.split(""), index: r + t }))), r + n.length; } else if (e.nodeType === Node.ELEMENT_NODE) { let t = r; return Array.from(e.childNodes).forEach((e) => { t = n(e, t); }), t; } return r; }; return n(e), t; }, processDirectText(e) { return e ? (e.match(/\S+\s*/g) || []).map((e, t) => ({ text: e, chars: e.split(""), index: t })) : []; }, checkReducedMotion() { typeof window < "u" && window.matchMedia && (this.prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches); }, clearTimeouts() { this.animationTimeouts.forEach((e) => clearTimeout(e)), this.animationTimeouts = []; }, start() { if (!this.isAnimating) { if (this.isAnimating = !0, this.isPaused = !1, this.$emit("start"), this.respectsReducedMotion && this.prefersReducedMotion) { this.showAllContent(); return; } if (this.animationMode === "none") { this.showAllContent(); return; } this.isStaticAnimationMode || this.showNextWord(); } }, pause() { !this.isAnimating || this.isPaused || (this.isPaused = !0, this.clearTimeouts(), this.$emit("pause")); }, resume() { this.isPaused && (this.isPaused = !1, this.$emit("resume"), this.showNextWord()); }, reset() { this.clearTimeouts(), this.isAnimating = !1, this.isPaused = !1, this.visibleWordCount = 0, this.visibleCharsPerWord = Array(this.words.length).fill(0), this.animationKey++; }, skipToEnd() { this.showAllContent(); }, showAllContent() { this.visibleWordCount = this.words.length, this.visibleCharsPerWord = this.words.map((e) => e.chars.length), setTimeout(() => { this.isAnimating = !1, this.$emit("complete"); }, 0); }, showNextWord() { if (this.isPaused || this.visibleWordCount >= this.words.length) { this.visibleWordCount >= this.words.length && this.completeAnimation(); return; } let e = setTimeout(() => { this.visibleWordCount++, this.$emit("progress", { wordsComplete: this.visibleWordCount, totalWords: this.words.length, progress: this.visibleWordCount / this.words.length }), this.animateCharsForWord(this.visibleWordCount - 1); }, this.timing.wordDelay); this.animationTimeouts.push(e); }, animateCharsForWord(e) { if (this.isPaused || e >= this.words.length) return; this.visibleCharsPerWord[e] = 0; let t = this.words[e].chars.length, n = () => { if (this.isPaused || this.visibleCharsPerWord[e] >= t) { this.visibleCharsPerWord[e] >= t && this.showNextWord(); return; } this.visibleCharsPerWord[e]++; let r = setTimeout(n, this.timing.characterDelay); this.animationTimeouts.push(r); }; n(); }, completeAnimation() { if (this.isAnimating = !1, this.clearTimeouts(), this.$emit("complete"), this.loop) { let e = setTimeout(() => { this.reset(), this.$nextTick(() => { this.start(); }); }, 500); this.animationTimeouts.push(e); } }, initializeContent() { if (this.isStaticAnimationMode) { this.autoStart && this.$nextTick(() => this.start()); return; } this.text ? this.words = this.processDirectText(this.text) : this.$refs.contentRef && (this.words = this.processTextToChars(this.$refs.contentRef)), this.visibleCharsPerWord = Array(this.words.length).fill(0), this.visibleWordCount = 0, this.autoStart && this.words.length > 0 && this.$nextTick(() => this.start()); } } }, v = [ "data-text-content", "aria-live", "aria-label" ], y = { key: 0, class: "d-motion-text__sr-only" }, b = ["aria-hidden"], x = ["data-text-content"], S = { key: 3, class: "d-motion-text__fallback" }; function C(e, t, n, r, _, C) { return f(), c("span", { ref: "contentRef", class: u(C.motionTextClasses), style: d(C.componentStyles), "data-text-content": C.isStaticAnimationMode ? n.text : void 0, "aria-live": _.isAnimating ? "polite" : "off", "aria-label": n.screenReaderText || void 0 }, [ n.screenReaderText ? (f(), c("span", y, h(n.screenReaderText), 1)) : s("", !0), C.isStaticAnimationMode ? (f(), c(i, { key: 1 }, [l(h(n.text) + " ", 1), n.text ? s("", !0) : m(e.$slots, "default", { key: 0 })], 64)) : (f(), c("span", { key: _.animationKey, class: "d-motion-text__content", "aria-hidden": _.isAnimating }, [(f(!0), c(i, null, p(_.words, (e, t) => (f(), o(a, { key: `${_.animationKey}-${t}`, name: `d-motion-text-word-${n.animationMode}` }, { default: g(() => [t < _.visibleWordCount ? (f(), c("span", { key: 0, class: "d-motion-text__word", "data-text-content": e.text, style: d({ "--word-index": t }) }, [(f(!0), c(i, null, p(e.chars, (e, r) => (f(), o(a, { key: `${_.animationKey}-${t}-${r}`, name: `d-motion-text-char-${n.animationMode}` }, { default: g(() => [r < _.visibleCharsPerWord[t] ? (f(), c("span", { key: 0, class: "d-motion-text__char", style: d({ "--char-index": r, "--char-delay": `${r * C.timing.characterDelay}ms` }) }, h(e), 5)) : s("", !0)]), _: 2 }, 1032, ["name"]))), 128))], 12, x)) : s("", !0)]), _: 2 }, 1032, ["name"]))), 128))], 8, b)), !_.words.length && !n.text && !C.isStaticAnimationMode ? (f(), c("span", S, [m(e.$slots, "default")])) : s("", !0) ], 14, v); } var w = /* @__PURE__ */ e(_, [["render", C]]); //#endregion export { w as default }; //# sourceMappingURL=motion-text.js.map