ruoyi-plus-vben5/packages/effects/layouts/src/widgets/theme-toggle/theme-button.vue

186 lines
4.1 KiB
Vue
Raw Normal View History

2024-05-19 21:20:42 +08:00
<script lang="ts" setup>
2024-06-08 19:49:06 +08:00
import { computed, nextTick } from 'vue';
2024-05-19 21:20:42 +08:00
import { VbenButton } from '@vben-core/shadcn-ui';
interface Props {
/**
* 类型
*/
type?: 'icon' | 'normal';
}
defineOptions({
name: 'ThemeToggleButton',
});
const props = withDefaults(defineProps<Props>(), {
type: 'normal',
});
const isDark = defineModel<boolean>();
const theme = computed(() => {
return isDark.value ? 'light' : 'dark';
});
const bindProps = computed(() => {
const type = props.type;
return type === 'normal'
? {
variant: 'heavy' as const,
2024-05-19 21:20:42 +08:00
}
: {
class: 'rounded-full',
size: 'icon' as const,
style: { padding: '7px' },
variant: 'icon' as const,
2024-05-19 21:20:42 +08:00
};
});
function toggleTheme(event: MouseEvent) {
const isAppearanceTransition =
// @ts-expect-error
document.startViewTransition &&
!window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!isAppearanceTransition || !event) {
isDark.value = !isDark.value;
return;
}
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y),
);
chore(deps): bump the non-breaking-changes group with 14 updates (#4347) * chore(deps): bump the non-breaking-changes group with 14 updates Bumps the non-breaking-changes group with 14 updates: | Package | From | To | | --- | --- | --- | | [typescript](https://github.com/microsoft/TypeScript) | `5.5.4` | `5.6.2` | | [@iconify/json](https://github.com/iconify/icon-sets) | `2.2.245` | `2.2.246` | | [postcss-preset-env](https://github.com/csstools/postcss-plugins/tree/HEAD/plugin-packs/postcss-preset-env) | `10.0.2` | `10.0.3` | | [@jspm/generator](https://github.com/jspm/generator) | `2.2.0` | `2.3.0` | | [vite-plugin-dts](https://github.com/qmhc/vite-plugin-dts) | `4.1.1` | `4.2.1` | | [eslint-plugin-command](https://github.com/antfu/eslint-plugin-command) | `0.2.3` | `0.2.4` | | [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.9.1` | `9.10.0` | | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.4.0` | `8.5.0` | | [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.4.0` | `8.5.0` | | [eslint](https://github.com/eslint/eslint) | `9.9.1` | `9.10.0` | | [eslint-plugin-perfectionist](https://github.com/azat-io/eslint-plugin-perfectionist) | `3.4.0` | `3.5.0` | | [watermark-js-plus](https://github.com/zhensherlock/watermark-js-plus) | `1.5.5` | `1.5.6` | | [circular-dependency-scanner](https://github.com/emosheeep/circular-dependency-scanner) | `2.2.2` | `2.3.0` | | [@tanstack/vue-query](https://github.com/TanStack/query/tree/HEAD/packages/vue-query) | `5.54.2` | `5.55.4` | Updates `typescript` from 5.5.4 to 5.6.2 - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.5.4...v5.6.2) Updates `@iconify/json` from 2.2.245 to 2.2.246 - [Commits](https://github.com/iconify/icon-sets/compare/2.2.245...2.2.246) Updates `postcss-preset-env` from 10.0.2 to 10.0.3 - [Changelog](https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/CHANGELOG.md) - [Commits](https://github.com/csstools/postcss-plugins/commits/HEAD/plugin-packs/postcss-preset-env) Updates `@jspm/generator` from 2.2.0 to 2.3.0 - [Release notes](https://github.com/jspm/generator/releases) - [Commits](https://github.com/jspm/generator/compare/2.2.0...2.3.0) Updates `vite-plugin-dts` from 4.1.1 to 4.2.1 - [Release notes](https://github.com/qmhc/vite-plugin-dts/releases) - [Changelog](https://github.com/qmhc/vite-plugin-dts/blob/main/CHANGELOG.md) - [Commits](https://github.com/qmhc/vite-plugin-dts/compare/v4.1.1...v4.2.1) Updates `eslint-plugin-command` from 0.2.3 to 0.2.4 - [Release notes](https://github.com/antfu/eslint-plugin-command/releases) - [Commits](https://github.com/antfu/eslint-plugin-command/compare/v0.2.3...v0.2.4) Updates `@eslint/js` from 9.9.1 to 9.10.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/commits/v9.10.0/packages/js) Updates `@typescript-eslint/eslint-plugin` from 8.4.0 to 8.5.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.5.0/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.4.0 to 8.5.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.5.0/packages/parser) Updates `eslint` from 9.9.1 to 9.10.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.9.1...v9.10.0) Updates `eslint-plugin-perfectionist` from 3.4.0 to 3.5.0 - [Release notes](https://github.com/azat-io/eslint-plugin-perfectionist/releases) - [Changelog](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/changelog.md) - [Commits](https://github.com/azat-io/eslint-plugin-perfectionist/compare/v3.4.0...v3.5.0) Updates `watermark-js-plus` from 1.5.5 to 1.5.6 - [Release notes](https://github.com/zhensherlock/watermark-js-plus/releases) - [Changelog](https://github.com/zhensherlock/watermark-js-plus/blob/main/CHANGELOG.md) - [Commits](https://github.com/zhensherlock/watermark-js-plus/compare/v1.5.5...v1.5.6) Updates `circular-dependency-scanner` from 2.2.2 to 2.3.0 - [Release notes](https://github.com/emosheeep/circular-dependency-scanner/releases) - [Changelog](https://github.com/emosheeep/circular-dependency-scanner/blob/master/CHANGELOG.md) - [Commits](https://github.com/emosheeep/circular-dependency-scanner/compare/v2.2.2...v2.3.0) Updates `@tanstack/vue-query` from 5.54.2 to 5.55.4 - [Release notes](https://github.com/TanStack/query/releases) - [Commits](https://github.com/TanStack/query/commits/v5.55.4/packages/vue-query) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: "@iconify/json" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: non-breaking-changes - dependency-name: postcss-preset-env dependency-type: direct:production update-type: version-update:semver-patch dependency-group: non-breaking-changes - dependency-name: "@jspm/generator" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: vite-plugin-dts dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: eslint-plugin-command dependency-type: direct:production update-type: version-update:semver-patch dependency-group: non-breaking-changes - dependency-name: "@eslint/js" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: eslint-plugin-perfectionist dependency-type: direct:development update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: watermark-js-plus dependency-type: direct:production update-type: version-update:semver-patch dependency-group: non-breaking-changes - dependency-name: circular-dependency-scanner dependency-type: direct:production update-type: version-update:semver-minor dependency-group: non-breaking-changes - dependency-name: "@tanstack/vue-query" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: non-breaking-changes ... Signed-off-by: dependabot[bot] <support@github.com> * chore: update deps * chore: typo --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-10 22:05:11 +08:00
// @ts-ignore startViewTransition
2024-05-19 21:20:42 +08:00
const transition = document.startViewTransition(async () => {
isDark.value = !isDark.value;
await nextTick();
});
transition.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
];
document.documentElement.animate(
{
clipPath: isDark.value ? [...clipPath].reverse() : clipPath,
},
{
duration: 450,
easing: 'ease-in',
pseudoElement: isDark.value
? '::view-transition-old(root)'
: '::view-transition-new(root)',
},
);
});
}
</script>
<template>
<VbenButton
:aria-label="theme"
:class="[`is-${theme}`]"
2024-05-19 21:20:42 +08:00
aria-live="polite"
class="theme-toggle cursor-pointer border-none bg-none"
2024-05-19 21:20:42 +08:00
v-bind="bindProps"
@click.stop="toggleTheme"
>
<svg aria-hidden="true" height="24" viewBox="0 0 24 24" width="24">
<mask
id="theme-toggle-moon"
class="theme-toggle__moon"
2024-06-23 14:21:27 +08:00
fill="hsl(var(--foreground)/80%)"
2024-05-19 21:20:42 +08:00
stroke="none"
>
<rect fill="white" height="100%" width="100%" x="0" y="0" />
<circle cx="40" cy="8" fill="black" r="11" />
</mask>
<circle
id="sun"
class="theme-toggle__sun"
2024-05-19 21:20:42 +08:00
cx="12"
cy="12"
mask="url(#theme-toggle-moon)"
r="11"
/>
<g class="theme-toggle__sun-beams">
2024-05-19 21:20:42 +08:00
<line x1="12" x2="12" y1="1" y2="3" />
<line x1="12" x2="12" y1="21" y2="23" />
<line x1="4.22" x2="5.64" y1="4.22" y2="5.64" />
<line x1="18.36" x2="19.78" y1="18.36" y2="19.78" />
<line x1="1" x2="3" y1="12" y2="12" />
<line x1="21" x2="23" y1="12" y2="12" />
<line x1="4.22" x2="5.64" y1="19.78" y2="18.36" />
<line x1="18.36" x2="19.78" y1="5.64" y2="4.22" />
</g>
</svg>
</VbenButton>
</template>
<style scoped>
.theme-toggle {
&__moon {
2024-05-19 21:20:42 +08:00
& > circle {
transition: transform 0.5s cubic-bezier(0, 0, 0.3, 1);
}
}
&__sun {
@apply fill-foreground/90 stroke-none;
2024-05-19 21:20:42 +08:00
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
transform-origin: center center;
&:hover > svg > & {
@apply fill-foreground/90;
2024-05-19 21:20:42 +08:00
}
}
&__sun-beams {
@apply stroke-foreground/90 stroke-[2px];
2024-05-19 21:20:42 +08:00
transition:
transform 1.6s cubic-bezier(0.5, 1.5, 0.75, 1.25),
opacity 0.6s cubic-bezier(0.25, 0, 0.3, 1);
transform-origin: center center;
&:hover > svg > & {
@apply stroke-foreground;
2024-05-19 21:20:42 +08:00
}
}
&.is-light {
.theme-toggle__sun {
@apply scale-50;
}
2024-05-19 21:20:42 +08:00
.theme-toggle__sun-beams {
transform: rotateZ(0.25turn);
2024-05-19 21:20:42 +08:00
}
}
&.is-dark {
.theme-toggle__moon {
& > circle {
transform: translateX(-20px);
2024-05-19 21:20:42 +08:00
}
}
2024-05-19 21:20:42 +08:00
.theme-toggle__sun-beams {
@apply opacity-0;
2024-05-19 21:20:42 +08:00
}
}
&:hover > svg {
.theme-toggle__sun,
.theme-toggle__moon {
@apply fill-foreground;
2024-05-19 21:20:42 +08:00
}
}
}
</style>