CustomizeThemeOptions.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import React, { type JSX, useMemo } from 'react';
  2. import { type GrowiThemeMetadata, GrowiThemeSchemeType } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import { ThemeColorBox } from './ThemeColorBox';
  5. type Props = {
  6. availableThemes: GrowiThemeMetadata[];
  7. selectedTheme?: string;
  8. onSelected?: (themeName: string) => void;
  9. };
  10. const CustomizeThemeOptions = (props: Props): JSX.Element => {
  11. const { t } = useTranslation('admin');
  12. const { availableThemes, selectedTheme, onSelected } = props;
  13. const lightNDarkThemes = useMemo(() => {
  14. return availableThemes.filter(
  15. (s) => s.schemeType === GrowiThemeSchemeType.BOTH,
  16. );
  17. }, [availableThemes]);
  18. const oneModeThemes = useMemo(() => {
  19. return availableThemes.filter(
  20. (s) => s.schemeType !== GrowiThemeSchemeType.BOTH,
  21. );
  22. }, [availableThemes]);
  23. return (
  24. <>
  25. {/* Light and Dark Themes */}
  26. <div>
  27. <h3 className="mb-3">
  28. {t('customize_settings.theme_desc.light_and_dark')}
  29. </h3>
  30. <div className="hstack gap-3 flex-wrap">
  31. {lightNDarkThemes.map((theme) => {
  32. return (
  33. <ThemeColorBox
  34. key={theme.name}
  35. isSelected={
  36. selectedTheme != null && selectedTheme === theme.name
  37. }
  38. metadata={theme}
  39. onSelected={() => onSelected?.(theme.name)}
  40. />
  41. );
  42. })}
  43. </div>
  44. </div>
  45. {/* Only one mode Theme */}
  46. <div className="mt-3">
  47. <h3 className="mb-3">{t('customize_settings.theme_desc.unique')}</h3>
  48. <div className="hstack gap-3 align-items-start flex-wrap">
  49. {oneModeThemes.map((theme) => {
  50. return (
  51. <ThemeColorBox
  52. key={theme.name}
  53. isSelected={
  54. selectedTheme != null && selectedTheme === theme.name
  55. }
  56. metadata={theme}
  57. onSelected={() => onSelected?.(theme.name)}
  58. />
  59. );
  60. })}
  61. </div>
  62. </div>
  63. </>
  64. );
  65. };
  66. export default CustomizeThemeOptions;