ThemeSwitch.tsx 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // src/components/ThemeSwitch.tsx
  2. import { Dropdown, type MenuProps } from "antd";
  3. import {
  4. DesktopOutlined,
  5. SunOutlined,
  6. MoonOutlined,
  7. CheckOutlined,
  8. } from "@ant-design/icons";
  9. import { useAppSelector } from "../../hooks";
  10. import {
  11. mode as _mode,
  12. themeChange,
  13. type TThemeMode,
  14. } from "../../reducers/theme";
  15. import store from "../../store";
  16. const icons = {
  17. system: <DesktopOutlined />,
  18. light: <SunOutlined />,
  19. dark: <MoonOutlined />,
  20. };
  21. const labels = {
  22. system: "跟随系统",
  23. light: "亮色主题",
  24. dark: "暗色主题",
  25. };
  26. const ThemeSwitch = () => {
  27. const themeMode = useAppSelector(_mode);
  28. const items: MenuProps["items"] = (
  29. ["system", "light", "dark"] as TThemeMode[]
  30. ).map((key) => ({
  31. key,
  32. icon: icons[key],
  33. label: labels[key],
  34. itemIcon: themeMode === key ? <CheckOutlined /> : null,
  35. }));
  36. return (
  37. <Dropdown
  38. menu={{
  39. items,
  40. onClick: ({ key }) => store.dispatch(themeChange(key as TThemeMode)),
  41. }}
  42. trigger={["click"]}
  43. >
  44. <span style={{ cursor: "pointer", fontSize: 18 }}>
  45. {icons[themeMode]}
  46. </span>
  47. </Dropdown>
  48. );
  49. };
  50. export default ThemeSwitch;