vuepress-theme-hope
Version:
A light vuepress theme with tons of features
83 lines • 3.31 kB
JavaScript
import { defineComponent, h, nextTick } from "vue";
import { usePure } from "@theme-hope/composables/index";
import { AutoIcon, DarkIcon, LightIcon, } from "@theme-hope/modules/outlook/components/icons/index";
import { useDarkMode } from "@theme-hope/modules/outlook/composables/index";
import "../styles/color-mode-switch.scss";
export default defineComponent({
name: "ColorModeSwitch",
setup() {
const { config, isDarkMode, status } = useDarkMode();
const isPure = usePure();
const updateDarkmodeStatus = () => {
if (config.value === "switch")
status.value = {
light: "dark",
dark: "auto",
auto: "light",
}[status.value];
else
status.value = status.value === "light" ? "dark" : "light";
};
const toggleDarkmode = async (event) => {
const useViewTransition =
// @ts-expect-error: Providing backward compatibility
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
document.startViewTransition &&
!window.matchMedia("(prefers-reduced-motion: reduce)").matches &&
!isPure.value;
if (!useViewTransition) {
updateDarkmodeStatus();
return;
}
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
const oldStatus = isDarkMode.value;
const transition = document.startViewTransition(async () => {
updateDarkmodeStatus();
await nextTick();
});
await transition.ready;
if (isDarkMode.value !== oldStatus)
document.documentElement.animate({
clipPath: isDarkMode.value
? [
`circle(${endRadius}px at ${x}px ${y}px)`,
`circle(0px at ${x}px ${y}px)`,
]
: [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
],
}, {
duration: 400,
pseudoElement: isDarkMode.value
? "::view-transition-old(root)"
: "::view-transition-new(root)",
});
};
return () => h("button", {
type: "button",
class: "vp-color-mode-switch",
id: "color-mode-switch",
onClick: toggleDarkmode,
}, [
h(AutoIcon, {
style: {
display: status.value === "auto" ? "block" : "none",
},
}),
h(DarkIcon, {
style: {
display: status.value === "dark" ? "block" : "none",
},
}),
h(LightIcon, {
style: {
display: status.value === "light" ? "block" : "none",
},
}),
]);
},
});
//# sourceMappingURL=ColorModeSwitch.js.map