@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
271 lines (270 loc) • 8.03 kB
JavaScript
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