ThemeSwitch.svelte 5.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <script lang="ts">
  2. import { switchTheme, type ThemeProps } from 'stdf/theme';
  3. import themes from '../../data/themes/index.js';
  4. import { currentColorStore } from '../../store.js';
  5. type ThemeItem = { name: string; name_CN: string; theme: ThemeProps };
  6. // 横排还是竖排
  7. export let vertical = false;
  8. const isZh = localStorage.getItem('lang') === 'zh_CN';
  9. const selectColorFunc = (e: MouseEvent, item: ThemeItem) => {
  10. // 阻止冒泡
  11. e.stopPropagation();
  12. currentColorStore.set(item.name);
  13. localStorage.setItem('theme_color', item.name);
  14. const theme = item.theme;
  15. switchTheme(theme);
  16. // 修改 HTML 的 meta name="theme-color" 属性,适配 Safari 的 tab 背景色,需要设置 light 和 dark 两种颜色
  17. const safariLight = theme.color.primaryWhite;
  18. const safariDark = theme.color.darkBlack;
  19. // 查找 meta 标签,name="theme-color" 且 media="(prefers-color-scheme: light)"
  20. const lightMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: light)"]');
  21. // 查找 meta 标签,name="theme-color" 且 media="(prefers-color-scheme: dark)"
  22. const darkMeta = document.querySelector('meta[name="theme-color"][media="(prefers-color-scheme: dark)"]');
  23. // 如果找到了,就修改它的 content 属性
  24. if (lightMeta) {
  25. lightMeta.setAttribute('content', safariLight);
  26. }
  27. if (darkMeta) {
  28. darkMeta.setAttribute('content', safariDark);
  29. }
  30. };
  31. const bgFunc = (str: string) => {
  32. return str.charAt(0) === '#' ? str : `rgb(${str})`;
  33. };
  34. </script>
  35. <div class="flex {vertical ? 'flex-col' : 'flex-row'} my-4 flex-wrap gap-2">
  36. {#each themes as item}
  37. <button
  38. class="flex items-center justify-between gap-2 border p-2 {$currentColorStore === item.name
  39. ? 'border-primary dark:border-dark'
  40. : 'border-gray-100 dark:border-gray-700'} cursor-pointer rounded-md"
  41. on:click={(e) => selectColorFunc(e, item)}
  42. >
  43. <div class="h-5 w-5 {$currentColorStore === item.name ? 'fill-primary dark:fill-dark' : 'fill-gray-300 dark:fill-gray-700'}">
  44. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  45. <path
  46. d="M12 2C17.5222 2 22 5.97778 22 10.8889C22 13.9556 19.5111 16.4444 16.4444 16.4444H14.4778C13.5556 16.4444 12.8111 17.1889 12.8111 18.1111C12.8111 18.5333 12.9778 18.9222 13.2333 19.2111C13.5 19.5111 13.6667 19.9 13.6667 20.3333C13.6667 21.2556 12.9 22 12 22C6.47778 22 2 17.5222 2 12C2 6.47778 6.47778 2 12 2ZM7.5 12C8.32843 12 9 11.3284 9 10.5C9 9.67157 8.32843 9 7.5 9C6.67157 9 6 9.67157 6 10.5C6 11.3284 6.67157 12 7.5 12ZM16.5 12C17.3284 12 18 11.3284 18 10.5C18 9.67157 17.3284 9 16.5 9C15.6716 9 15 9.67157 15 10.5C15 11.3284 15.6716 12 16.5 12ZM12 9C12.8284 9 13.5 8.32843 13.5 7.5C13.5 6.67157 12.8284 6 12 6C11.1716 6 10.5 6.67157 10.5 7.5C10.5 8.32843 11.1716 9 12 9Z"
  47. >
  48. </path>
  49. </svg>
  50. </div>
  51. <div class="whitespace-nowrap">{isZh ? item.name_CN : item.name}</div>
  52. <div class="flex justify-between gap-2">
  53. <!-- theme -->
  54. <div class="flex overflow-hidden rounded-sm">
  55. <div class="bg-primary w-6" style="background-color: {bgFunc(item.theme.color.primary.default)};"></div>
  56. <div class="bg-dark w-6" style="background-color: {bgFunc(item.theme.color.dark.default)};"></div>
  57. </div>
  58. <div class="flex flex-col justify-between gap-1">
  59. <!-- Functional -->
  60. <div class="flex gap-0.5">
  61. <div class="h-3 w-3 rounded-sm" style="background-color: {bgFunc(item.theme.color.functional.success)};"></div>
  62. <div class="h-3 w-3 rounded-sm" style="background-color: {bgFunc(item.theme.color.functional.warning)};"></div>
  63. <div class="h-3 w-3 rounded-sm" style="background-color: {bgFunc(item.theme.color.functional.error)};"></div>
  64. <div class="h-3 w-3 rounded-sm" style="background-color: {bgFunc(item.theme.color.functional.info)};"></div>
  65. </div>
  66. <!-- Extended -->
  67. <div class="flex justify-between gap-0.5">
  68. {#each item.theme.color.extend as child}
  69. <div class="h-3 w-3 rounded-sm" style="background-color: {bgFunc(child.color)};"></div>
  70. {/each}
  71. </div>
  72. </div>
  73. </div>
  74. </button>
  75. {/each}
  76. {#if vertical}
  77. <a
  78. href="/guide/generator"
  79. target="_blank"
  80. class="text-primary hover:border-primary dark:text-dark dark:hover:border-dark group flex items-center justify-center gap-2 rounded border border-gray-100 py-2 transition-all duration-300 dark:border-gray-700"
  81. >
  82. <svg class="h-5 w-5 transition-all duration-300 group-hover:scale-95" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  83. <path
  84. class="fill-primary dark:fill-dark"
  85. d="M15.1986 9.94435C14.7649 9.53358 14.4859 8.98601 14.4085 8.39371L14.0056 5.31126L11.275 6.79711C10.7503 7.08262 10.1433 7.17876 9.55608 7.06936L6.49998 6.50003L7.06931 9.55612C7.17871 10.1434 7.08257 10.7503 6.79707 11.275L5.31121 14.0056L8.39367 14.4085C8.98596 14.4859 9.53353 14.7649 9.94431 15.1986L12.0821 17.4555L13.4178 14.6485C13.6745 14.1091 14.109 13.6745 14.6484 13.4179L17.4555 12.0821L15.1986 9.94435ZM15.2238 15.5078L13.0111 20.1579C12.8687 20.4572 12.5107 20.5843 12.2115 20.4419C12.1448 20.4102 12.0845 20.3664 12.0337 20.3127L8.49229 16.574C8.39749 16.4739 8.27113 16.4095 8.13445 16.3917L3.02816 15.7242C2.69958 15.6812 2.46804 15.3801 2.51099 15.0515C2.52056 14.9782 2.54359 14.9074 2.5789 14.8425L5.04031 10.3191C5.1062 10.198 5.12839 10.0579 5.10314 9.92241L4.16 4.85979C4.09931 4.53402 4.3142 4.22074 4.63997 4.16005C4.7126 4.14652 4.78711 4.14652 4.85974 4.16005L9.92237 5.10319C10.0579 5.12843 10.198 5.10625 10.319 5.04036L14.8424 2.57895C15.1335 2.42056 15.4979 2.52812 15.6562 2.81919C15.6916 2.88409 15.7146 2.95495 15.7241 3.02821L16.3916 8.13449C16.4095 8.27118 16.4739 8.39754 16.5739 8.49233L20.3127 12.0337C20.5533 12.2616 20.5636 12.6414 20.3357 12.8819C20.2849 12.9356 20.2246 12.9794 20.1579 13.0111L15.5078 15.2238C15.3833 15.2831 15.283 15.3833 15.2238 15.5078ZM16.0206 17.4349L17.4348 16.0207L21.6775 20.2633L20.2633 21.6775L16.0206 17.4349Z"
  86. >
  87. </path>
  88. </svg>
  89. {isZh ? '创建新主题' : 'Create new theme'}
  90. </a>
  91. {/if}
  92. </div>