UNPKG

vuepress-theme-hope

Version:

A light vuepress theme with tons of features

162 lines 7.25 kB
import { hasGlobalComponent, isString } from "@vuepress/helper/client"; import { watchImmediate } from "@vueuse/core"; import { computed, defineComponent, h, nextTick, onMounted, ref, resolveComponent, } from "vue"; import { useFrontmatter, withBase } from "vuepress/client"; import DropTransition from "@theme-hope/components/transitions/DropTransition"; import { useAuthorInfo } from "@theme-hope/composables/useAuthorInfo"; import "../../styles/home/portfolio-hero.scss"; export default defineComponent({ name: "PortfolioHero", slots: Object, setup(_props, { slots }) { const authorInfo = useAuthorInfo(); const frontmatter = useFrontmatter(); const index = ref(0); const currentTitle = computed(() => frontmatter.value.titles?.[index.value] ?? ""); const title = ref(""); const avatar = computed(() => { const { name, avatar, avatarDark, avatarAlt, avatarStyle } = frontmatter.value; return { name: name ?? authorInfo.value.name, avatar: avatar ? withBase(avatar) : null, avatarDark: avatarDark ? withBase(avatarDark) : null, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing alt: (avatarAlt || name) ?? "", style: avatarStyle ?? null, }; }); const bg = computed(() => { const { bgImage, bgImageDark, bgImageStyle } = frontmatter.value; return { image: isString(bgImage) ? withBase(bgImage) : null, imageDark: isString(bgImageDark) ? withBase(bgImageDark) : null, style: bgImageStyle ?? null, }; }); const info = computed(() => { const { welcome, name, titles = [], medias } = frontmatter.value; return { name: name ?? authorInfo.value.name, welcome: welcome ?? "👋 Hi There, I'm", title: title.value, titles: titles, medias: medias ?? null, }; }); const startTyping = () => { title.value = ""; let charIndex = 0; let shouldStop = false; const typeNext = async () => { if (!shouldStop) { title.value += currentTitle.value[charIndex]; charIndex += 1; await nextTick(); if (charIndex < currentTitle.value.length) { setTimeout(() => { void typeNext(); }, 150); } else { const length = info.value.titles.length; setTimeout(() => { index.value = length <= 1 || index.value === info.value.titles.length - 1 ? 0 : index.value + 1; }, 1000); } } }; void typeNext(); return () => { shouldStop = true; }; }; let stop; onMounted(() => { watchImmediate(currentTitle, () => { stop?.(); stop = startTyping(); }); }); return () => h("section", { id: "portfolio", class: ["vp-portfolio", { bg: bg.value.image }], }, [ slots.portfolioBg?.(bg.value) ?? [ bg.value.image ? h("div", { class: ["vp-portfolio-mask", { light: bg.value.imageDark }], style: [ { background: `url(${bg.value.image}) center/cover no-repeat`, }, bg.value.style, ], }) : null, bg.value.imageDark ? h("div", { class: "vp-portfolio-mask dark", style: [ { background: `url(${bg.value.imageDark}) center/cover no-repeat`, }, bg.value.style, ], }) : null, ], slots.portfolioAvatar?.(avatar.value) ?? h("div", { class: "vp-portfolio-avatar" }, [ h(DropTransition, { delay: 0.04 }, () => { const { avatar: avatarLight, avatarDark, name: title, alt, style, } = avatar.value; return [ avatarLight ? h("img", { key: "light", class: { light: avatarDark }, src: avatarLight, title, alt, style, }) : null, avatarDark ? h("img", { key: "dark", class: "dark", src: avatarDark, title, alt, style, }) : null, ]; }), ]), h("div", { class: "vp-portfolio-container" }, slots.portfolioInfo?.(info.value) ?? h("div", { class: "vp-portfolio-info" }, [ h(DropTransition, { appear: true, delay: 0.08 }, () => h("h6", { class: "vp-portfolio-welcome" }, info.value.welcome)), h(DropTransition, { appear: true, delay: 0.12 }, () => h("h1", { class: "vp-portfolio-name", id: "main-title" }, info.value.name)), h(DropTransition, { appear: true, delay: 0.16 }, () => h("h2", { class: "vp-portfolio-title" }, title.value)), h(DropTransition, { appear: true, delay: 0.2 }, () => info.value.medias ? h("div", { class: "vp-portfolio-medias" }, info.value.medias.map(({ name, url, icon }) => h("a", { class: "vp-portfolio-media", href: url, rel: "noopener noreferrer", target: "_blank", title: name, }, h(resolveComponent("VPIcon"), { icon, sizing: "both", })))) : hasGlobalComponent("SocialMedias") ? h(resolveComponent("SocialMedias")) : null), ])), ]); }, }); //# sourceMappingURL=PortfolioHero.js.map